diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..165b1f687 --- /dev/null +++ b/.clang-format @@ -0,0 +1,64 @@ +--- +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: true +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: false +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IndentCaseLabels: true +IndentFunctionDeclarationAfterType: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +Language: Cpp +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Always +... diff --git a/.git-pre-commit b/.git-pre-commit new file mode 100755 index 000000000..69a71bea9 --- /dev/null +++ b/.git-pre-commit @@ -0,0 +1,51 @@ +#!/bin/bash + +# This hook purpose is to keep coding style consistent between all developers +# It is automatically installed in .git/hooks folder by cmake on first run. + +# From https://github.com/tatsuhiro-t/nghttp2/blob/master/pre-commit + +function invalid-format-detected { + cat git-clang-format.diff + echo "*****************" + echo "$0: Invalid coding style detected (see git-clang-format.diff for issues). Please correct it using one of the following:" + echo "1) Apply patch located at git-clang-format.diff using:" + echo " cd $(git rev-parse --show-toplevel) && $1" + echo "2) Use clang-format to correctly format source code using:" + echo " $2" + echo "3) Reformat these lines manually." + echo "*** Aborting commit.***" + exit 1 +} +function git-clang-format-diffing { + format_diff=$(which git-clang-format) + format_diff_options="--style=file" + + #only diffing commited files, ignored staged one + $format_diff $format_diff_options --diff $(git --no-pager diff --cached --name-status | grep -v '^D' | cut -f2) > git-clang-format.diff + + if ! grep -q -E '(no modified files to format|clang-format did not modify any files)' git-clang-format.diff; then + invalid-format-detected "git apply git-clang-format.diff" "clang-format $format_diff_options -i " + fi +} + +function clang-format-diff-diffing { + format_diff=$(find /usr/bin/ -name 'clang-format-diff*' -type f | tail -n1) + format_diff_options="-style file" + + git diff-index --cached --diff-filter=ACMR -p HEAD -- | $format_diff $format_diff_options -p1 > git-clang-format.diff + if [ -s git-clang-format.diff ]; then + invalid-format-detected "patch -p0 < git-clang-format.diff" "${format_diff/-diff/} $format_diff_options -i " + fi +} + +set -e +if which git-clang-format &>/dev/null; then + git-clang-format-diffing $@ +elif [ ! -z "$(find /usr/bin/ /usr/local/bin/ /opt/bin/ -name 'clang-format-diff*' -type f 2>/dev/null)" ]; then + # Warning! We need at least version 1.6... + clang-format-diff-diffing $@ +else + echo "$0: Please install clang-format (coding style checker) - could not find git-clang-format nor clang-format-diff in PATH. Skipping code verification..." + exit 0 +fi diff --git a/.gitignore b/.gitignore index 7e8bce008..3e162d2d6 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,12 @@ liblinphone-iphone-sdk*.zip xcuserdata/ Classes/LinphoneIOSVersion.h Pods/ -build \ No newline at end of file +build +test-reports +WORK +Makefile +OUTPUT +git-clang-format.diff +submodules/tunnel +submodules/binaries/dummy-*.a +linphone-iphone.ipa diff --git a/.gitmodules b/.gitmodules index 516d2b1a9..1fe8d627b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,61 +3,55 @@ url = git://git.linphone.org/linphone [submodule "submodules/externals/gsm"] path = submodules/externals/gsm - url = git://git.linphone.org/gsm.git + url = git://git.linphone.org/gsm [submodule "submodules/externals/speex"] path = submodules/externals/speex - url = git://git.linphone.org/speex.git -[submodule "submodules/msilbc"] - path = submodules/msilbc - url = git://git.linphone.org/msilbc.git -[submodule "submodules/libilbc-rfc3951"] - path = submodules/libilbc-rfc3951 - url = git://git.linphone.org/libilbc-rfc3951.git + url = git://git.linphone.org/speex [submodule "submodules/externals/opencore-amr"] path = submodules/externals/opencore-amr - url = git://git.code.sf.net/p/opencore-amr/code + url = git://git.linphone.org/opencore-amr ignore = dirty [submodule "submodules/msamr"] path = submodules/msamr - url = git://git.linphone.org/msamr.git + url = git://git.linphone.org/msamr [submodule "submodules/externals/ffmpeg"] path = submodules/externals/ffmpeg - url = git://git.linphone.org/ffmpeg.git + url = git://git.linphone.org/ffmpeg [submodule "submodules/externals/x264"] path = submodules/externals/x264 - url = git://git.linphone.org/x264.git + url = git://git.linphone.org/x264 ignore = dirty [submodule "submodules/msx264"] path = submodules/msx264 - url = git://git.linphone.org/msx264.git + url = git://git.linphone.org/msx264 [submodule "submodules/externals/libvpx"] path = submodules/externals/libvpx - url = http://git.chromium.org/webm/libvpx.git + url = git://git.linphone.org/libvpx ignore = dirty [submodule "submodules/bzrtp"] path = submodules/bzrtp - url = git://git.linphone.org/bzrtp.git + url = git://git.linphone.org/bzrtp [submodule "submodules/mssilk"] path = submodules/mssilk - url = git://git.linphone.org/mssilk.git + url = git://git.linphone.org/mssilk [submodule "submodules/externals/srtp"] path = submodules/externals/srtp - url = git://git.linphone.org/srtp.git + url = git://git.linphone.org/srtp [submodule "submodules/bcg729"] path = submodules/bcg729 - url = git://git.linphone.org/bcg729.git + url = git://git.linphone.org/bcg729 [submodule "submodules/belle-sip"] path = submodules/belle-sip url = git://git.linphone.org/belle-sip [submodule "submodules/externals/antlr3"] path = submodules/externals/antlr3 - url = git://git.linphone.org/antlr3.git + url = git://git.linphone.org/antlr3 [submodule "submodules/externals/polarssl"] path = submodules/externals/polarssl - url = git://git.linphone.org/polarssl.git + url = git://git.linphone.org/polarssl [submodule "submodules/externals/opus"] path = submodules/externals/opus - url = git://git.opus-codec.org/opus.git + url = git://git.linphone.org/opus ignore = dirty [submodule "submodules/externals/libxml2"] path = submodules/externals/libxml2 @@ -65,18 +59,26 @@ ignore = dirty [submodule "submodules/cunit"] path = submodules/cunit - url = git://git.linphone.org/cunit.git + url = git://git.linphone.org/cunit + ignore = dirty [submodule "submodules/externals/openh264"] path = submodules/externals/openh264 url = https://github.com/cisco/openh264 ignore = dirty [submodule "submodules/msopenh264"] path = submodules/msopenh264 - url = git://git.linphone.org/msopenh264.git + url = git://git.linphone.org/msopenh264 [submodule "submodules/mswebrtc"] path = submodules/mswebrtc - url = git://git.linphone.org/mswebrtc.git + url = git://git.linphone.org/mswebrtc [submodule "Classes/KIF"] path = Classes/KIF - url = https://github.com/kif-framework/KIF.git - branch = origin/v3.1.2 + url = https://github.com/kif-framework/KIF + ignore = dirty +[submodule "submodules/cmake-builder"] + path = submodules/cmake-builder + url = git://git.linphone.org/linphone-cmake-builder +[submodule "submodules/externals/vo-amrwbenc"] + path = submodules/externals/vo-amrwbenc + url = git://git.linphone.org/vo-amrwbenc + ignore = dirty diff --git a/.travis.yml b/.travis.yml index 3a22f99d2..8970b7494 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,27 +1,29 @@ language: objective-c -xcode_project: linphone.xcworkspace -xcode_scheme: linphone - -git: - submodules: false env: global: - - VERSION="8.1" - - KIF_SCREENSHOTS="${TRAVIS_BUILD_DIR}/Screenshots" + - secure: "JPPcWdmNIJiR3YcIwe0LRYce6qDdsiagO+eKKAp7eVk/wD9UHbz96Ms2FFkXxPhRJB1PA6Pf8FpAzIL2YRiJL9jRtKHSvtdF1cSto+57XyBkCsw7PkMVUIxp7fg6Wiwn3H3tucF8jisIkv/Pn7R+9EqePkZSqqu3+ig5AX9ApQ4=" + - KIF_SCREENSHOTS=$PWD/Screens -install: - - cd submodules/build - - make download-sdk - - cd ../.. - - pod install - - ls -la +before_install: + - brew update 1>/dev/null + - brew install doxygen nasm yasm optipng imagemagick coreutils intltool ninja antlr + - brew upgrade cmake + - wget --no-check-certificate https://raw.githubusercontent.com/FFmpeg/gas-preprocessor/master/gas-preprocessor.pl + - chmod +x gas-preprocessor.pl + - sudo mv gas-preprocessor.pl /usr/local/bin + - sudo ln -s /usr/local/bin/glibtoolize /usr/local/bin/libtoolize + - sudo ln -s /usr/bin/strings /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/strings + - git submodule update --init --recursive + +install: + - ./prepare.py -d x86_64 -G Ninja + - make -j4 -s 1>/dev/null + - mkdir -p $KIF_SCREENSHOTS script: - - export KIF_SCREENSHOTS=$TRAVIS_BUILD_DIR/Screenshots - - mkdir -p "$KIF_SCREENSHOTS" - - echo $KIF_SCREENSHOTS - - xcodebuild -scheme linphone -workspace linphone.xcworkspace -sdk iphonesimulator8.1 test + - xctool -project linphone.xcodeproj -scheme linphone -sdk iphonesimulator -destination name='iPhone 6' build 1>/dev/null + - xctool -project linphone.xcodeproj -scheme linphone -sdk iphonesimulator -destination name='iPhone 6' test -after_failure: - - ls -la $KIF_SCREENSHOTS \ No newline at end of file +after_script: + - ./Tools/imgur_upload.sh diff --git a/.tx/config b/.tx/config index cf79ceeeb..45513ba7d 100644 --- a/.tx/config +++ b/.tx/config @@ -3,192 +3,216 @@ host = https://www.transifex.com minimum_perc = 1 [linphone-ios.localizablestrings] +source_lang = en file_filter = Resources/.lproj/Localizable.strings source_file = Resources/en.lproj/Localizable.strings + +[linphone-ios.aboutviewstrings] source_lang = en +file_filter = Classes/.lproj/AboutView.strings +source_file = Classes/Base.lproj/AboutView.strings -[linphone-ios.aboutviewcontrollerstrings] -file_filter = Classes/.lproj/AboutViewController.strings -source_file = Classes/Base.lproj/AboutViewController.strings +[linphone-ios.assistantviewstrings] source_lang = en +file_filter = Classes/.lproj/AssistantView.strings +source_file = Classes/Base.lproj/AssistantView.strings - -[linphone-ios.chatroomviewcontrollerstrings] -file_filter = Classes/.lproj/ChatRoomViewController.strings -source_file = Classes/Base.lproj/ChatRoomViewController.strings +[linphone-ios.assistantviewscreensstrings] source_lang = en +file_filter = Classes/.lproj/AssistantViewScreens.strings +source_file = Classes/Base.lproj/AssistantViewScreens.strings - -[linphone-ios.chatviewcontrollerstrings] -file_filter = Classes/.lproj/ChatViewController.strings -source_file = Classes/Base.lproj/ChatViewController.strings +[linphone-ios.callincomingviewstrings] source_lang = en +file_filter = Classes/.lproj/CallIncomingView.strings +source_file = Classes/Base.lproj/CallIncomingView.strings - -[linphone-ios.contactdetailslabelviewcontrollerstrings] -file_filter = Classes/.lproj/ContactDetailsLabelViewController.strings -source_file = Classes/Base.lproj/ContactDetailsLabelViewController.strings +[linphone-ios.calloutgoingviewstrings] source_lang = en +file_filter = Classes/.lproj/CallOutgoingView.strings +source_file = Classes/Base.lproj/CallOutgoingView.strings - -[linphone-ios.contactdetailsviewcontrollerstrings] -file_filter = Classes/.lproj/ContactDetailsViewController.strings -source_file = Classes/Base.lproj/ContactDetailsViewController.strings +[linphone-ios.callviewstrings] source_lang = en +file_filter = Classes/.lproj/CallView.strings +source_file = Classes/Base.lproj/CallView.strings - -[linphone-ios.contactsviewcontrollerstrings] -file_filter = Classes/.lproj/ContactsViewController.strings -source_file = Classes/Base.lproj/ContactsViewController.strings +[linphone-ios.callviewipadstrings] source_lang = en +file_filter = Classes/.lproj/CallView~ipad.strings +source_file = Classes/Base.lproj/CallView~ipad.strings - -[linphone-ios.dialerviewcontrollerstrings] -file_filter = Classes/.lproj/DialerViewController.strings -source_file = Classes/Base.lproj/DialerViewController.strings +[linphone-ios.chatconversationcreateviewstrings] source_lang = en +file_filter = Classes/.lproj/ChatConversationCreateView.strings +source_file = Classes/Base.lproj/ChatConversationCreateView.strings - -[linphone-ios.dialerviewcontrolleripadstrings] -file_filter = Classes/.lproj/DialerViewController~ipad.strings -source_file = Classes/Base.lproj/DialerViewController~ipad.strings +[linphone-ios.chatconversationviewstrings] source_lang = en +file_filter = Classes/.lproj/ChatConversationView.strings +source_file = Classes/Base.lproj/ChatConversationView.strings - -[linphone-ios.firstloginviewcontrollerstrings] -file_filter = Classes/.lproj/FirstLoginViewController.strings -source_file = Classes/Base.lproj/FirstLoginViewController.strings +[linphone-ios.chatslistviewstrings] source_lang = en +file_filter = Classes/.lproj/ChatsListView.strings +source_file = Classes/Base.lproj/ChatsListView.strings - -[linphone-ios.historydetailsviewcontrollerstrings] -file_filter = Classes/.lproj/HistoryDetailsViewController.strings -source_file = Classes/Base.lproj/HistoryDetailsViewController.strings +[linphone-ios.contactdetailsviewstrings] source_lang = en +file_filter = Classes/.lproj/ContactDetailsView.strings +source_file = Classes/Base.lproj/ContactDetailsView.strings - -[linphone-ios.historyviewcontrollerstrings] -file_filter = Classes/.lproj/HistoryViewController.strings -source_file = Classes/Base.lproj/HistoryViewController.strings +[linphone-ios.contactslistviewstrings] source_lang = en +file_filter = Classes/.lproj/ContactsListView.strings +source_file = Classes/Base.lproj/ContactsListView.strings - -[linphone-ios.imageviewcontrollerstrings] -file_filter = Classes/.lproj/ImageViewController.strings -source_file = Classes/Base.lproj/ImageViewController.strings +[linphone-ios.dialerviewstrings] source_lang = en +file_filter = Classes/.lproj/DialerView.strings +source_file = Classes/Base.lproj/DialerView.strings - -[linphone-ios.incallviewcontrollerstrings] -file_filter = Classes/.lproj/InCallViewController.strings -source_file = Classes/Base.lproj/InCallViewController.strings +[linphone-ios.dialerviewipadstrings] source_lang = en +file_filter = Classes/.lproj/DialerView~ipad.strings +source_file = Classes/Base.lproj/DialerView~ipad.strings - -[linphone-ios.incomingcallviewcontrollerstrings] -file_filter = Classes/.lproj/IncomingCallViewController.strings -source_file = Classes/Base.lproj/IncomingCallViewController.strings +[linphone-ios.firstloginviewstrings] source_lang = en +file_filter = Classes/.lproj/FirstLoginView.strings +source_file = Classes/Base.lproj/FirstLoginView.strings - -[linphone-ios.incomingcallviewcontrolleripadstrings] -file_filter = Classes/.lproj/IncomingCallViewController~ipad.strings -source_file = Classes/Base.lproj/IncomingCallViewController~ipad.strings +[linphone-ios.historydetailsviewstrings] source_lang = en +file_filter = Classes/.lproj/HistoryDetailsView.strings +source_file = Classes/Base.lproj/HistoryDetailsView.strings - -[linphone-ios.wizardviewcontrollerstrings] -file_filter = Classes/.lproj/WizardViewController.strings -source_file = Classes/Base.lproj/WizardViewController.strings +[linphone-ios.historylistviewstrings] source_lang = en +file_filter = Classes/.lproj/HistoryListView.strings +source_file = Classes/Base.lproj/HistoryListView.strings - -[linphone-ios.wizardviewcontrolleripadstrings] -file_filter = Classes/.lproj/WizardViewController~ipad.strings -source_file = Classes/Base.lproj/WizardViewController~ipad.strings +[linphone-ios.imageviewstrings] source_lang = en +file_filter = Classes/.lproj/ImageView.strings +source_file = Classes/Base.lproj/ImageView.strings - -[linphone-ios.wizardviewsstrings] -file_filter = Classes/.lproj/WizardViews.strings -source_file = Classes/Base.lproj/WizardViews.strings +[linphone-ios.launchscreenstrings] source_lang = en +file_filter = Classes/.lproj/LaunchScreen.strings +source_file = Classes/Base.lproj/LaunchScreen.strings - -[linphone-ios.uicallbarstrings] -file_filter = Classes/LinphoneUI/.lproj/UICallBar.strings -source_file = Classes/LinphoneUI/Base.lproj/UICallBar.strings +[linphone-ios.settingsviewstrings] source_lang = en +file_filter = Classes/.lproj/SettingsView.strings +source_file = Classes/Base.lproj/SettingsView.strings - -[linphone-ios.uicallbaripadstrings] -file_filter = Classes/LinphoneUI/.lproj/UICallBar~ipad.strings -source_file = Classes/LinphoneUI/Base.lproj/UICallBar~ipad.strings +[linphone-ios.sidemenuviewstrings] source_lang = en +file_filter = Classes/.lproj/SideMenuView.strings +source_file = Classes/Base.lproj/SideMenuView.strings - -[linphone-ios.uicallcellstrings] -file_filter = Classes/LinphoneUI/.lproj/UICallCell.strings -source_file = Classes/LinphoneUI/Base.lproj/UICallCell.strings +[linphone-ios.sidemenuviewipadstrings] source_lang = en +file_filter = Classes/.lproj/SideMenuView~ipad.strings +source_file = Classes/Base.lproj/SideMenuView~ipad.strings +[linphone-ios.statusbarviewstrings] +source_lang = en +file_filter = Classes/LinphoneUI/.lproj/StatusBarView.strings +source_file = Classes/LinphoneUI/Base.lproj/StatusBarView.strings + +[linphone-ios.tabbarviewstrings] +source_lang = en +file_filter = Classes/LinphoneUI/.lproj/TabBarView.strings +source_file = Classes/LinphoneUI/Base.lproj/TabBarView.strings + +[linphone-ios.uicallconferencecellstrings] +source_lang = en +file_filter = Classes/LinphoneUI/.lproj/UICallConferenceCell.strings +source_file = Classes/LinphoneUI/Base.lproj/UICallConferenceCell.strings + +[linphone-ios.uicallpausedcellstrings] +source_lang = en +file_filter = Classes/LinphoneUI/.lproj/UICallPausedCell.strings +source_file = Classes/LinphoneUI/Base.lproj/UICallPausedCell.strings + +[linphone-ios.uichatbubblephotocellstrings] +source_lang = en +file_filter = Classes/LinphoneUI/.lproj/UIChatBubblePhotoCell.strings +source_file = Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.strings + +[linphone-ios.uichatbubbletextcellstrings] +source_lang = en +file_filter = Classes/LinphoneUI/.lproj/UIChatBubbleTextCell.strings +source_file = Classes/LinphoneUI/Base.lproj/UIChatBubbleTextCell.strings [linphone-ios.uichatcellstrings] +source_lang = en file_filter = Classes/LinphoneUI/.lproj/UIChatCell.strings source_file = Classes/LinphoneUI/Base.lproj/UIChatCell.strings + +[linphone-ios.uichatcreatecellstrings] source_lang = en +file_filter = Classes/LinphoneUI/.lproj/UIChatCreateCell.strings +source_file = Classes/LinphoneUI/Base.lproj/UIChatCreateCell.strings - -[linphone-ios.uichatroomcellstrings] -file_filter = Classes/LinphoneUI/.lproj/UIChatRoomCell.strings -source_file = Classes/LinphoneUI/Base.lproj/UIChatRoomCell.strings +[linphone-ios.uiconfirmationdialogstrings] source_lang = en - - -[linphone-ios.uiconferenceheaderstrings] -file_filter = Classes/LinphoneUI/.lproj/UIConferenceHeader.strings -source_file = Classes/LinphoneUI/Base.lproj/UIConferenceHeader.strings -source_lang = en - +file_filter = Classes/LinphoneUI/.lproj/UIConfirmationDialog.strings +source_file = Classes/LinphoneUI/Base.lproj/UIConfirmationDialog.strings [linphone-ios.uicontactcellstrings] +source_lang = en file_filter = Classes/LinphoneUI/.lproj/UIContactCell.strings source_file = Classes/LinphoneUI/Base.lproj/UIContactCell.strings + +[linphone-ios.uicontactdetailscellstrings] source_lang = en - - -[linphone-ios.uicontactdetailsfooterstrings] -file_filter = Classes/LinphoneUI/.lproj/UIContactDetailsFooter.strings -source_file = Classes/LinphoneUI/Base.lproj/UIContactDetailsFooter.strings -source_lang = en - - -[linphone-ios.uicontactdetailsheaderstrings] -file_filter = Classes/LinphoneUI/.lproj/UIContactDetailsHeader.strings -source_file = Classes/LinphoneUI/Base.lproj/UIContactDetailsHeader.strings -source_lang = en - +file_filter = Classes/LinphoneUI/.lproj/UIContactDetailsCell.strings +source_file = Classes/LinphoneUI/Base.lproj/UIContactDetailsCell.strings [linphone-ios.uihistorycellstrings] +source_lang = en file_filter = Classes/LinphoneUI/.lproj/UIHistoryCell.strings source_file = Classes/LinphoneUI/Base.lproj/UIHistoryCell.strings + +[linphone-ios.inappsettingsaccountstrings] source_lang = en +file_filter = Settings/InAppSettings.bundle/.lproj/Account.strings +source_file = Settings/InAppSettings.bundle/en.lproj/Account.strings - -[linphone-ios.uimainbarstrings] -file_filter = Classes/LinphoneUI/.lproj/UIMainBar.strings -source_file = Classes/LinphoneUI/Base.lproj/UIMainBar.strings +[linphone-ios.inappsettingsadvancedstrings] source_lang = en +file_filter = Settings/InAppSettings.bundle/.lproj/Advanced.strings +source_file = Settings/InAppSettings.bundle/en.lproj/Advanced.strings - -[linphone-ios.uimainbaripadstrings] -file_filter = Classes/LinphoneUI/.lproj/UIMainBar~ipad.strings -source_file = Classes/LinphoneUI/Base.lproj/UIMainBar~ipad.strings +[linphone-ios.inappsettingsaudiostrings] source_lang = en +file_filter = Settings/InAppSettings.bundle/.lproj/Audio.strings +source_file = Settings/InAppSettings.bundle/en.lproj/Audio.strings - -[linphone-ios.uistatebarstrings] -file_filter = Classes/LinphoneUI/.lproj/UIStateBar.strings -source_file = Classes/LinphoneUI/Base.lproj/UIStateBar.strings +[linphone-ios.inappsettingscallstrings] source_lang = en +file_filter = Settings/InAppSettings.bundle/.lproj/Call.strings +source_file = Settings/InAppSettings.bundle/en.lproj/Call.strings +[linphone-ios.inappsettingsnetworkstrings] +source_lang = en +file_filter = Settings/InAppSettings.bundle/.lproj/Network.strings +source_file = Settings/InAppSettings.bundle/en.lproj/Network.strings + +[linphone-ios.inappsettingsrootstrings] +source_lang = en +file_filter = Settings/InAppSettings.bundle/.lproj/Root.strings +source_file = Settings/InAppSettings.bundle/en.lproj/Root.strings + +[linphone-ios.inappsettingstunnelstrings] +source_lang = en +file_filter = Settings/InAppSettings.bundle/.lproj/Tunnel.strings +source_file = Settings/InAppSettings.bundle/en.lproj/Tunnel.strings + +[linphone-ios.inappsettingsvideostrings] +source_lang = en +file_filter = Settings/InAppSettings.bundle/.lproj/Video.strings +source_file = Settings/InAppSettings.bundle/en.lproj/Video.strings diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..dd9ec5d7d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,40 @@ +# Contributing + +We love pull requests from everyone. By participating in this project, you +agree to abide by the [Contributor License Agreement](http://www.belledonne-communications.com/downloads/Belledonne_communications_CA.pdf). + +# How to contribute + +## Translation Requests + +Translations are handled only on the [Transifex platform](https://www.transifex.com/belledonne-communications/public/). + +## Reporting Bugs + +* Make sure you have a [GitHub account](https://github.com/signup/free) +* Submit a ticket for your issue, assuming one does not already exist. + * Clearly describe the issue including steps to reproduce. + Consider doing a video record to help understand the scenario. + * Provide Linphone version as well as Liblinphone, both available in the `About` page. + * Provide your iOS version as well as affected device. + * Attach application logs + * Go to `Settings -> Advanced` + * Enable `Debug` + * Click `Clear logs` to remove older logs + * Reproduce your issue + * Use `Settings -> About -> Send logs` to send it by email to yourself + * Clean these logs if needed, then attach them to your issue + +## Submitting Changes + +* Sign the [Contributor License Agreement](http://www.belledonne-communications.com/downloads/Belledonne_communications_CA.pdf). +* Push your changes to a topic branch in your fork of the repository. +* Submit a pull request to the repository in the Belledonne Communications organization. +* We will then review, comment and/or integrate your request. It can take few minutes or several weeks depending on our schedule. + +# Additional Resources + +* [Contributor License Agreement](http://www.belledonne-communications.com/downloads/Belledonne_communications_CA.pdf) +* [General Linphone documentation](https://wiki.linphone.org/wiki/) +* [Linphone developers mailing list](https://lists.nongnu.org/mailman/listinfo/linphone-developers) +* [Linphone users mailing list](https://lists.nongnu.org/mailman/listinfo/linphone-users) diff --git a/Classes/AboutView.h b/Classes/AboutView.h new file mode 100644 index 000000000..cf06159a4 --- /dev/null +++ b/Classes/AboutView.h @@ -0,0 +1,39 @@ +/* AboutViewController.h + * + * Copyright (C) 2009 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import + +#import "UICompositeView.h" + +@interface AboutView : UIViewController { +} + +@property(nonatomic, strong) IBOutlet UILabel *linphoneLabel; +@property(nonatomic, strong) IBOutlet UILabel *linphoneIphoneVersionLabel; +@property(nonatomic, strong) IBOutlet UILabel *linphoneCoreVersionLabel; +@property(nonatomic, strong) IBOutlet UILabel *linkLabel; +@property(nonatomic, strong) IBOutlet UILabel *copyrightLabel; +@property(nonatomic, strong) IBOutlet UILabel *licenseLabel; +@property(weak, nonatomic) IBOutlet UIView *contentView; +@property(nonatomic, strong) IBOutlet UIWebView *licensesView; + +- (IBAction)onLinkTap:(id)sender; +- (IBAction)onDialerBackClick:(id)sender; + +@end diff --git a/Classes/AboutView.m b/Classes/AboutView.m new file mode 100644 index 000000000..2255b82aa --- /dev/null +++ b/Classes/AboutView.m @@ -0,0 +1,137 @@ +/* AboutViewController.m + * + * Copyright (C) 2009 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "PhoneMainView.h" +#import "LinphoneManager.h" +#include "linphone/lpconfig.h" +#include "LinphoneIOSVersion.h" + +@implementation AboutView + +#pragma mark - ViewController Functions + +- (void)viewDidLoad { + [super viewDidLoad]; + + UIScrollView *scrollView = (UIScrollView *)self.view; + [scrollView addSubview:_contentView]; + [scrollView setContentSize:[_contentView bounds].size]; + + [_linphoneLabel setText:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]]; + + [_linphoneIphoneVersionLabel + setText:[NSString stringWithFormat:@"%@ iPhone %@", + [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"], + [NSString stringWithUTF8String:LINPHONE_IOS_VERSION]]]; + + [_linphoneCoreVersionLabel + setText:[NSString stringWithFormat:@"%@ Core %s", + [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"], + linphone_core_get_version()]]; + + if (IPAD) { + [LinphoneUtils adjustFontSize:self.view mult:2.22f]; + } + + [AboutView removeBackground:_licensesView]; + + // Create a request to the resource + NSURLRequest *request = + [NSURLRequest requestWithURL:[NSURL fileURLWithPath:[LinphoneManager bundleFile:@"licenses.html"]]]; + // Load the resource using the request + [_licensesView setDelegate:self]; + [_licensesView loadRequest:request]; + [[AboutView defaultScrollView:_licensesView] setScrollEnabled:FALSE]; +} + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:nil + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:YES + fragmentWith:nil]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - + ++ (void)removeBackground:(UIView *)view { + for (UIView *subview in [view subviews]) { + [subview setOpaque:NO]; + [subview setBackgroundColor:[UIColor clearColor]]; + } + [view setOpaque:NO]; + [view setBackgroundColor:[UIColor clearColor]]; +} + ++ (UIScrollView *)defaultScrollView:(UIWebView *)webView { + return webView.scrollView; +} + +#pragma mark - Action Functions + +- (IBAction)onLinkTap:(id)sender { + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:_linkLabel.text]]; +} + +#pragma mark - UIWebViewDelegate Functions + +- (void)webViewDidFinishLoad:(UIWebView *)webView { + CGSize size = [webView sizeThatFits:CGSizeMake(self.view.bounds.size.width, 10000.0f)]; + float diff = size.height - webView.bounds.size.height; + + CGRect contentFrame = [self.view bounds]; + contentFrame.size.height += diff; + [_contentView setAutoresizesSubviews:FALSE]; + [_contentView setFrame:contentFrame]; + [_contentView setAutoresizesSubviews:TRUE]; + [(UIScrollView *)self.view setContentSize:contentFrame.size]; + + CGRect licensesViewFrame = [_licensesView frame]; + licensesViewFrame.size.height += diff; + [_licensesView setFrame:licensesViewFrame]; +} + +- (BOOL)webView:(UIWebView *)inWeb + shouldStartLoadWithRequest:(NSURLRequest *)inRequest + navigationType:(UIWebViewNavigationType)inType { + if (inType == UIWebViewNavigationTypeLinkClicked) { + [[UIApplication sharedApplication] openURL:[inRequest URL]]; + return NO; + } + + return YES; +} + +- (IBAction)onDialerBackClick:(id)sender { + [PhoneMainView.instance changeCurrentView:DialerView.compositeViewDescription]; +} +@end diff --git a/Classes/AboutViewController.h b/Classes/AboutViewController.h deleted file mode 100644 index 041031e06..000000000 --- a/Classes/AboutViewController.h +++ /dev/null @@ -1,39 +0,0 @@ -/* AboutViewController.h - * - * Copyright (C) 2009 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UICompositeViewController.h" - -@interface AboutViewController : UIViewController { -} - -@property (nonatomic, retain) IBOutlet UILabel *linphoneLabel; -@property (nonatomic, retain) IBOutlet UILabel *linphoneIphoneVersionLabel; -@property (nonatomic, retain) IBOutlet UILabel *linphoneCoreVersionLabel; -@property (nonatomic, retain) IBOutlet UIView *contentView; -@property (nonatomic, retain) IBOutlet UILabel *linkLabel; -@property (nonatomic, retain) IBOutlet UILabel *copyrightLabel; -@property (nonatomic, retain) IBOutlet UILabel *licenseLabel; -@property (nonatomic, retain) IBOutlet UIWebView *licensesView; -@property (nonatomic, retain) IBOutlet UITapGestureRecognizer *linkTapGestureRecognizer; - -- (IBAction)onLinkTap:(id)sender; - -@end diff --git a/Classes/AboutViewController.m b/Classes/AboutViewController.m deleted file mode 100644 index c0f3ef92b..000000000 --- a/Classes/AboutViewController.m +++ /dev/null @@ -1,170 +0,0 @@ -/* AboutViewController.m - * - * Copyright (C) 2009 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "AboutViewController.h" -#import "LinphoneManager.h" -#include "linphone/lpconfig.h" -#include "LinphoneIOSVersion.h" - -@implementation AboutViewController - -@synthesize linphoneCoreVersionLabel; -@synthesize linphoneLabel; -@synthesize linphoneIphoneVersionLabel; -@synthesize contentView; -@synthesize linkTapGestureRecognizer; -@synthesize linkLabel; -@synthesize licensesView; -@synthesize licenseLabel; -@synthesize copyrightLabel; - - -#pragma mark - Lifecycle Functions - -- (id)init { - self = [super initWithNibName:@"AboutViewController" bundle:[NSBundle mainBundle]]; - if (self != nil) { - self->linkTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onLinkTap:)]; - } - return self; -} - -- (void)dealloc { - [linphoneCoreVersionLabel release]; - [linphoneIphoneVersionLabel release]; - [contentView release]; - [linkTapGestureRecognizer release]; - [linkLabel release]; - [licensesView release]; - - [super dealloc]; -} - - -#pragma mark - ViewController Functions - -- (void)viewDidLoad { - [super viewDidLoad]; - - [linkLabel setText:NSLocalizedString(@"http://www.linphone.org", nil)]; - [licenseLabel setText:NSLocalizedString(@"GNU General Public License V2 ", nil)]; - [copyrightLabel setText:NSLocalizedString(@"© 2010-2012 Belledonne Communications ", nil)]; - - [linkLabel addGestureRecognizer:linkTapGestureRecognizer]; - - UIScrollView *scrollView = (UIScrollView *)self.view; - [scrollView addSubview:contentView]; - [scrollView setContentSize:[contentView bounds].size]; - - [linphoneLabel setText:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]]; - - [linphoneIphoneVersionLabel setText:[NSString stringWithFormat:@"%@ iPhone %@", - [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"], - [NSString stringWithUTF8String:LINPHONE_IOS_VERSION]] - ]; - - [linphoneCoreVersionLabel setText:[NSString stringWithFormat:@"%@ Core %s", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"], linphone_core_get_version()]]; - - if([LinphoneManager runningOnIpad]) { - [LinphoneUtils adjustFontSize:self.view mult:2.22f]; - } - - [AboutViewController removeBackground:licensesView]; - - // Create a request to the resource - NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:[LinphoneManager bundleFile:@"licenses.html"]]] ; - // Load the resource using the request - [licensesView setDelegate:self]; - [licensesView loadRequest:request]; - [[AboutViewController defaultScrollView:licensesView] setScrollEnabled:FALSE]; -} - - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"About" - content:@"AboutViewController" - stateBar:nil - stateBarEnabled:false - tabBar:@"UIMainBar" - tabBarEnabled:true - fullscreen:false - landscapeMode:[LinphoneManager runningOnIpad] - portraitMode:true]; - } - return compositeDescription; -} - - -#pragma mark - - -+ (void)removeBackground:(UIView *)view { - for (UIView *subview in [view subviews]) { - [subview setOpaque:NO]; - [subview setBackgroundColor:[UIColor clearColor]]; - } - [view setOpaque:NO]; - [view setBackgroundColor:[UIColor clearColor]]; -} - -+ (UIScrollView *)defaultScrollView:(UIWebView *)webView { - return webView.scrollView; -} - - -#pragma mark - Action Functions - -- (IBAction)onLinkTap:(id)sender { - [[UIApplication sharedApplication] openURL:[NSURL URLWithString:linkLabel.text]]; -} - - -#pragma mark - UIWebViewDelegate Functions - -- (void)webViewDidFinishLoad:(UIWebView *)webView { - CGSize size = [webView sizeThatFits:CGSizeMake(self.view.bounds.size.width, 10000.0f)]; - float diff = size.height - webView.bounds.size.height; - - UIScrollView *scrollView = (UIScrollView *)self.view; - CGRect contentFrame = [contentView bounds]; - contentFrame.size.height += diff; - [contentView setAutoresizesSubviews:FALSE]; - [contentView setFrame:contentFrame]; - [contentView setAutoresizesSubviews:TRUE]; - [scrollView setContentSize:contentFrame.size]; - CGRect licensesViewFrame = [licensesView frame]; - licensesViewFrame.size.height += diff; - [licensesView setFrame:licensesViewFrame]; -} - -- (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType { - if (inType == UIWebViewNavigationTypeLinkClicked) { - [[UIApplication sharedApplication] openURL:[inRequest URL]]; - return NO; - } - - return YES; -} - - -@end diff --git a/Classes/AssistantView.h b/Classes/AssistantView.h new file mode 100644 index 000000000..25226c189 --- /dev/null +++ b/Classes/AssistantView.h @@ -0,0 +1,75 @@ +/* AssistantViewController.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import +#import +#import "UICompositeView.h" +#import "TPKeyboardAvoidingScrollView.h" + +@interface AssistantView : TPMultiLayoutViewController { + @private + LinphoneAccountCreator *account_creator; + UIView *currentView; + UIView *nextView; + NSMutableArray *historyViews; + LinphoneProxyConfig *new_config; + LinphoneProxyConfig *previous_default_config; +} + +@property(nonatomic, strong) IBOutlet TPKeyboardAvoidingScrollView *contentView; +@property(nonatomic, strong) IBOutlet UIView *waitView; +@property(nonatomic, strong) IBOutlet UIButton *backButton; + +@property(nonatomic, strong) IBOutlet UIView *welcomeView; +@property(nonatomic, strong) IBOutlet UIView *createAccountView; +@property(nonatomic, strong) IBOutlet UIView *createAccountActivationView; +@property(nonatomic, strong) IBOutlet UIView *linphoneLoginView; +@property(nonatomic, strong) IBOutlet UIView *loginView; +@property(nonatomic, strong) IBOutlet UIView *remoteProvisioningLoginView; +@property(strong, nonatomic) IBOutlet UIView *remoteProvisioningView; + +@property(nonatomic, strong) IBOutlet UIImageView *welcomeLogoImage; +@property(nonatomic, strong) IBOutlet UIButton *gotoCreateAccountButton; +@property(nonatomic, strong) IBOutlet UIButton *gotoLinphoneLoginButton; +@property(nonatomic, strong) IBOutlet UIButton *gotoLoginButton; +@property(nonatomic, strong) IBOutlet UIButton *gotoRemoteProvisioningButton; + ++ (NSString *)errorForStatus:(LinphoneAccountCreatorStatus)status; + +- (void)reset; +- (void)fillDefaultValues; + +- (IBAction)onBackClick:(id)sender; +- (IBAction)onDialerClick:(id)sender; + +- (IBAction)onGotoCreateAccountClick:(id)sender; +- (IBAction)onGotoLinphoneLoginClick:(id)sender; +- (IBAction)onGotoLoginClick:(id)sender; +- (IBAction)onGotoRemoteProvisioningClick:(id)sender; + +- (IBAction)onCreateAccountClick:(id)sender; +- (IBAction)onCreateAccountActivationClick:(id)sender; +- (IBAction)onLinphoneLoginClick:(id)sender; +- (IBAction)onLoginClick:(id)sender; +- (IBAction)onRemoteProvisioningLoginClick:(id)sender; +- (IBAction)onRemoteProvisioningDownloadClick:(id)sender; + +- (IBAction)onTransportChange:(id)sender; + +@end diff --git a/Classes/AssistantView.m b/Classes/AssistantView.m new file mode 100644 index 000000000..0c5d54e7d --- /dev/null +++ b/Classes/AssistantView.m @@ -0,0 +1,750 @@ + +/* AssistantViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "AssistantView.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" +#import "UITextField+DoneButton.h" +#import "UIAssistantTextField.h" + +#import +#import +#import +#import + +typedef enum _ViewElement { + ViewElement_Username = 100, + ViewElement_Password = 101, + ViewElement_Password2 = 102, + ViewElement_Email = 103, + ViewElement_Domain = 104, + ViewElement_URL = 105, + ViewElement_DisplayName = 106, + ViewElement_TextFieldCount = 6, + ViewElement_Transport = 110, + ViewElement_Username_Label = 120, + ViewElement_NextButton = 130, +} ViewElement; + +@implementation AssistantView + +#pragma mark - Lifecycle Functions + +- (id)init { + self = [super initWithNibName:NSStringFromClass(self.class) bundle:[NSBundle mainBundle]]; + if (self != nil) { + [[NSBundle mainBundle] loadNibNamed:@"AssistantViewScreens" owner:self options:nil]; + historyViews = [[NSMutableArray alloc] init]; + currentView = nil; + } + return self; +} + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:nil + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:NO + fragmentWith:nil]; + + compositeDescription.darkBackground = true; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(registrationUpdateEvent:) + name:kLinphoneRegistrationUpdate + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(configuringUpdate:) + name:kLinphoneConfiguringStateUpdate + object:nil]; + // we will set the new default proxy config in the assistant + previous_default_config = linphone_core_get_default_proxy_config([LinphoneManager getLc]); + linphone_core_set_default_proxy_config([LinphoneManager getLc], NULL); + + new_config = NULL; + [self resetTextFields]; + [self changeView:_welcomeView back:FALSE animation:FALSE]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + // if we quit assistant without creating a new proxy config, just restore the previous one + if (!linphone_core_get_default_proxy_config([LinphoneManager getLc])) { + linphone_core_set_default_proxy_config([LinphoneManager getLc], previous_default_config); + } +} + +- (void)fitContent { + // always resize content view so that it fits whole available width + CGRect frame = currentView.frame; + frame.size.width = _contentView.bounds.size.width; + currentView.frame = frame; + + [_contentView setContentSize:frame.size]; + [_contentView contentSizeToFit]; +} + +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { + [self fitContent]; +} + +#pragma mark - Utils + +- (void)resetLiblinphone { + if (account_creator) { + linphone_account_creator_unref(account_creator); + account_creator = NULL; + } + [[LinphoneManager instance] resetLinphoneCore]; + account_creator = linphone_account_creator_new( + [LinphoneManager getLc], + [LinphoneManager.instance lpConfigStringForKey:@"xmlrpc_url" inSection:@"assistant" withDefault:@""] + .UTF8String); + linphone_account_creator_set_user_data(account_creator, (__bridge void *)(self)); + linphone_account_creator_cbs_set_existence_tested(linphone_account_creator_get_callbacks(account_creator), + assistant_existence_tested); + linphone_account_creator_cbs_set_create_account(linphone_account_creator_get_callbacks(account_creator), + assistant_create_account); + linphone_account_creator_cbs_set_validation_tested(linphone_account_creator_get_callbacks(account_creator), + assistant_validation_tested); +} +- (void)loadAssistantConfig:(NSString *)rcFilename { + NSString *fullPath = [@"file://" stringByAppendingString:[LinphoneManager bundleFile:rcFilename]]; + linphone_core_set_provisioning_uri([LinphoneManager getLc], fullPath.UTF8String); + [[LinphoneManager instance] lpConfigSetInt:1 forKey:@"transient_provisioning" inSection:@"misc"]; + + [self resetLiblinphone]; +} + +- (void)reset { + [[LinphoneManager instance] removeAllAccounts]; + [[LinphoneManager instance] lpConfigSetBool:FALSE forKey:@"pushnotification_preference"]; + + LinphoneCore *lc = [LinphoneManager getLc]; + LCSipTransports transportValue = {5060, 5060, -1, -1}; + + if (linphone_core_set_sip_transports(lc, &transportValue)) { + LOGE(@"cannot set transport"); + } + + [[LinphoneManager instance] lpConfigSetBool:FALSE forKey:@"ice_preference"]; + [[LinphoneManager instance] lpConfigSetString:@"" forKey:@"stun_preference"]; + linphone_core_set_stun_server(lc, NULL); + linphone_core_set_firewall_policy(lc, LinphonePolicyNoFirewall); + [self resetTextFields]; + [self changeView:_welcomeView back:FALSE animation:FALSE]; + _waitView.hidden = TRUE; +} + +- (void)clearHistory { + [historyViews removeAllObjects]; +} + ++ (NSString *)errorForStatus:(LinphoneAccountCreatorStatus)status { + BOOL usePhoneNumber = [[LinphoneManager instance] lpConfigBoolForKey:@"use_phone_number" inSection:@"assistant"]; + switch (status) { + case LinphoneAccountCreatorEmailInvalid: + return NSLocalizedString(@"Invalid email.", nil); + case LinphoneAccountCreatorUsernameInvalid: + return usePhoneNumber ? NSLocalizedString(@"Invalid phone number.", nil) + : NSLocalizedString(@"Invalid username.", nil); + case LinphoneAccountCreatorUsernameTooShort: + return usePhoneNumber ? NSLocalizedString(@"Phone number too short.", nil) + : NSLocalizedString(@"Username too short.", nil); + case LinphoneAccountCreatorUsernameInvalidSize: + return usePhoneNumber ? NSLocalizedString(@"Phone number length invalid.", nil) + : NSLocalizedString(@"Username length invalid.", nil); + case LinphoneAccountCreatorPasswordTooShort: + return NSLocalizedString(@"Password too short.", nil); + case LinphoneAccountCreatorDomainInvalid: + return NSLocalizedString(@"Invalid domain.", nil); + case LinphoneAccountCreatorRouteInvalid: + return NSLocalizedString(@"Invalid route.", nil); + case LinphoneAccountCreatorDisplayNameInvalid: + return NSLocalizedString(@"Invalid display name.", nil); + case LinphoneAccountCreatorReqFailed: + return NSLocalizedString(@"Failed to query the server. Please try again later", nil); + case LinphoneAccountCreatorTransportNotSupported: + return NSLocalizedString(@"Unsupported transport", nil); + case LinphoneAccountCreatorAccountCreated: + case LinphoneAccountCreatorAccountExist: + case LinphoneAccountCreatorAccountNotCreated: + case LinphoneAccountCreatorAccountNotExist: + case LinphoneAccountCreatorAccountNotValidated: + case LinphoneAccountCreatorAccountValidated: + case LinphoneAccountCreatorOK: + break; + } + return nil; +} + +- (void)configureProxyConfig { + LinphoneCore *lc = [LinphoneManager getLc]; + LinphoneManager *lm = [LinphoneManager instance]; + + // remove previous proxy config, if any + if (new_config != NULL) { + const LinphoneAuthInfo *auth = linphone_proxy_config_find_auth_info(new_config); + linphone_core_remove_proxy_config(lc, new_config); + if (auth) { + linphone_core_remove_auth_info(lc, auth); + } + } + + new_config = linphone_account_creator_configure(account_creator); + + if (new_config) { + [lm configurePushTokenForProxyConfig:new_config]; + linphone_core_set_default_proxy_config(lc, new_config); + // reload address book to prepend proxy config domain to contacts' phone number + // todo: STOP doing that! + [[[LinphoneManager instance] fastAddressBook] reload]; + } +} + +#pragma mark - UI update + +- (void)changeView:(UIView *)view back:(BOOL)back animation:(BOOL)animation { + + static BOOL placement_done = NO; // indicates if the button placement has been done in the assistant choice view + + _backButton.hidden = (view == _welcomeView); + + [self displayUsernameAsPhoneOrUsername]; + + if (view == _welcomeView) { + BOOL show_logo = + [[LinphoneManager instance] lpConfigBoolForKey:@"show_assistant_logo_in_choice_view_preference"]; + BOOL show_extern = ![[LinphoneManager instance] lpConfigBoolForKey:@"hide_assistant_custom_account"]; + BOOL show_new = ![[LinphoneManager instance] lpConfigBoolForKey:@"hide_assistant_create_account"]; + + if (!placement_done) { + // visibility + _welcomeLogoImage.hidden = !show_logo; + _gotoLoginButton.hidden = !show_extern; + _gotoCreateAccountButton.hidden = !show_new; + + // placement + if (show_logo && show_new && !show_extern) { + // lower both remaining buttons + [_gotoCreateAccountButton setCenter:[_gotoLinphoneLoginButton center]]; + [_gotoLoginButton setCenter:[_gotoLoginButton center]]; + + } else if (!show_logo && !show_new && show_extern) { + // move up the extern button + [_gotoLoginButton setCenter:[_gotoCreateAccountButton center]]; + } + placement_done = YES; + } + if (!show_extern && !show_logo) { + // no option to create or specify a custom account: go to connect view directly + view = _linphoneLoginView; + } + } + + // Animation + if (animation && [[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"] == true) { + CATransition *trans = [CATransition animation]; + [trans setType:kCATransitionPush]; + [trans setDuration:0.35]; + [trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; + if (back) { + [trans setSubtype:kCATransitionFromLeft]; + } else { + [trans setSubtype:kCATransitionFromRight]; + } + [_contentView.layer addAnimation:trans forKey:@"Transition"]; + } + + // Stack current view + if (currentView != nil) { + if (!back) + [historyViews addObject:currentView]; + [currentView removeFromSuperview]; + } + + // Set current view + currentView = view; + [_contentView insertSubview:currentView atIndex:0]; + [_contentView setContentOffset:CGPointMake(0, -_contentView.contentInset.top) animated:NO]; + [self fitContent]; + + // Resize next button to fix text length + UIButton *button = [self findButton:ViewElement_NextButton]; + CGSize size = [button.titleLabel.text sizeWithFont:button.titleLabel.font]; + size.width += 60; + CGRect frame = button.frame; + frame.origin.x += (button.frame.size.width - size.width) / 2; + frame.size.width = size.width; + [button setFrame:frame]; + + [self prepareErrorLabels]; +} + +- (void)fillDefaultValues { + [self resetTextFields]; + + LinphoneProxyConfig *current_conf = linphone_core_get_default_proxy_config([LinphoneManager getLc]); + if (current_conf != NULL) { + if (linphone_proxy_config_find_auth_info(current_conf) != NULL) { + LOGI(@"A proxy config was set up with the remote provisioning, skip assistant"); + [self onDialerClick:nil]; + } + } + + LinphoneProxyConfig *default_conf = linphone_core_create_proxy_config([LinphoneManager getLc]); + const char *identity = linphone_proxy_config_get_identity(default_conf); + if (identity) { + LinphoneAddress *default_addr = linphone_address_new(identity); + if (default_addr) { + const char *domain = linphone_address_get_domain(default_addr); + const char *username = linphone_address_get_username(default_addr); + if (domain && strlen(domain) > 0) { + [self findTextField:ViewElement_Domain].text = [NSString stringWithUTF8String:domain]; + } + if (username && strlen(username) > 0 && username[0] != '?') { + [self findTextField:ViewElement_Username].text = [NSString stringWithUTF8String:username]; + } + } + } + + [self changeView:_remoteProvisioningLoginView back:FALSE animation:TRUE]; + + linphone_proxy_config_destroy(default_conf); +} + +- (void)resetTextFields { + for (UIView *view in @[ + _welcomeView, + _createAccountView, + _linphoneLoginView, + _loginView, + _createAccountActivationView, + _remoteProvisioningLoginView + ]) { + [AssistantView cleanTextField:view]; +#if DEBUG + UIAssistantTextField *atf = + (UIAssistantTextField *)[self findView:ViewElement_Domain inView:view ofType:UIAssistantTextField.class]; + atf.text = @"test.linphone.org"; +#endif + } +} + +- (void)displayUsernameAsPhoneOrUsername { + BOOL usePhoneNumber = [LinphoneManager.instance lpConfigBoolForKey:@"use_phone_number"]; + + NSString *label = usePhoneNumber ? NSLocalizedString(@"PHONE NUMBER", nil) : NSLocalizedString(@"USERNAME", nil); + [self findLabel:ViewElement_Username_Label].text = label; + + UITextField *text = [self findTextField:ViewElement_Username]; + if (usePhoneNumber) { + text.keyboardType = UIKeyboardTypePhonePad; + [text addDoneButton]; + } else { + text.keyboardType = UIKeyboardTypeDefault; + } +} + ++ (void)cleanTextField:(UIView *)view { + if ([view isKindOfClass:UIAssistantTextField.class]) { + [(UIAssistantTextField *)view setText:@""]; + ((UIAssistantTextField *)view).canShowError = NO; + } else { + for (UIView *subview in view.subviews) { + [AssistantView cleanTextField:subview]; + } + } +} + +- (void)shouldEnableNextButton { + BOOL invalidInputs = NO; + for (int i = 0; i < ViewElement_TextFieldCount; i++) { + UIAssistantTextField *field = [self findTextField:100 + i]; + if (field) { + invalidInputs |= (field.isInvalid || field.lastText.length == 0); + } + } + [self findButton:ViewElement_NextButton].enabled = !invalidInputs; +} + +- (UIView *)findView:(ViewElement)tag inView:view ofType:(Class)type { + for (UIView *child in [view subviews]) { + if (child.tag == tag) { + return child; + } else { + UIView *o = [self findView:tag inView:child ofType:type]; + if (o) + return o; + } + } + return nil; +} + +- (UIAssistantTextField *)findTextField:(ViewElement)tag { + return (UIAssistantTextField *)[self findView:tag inView:self.contentView ofType:[UIAssistantTextField class]]; +} + +- (UIButton *)findButton:(ViewElement)tag { + return (UIButton *)[self findView:tag inView:self.contentView ofType:[UIButton class]]; +} + +- (UILabel *)findLabel:(ViewElement)tag { + return (UILabel *)[self findView:tag inView:self.contentView ofType:[UILabel class]]; +} + +- (void)prepareErrorLabels { + UIAssistantTextField *createUsername = [self findTextField:ViewElement_Username]; + [createUsername showError:[AssistantView errorForStatus:LinphoneAccountCreatorUsernameInvalid] + when:^BOOL(NSString *inputEntry) { + LinphoneAccountCreatorStatus s = + linphone_account_creator_set_username(account_creator, inputEntry.UTF8String); + createUsername.errorLabel.text = [AssistantView errorForStatus:s]; + return s != LinphoneAccountCreatorOK; + }]; + + UIAssistantTextField *password = [self findTextField:ViewElement_Password]; + [password showError:[AssistantView errorForStatus:LinphoneAccountCreatorPasswordTooShort] + when:^BOOL(NSString *inputEntry) { + LinphoneAccountCreatorStatus s = + linphone_account_creator_set_password(account_creator, inputEntry.UTF8String); + password.errorLabel.text = [AssistantView errorForStatus:s]; + return s != LinphoneAccountCreatorOK; + }]; + + UIAssistantTextField *password2 = [self findTextField:ViewElement_Password2]; + [password2 showError:NSLocalizedString(@"Passwords do not match.", nil) + when:^BOOL(NSString *inputEntry) { + return ![inputEntry isEqualToString:[self findTextField:ViewElement_Password].text]; + }]; + + UIAssistantTextField *email = [self findTextField:ViewElement_Email]; + [email showError:[AssistantView errorForStatus:LinphoneAccountCreatorEmailInvalid] + when:^BOOL(NSString *inputEntry) { + LinphoneAccountCreatorStatus s = + linphone_account_creator_set_email(account_creator, inputEntry.UTF8String); + email.errorLabel.text = [AssistantView errorForStatus:s]; + return s != LinphoneAccountCreatorOK; + }]; + + UIAssistantTextField *domain = [self findTextField:ViewElement_Domain]; + [domain showError:[AssistantView errorForStatus:LinphoneAccountCreatorDomainInvalid] + when:^BOOL(NSString *inputEntry) { + LinphoneAccountCreatorStatus s = + linphone_account_creator_set_domain(account_creator, inputEntry.UTF8String); + domain.errorLabel.text = [AssistantView errorForStatus:s]; + return s != LinphoneAccountCreatorOK; + }]; + + UIAssistantTextField *url = [self findTextField:ViewElement_URL]; + [url showError:NSLocalizedString(@"Invalid remote provisioning URL", nil) + when:^BOOL(NSString *inputEntry) { + if (inputEntry.length > 0) { + // missing prefix will result in http:// being used + if ([inputEntry rangeOfString:@"://"].location == NSNotFound) { + inputEntry = [NSString stringWithFormat:@"http://%@", inputEntry]; + } + return (linphone_core_set_provisioning_uri([LinphoneManager getLc], inputEntry.UTF8String) != 0); + } + return TRUE; + }]; + + UIAssistantTextField *displayName = [self findTextField:ViewElement_DisplayName]; + [displayName showError:[AssistantView errorForStatus:LinphoneAccountCreatorDisplayNameInvalid] + when:^BOOL(NSString *inputEntry) { + LinphoneAccountCreatorStatus s = + linphone_account_creator_set_display_name(account_creator, inputEntry.UTF8String); + displayName.errorLabel.text = [AssistantView errorForStatus:s]; + return s != LinphoneAccountCreatorOK; + }]; + + [self shouldEnableNextButton]; +} + +#pragma mark - Event Functions + +- (void)registrationUpdateEvent:(NSNotification *)notif { + NSString *message = [notif.userInfo objectForKey:@"message"]; + [self registrationUpdate:[[notif.userInfo objectForKey:@"state"] intValue] + forProxy:[[notif.userInfo objectForKeyedSubscript:@"cfg"] pointerValue] + message:message]; +} + +- (void)registrationUpdate:(LinphoneRegistrationState)state + forProxy:(LinphoneProxyConfig *)proxy + message:(NSString *)message { + // in assistant we only care about ourself + if (proxy != new_config) { + return; + } + + switch (state) { + case LinphoneRegistrationOk: { + _waitView.hidden = true; + [PhoneMainView.instance changeCurrentView:DialerView.compositeViewDescription]; + break; + } + case LinphoneRegistrationNone: + case LinphoneRegistrationCleared: { + _waitView.hidden = true; + break; + } + case LinphoneRegistrationFailed: { + _waitView.hidden = true; + if ([message isEqualToString:@"Forbidden"]) { + message = NSLocalizedString(@"Incorrect username or password.", nil); + } + DTAlertView *alert = [[DTAlertView alloc] initWithTitle:NSLocalizedString(@"Registration failure", nil) + message:message + delegate:nil + cancelButtonTitle:@"Cancel" + otherButtonTitles:nil]; + [alert addButtonWithTitle:@"Continue" + block:^(void) { + [PhoneMainView.instance changeCurrentView:DialerView.compositeViewDescription]; + }]; + [alert show]; + break; + } + case LinphoneRegistrationProgress: { + _waitView.hidden = false; + break; + } + default: + break; + } +} + +- (void)configuringUpdate:(NSNotification *)notif { + LinphoneConfiguringState status = (LinphoneConfiguringState)[[notif.userInfo valueForKey:@"state"] integerValue]; + + _waitView.hidden = true; + + switch (status) { + case LinphoneConfiguringSuccessful: + if (nextView == nil) { + [self fillDefaultValues]; + } else { + [self changeView:nextView back:false animation:TRUE]; + nextView = nil; + } + break; + case LinphoneConfiguringFailed: { + NSString *error_message = [notif.userInfo valueForKey:@"message"]; + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Provisioning Load error", nil) + message:error_message + delegate:nil + cancelButtonTitle:NSLocalizedString(@"OK", nil) + otherButtonTitles:nil]; + [alert show]; + break; + } + + case LinphoneConfiguringSkipped: + default: + break; + } +} + +#pragma mark - Account creator callbacks + +void assistant_existence_tested(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status) { + AssistantView *thiz = (__bridge AssistantView *)(linphone_account_creator_get_user_data(creator)); + thiz.waitView.hidden = YES; + if (status == LinphoneAccountCreatorAccountExist) { + [[thiz findTextField:ViewElement_Username] showError:NSLocalizedString(@"This name is already taken.", nil)]; + [thiz findButton:ViewElement_NextButton].enabled = NO; + } else if (status == LinphoneAccountCreatorAccountNotExist) { + linphone_account_creator_create_account(thiz->account_creator); + } +} + +void assistant_create_account(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status) { + AssistantView *thiz = (__bridge AssistantView *)(linphone_account_creator_get_user_data(creator)); + thiz.waitView.hidden = YES; + if (status == LinphoneAccountCreatorAccountCreated) { + [thiz changeView:thiz.createAccountActivationView back:FALSE animation:TRUE]; + } else { + UIAlertView *errorView = [[UIAlertView alloc] + initWithTitle:NSLocalizedString(@"Account creation issue", nil) + message:NSLocalizedString(@"Your account could not be created, please try again later.", nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Continue", nil) + otherButtonTitles:nil, nil]; + [errorView show]; + } +} + +void assistant_validation_tested(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status) { + AssistantView *thiz = (__bridge AssistantView *)(linphone_account_creator_get_user_data(creator)); + thiz.waitView.hidden = YES; + if (status == LinphoneAccountCreatorAccountValidated) { + [thiz configureProxyConfig]; + } else if (status == LinphoneAccountCreatorAccountNotValidated) { + DTAlertView *alert = [[DTAlertView alloc] + initWithTitle:NSLocalizedString(@"Account validation failed", nil) + message: + NSLocalizedString( + @"Your account could not be checked yet. You can skip this validation or try again later.", + nil)]; + [alert addCancelButtonWithTitle:NSLocalizedString(@"Back", nil) block:nil]; + [alert addButtonWithTitle:NSLocalizedString(@"Skip verification", nil) + block:^{ + [thiz configureProxyConfig]; + [PhoneMainView.instance changeCurrentView:DialerView.compositeViewDescription]; + }]; + [alert show]; + } +} + +#pragma mark - UITextFieldDelegate Functions + +- (void)textFieldDidEndEditing:(UITextField *)textField { + UIAssistantTextField *atf = (UIAssistantTextField *)textField; + [atf textFieldDidEndEditing:atf]; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + [textField resignFirstResponder]; + if (textField.returnKeyType == UIReturnKeyNext) { + // text fields must be ordored by increasing tag value + NSInteger tag = textField.tag + 1; + while (tag < ViewElement_NextButton) { + UIView *v = [self.view viewWithTag:tag]; + if ([v isKindOfClass:UITextField.class]) { + [v becomeFirstResponder]; + break; + } + tag++; + } + } else if (textField.returnKeyType == UIReturnKeyDone) { + [[self findButton:ViewElement_NextButton] sendActionsForControlEvents:UIControlEventTouchUpInside]; + } + return YES; +} + +- (BOOL)textField:(UITextField *)textField + shouldChangeCharactersInRange:(NSRange)range + replacementString:(NSString *)string { + UIAssistantTextField *atf = (UIAssistantTextField *)textField; + [atf textField:atf shouldChangeCharactersInRange:range replacementString:string]; + if (atf.tag == ViewElement_Username && currentView == _createAccountView) { + atf.text = [atf.text stringByReplacingCharactersInRange:range withString:string.lowercaseString]; + [self shouldEnableNextButton]; + return NO; + } + [self shouldEnableNextButton]; + return YES; +} + +#pragma mark - Action Functions + +- (IBAction)onGotoCreateAccountClick:(id)sender { + nextView = _createAccountView; + [self loadAssistantConfig:@"assistant_linphone_create.rc"]; +} + +- (IBAction)onGotoLinphoneLoginClick:(id)sender { + nextView = _linphoneLoginView; + [self loadAssistantConfig:@"assistant_linphone_existing.rc"]; +} + +- (IBAction)onGotoLoginClick:(id)sender { + nextView = _loginView; + [self loadAssistantConfig:@"assistant_external_sip.rc"]; +} + +- (IBAction)onGotoRemoteProvisioningClick:(id)sender { + nextView = _remoteProvisioningView; + [self loadAssistantConfig:@"assistant_remote.rc"]; + [self findTextField:ViewElement_URL].text = + [[LinphoneManager instance] lpConfigStringForKey:@"config-uri" inSection:@"misc"]; +} + +- (IBAction)onCreateAccountClick:(id)sender { + _waitView.hidden = NO; + linphone_account_creator_test_existence(account_creator); +} + +- (IBAction)onCreateAccountActivationClick:(id)sender { + _waitView.hidden = NO; + linphone_account_creator_test_validation(account_creator); +} + +- (IBAction)onLinphoneLoginClick:(id)sender { + _waitView.hidden = NO; + [self configureProxyConfig]; +} + +- (IBAction)onLoginClick:(id)sender { + _waitView.hidden = NO; + [self configureProxyConfig]; +} + +- (IBAction)onRemoteProvisioningLoginClick:(id)sender { + _waitView.hidden = NO; + [[LinphoneManager instance] lpConfigSetInt:1 forKey:@"transient_provisioning" inSection:@"misc"]; + [self configureProxyConfig]; +} + +- (IBAction)onRemoteProvisioningDownloadClick:(id)sender { + [_waitView setHidden:false]; + [self resetLiblinphone]; +} + +- (IBAction)onTransportChange:(id)sender { + UISegmentedControl *transports = sender; + NSString *type = [transports titleForSegmentAtIndex:[transports selectedSegmentIndex]]; + linphone_account_creator_set_transport(account_creator, linphone_transport_parse(type.lowercaseString.UTF8String)); +} + +- (IBAction)onBackClick:(id)sender { + if ([historyViews count] > 0) { + UIView *view = [historyViews lastObject]; + [historyViews removeLastObject]; + [self changeView:view back:TRUE animation:TRUE]; + } +} + +- (IBAction)onDialerClick:(id)sender { + [PhoneMainView.instance changeCurrentView:DialerView.compositeViewDescription]; +} + +@end diff --git a/Classes/Base.lproj/AboutView.strings b/Classes/Base.lproj/AboutView.strings new file mode 100644 index 000000000..5cce46d13 Binary files /dev/null and b/Classes/Base.lproj/AboutView.strings differ diff --git a/Classes/Base.lproj/AboutView.xib b/Classes/Base.lproj/AboutView.xib new file mode 100644 index 000000000..8ea48f462 --- /dev/null +++ b/Classes/Base.lproj/AboutView.xib @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/AboutViewController.strings b/Classes/Base.lproj/AboutViewController.strings deleted file mode 100644 index 2f4d991a1..000000000 Binary files a/Classes/Base.lproj/AboutViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/AboutViewController.xib b/Classes/Base.lproj/AboutViewController.xib deleted file mode 100644 index 052697f51..000000000 --- a/Classes/Base.lproj/AboutViewController.xib +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/Base.lproj/AssistantSubviews.strings b/Classes/Base.lproj/AssistantSubviews.strings new file mode 100644 index 000000000..10e7b95e4 Binary files /dev/null and b/Classes/Base.lproj/AssistantSubviews.strings differ diff --git a/Classes/Base.lproj/AssistantView.strings b/Classes/Base.lproj/AssistantView.strings new file mode 100644 index 000000000..d3126f715 Binary files /dev/null and b/Classes/Base.lproj/AssistantView.strings differ diff --git a/Classes/Base.lproj/AssistantView.xib b/Classes/Base.lproj/AssistantView.xib new file mode 100644 index 000000000..2462d7a2c --- /dev/null +++ b/Classes/Base.lproj/AssistantView.xib @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/AssistantViewScreens.strings b/Classes/Base.lproj/AssistantViewScreens.strings new file mode 100644 index 000000000..7ca41d570 Binary files /dev/null and b/Classes/Base.lproj/AssistantViewScreens.strings differ diff --git a/Classes/Base.lproj/AssistantViewScreens.xib b/Classes/Base.lproj/AssistantViewScreens.xib new file mode 100644 index 000000000..885ad3d69 --- /dev/null +++ b/Classes/Base.lproj/AssistantViewScreens.xib @@ -0,0 +1,807 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/AssistantViews.strings b/Classes/Base.lproj/AssistantViews.strings new file mode 100644 index 000000000..8b6aa3f3b Binary files /dev/null and b/Classes/Base.lproj/AssistantViews.strings differ diff --git a/Classes/Base.lproj/AssistantView~ipad.strings b/Classes/Base.lproj/AssistantView~ipad.strings new file mode 100644 index 000000000..75a68e71e Binary files /dev/null and b/Classes/Base.lproj/AssistantView~ipad.strings differ diff --git a/Classes/Base.lproj/CallIncomingView.strings b/Classes/Base.lproj/CallIncomingView.strings new file mode 100644 index 000000000..383ae2d16 Binary files /dev/null and b/Classes/Base.lproj/CallIncomingView.strings differ diff --git a/Classes/Base.lproj/CallIncomingView.xib b/Classes/Base.lproj/CallIncomingView.xib new file mode 100644 index 000000000..61be53820 --- /dev/null +++ b/Classes/Base.lproj/CallIncomingView.xib @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/CallOutgoingView.strings b/Classes/Base.lproj/CallOutgoingView.strings new file mode 100644 index 000000000..4d3828f11 Binary files /dev/null and b/Classes/Base.lproj/CallOutgoingView.strings differ diff --git a/Classes/Base.lproj/CallOutgoingView.xib b/Classes/Base.lproj/CallOutgoingView.xib new file mode 100644 index 000000000..1bc8bc9e4 --- /dev/null +++ b/Classes/Base.lproj/CallOutgoingView.xib @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/CallView.strings b/Classes/Base.lproj/CallView.strings new file mode 100644 index 000000000..d3447624d Binary files /dev/null and b/Classes/Base.lproj/CallView.strings differ diff --git a/Classes/Base.lproj/CallView.xib b/Classes/Base.lproj/CallView.xib new file mode 100644 index 000000000..f43d8dfd8 --- /dev/null +++ b/Classes/Base.lproj/CallView.xib @@ -0,0 +1,1342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/CallView~ipad.strings b/Classes/Base.lproj/CallView~ipad.strings new file mode 100644 index 000000000..d3447624d Binary files /dev/null and b/Classes/Base.lproj/CallView~ipad.strings differ diff --git a/Classes/Base.lproj/CallView~ipad.xib b/Classes/Base.lproj/CallView~ipad.xib new file mode 100644 index 000000000..ceb08b808 --- /dev/null +++ b/Classes/Base.lproj/CallView~ipad.xib @@ -0,0 +1,1342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/ChatConversationCreateView.strings b/Classes/Base.lproj/ChatConversationCreateView.strings new file mode 100644 index 000000000..59fc38050 Binary files /dev/null and b/Classes/Base.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/Base.lproj/ChatConversationCreateView.xib b/Classes/Base.lproj/ChatConversationCreateView.xib new file mode 100644 index 000000000..d84a1581c --- /dev/null +++ b/Classes/Base.lproj/ChatConversationCreateView.xib @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/ChatConversationView.strings b/Classes/Base.lproj/ChatConversationView.strings new file mode 100644 index 000000000..67cc34ce7 Binary files /dev/null and b/Classes/Base.lproj/ChatConversationView.strings differ diff --git a/Classes/Base.lproj/ChatConversationView.xib b/Classes/Base.lproj/ChatConversationView.xib new file mode 100644 index 000000000..f36ddc7ba --- /dev/null +++ b/Classes/Base.lproj/ChatConversationView.xib @@ -0,0 +1,518 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/ChatRoomView.strings b/Classes/Base.lproj/ChatRoomView.strings new file mode 100644 index 000000000..fcaf31239 Binary files /dev/null and b/Classes/Base.lproj/ChatRoomView.strings differ diff --git a/Classes/Base.lproj/ChatRoomViewController.strings b/Classes/Base.lproj/ChatRoomViewController.strings deleted file mode 100644 index e43729de3..000000000 Binary files a/Classes/Base.lproj/ChatRoomViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/ChatRoomViewController.xib b/Classes/Base.lproj/ChatRoomViewController.xib deleted file mode 100644 index 9e0649197..000000000 --- a/Classes/Base.lproj/ChatRoomViewController.xib +++ /dev/null @@ -1,284 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Classes/Base.lproj/ChatView.strings b/Classes/Base.lproj/ChatView.strings new file mode 100644 index 000000000..0a6a5b802 Binary files /dev/null and b/Classes/Base.lproj/ChatView.strings differ diff --git a/Classes/Base.lproj/ChatViewController.strings b/Classes/Base.lproj/ChatViewController.strings deleted file mode 100644 index df5f383df..000000000 Binary files a/Classes/Base.lproj/ChatViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/ChatViewController.xib b/Classes/Base.lproj/ChatViewController.xib deleted file mode 100644 index 4f30247c4..000000000 --- a/Classes/Base.lproj/ChatViewController.xib +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/Base.lproj/ChatsListView.strings b/Classes/Base.lproj/ChatsListView.strings new file mode 100644 index 000000000..0b47e4e67 Binary files /dev/null and b/Classes/Base.lproj/ChatsListView.strings differ diff --git a/Classes/Base.lproj/ChatsListView.xib b/Classes/Base.lproj/ChatsListView.xib new file mode 100644 index 000000000..facfd51be --- /dev/null +++ b/Classes/Base.lproj/ChatsListView.xib @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/ContactDetailsLabelViewController.strings b/Classes/Base.lproj/ContactDetailsLabelViewController.strings deleted file mode 100644 index 8b94d8006..000000000 Binary files a/Classes/Base.lproj/ContactDetailsLabelViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/ContactDetailsLabelViewController.xib b/Classes/Base.lproj/ContactDetailsLabelViewController.xib deleted file mode 100644 index 86563261f..000000000 --- a/Classes/Base.lproj/ContactDetailsLabelViewController.xib +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Classes/Base.lproj/ContactDetailsView.strings b/Classes/Base.lproj/ContactDetailsView.strings new file mode 100644 index 000000000..e1f38b24f Binary files /dev/null and b/Classes/Base.lproj/ContactDetailsView.strings differ diff --git a/Classes/Base.lproj/ContactDetailsView.xib b/Classes/Base.lproj/ContactDetailsView.xib new file mode 100644 index 000000000..8509227f8 --- /dev/null +++ b/Classes/Base.lproj/ContactDetailsView.xib @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/ContactDetailsViewController.strings b/Classes/Base.lproj/ContactDetailsViewController.strings deleted file mode 100644 index 03077eff7..000000000 Binary files a/Classes/Base.lproj/ContactDetailsViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/ContactDetailsViewController.xib b/Classes/Base.lproj/ContactDetailsViewController.xib deleted file mode 100644 index ae71b3d63..000000000 --- a/Classes/Base.lproj/ContactDetailsViewController.xib +++ /dev/null @@ -1,149 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Classes/Base.lproj/ContactsListView.strings b/Classes/Base.lproj/ContactsListView.strings new file mode 100644 index 000000000..75457d146 Binary files /dev/null and b/Classes/Base.lproj/ContactsListView.strings differ diff --git a/Classes/Base.lproj/ContactsListView.xib b/Classes/Base.lproj/ContactsListView.xib new file mode 100644 index 000000000..07a46be74 --- /dev/null +++ b/Classes/Base.lproj/ContactsListView.xib @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/ContactsView.strings b/Classes/Base.lproj/ContactsView.strings new file mode 100644 index 000000000..933e3a629 Binary files /dev/null and b/Classes/Base.lproj/ContactsView.strings differ diff --git a/Classes/Base.lproj/ContactsViewController.strings b/Classes/Base.lproj/ContactsViewController.strings deleted file mode 100644 index c293d1ca7..000000000 Binary files a/Classes/Base.lproj/ContactsViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/ContactsViewController.xib b/Classes/Base.lproj/ContactsViewController.xib deleted file mode 100644 index 96630bbeb..000000000 --- a/Classes/Base.lproj/ContactsViewController.xib +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/Base.lproj/DialerView.strings b/Classes/Base.lproj/DialerView.strings new file mode 100644 index 000000000..bf9f7ce85 Binary files /dev/null and b/Classes/Base.lproj/DialerView.strings differ diff --git a/Classes/Base.lproj/DialerView.xib b/Classes/Base.lproj/DialerView.xib new file mode 100644 index 000000000..3fa40a409 --- /dev/null +++ b/Classes/Base.lproj/DialerView.xib @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/DialerViewController.strings b/Classes/Base.lproj/DialerViewController.strings deleted file mode 100644 index ec1ffab03..000000000 Binary files a/Classes/Base.lproj/DialerViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/DialerViewController.xib b/Classes/Base.lproj/DialerViewController.xib deleted file mode 100644 index 5bf776102..000000000 --- a/Classes/Base.lproj/DialerViewController.xib +++ /dev/null @@ -1,373 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/Base.lproj/DialerViewController~ipad.strings b/Classes/Base.lproj/DialerViewController~ipad.strings deleted file mode 100644 index ebef471b0..000000000 Binary files a/Classes/Base.lproj/DialerViewController~ipad.strings and /dev/null differ diff --git a/Classes/Base.lproj/DialerViewController~ipad.xib b/Classes/Base.lproj/DialerViewController~ipad.xib deleted file mode 100644 index 63f48482e..000000000 --- a/Classes/Base.lproj/DialerViewController~ipad.xib +++ /dev/null @@ -1,411 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/Base.lproj/DialerView~ipad.strings b/Classes/Base.lproj/DialerView~ipad.strings new file mode 100644 index 000000000..73c5de5ae Binary files /dev/null and b/Classes/Base.lproj/DialerView~ipad.strings differ diff --git a/Classes/Base.lproj/DialerView~ipad.xib b/Classes/Base.lproj/DialerView~ipad.xib new file mode 100644 index 000000000..6b554e8bf --- /dev/null +++ b/Classes/Base.lproj/DialerView~ipad.xib @@ -0,0 +1,739 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/FirstLoginView.strings b/Classes/Base.lproj/FirstLoginView.strings new file mode 100644 index 000000000..79d9cfea7 Binary files /dev/null and b/Classes/Base.lproj/FirstLoginView.strings differ diff --git a/Classes/Base.lproj/FirstLoginView.xib b/Classes/Base.lproj/FirstLoginView.xib new file mode 100644 index 000000000..8f1b51bcd --- /dev/null +++ b/Classes/Base.lproj/FirstLoginView.xib @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/FirstLoginViewController.strings b/Classes/Base.lproj/FirstLoginViewController.strings deleted file mode 100644 index 9a0f04f2d..000000000 Binary files a/Classes/Base.lproj/FirstLoginViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/FirstLoginViewController.xib b/Classes/Base.lproj/FirstLoginViewController.xib deleted file mode 100644 index 7693bbc4d..000000000 --- a/Classes/Base.lproj/FirstLoginViewController.xib +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Classes/Base.lproj/HistoryDetailsView.strings b/Classes/Base.lproj/HistoryDetailsView.strings new file mode 100644 index 000000000..3aac4d589 Binary files /dev/null and b/Classes/Base.lproj/HistoryDetailsView.strings differ diff --git a/Classes/Base.lproj/HistoryDetailsView.xib b/Classes/Base.lproj/HistoryDetailsView.xib new file mode 100644 index 000000000..6104ac807 --- /dev/null +++ b/Classes/Base.lproj/HistoryDetailsView.xib @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/HistoryDetailsViewController.strings b/Classes/Base.lproj/HistoryDetailsViewController.strings deleted file mode 100644 index 9ea355e8d..000000000 Binary files a/Classes/Base.lproj/HistoryDetailsViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/HistoryDetailsViewController.xib b/Classes/Base.lproj/HistoryDetailsViewController.xib deleted file mode 100644 index 05a1ac272..000000000 --- a/Classes/Base.lproj/HistoryDetailsViewController.xib +++ /dev/null @@ -1,273 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/Base.lproj/HistoryListView.strings b/Classes/Base.lproj/HistoryListView.strings new file mode 100644 index 000000000..1d0c576ad Binary files /dev/null and b/Classes/Base.lproj/HistoryListView.strings differ diff --git a/Classes/Base.lproj/HistoryListView.xib b/Classes/Base.lproj/HistoryListView.xib new file mode 100644 index 000000000..bd1aab325 --- /dev/null +++ b/Classes/Base.lproj/HistoryListView.xib @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/HistoryView.strings b/Classes/Base.lproj/HistoryView.strings new file mode 100644 index 000000000..d29c7a5b6 Binary files /dev/null and b/Classes/Base.lproj/HistoryView.strings differ diff --git a/Classes/Base.lproj/HistoryViewController.strings b/Classes/Base.lproj/HistoryViewController.strings deleted file mode 100644 index 39300297a..000000000 Binary files a/Classes/Base.lproj/HistoryViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/HistoryViewController.xib b/Classes/Base.lproj/HistoryViewController.xib deleted file mode 100644 index 395069f00..000000000 --- a/Classes/Base.lproj/HistoryViewController.xib +++ /dev/null @@ -1,158 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Classes/Base.lproj/ImageView.strings b/Classes/Base.lproj/ImageView.strings new file mode 100644 index 000000000..ade838734 Binary files /dev/null and b/Classes/Base.lproj/ImageView.strings differ diff --git a/Classes/Base.lproj/ImageView.xib b/Classes/Base.lproj/ImageView.xib new file mode 100644 index 000000000..6ed90765a --- /dev/null +++ b/Classes/Base.lproj/ImageView.xib @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/ImageViewController.strings b/Classes/Base.lproj/ImageViewController.strings deleted file mode 100644 index c08d5260a..000000000 Binary files a/Classes/Base.lproj/ImageViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/ImageViewController.xib b/Classes/Base.lproj/ImageViewController.xib deleted file mode 100644 index 9f0f00db1..000000000 --- a/Classes/Base.lproj/ImageViewController.xib +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Classes/Base.lproj/InCallView.strings b/Classes/Base.lproj/InCallView.strings new file mode 100644 index 000000000..229e293de Binary files /dev/null and b/Classes/Base.lproj/InCallView.strings differ diff --git a/Classes/Base.lproj/InCallViewController.strings b/Classes/Base.lproj/InCallViewController.strings deleted file mode 100644 index a592b9719..000000000 Binary files a/Classes/Base.lproj/InCallViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/InCallViewController.xib b/Classes/Base.lproj/InCallViewController.xib deleted file mode 100644 index a1239218f..000000000 --- a/Classes/Base.lproj/InCallViewController.xib +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/Base.lproj/IncomingCallView.strings b/Classes/Base.lproj/IncomingCallView.strings new file mode 100644 index 000000000..d880a031c Binary files /dev/null and b/Classes/Base.lproj/IncomingCallView.strings differ diff --git a/Classes/Base.lproj/IncomingCallViewController.strings b/Classes/Base.lproj/IncomingCallViewController.strings deleted file mode 100644 index 1ea6da905..000000000 Binary files a/Classes/Base.lproj/IncomingCallViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/IncomingCallViewController.xib b/Classes/Base.lproj/IncomingCallViewController.xib deleted file mode 100644 index 70078f290..000000000 --- a/Classes/Base.lproj/IncomingCallViewController.xib +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Classes/Base.lproj/IncomingCallViewController~ipad.strings b/Classes/Base.lproj/IncomingCallViewController~ipad.strings deleted file mode 100644 index c82d0111a..000000000 Binary files a/Classes/Base.lproj/IncomingCallViewController~ipad.strings and /dev/null differ diff --git a/Classes/Base.lproj/IncomingCallViewController~ipad.xib b/Classes/Base.lproj/IncomingCallViewController~ipad.xib deleted file mode 100644 index d296c73bb..000000000 --- a/Classes/Base.lproj/IncomingCallViewController~ipad.xib +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/Base.lproj/IncomingCallView~ipad.strings b/Classes/Base.lproj/IncomingCallView~ipad.strings new file mode 100644 index 000000000..322b0100b Binary files /dev/null and b/Classes/Base.lproj/IncomingCallView~ipad.strings differ diff --git a/Classes/Base.lproj/LaunchScreen.strings b/Classes/Base.lproj/LaunchScreen.strings new file mode 100644 index 000000000..d20f77ce5 Binary files /dev/null and b/Classes/Base.lproj/LaunchScreen.strings differ diff --git a/Classes/Base.lproj/LaunchScreen.xib b/Classes/Base.lproj/LaunchScreen.xib new file mode 100644 index 000000000..7704de7e7 --- /dev/null +++ b/Classes/Base.lproj/LaunchScreen.xib @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/PhoneMainView.xib b/Classes/Base.lproj/PhoneMainView.xib index 7a775401b..13d8cc75c 100644 --- a/Classes/Base.lproj/PhoneMainView.xib +++ b/Classes/Base.lproj/PhoneMainView.xib @@ -1,8 +1,8 @@ - + - - + + @@ -13,33 +13,38 @@ - - - + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + - + + + - + - - - - - - - diff --git a/Classes/Base.lproj/SettingsView.strings b/Classes/Base.lproj/SettingsView.strings new file mode 100644 index 000000000..eda4583d1 Binary files /dev/null and b/Classes/Base.lproj/SettingsView.strings differ diff --git a/Classes/Base.lproj/SettingsView.xib b/Classes/Base.lproj/SettingsView.xib new file mode 100644 index 000000000..32dc99fa4 --- /dev/null +++ b/Classes/Base.lproj/SettingsView.xib @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/SettingsViewController.xib b/Classes/Base.lproj/SettingsViewController.xib deleted file mode 100644 index a3294b948..000000000 --- a/Classes/Base.lproj/SettingsViewController.xib +++ /dev/null @@ -1,276 +0,0 @@ - - - - 1536 - 11E53 - 2840 - 1138.47 - 569.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1926 - - - IBProxyObject - IBUINavigationBar - IBUINavigationController - IBUINavigationItem - IBUIView - IBUIViewController - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - {320, 460} - - - _NS:9 - - 3 - MCAwAA - - IBCocoaTouchFramework - - - NO - - - IBCocoaTouchFramework - - - - 1 - 1 - - IBCocoaTouchFramework - NO - - - - NO - NO - - - - 1 - 1 - - YES - IBCocoaTouchFramework - NO - - - 256 - {0, 0} - _NS:15 - NO - YES - YES - IBCocoaTouchFramework - 1 - NO - - - - - - - - - view - - - - 9 - - - - navigationController - - - - 15 - - - - settingsController - - - - 8 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 4 - - - - - - 10 - - - - - - navigationController - - - 11 - - - navigationBar - - - 6 - - - - - - settingsController - - - 14 - - - - settingsItem - - - - - SettingsViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UINavigationControllerEx - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UINavigationBarEx - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - IASKAppSettingsViewControllerEx - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 19 - - - - - IASKAppSettingsViewController - UITableViewController - - delegate - id - - - delegate - - delegate - id - - - - IBProjectSource - ./Classes/IASKAppSettingsViewController.h - - - - IASKAppSettingsViewControllerEx - IASKAppSettingsViewController - - IBProjectSource - ./Classes/IASKAppSettingsViewControllerEx.h - - - - SettingsViewController - UIViewController - - UINavigationController - IASKAppSettingsViewController - - - - navigationController - UINavigationController - - - settingsController - IASKAppSettingsViewController - - - - IBProjectSource - ./Classes/SettingsViewController.h - - - - UINavigationBarEx - UINavigationBar - - IBProjectSource - ./Classes/UINavigationBarEx.h - - - - UINavigationControllerEx - UINavigationController - - IBProjectSource - ./Classes/UINavigationControllerEx.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - YES - 3 - 1926 - - diff --git a/Classes/Base.lproj/SideMenuView.strings b/Classes/Base.lproj/SideMenuView.strings new file mode 100644 index 000000000..98c49fa04 Binary files /dev/null and b/Classes/Base.lproj/SideMenuView.strings differ diff --git a/Classes/Base.lproj/SideMenuView.xib b/Classes/Base.lproj/SideMenuView.xib new file mode 100644 index 000000000..50397d262 --- /dev/null +++ b/Classes/Base.lproj/SideMenuView.xib @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/SideMenuView~ipad.strings b/Classes/Base.lproj/SideMenuView~ipad.strings new file mode 100644 index 000000000..98c49fa04 Binary files /dev/null and b/Classes/Base.lproj/SideMenuView~ipad.strings differ diff --git a/Classes/Base.lproj/SideMenuView~ipad.xib b/Classes/Base.lproj/SideMenuView~ipad.xib new file mode 100644 index 000000000..175226f7a --- /dev/null +++ b/Classes/Base.lproj/SideMenuView~ipad.xib @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/WizardViewController.strings b/Classes/Base.lproj/WizardViewController.strings deleted file mode 100644 index 638e700a9..000000000 Binary files a/Classes/Base.lproj/WizardViewController.strings and /dev/null differ diff --git a/Classes/Base.lproj/WizardViewController.xib b/Classes/Base.lproj/WizardViewController.xib deleted file mode 100644 index bc04a016c..000000000 --- a/Classes/Base.lproj/WizardViewController.xib +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Classes/Base.lproj/WizardViewController~ipad.strings b/Classes/Base.lproj/WizardViewController~ipad.strings deleted file mode 100644 index be01bf7ee..000000000 Binary files a/Classes/Base.lproj/WizardViewController~ipad.strings and /dev/null differ diff --git a/Classes/Base.lproj/WizardViewController~ipad.xib b/Classes/Base.lproj/WizardViewController~ipad.xib deleted file mode 100644 index ad94a9549..000000000 --- a/Classes/Base.lproj/WizardViewController~ipad.xib +++ /dev/null @@ -1,203 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/Base.lproj/WizardViews.strings b/Classes/Base.lproj/WizardViews.strings deleted file mode 100644 index 8083292b3..000000000 Binary files a/Classes/Base.lproj/WizardViews.strings and /dev/null differ diff --git a/Classes/Base.lproj/WizardViews.xib b/Classes/Base.lproj/WizardViews.xib deleted file mode 100644 index ccd52f81a..000000000 --- a/Classes/Base.lproj/WizardViews.xib +++ /dev/null @@ -1,533 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/CallConferenceTableView.h b/Classes/CallConferenceTableView.h new file mode 100644 index 000000000..d7d8b201f --- /dev/null +++ b/Classes/CallConferenceTableView.h @@ -0,0 +1,16 @@ +// +// CallConferenceTableView.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 14/10/15. +// +// + +#import + +@interface CallConferenceTableView : UITableViewController { + @private + NSTimer *updateTime; +} + +@end diff --git a/Classes/CallConferenceTableView.m b/Classes/CallConferenceTableView.m new file mode 100644 index 000000000..7a5f389a8 --- /dev/null +++ b/Classes/CallConferenceTableView.m @@ -0,0 +1,99 @@ +/* InCallTableViewController.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "CallConferenceTableView.h" +#import "UICallConferenceCell.h" +#import "LinphoneManager.h" +#import "Utils.h" + +@implementation CallConferenceTableView + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + updateTime = + [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(update) userInfo:nil repeats:YES]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + if (updateTime != nil) { + [updateTime invalidate]; + updateTime = nil; + } +} + +#pragma mark - UI change + +- (void)update { + [self.tableView reloadData]; +} + +#pragma mark - UITableViewDataSource Functions +- (LinphoneCall *)conferenceCallForRow:(NSInteger)row { + const MSList *calls = linphone_core_get_calls([LinphoneManager getLc]); + int i = -1; + while (calls) { + if (linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(calls->data))) { + i++; + if (i == row) + break; + } + calls = calls->next; + } + return (calls ? calls->data : NULL); +} + +#pragma mark - UITableViewDataSource Functions + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + NSString *kCellId = NSStringFromClass(UICallConferenceCell.class); + UICallConferenceCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + if (cell == nil) { + cell = [[UICallConferenceCell alloc] initWithIdentifier:kCellId]; + } + [cell setCall:[self conferenceCallForRow:indexPath.row]]; + return cell; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + const MSList *calls = linphone_core_get_calls([LinphoneManager getLc]); + int count = 0; + while (calls) { + if (linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(calls->data))) { + count++; + } + calls = calls->next; + } + return count; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { + return 1e-5; +} +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { + return 1e-5; +} + +@end diff --git a/Classes/CallIncomingView.h b/Classes/CallIncomingView.h new file mode 100644 index 000000000..05d12b915 --- /dev/null +++ b/Classes/CallIncomingView.h @@ -0,0 +1,49 @@ +/* IncomingCallViewController.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import + +#import "UICompositeView.h" +#import "TPMultiLayoutViewController.h" +#import "UIRoundedImageView.h" +#include "LinphoneManager.h" + +@protocol IncomingCallViewDelegate + +- (void)incomingCallAccepted:(LinphoneCall *)call evenWithVideo:(BOOL)video; +- (void)incomingCallDeclined:(LinphoneCall *)call; +- (void)incomingCallAborted:(LinphoneCall *)call; + +@end + +@interface CallIncomingView : TPMultiLayoutViewController { +} +@property(weak, nonatomic) IBOutlet UILabel *nameLabel; +@property(nonatomic, strong) IBOutlet UILabel *addressLabel; +@property(nonatomic, strong) IBOutlet UIRoundedImageView *avatarImage; +@property(nonatomic, assign) LinphoneCall *call; +@property(nonatomic, strong) id delegate; +@property(weak, nonatomic) IBOutlet UIView *tabVideoBar; +@property(weak, nonatomic) IBOutlet UIView *tabBar; + +- (IBAction)onAcceptClick:(id)event; +- (IBAction)onDeclineClick:(id)event; +- (IBAction)onAcceptAudioOnlyClick:(id)sender; + +@end diff --git a/Classes/CallIncomingView.m b/Classes/CallIncomingView.m new file mode 100644 index 000000000..ec431a6d0 --- /dev/null +++ b/Classes/CallIncomingView.m @@ -0,0 +1,133 @@ +/* IncomingCallViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "CallIncomingView.h" +#import "LinphoneManager.h" +#import "FastAddressBook.h" +#import "PhoneMainView.h" +#import "Utils.h" + +@implementation CallIncomingView + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(callUpdateEvent:) + name:kLinphoneCallUpdate + object:nil]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneCallUpdate object:nil]; +} + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:nil + sideMenu:CallSideMenuView.class + fullscreen:false + isLeftFragment:YES + fragmentWith:nil]; + compositeDescription.darkBackground = true; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - Event Functions + +- (void)callUpdateEvent:(NSNotification *)notif { + LinphoneCall *acall = [[notif.userInfo objectForKey:@"call"] pointerValue]; + LinphoneCallState astate = [[notif.userInfo objectForKey:@"state"] intValue]; + [self callUpdate:acall state:astate]; +} + +- (void)callUpdate:(LinphoneCall *)acall state:(LinphoneCallState)astate { + if (_call == acall && (astate == LinphoneCallEnd || astate == LinphoneCallError)) { + [_delegate incomingCallAborted:_call]; + [self dismiss]; + } else if ([LinphoneManager.instance lpConfigBoolForKey:@"auto_answer"]) { + LinphoneCallState state = linphone_call_get_state(_call); + if (state == LinphoneCallIncomingReceived) { + LOGI(@"Auto answering call"); + [self onAcceptClick:nil]; + } + } +} + +#pragma mark - + +- (void)dismiss { + if ([[PhoneMainView.instance currentView] equal:CallIncomingView.compositeViewDescription]) { + [PhoneMainView.instance popCurrentView]; + } +} + +- (void)update { + const LinphoneAddress *addr = linphone_call_get_remote_address(_call); + [ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr]; + char *uri = linphone_address_as_string_uri_only(addr); + _addressLabel.text = [NSString stringWithUTF8String:uri]; + ms_free(uri); + [_avatarImage setImage:[FastAddressBook imageForAddress:addr thumbnail:NO] bordered:YES withRoundedRadius:YES]; + + _tabBar.hidden = linphone_call_params_video_enabled(linphone_call_get_remote_params(_call)); + _tabVideoBar.hidden = !_tabBar.hidden; +} + +#pragma mark - Property Functions + +- (void)setCall:(LinphoneCall *)call { + _call = call; + [self update]; + [self callUpdate:_call state:linphone_call_get_state(call)]; +} + +#pragma mark - Action Functions + +- (IBAction)onAcceptClick:(id)event { + [self dismiss]; + [_delegate incomingCallAccepted:_call evenWithVideo:YES]; +} + +- (IBAction)onDeclineClick:(id)event { + [self dismiss]; + [_delegate incomingCallDeclined:_call]; +} + +- (IBAction)onAcceptAudioOnlyClick:(id)sender { + [self dismiss]; + [_delegate incomingCallAccepted:_call evenWithVideo:NO]; +} + +@end diff --git a/Classes/LinphoneUI/UIDigitButtonLongVoiceMail.h b/Classes/CallOutgoingView.h similarity index 58% rename from Classes/LinphoneUI/UIDigitButtonLongVoiceMail.h rename to Classes/CallOutgoingView.h index 2bfaf7b64..183975da9 100644 --- a/Classes/LinphoneUI/UIDigitButtonLongVoiceMail.h +++ b/Classes/CallOutgoingView.h @@ -1,7 +1,6 @@ - -/* UIDigitButton.h +/* OutgoingCallViewController.h * - * Copyright (C) 2011 Belledonne Comunications, Grenoble, France + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,16 +19,17 @@ #import -#import "UIDigitButton.h" +#import "UICompositeView.h" +#import "TPMultiLayoutViewController.h" +#include "linphone/linphonecore.h" +#import "UIRoundedImageView.h" - -@interface UIDigitButtonLongVoiceMail : UIDigitButton { +@interface CallOutgoingView : TPMultiLayoutViewController { } +@property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage; +@property(weak, nonatomic) IBOutlet UILabel *nameLabel; +@property(weak, nonatomic) IBOutlet UILabel *addressLabel; -/* 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; +- (IBAction)onDeclineClick:(id)sender; @end diff --git a/Classes/CallOutgoingView.m b/Classes/CallOutgoingView.m new file mode 100644 index 000000000..b8807ca08 --- /dev/null +++ b/Classes/CallOutgoingView.m @@ -0,0 +1,73 @@ +/* OutgoingCallViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "CallOutgoingView.h" +#import "PhoneMainView.h" + +@implementation CallOutgoingView + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:nil + sideMenu:CallSideMenuView.class + fullscreen:false + isLeftFragment:NO + fragmentWith:nil]; + + compositeDescription.darkBackground = true; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); + if (!call) { + if (![PhoneMainView.instance popCurrentView]) { + [PhoneMainView.instance changeCurrentView:DialerView.compositeViewDescription]; + } + } else { + const LinphoneAddress *addr = linphone_call_get_remote_address(call); + [ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr]; + char *uri = linphone_address_as_string_uri_only(addr); + _addressLabel.text = [NSString stringWithUTF8String:uri]; + ms_free(uri); + [_avatarImage setImage:[FastAddressBook imageForAddress:addr thumbnail:NO] bordered:YES withRoundedRadius:YES]; + } +} + +- (IBAction)onDeclineClick:(id)sender { + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); + if (call) { + linphone_core_terminate_call([LinphoneManager getLc], call); + } + [PhoneMainView.instance popCurrentView]; +} +@end diff --git a/Classes/LinphoneUI/UITransparentTVCell.h b/Classes/CallPausedTableView.h similarity index 82% rename from Classes/LinphoneUI/UITransparentTVCell.h rename to Classes/CallPausedTableView.h index a0318cbd4..7b64bc45e 100644 --- a/Classes/LinphoneUI/UITransparentTVCell.h +++ b/Classes/CallPausedTableView.h @@ -1,4 +1,4 @@ -/* UITransparentTVCell.h +/* InCallTableViewController.h * * Copyright (C) 2012 Belledonne Comunications, Grenoble, France * @@ -10,7 +10,7 @@ * 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. + * 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 @@ -19,6 +19,9 @@ #import -@interface UITransparentTVCell : UITableViewCell +@interface CallPausedTableView : UITableViewController { + @private + NSTimer *updateTime; +} @end diff --git a/Classes/CallPausedTableView.m b/Classes/CallPausedTableView.m new file mode 100644 index 000000000..2f62d8e41 --- /dev/null +++ b/Classes/CallPausedTableView.m @@ -0,0 +1,112 @@ +/* InCallTableViewController.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "CallPausedTableView.h" +#import "UICallPausedCell.h" +#import "LinphoneManager.h" +#import "Utils.h" + +@implementation CallPausedTableView + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + updateTime = + [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(update) userInfo:nil repeats:YES]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + if (updateTime != nil) { + [updateTime invalidate]; + updateTime = nil; + } +} + +#pragma mark - UI change + +- (void)update { + [self.tableView reloadData]; + CGRect newOrigin = self.tableView.frame; + newOrigin.size.height = + [self tableView:self.tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]] * + [self tableView:self.tableView numberOfRowsInSection:0]; + newOrigin.origin.y += self.tableView.frame.size.height - newOrigin.size.height; + self.tableView.frame = newOrigin; +} + +#pragma mark - UITableViewDataSource Functions +- (LinphoneCall *)conferenceCallForRow:(NSInteger)row { + const MSList *calls = linphone_core_get_calls([LinphoneManager getLc]); + int i = -1; + while (calls) { + if (linphone_call_get_state(calls->data) == LinphoneCallPaused) { + i++; + if (i == row) + break; + } + calls = calls->next; + } + // we should reach this only when we are querying for conference + return (calls ? calls->data : NULL); +} + +#pragma mark - UITableViewDataSource Functions + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + NSString *kCellId = NSStringFromClass(UICallPausedCell.class); + UICallPausedCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + if (cell == nil) { + cell = [[UICallPausedCell alloc] initWithIdentifier:kCellId]; + } + [cell setCall:[self conferenceCallForRow:indexPath.row]]; + return cell; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + const MSList *calls = linphone_core_get_calls([LinphoneManager getLc]); + int count = 0; + int conference_in_pause = 0; + while (calls) { + LinphoneCall *call = calls->data; + if (linphone_call_get_state(call) == LinphoneCallPaused) { + count++; + } + if (linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call)) && + !linphone_core_is_in_conference([LinphoneManager getLc])) { + conference_in_pause = 1; + } + calls = calls->next; + } + return count + conference_in_pause; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { + return 1e-5; +} +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { + return 1e-5; +} + +@end diff --git a/Classes/CallSideMenuView.h b/Classes/CallSideMenuView.h new file mode 100644 index 000000000..b3b40a169 --- /dev/null +++ b/Classes/CallSideMenuView.h @@ -0,0 +1,20 @@ +// +// SideMenuViewController.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 28/07/15. +// +// + +#import + +#import "SideMenuTableView.h" +#import "PhoneMainView.h" + +@interface CallSideMenuView : UIViewController + +@property(weak, nonatomic) IBOutlet UILabel *statsLabel; + +- (IBAction)onLateralSwipe:(id)sender; + +@end diff --git a/Classes/CallSideMenuView.m b/Classes/CallSideMenuView.m new file mode 100644 index 000000000..a8bb1cdb8 --- /dev/null +++ b/Classes/CallSideMenuView.m @@ -0,0 +1,146 @@ +// +// SideMenuViewController.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 28/07/15. +// +// + +#import "CallSideMenuView.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" + +@implementation CallSideMenuView { + NSTimer *updateTimer; +} + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + updateTimer = + [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateStats) userInfo:nil repeats:YES]; + [self updateStats]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + if (updateTimer != nil) { + [updateTimer invalidate]; + updateTimer = nil; + } +} + +- (IBAction)onLateralSwipe:(id)sender { + [PhoneMainView.instance.mainViewController hideSideMenu:YES]; +} + ++ (NSString *)iceToString:(LinphoneIceState)state { + switch (state) { + case LinphoneIceStateNotActivated: + return NSLocalizedString(@"Not activated", @"ICE has not been activated for this call"); + break; + case LinphoneIceStateFailed: + return NSLocalizedString(@"Failed", @"ICE processing has failed"); + break; + case LinphoneIceStateInProgress: + return NSLocalizedString(@"In progress", @"ICE process is in progress"); + break; + case LinphoneIceStateHostConnection: + return NSLocalizedString(@"Direct connection", + @"ICE has established a direct connection to the remote host"); + break; + case LinphoneIceStateReflexiveConnection: + return NSLocalizedString( + @"NAT(s) connection", + @"ICE has established a connection to the remote host through one or several NATs"); + break; + case LinphoneIceStateRelayConnection: + return NSLocalizedString(@"Relay connection", @"ICE has established a connection through a relay"); + break; + } +} + +- (NSString *)updateStatsForCall:(LinphoneCall *)call stream:(LinphoneStreamType)stream { + NSMutableString *result = [[NSMutableString alloc] init]; + const PayloadType *payload = NULL; + const LinphoneCallStats *stats; + const LinphoneCallParams *params = linphone_call_get_current_params(call); + NSString *name; + + switch (stream) { + case LinphoneStreamTypeAudio: + name = @"Audio"; + payload = linphone_call_params_get_used_audio_codec(params); + stats = linphone_call_get_audio_stats(call); + break; + case LinphoneStreamTypeText: + name = @"Text"; + payload = linphone_call_params_get_used_text_codec(params); + stats = linphone_call_get_text_stats(call); + break; + case LinphoneStreamTypeVideo: + name = @"Video"; + payload = linphone_call_params_get_used_video_codec(params); + stats = linphone_call_get_video_stats(call); + break; + case LinphoneStreamTypeUnknown: + break; + } + if (payload == NULL) { + return result; + } + + [result appendString:@"\n"]; + [result appendString:name]; + [result appendString:@"\n"]; + + [result appendString:[NSString stringWithFormat:@"Codec: %s/%iHz", payload->mime_type, payload->clock_rate]]; + if (stream == LinphoneStreamTypeAudio) { + [result appendString:[NSString stringWithFormat:@"/%i channels", payload->channels]]; + } + [result appendString:@"\n"]; + + if (stats != NULL) { + [result appendString:[NSString stringWithFormat:@"Upload bandwidth: %1.1f kbits/s", stats->upload_bandwidth]]; + [result appendString:@"\n"]; + [result + appendString:[NSString stringWithFormat:@"Download bandwidth: %1.1f kbits/s", stats->download_bandwidth]]; + [result appendString:@"\n"]; + [result appendString:[NSString stringWithFormat:@"ICE state: %@", [self.class iceToString:stats->ice_state]]]; + [result appendString:@"\n"]; + + if (stream == LinphoneStreamTypeVideo) { + MSVideoSize sentSize = linphone_call_params_get_sent_video_size(params); + MSVideoSize recvSize = linphone_call_params_get_received_video_size(params); + float sentFPS = linphone_call_params_get_sent_framerate(params); + float recvFPS = linphone_call_params_get_received_framerate(params); + [result appendString:[NSString stringWithFormat:@"Sent video resolution: %dx%d (%.1fFPS)", sentSize.width, + sentSize.height, sentFPS]]; + [result appendString:@"\n"]; + [result appendString:[NSString stringWithFormat:@"Received video resolution: %dx%d (%.1fFPS)", + recvSize.width, recvSize.height, recvFPS]]; + [result appendString:@"\n"]; + } + } + return result; +} + +- (void)updateStats { + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); + + if (!call) { + _statsLabel.text = NSLocalizedString(@"No call in progress", nil); + return; + } + + NSMutableString *stats = [[NSMutableString alloc] init]; + + [stats appendString:[self updateStatsForCall:call stream:LinphoneStreamTypeAudio]]; + [stats appendString:[self updateStatsForCall:call stream:LinphoneStreamTypeVideo]]; + [stats appendString:[self updateStatsForCall:call stream:LinphoneStreamTypeText]]; + + _statsLabel.text = stats; +} + +@end diff --git a/Classes/CallSideMenuView.xib b/Classes/CallSideMenuView.xib new file mode 100644 index 000000000..efe501257 --- /dev/null +++ b/Classes/CallSideMenuView.xib @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/CallView.h b/Classes/CallView.h new file mode 100644 index 000000000..9647eee25 --- /dev/null +++ b/Classes/CallView.h @@ -0,0 +1,110 @@ +/* InCallViewController.h + * + * Copyright (C) 2009 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import + +#import "VideoZoomHandler.h" +#import "UICamSwitch.h" + +#import "UICompositeView.h" +#import "CallPausedTableView.h" + +#import "UIMicroButton.h" +#import "UIPauseButton.h" +#import "UISpeakerButton.h" +#import "UIVideoButton.h" +#import "UIHangUpButton.h" +#import "UIDigitButton.h" +#import "UIRoundedImageView.h" +#import "UIBouncingView.h" + +@class VideoView; + +@interface CallView : TPMultiLayoutViewController { + @private + UITapGestureRecognizer *singleFingerTap; + NSTimer *hideControlsTimer; + NSTimer *videoDismissTimer; + BOOL videoShown; + VideoZoomHandler *videoZoomHandler; +} + +@property(nonatomic, strong) IBOutlet CallPausedTableView *pausedCallsTable; + +@property(nonatomic, strong) IBOutlet UIView *videoGroup; +@property(nonatomic, strong) IBOutlet UIView *videoView; +@property(nonatomic, strong) IBOutlet UIView *videoPreview; +@property(nonatomic, strong) IBOutlet UICamSwitch *videoCameraSwitch; +@property(nonatomic, strong) IBOutlet UIActivityIndicatorView *videoWaitingForFirstImage; +@property(weak, nonatomic) IBOutlet UIView *callView; + +@property(nonatomic, strong) IBOutlet UIPauseButton *callPauseButton; +@property(nonatomic, strong) IBOutlet UIButton *optionsConferenceButton; +@property(nonatomic, strong) IBOutlet UIVideoButton *videoButton; +@property(nonatomic, strong) IBOutlet UIMicroButton *microButton; +@property(nonatomic, strong) IBOutlet UISpeakerButton *speakerButton; +@property(nonatomic, strong) IBOutlet UIToggleButton *routesButton; +@property(nonatomic, strong) IBOutlet UIToggleButton *optionsButton; +@property(nonatomic, strong) IBOutlet UIHangUpButton *hangupButton; +@property(nonatomic, strong) IBOutlet UIView *numpadView; +@property(nonatomic, strong) IBOutlet UIView *routesView; +@property(nonatomic, strong) IBOutlet UIView *optionsView; +@property(nonatomic, strong) IBOutlet UIButton *routesEarpieceButton; +@property(nonatomic, strong) IBOutlet UIButton *routesSpeakerButton; +@property(nonatomic, strong) IBOutlet UIButton *routesBluetoothButton; +@property(nonatomic, strong) IBOutlet UIButton *optionsAddButton; +@property(nonatomic, strong) IBOutlet UIButton *optionsTransferButton; +@property(nonatomic, strong) IBOutlet UIToggleButton *numpadButton; +@property(weak, nonatomic) IBOutlet UIPauseButton *conferencePauseButton; +@property(weak, nonatomic) IBOutlet UIBouncingView *chatNotificationView; +@property(weak, nonatomic) IBOutlet UILabel *chatNotificationLabel; + +@property(weak, nonatomic) IBOutlet UIView *bottomBar; +@property(nonatomic, strong) IBOutlet UIDigitButton *oneButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *twoButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *threeButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *fourButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *fiveButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *sixButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *sevenButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *eightButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *nineButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *starButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *zeroButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *hashButton; +@property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage; +@property(weak, nonatomic) IBOutlet UILabel *nameLabel; +@property(weak, nonatomic) IBOutlet UILabel *durationLabel; +@property(weak, nonatomic) IBOutlet UIView *pausedByRemoteView; +@property(weak, nonatomic) IBOutlet UIView *noActiveCallView; +@property(weak, nonatomic) IBOutlet UIView *conferenceView; +@property(strong, nonatomic) IBOutlet CallPausedTableView *conferenceCallsTable; + +- (IBAction)onRoutesClick:(id)sender; +- (IBAction)onRoutesBluetoothClick:(id)sender; +- (IBAction)onRoutesEarpieceClick:(id)sender; +- (IBAction)onRoutesSpeakerClick:(id)sender; +- (IBAction)onOptionsClick:(id)sender; +- (IBAction)onOptionsTransferClick:(id)sender; +- (IBAction)onOptionsAddClick:(id)sender; +- (IBAction)onOptionsConferenceClick:(id)sender; +- (IBAction)onNumpadClick:(id)sender; +- (IBAction)onChatClick:(id)sender; + +@end diff --git a/Classes/CallView.m b/Classes/CallView.m new file mode 100644 index 000000000..c80986893 --- /dev/null +++ b/Classes/CallView.m @@ -0,0 +1,898 @@ +/* InCallViewController.h + * + * Copyright (C) 2009 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import +#import +#import +#import +#import +#import + +#import "CallView.h" +#import "CallSideMenuView.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" +#import "Utils.h" + +#include "linphone/linphonecore.h" + +const NSInteger SECURE_BUTTON_TAG = 5; + +@implementation CallView { + BOOL hiddenVolume; +} + +#pragma mark - Lifecycle Functions + +- (id)init { + self = [super initWithNibName:NSStringFromClass(self.class) bundle:[NSBundle mainBundle]]; + if (self != nil) { + singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(toggleControls:)]; + videoZoomHandler = [[VideoZoomHandler alloc] init]; + } + return self; +} + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:nil + sideMenu:CallSideMenuView.class + fullscreen:false + isLeftFragment:YES + fragmentWith:nil]; + compositeDescription.darkBackground = true; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - ViewController Functions + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + + [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; + UIDevice *device = [UIDevice currentDevice]; + device.proximityMonitoringEnabled = YES; + + [PhoneMainView.instance setVolumeHidden:TRUE]; + hiddenVolume = TRUE; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + [self disableVideoDisplay:NO]; + + if (hideControlsTimer != nil) { + [hideControlsTimer invalidate]; + hideControlsTimer = nil; + } + + if (hiddenVolume) { + [PhoneMainView.instance setVolumeHidden:FALSE]; + hiddenVolume = FALSE; + } + + if (videoDismissTimer) { + [self dismissVideoActionSheet:videoDismissTimer]; + [videoDismissTimer invalidate]; + videoDismissTimer = nil; + } + + // Remove observer + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneCallUpdate object:nil]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(messageReceived:) + name:kLinphoneMessageReceived + object:nil]; + [self updateUnreadMessage:FALSE]; + + // Update on show + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); + LinphoneCallState state = (call != NULL) ? linphone_call_get_state(call) : 0; + [self callUpdate:call state:state animated:FALSE]; + [self hideRoutes:FALSE]; + [self hideOptions:FALSE]; + [self hidePad:FALSE]; + [self showSpeaker]; + [self callDurationUpdate]; + [self onCurrentCallChange]; + + // Set windows (warn memory leaks) + linphone_core_set_native_video_window_id([LinphoneManager getLc], (__bridge void *)(_videoView)); + linphone_core_set_native_preview_window_id([LinphoneManager getLc], (__bridge void *)(_videoPreview)); + + // Enable tap + [singleFingerTap setEnabled:TRUE]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(callUpdateEvent:) + name:kLinphoneCallUpdate + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(bluetoothAvailabilityUpdateEvent:) + name:kLinphoneBluetoothAvailabilityUpdate + object:nil]; + + [NSTimer scheduledTimerWithTimeInterval:1 + target:self + selector:@selector(callDurationUpdate) + userInfo:nil + repeats:YES]; +} + +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [[UIApplication sharedApplication] setIdleTimerDisabled:false]; + UIDevice *device = [UIDevice currentDevice]; + device.proximityMonitoringEnabled = NO; + + [PhoneMainView.instance fullScreen:false]; + // Disable tap + [singleFingerTap setEnabled:FALSE]; + + if (linphone_core_get_calls_nb([LinphoneManager getLc]) == 0) { + // reseting speaker button because no more call + _speakerButton.selected = FALSE; + } +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + [singleFingerTap setNumberOfTapsRequired:1]; + [singleFingerTap setCancelsTouchesInView:FALSE]; + [self.videoView addGestureRecognizer:singleFingerTap]; + + [videoZoomHandler setup:_videoGroup]; + _videoGroup.alpha = 0; + + [_videoCameraSwitch setPreview:_videoPreview]; + + UIPanGestureRecognizer *dragndrop = + [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(moveVideoPreview:)]; + dragndrop.minimumNumberOfTouches = 1; + [_videoPreview addGestureRecognizer:dragndrop]; + + [_zeroButton setDigit:'0']; + [_zeroButton setDtmf:true]; + [_oneButton setDigit:'1']; + [_oneButton setDtmf:true]; + [_twoButton setDigit:'2']; + [_twoButton setDtmf:true]; + [_threeButton setDigit:'3']; + [_threeButton setDtmf:true]; + [_fourButton setDigit:'4']; + [_fourButton setDtmf:true]; + [_fiveButton setDigit:'5']; + [_fiveButton setDtmf:true]; + [_sixButton setDigit:'6']; + [_sixButton setDtmf:true]; + [_sevenButton setDigit:'7']; + [_sevenButton setDtmf:true]; + [_eightButton setDigit:'8']; + [_eightButton setDtmf:true]; + [_nineButton setDigit:'9']; + [_nineButton setDtmf:true]; + [_starButton setDigit:'*']; + [_starButton setDtmf:true]; + [_hashButton setDigit:'#']; + [_hashButton setDtmf:true]; +} + +- (void)viewDidUnload { + [PhoneMainView.instance.view removeGestureRecognizer:singleFingerTap]; + // Remove all observer + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super viewDidUnload]; +} + +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { + [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; + [self updateUnreadMessage:NO]; + [self previewTouchLift]; + [self showStatusBar:!videoShown || (_nameLabel.alpha > 0.f)]; +} + +#pragma mark - + +- (void)updateBottomBar:(LinphoneCall *)call state:(LinphoneCallState)state { + LinphoneCore *lc = [LinphoneManager getLc]; + + [_speakerButton update]; + [_microButton update]; + [_callPauseButton update]; + [_conferencePauseButton update]; + [_videoButton update]; + [_hangupButton update]; + + _optionsButton.enabled = (!call || !linphone_call_media_in_progress(call)); + _optionsTransferButton.enabled = call && !linphone_call_media_in_progress(call); + // Show Pause/Conference button following call count + if (linphone_core_get_calls_nb(lc) > 1) { + bool enabled = ((linphone_core_get_current_call(lc) != NULL) || linphone_core_is_in_conference(lc)); + const MSList *list = linphone_core_get_calls(lc); + while (list != NULL) { + LinphoneCall *call = (LinphoneCall *)list->data; + LinphoneCallState state = linphone_call_get_state(call); + if (state == LinphoneCallIncomingReceived || state == LinphoneCallOutgoingInit || + state == LinphoneCallOutgoingProgress || state == LinphoneCallOutgoingRinging || + state == LinphoneCallOutgoingEarlyMedia || state == LinphoneCallConnected) { + enabled = false; + } + list = list->next; + } + _optionsConferenceButton.enabled = enabled; + } else { + _optionsConferenceButton.enabled = NO; + } + + // Disable transfert in conference + if (linphone_core_get_current_call(lc) == NULL) { + [_optionsTransferButton setEnabled:FALSE]; + } else { + [_optionsTransferButton setEnabled:TRUE]; + } + + switch (state) { + case LinphoneCallEnd: + case LinphoneCallError: + case LinphoneCallIncoming: + case LinphoneCallOutgoing: + [self hidePad:TRUE]; + [self hideOptions:TRUE]; + [self hideRoutes:TRUE]; + default: + break; + } +} + +- (void)bluetoothAvailabilityUpdate:(bool)available { + if (available) { + [self hideSpeaker]; + } else { + [self showSpeaker]; + } +} + +- (void)toggleControls:(id)sender { + bool controlsHidden = (_bottomBar.alpha == 0.0); + if (controlsHidden) { + [self showControls:sender]; + } else { + [self hideControls:sender]; + } +} + +- (void)showControls:(id)sender { + if (hideControlsTimer) { + [hideControlsTimer invalidate]; + hideControlsTimer = nil; + } + + if ([[PhoneMainView.instance currentView] equal:CallView.compositeViewDescription]) { + // show controls + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.35]; + _pausedCallsTable.tableView.alpha = _videoCameraSwitch.alpha = _callPauseButton.alpha = 1.0; + _routesView.alpha = _optionsView.alpha = _numpadView.alpha = _bottomBar.alpha = 1.0; + _nameLabel.alpha = _durationLabel.alpha = .8; + + [self showStatusBar:true]; + + [UIView commitAnimations]; + + [PhoneMainView.instance showTabBar:true]; + + // hide controls in 5 sec + hideControlsTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 + target:self + selector:@selector(hideControls:) + userInfo:nil + repeats:NO]; + } +} + +- (void)hideControls:(id)sender { + if (!videoShown) + return; + + if (hideControlsTimer) { + [hideControlsTimer invalidate]; + hideControlsTimer = nil; + } + + if ([[PhoneMainView.instance currentView] equal:CallView.compositeViewDescription]) { + + [PhoneMainView.instance showTabBar:false]; + + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.3]; + _pausedCallsTable.tableView.alpha = _videoCameraSwitch.alpha = _nameLabel.alpha = _durationLabel.alpha = + _callPauseButton.alpha = 0.0; + _routesView.alpha = _optionsView.alpha = _numpadView.alpha = _bottomBar.alpha = 0.0; + [self showStatusBar:false]; + [UIView commitAnimations]; + } +} + +- (void)enableVideoDisplay:(BOOL)animation { + if (videoShown && animation) + return; + + videoShown = true; + + [videoZoomHandler resetZoom]; + + if (animation) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:1.0]; + } + + [_videoGroup setAlpha:1.0]; + + [self hideControls:nil]; + + if (animation) { + [UIView commitAnimations]; + } + + _videoPreview.hidden = (!linphone_core_self_view_enabled([LinphoneManager getLc])); + + if ([LinphoneManager instance].frontCamId != nil) { + // only show camera switch button if we have more than 1 camera + [_videoCameraSwitch setHidden:FALSE]; + } + + [PhoneMainView.instance fullScreen:true]; + [PhoneMainView.instance showTabBar:false]; + +#ifdef TEST_VIDEO_VIEW_CHANGE + [NSTimer scheduledTimerWithTimeInterval:5.0 + target:self + selector:@selector(_debugChangeVideoView) + userInfo:nil + repeats:YES]; +#endif + // [self batteryLevelChanged:nil]; + + [_videoWaitingForFirstImage setHidden:NO]; + [_videoWaitingForFirstImage startAnimating]; + + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); + // linphone_call_params_get_used_video_codec return 0 if no video stream enabled + if (call != NULL && linphone_call_params_get_used_video_codec(linphone_call_get_current_params(call))) { + linphone_call_set_next_video_frame_decoded_callback(call, hideSpinner, (__bridge void *)(self)); + } +} + +- (void)disableVideoDisplay:(BOOL)animation { + if (!videoShown && animation) + return; + + videoShown = false; + if (animation) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:1.0]; + } + + [_videoGroup setAlpha:0.0]; + [PhoneMainView.instance showTabBar:true]; + + [self showControls:nil]; + + [_videoCameraSwitch setHidden:TRUE]; + + if (animation) { + [UIView commitAnimations]; + } + + if (hideControlsTimer != nil) { + [hideControlsTimer invalidate]; + hideControlsTimer = nil; + } + + [PhoneMainView.instance fullScreen:false]; +} + +- (void)displayVideoCall:(BOOL)animated { + [self enableVideoDisplay:animated]; +} + +- (void)displayTableCall:(BOOL)animated { + [self disableVideoDisplay:animated]; +} + +- (void)showStatusBar:(BOOL)show { + /* we cannot use [PhoneMainView.instance show]; because it will automatically + resize current view to fill empty space, which will resize video. This is + indesirable since we do not want to crop/rescale video view */ + PhoneMainView.instance.mainViewController.statusBarView.hidden = !show; +} +#pragma mark - Spinner Functions + +- (void)hideSpinnerIndicator:(LinphoneCall *)call { + _videoWaitingForFirstImage.hidden = TRUE; +} + +static void hideSpinner(LinphoneCall *call, void *user_data) { + CallView *thiz = (__bridge CallView *)user_data; + [thiz hideSpinnerIndicator:call]; +} + +#pragma mark - UI modification + +- (void)callDurationUpdate { + int duration = linphone_core_get_current_call([LinphoneManager getLc]) + ? linphone_call_get_duration(linphone_core_get_current_call([LinphoneManager getLc])) + : 0; + _durationLabel.text = [LinphoneUtils durationToString:duration]; +} + +- (void)onCurrentCallChange { + LinphoneCore *lc = [LinphoneManager getLc]; + LinphoneCall *call = linphone_core_get_current_call(lc); + + _noActiveCallView.hidden = (call || linphone_core_is_in_conference(lc)); + _callView.hidden = !call; + _conferenceView.hidden = !linphone_core_is_in_conference(lc); + _callPauseButton.hidden = !call && !linphone_core_is_in_conference(lc); + + [_callPauseButton setType:UIPauseButtonType_CurrentCall call:call]; + [_conferencePauseButton setType:UIPauseButtonType_Conference call:call]; + + if (!_callView.hidden) { + const LinphoneAddress *addr = linphone_call_get_remote_address(call); + [ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr]; + char *uri = linphone_address_as_string_uri_only(addr); + ms_free(uri); + [_avatarImage setImage:[FastAddressBook imageForAddress:addr thumbnail:NO] bordered:YES withRoundedRadius:YES]; + } +} + +- (void)showPad:(BOOL)animated { + [_numpadButton setOn]; + if ([_numpadView isHidden]) { + if (animated) { + [self showAnimation:_numpadView + completion:^(BOOL finished){ + }]; + } else { + [_numpadView setHidden:FALSE]; + } + } +} + +- (void)hidePad:(BOOL)animated { + [_numpadButton setOff]; + if (![_numpadView isHidden]) { + if (animated) { + [self hideAnimation:_numpadView + completion:^(BOOL finished){ + }]; + } else { + [_numpadView setHidden:TRUE]; + } + } +} + +- (void)showRoutes:(BOOL)animated { + if (![LinphoneManager runningOnIpad]) { + [_routesButton setOn]; + [_routesBluetoothButton setSelected:[[LinphoneManager instance] bluetoothEnabled]]; + [_routesSpeakerButton setSelected:[[LinphoneManager instance] speakerEnabled]]; + [_routesEarpieceButton setSelected:!([[LinphoneManager instance] bluetoothEnabled] || + [[LinphoneManager instance] speakerEnabled])]; + if ([_routesView isHidden]) { + if (animated) { + [self showAnimation:_routesView + completion:^(BOOL finished){ + }]; + } else { + [_routesView setHidden:FALSE]; + } + } + } +} + +- (void)hideRoutes:(BOOL)animated { + if (![LinphoneManager runningOnIpad]) { + [_routesButton setOff]; + if (![_routesView isHidden]) { + if (animated) { + [self hideAnimation:_routesView + completion:^(BOOL finished){ + }]; + } else { + [_routesView setHidden:TRUE]; + } + } + } +} + +- (void)showOptions:(BOOL)animated { + [_optionsButton setOn]; + if ([_optionsView isHidden]) { + if (animated) { + [self showAnimation:_optionsView + completion:^(BOOL finished){ + }]; + } else { + [_optionsView setHidden:FALSE]; + } + } +} + +- (void)hideOptions:(BOOL)animated { + [_optionsButton setOff]; + if (![_optionsView isHidden]) { + if (animated) { + [self hideAnimation:_optionsView + completion:^(BOOL finished){ + }]; + } else { + [_optionsView setHidden:TRUE]; + } + } +} + +- (void)showSpeaker { + if (![LinphoneManager runningOnIpad]) { + [_speakerButton setHidden:FALSE]; + [_routesButton setHidden:TRUE]; + } +} + +- (void)hideSpeaker { + if (![LinphoneManager runningOnIpad]) { + [_speakerButton setHidden:TRUE]; + [_routesButton setHidden:FALSE]; + } +} + +#pragma mark - Event Functions + +- (void)bluetoothAvailabilityUpdateEvent:(NSNotification *)notif { + bool available = [[notif.userInfo objectForKey:@"available"] intValue]; + [self bluetoothAvailabilityUpdate:available]; +} + +- (void)callUpdateEvent:(NSNotification *)notif { + LinphoneCall *call = [[notif.userInfo objectForKey:@"call"] pointerValue]; + LinphoneCallState state = [[notif.userInfo objectForKey:@"state"] intValue]; + [self callUpdate:call state:state animated:TRUE]; +} + +- (void)callUpdate:(LinphoneCall *)call state:(LinphoneCallState)state animated:(BOOL)animated { + LinphoneCore *lc = [LinphoneManager getLc]; + [self updateBottomBar:call state:state]; + if (hiddenVolume) { + [PhoneMainView.instance setVolumeHidden:FALSE]; + hiddenVolume = FALSE; + } + + // Update tables + [_pausedCallsTable.tableView reloadData]; + [_conferenceCallsTable.tableView reloadData]; + + static LinphoneCall *currentCall = NULL; + if (!currentCall || linphone_core_get_current_call(lc) != currentCall) { + currentCall = linphone_core_get_current_call(lc); + [self onCurrentCallChange]; + } + + // Fake call update + if (call == NULL) { + return; + } + + if (state != LinphoneCallPausedByRemote) { + _pausedByRemoteView.hidden = YES; + } + + switch (state) { + case LinphoneCallIncomingReceived: + case LinphoneCallOutgoingInit: + case LinphoneCallConnected: + case LinphoneCallStreamsRunning: { + // check video + if (linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { + [self displayVideoCall:animated]; + } else { + [self displayTableCall:animated]; + const LinphoneCallParams *param = linphone_call_get_current_params(call); + const LinphoneCallAppData *callAppData = + (__bridge const LinphoneCallAppData *)(linphone_call_get_user_pointer(call)); + if (state == LinphoneCallStreamsRunning && callAppData->videoRequested && + linphone_call_params_low_bandwidth_enabled(param)) { + // too bad video was not enabled because low bandwidth + UIAlertView *alert = [[UIAlertView alloc] + initWithTitle:NSLocalizedString(@"Low bandwidth", nil) + message:NSLocalizedString(@"Video cannot be activated because of low bandwidth " + @"condition, only audio is available", + nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Continue", nil) + otherButtonTitles:nil]; + [alert show]; + callAppData->videoRequested = FALSE; /*reset field*/ + } + } + break; + } + case LinphoneCallUpdatedByRemote: { + const LinphoneCallParams *current = linphone_call_get_current_params(call); + const LinphoneCallParams *remote = linphone_call_get_remote_params(call); + + /* remote wants to add video */ + if (linphone_core_video_display_enabled(lc) && !linphone_call_params_video_enabled(current) && + linphone_call_params_video_enabled(remote) && + !linphone_core_get_video_policy(lc)->automatically_accept) { + linphone_core_defer_call_update(lc, call); + [self displayAskToEnableVideoCall:call]; + } else if (linphone_call_params_video_enabled(current) && !linphone_call_params_video_enabled(remote)) { + [self displayTableCall:animated]; + } + break; + } + case LinphoneCallPausing: + case LinphoneCallPaused: + [self displayTableCall:animated]; + break; + case LinphoneCallPausedByRemote: + if (call == linphone_core_get_current_call(lc)) { + _pausedByRemoteView.hidden = NO; + } + break; + case LinphoneCallEnd: + case LinphoneCallError: + default: + break; + } +} + +#pragma mark - ActionSheet Functions + +- (void)displayAskToEnableVideoCall:(LinphoneCall *)call { + if (linphone_core_get_video_policy([LinphoneManager getLc])->automatically_accept) + return; + + NSString *username = [FastAddressBook displayNameForAddress:linphone_call_get_remote_address(call)]; + NSString *title = [NSString stringWithFormat:NSLocalizedString(@"%@ would like to enable video", nil), username]; + UIConfirmationDialog *sheet = [UIConfirmationDialog ShowWithMessage:title + cancelMessage:nil + confirmMessage:NSLocalizedString(@"ACCEPT", nil) + onCancelClick:^() { + LOGI(@"User declined video proposal"); + if (call == linphone_core_get_current_call([LinphoneManager getLc])) { + LinphoneCallParams *paramsCopy = linphone_call_params_copy(linphone_call_get_current_params(call)); + linphone_core_accept_call_update([LinphoneManager getLc], call, paramsCopy); + linphone_call_params_destroy(paramsCopy); + [videoDismissTimer invalidate]; + videoDismissTimer = nil; + } + } + onConfirmationClick:^() { + LOGI(@"User accept video proposal"); + if (call == linphone_core_get_current_call([LinphoneManager getLc])) { + LinphoneCallParams *paramsCopy = linphone_call_params_copy(linphone_call_get_current_params(call)); + linphone_call_params_enable_video(paramsCopy, TRUE); + linphone_core_accept_call_update([LinphoneManager getLc], call, paramsCopy); + linphone_call_params_destroy(paramsCopy); + [videoDismissTimer invalidate]; + videoDismissTimer = nil; + } + } + inController:self]; + videoDismissTimer = [NSTimer scheduledTimerWithTimeInterval:30 + target:self + selector:@selector(dismissVideoActionSheet:) + userInfo:sheet + repeats:NO]; +} + +- (void)dismissVideoActionSheet:(NSTimer *)timer { + UIConfirmationDialog *sheet = (UIConfirmationDialog *)timer.userInfo; + [sheet dismiss]; +} + +#pragma mark VideoPreviewMoving + +- (void)moveVideoPreview:(UIPanGestureRecognizer *)dragndrop { + CGPoint center = [dragndrop locationInView:_videoPreview.superview]; + _videoPreview.center = center; + if (dragndrop.state == UIGestureRecognizerStateEnded) { + [self previewTouchLift]; + } +} + +- (CGFloat)coerce:(CGFloat)value betweenMin:(CGFloat)min andMax:(CGFloat)max { + if (value > max) { + value = max; + } + if (value < min) { + value = min; + } + return value; +} + +- (void)previewTouchLift { + CGRect previewFrame = _videoPreview.frame; + previewFrame.origin.x = [self coerce:previewFrame.origin.x + betweenMin:5 + andMax:(self.view.frame.size.width - previewFrame.size.width - 5)]; + previewFrame.origin.y = [self coerce:previewFrame.origin.y + betweenMin:5 + andMax:(self.view.frame.size.height - previewFrame.size.height - 5)]; + + if (!CGRectEqualToRect(previewFrame, _videoPreview.frame)) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [UIView animateWithDuration:0.3 + animations:^{ + LOGI(@"Recentering preview to %@", NSStringFromCGRect(previewFrame)); + _videoPreview.frame = previewFrame; + }]; + }); + } +} + +#pragma mark - Action Functions + +- (IBAction)onNumpadClick:(id)sender { + if ([_numpadView isHidden]) { + [self showPad:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; + } else { + [self hidePad:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; + } +} + +- (IBAction)onChatClick:(id)sender { + ChatsListView *view = VIEW(ChatsListView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; +} + +- (IBAction)onRoutesBluetoothClick:(id)sender { + [self hideRoutes:TRUE]; + [[LinphoneManager instance] setBluetoothEnabled:TRUE]; +} + +- (IBAction)onRoutesEarpieceClick:(id)sender { + [self hideRoutes:TRUE]; + [[LinphoneManager instance] setSpeakerEnabled:FALSE]; + [[LinphoneManager instance] setBluetoothEnabled:FALSE]; +} + +- (IBAction)onRoutesSpeakerClick:(id)sender { + [self hideRoutes:TRUE]; + [[LinphoneManager instance] setSpeakerEnabled:TRUE]; +} + +- (IBAction)onRoutesClick:(id)sender { + if ([_routesView isHidden]) { + [self showRoutes:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; + } else { + [self hideRoutes:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; + } +} + +- (IBAction)onOptionsTransferClick:(id)sender { + [self hideOptions:TRUE]; + // Go to dialer view + DialerView *view = VIEW(DialerView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; + if (view != nil) { + [view setAddress:@""]; + [view setTransferMode:TRUE]; + } +} + +- (IBAction)onOptionsAddClick:(id)sender { + [self hideOptions:TRUE]; + // Go to dialer view + DialerView *view = VIEW(DialerView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; + [view setAddress:@""]; + [view setTransferMode:FALSE]; +} + +- (IBAction)onOptionsClick:(id)sender { + if ([_optionsView isHidden]) { + [self showOptions:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; + } else { + [self hideOptions:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; + } +} + +- (IBAction)onOptionsConferenceClick:(id)sender { + linphone_core_add_all_to_conference([LinphoneManager getLc]); +} + +#pragma mark - Animation + +- (void)showAnimation:(UIView *)target completion:(void (^)(BOOL finished))completion { + CGRect frame = target.frame; + int original_y = frame.origin.y; + frame.origin.y = self.view.frame.size.height; + target.frame = frame; + frame.origin.y = original_y; + target.hidden = NO; + + [UIView animateWithDuration:0.5 + delay:0.0 + options:UIViewAnimationOptionCurveEaseOut + animations:^{ + target.frame = frame; + } + completion:^(BOOL finished) { + target.frame = frame; // in case application did not finish + completion(finished); + }]; +} + +- (void)hideAnimation:(UIView *)target completion:(void (^)(BOOL finished))completion { + int original_y = target.frame.origin.y; + CGRect newFrame = target.frame; + newFrame.origin.y = self.view.frame.size.height; + [UIView animateWithDuration:0.5 + delay:0.0 + options:UIViewAnimationOptionCurveEaseIn + animations:^{ + target.frame = newFrame; + } + completion:^(BOOL finished) { + CGRect originFrame = target.frame; + originFrame.origin.y = original_y; + target.hidden = YES; + target.frame = originFrame; + completion(finished); + }]; +} + +#pragma mark - Bounce +- (void)messageReceived:(NSNotification *)notif { + [self updateUnreadMessage:TRUE]; +} +- (void)updateUnreadMessage:(BOOL)appear { + int unreadMessage = [LinphoneManager unreadMessageCount]; + if (unreadMessage > 0) { + _chatNotificationLabel.text = [NSString stringWithFormat:@"%i", unreadMessage]; + [_chatNotificationView startAnimating:appear]; + } else { + [_chatNotificationView stopAnimating:appear]; + } +} +@end diff --git a/Classes/ChatConversationCreateTableView.h b/Classes/ChatConversationCreateTableView.h new file mode 100644 index 000000000..252a08158 --- /dev/null +++ b/Classes/ChatConversationCreateTableView.h @@ -0,0 +1,14 @@ +// +// ChatConversationSearchTableView.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 30/09/15. +// +// + +#import + +@interface ChatConversationCreateTableView : UITableViewController +@property(weak, nonatomic) IBOutlet UISearchBar *searchBar; + +@end diff --git a/Classes/ChatConversationCreateTableView.m b/Classes/ChatConversationCreateTableView.m new file mode 100644 index 000000000..a82b4fa89 --- /dev/null +++ b/Classes/ChatConversationCreateTableView.m @@ -0,0 +1,121 @@ +// +// MyTableViewController.m +// UISearchDisplayController +// +// Created by Phillip Harris on 4/19/14. +// Copyright (c) 2014 Phillip Harris. All rights reserved. +// + +#import "ChatConversationCreateTableView.h" +#import "UIChatCreateCell.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" + +@interface ChatConversationCreateTableView () + +@property(nonatomic, strong) NSMutableDictionary *contacts; +@property(nonatomic, strong) NSDictionary *allContacts; +@end + +@implementation ChatConversationCreateTableView + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + self.allContacts = + [[NSDictionary alloc] initWithDictionary:LinphoneManager.instance.fastAddressBook.addressBookMap]; + self.contacts = [[NSMutableDictionary alloc] initWithCapacity:_allContacts.count]; + [_searchBar becomeFirstResponder]; + [_searchBar setText:@""]; + [self searchBar:_searchBar textDidChange:_searchBar.text]; + self.tableView.accessibilityIdentifier = @"Suggested addresses"; +} + +- (void)reloadDataWithFilter:(NSString *)filter { + [_contacts removeAllObjects]; + + [_allContacts enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { + NSString *address = (NSString *)key; + ABRecordRef person = (__bridge ABRecordRef)(value); + NSString *name = [FastAddressBook displayNameForContact:person]; + if ((filter.length == 0) || ([name.lowercaseString containsString:filter.lowercaseString]) || + ([address.lowercaseString containsString:filter.lowercaseString])) { + _contacts[address] = name; + } + + }]; + // also add current entry, if not listed + NSString *nsuri = filter.lowercaseString; + LinphoneAddress *addr = linphone_core_interpret_url([LinphoneManager getLc], nsuri.UTF8String); + if (addr) { + char *uri = linphone_address_as_string(addr); + nsuri = [NSString stringWithUTF8String:uri]; + ms_free(uri); + linphone_address_destroy(addr); + } + if (nsuri.length > 0 && [_contacts valueForKey:nsuri] == nil) { + _contacts[nsuri] = filter; + } + + [self.tableView reloadData]; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return [self.contacts count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + NSString *kCellId = NSStringFromClass(UIChatCreateCell.class); + UIChatCreateCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + if (cell == nil) { + cell = [[UIChatCreateCell alloc] initWithIdentifier:kCellId]; + } + cell.displayNameLabel.text = [_contacts.allValues objectAtIndex:indexPath.row]; + cell.addressLabel.text = [_contacts.allKeys objectAtIndex:indexPath.row]; + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + LinphoneChatRoom *room = linphone_core_get_chat_room_from_uri( + [LinphoneManager getLc], ((NSString *)[_contacts.allKeys objectAtIndex:indexPath.row]).UTF8String); + if (!room) { + [PhoneMainView.instance popCurrentView]; + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid address", nil) + message:@"Please specify the entire SIP address for the chat" + delegate:nil + cancelButtonTitle:NSLocalizedString(@"OK", nil) + otherButtonTitles:nil]; + [alert show]; + } else { + ChatConversationView *view = VIEW(ChatConversationView); + [view setChatRoom:room]; + [PhoneMainView.instance popCurrentView]; + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE]; + } +} + +- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { + searchBar.showsCancelButton = (searchText.length > 0); + [self reloadDataWithFilter:searchText]; +} + +- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar { + [searchBar setShowsCancelButton:FALSE animated:TRUE]; +} + +- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar { + [searchBar setShowsCancelButton:(searchBar.text.length > 0) animated:TRUE]; +} + +- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { + [searchBar resignFirstResponder]; +} + +- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { + [searchBar resignFirstResponder]; +} +@end diff --git a/Classes/ChatConversationCreateView.h b/Classes/ChatConversationCreateView.h new file mode 100644 index 000000000..676bc3543 --- /dev/null +++ b/Classes/ChatConversationCreateView.h @@ -0,0 +1,19 @@ +// +// ChatConversationCreateViewViewController.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 12/10/15. +// +// + +#import +#import "ChatConversationCreateTableView.h" +#import "UICompositeView.h" + +@interface ChatConversationCreateView : UIViewController + +@property(strong, nonatomic) IBOutlet ChatConversationCreateTableView *tableController; + +- (IBAction)onBackClick:(id)sender; + +@end diff --git a/Classes/ChatConversationCreateView.m b/Classes/ChatConversationCreateView.m new file mode 100644 index 000000000..0691b645b --- /dev/null +++ b/Classes/ChatConversationCreateView.m @@ -0,0 +1,45 @@ +// +// ChatConversationCreateViewViewController.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 12/10/15. +// +// + +#import "ChatConversationCreateView.h" +#import "PhoneMainView.h" + +@implementation ChatConversationCreateView + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:TabBarView.class + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:NO + fragmentWith:ChatsListView.class]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [_tableController.tableView reloadData]; +} + +#pragma mark - searchBar delegate + +- (IBAction)onBackClick:(id)sender { + [PhoneMainView.instance popCurrentView]; +} +@end diff --git a/Classes/ChatConversationTableView.h b/Classes/ChatConversationTableView.h new file mode 100644 index 000000000..87d19bf89 --- /dev/null +++ b/Classes/ChatConversationTableView.h @@ -0,0 +1,47 @@ +/* ChatRoomTableViewController.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import +#include "linphone/linphonecore.h" + +#import "UICheckBoxTableView.h" + +@protocol ChatConversationDelegate + +- (BOOL)startImageUpload:(UIImage *)image url:(NSURL *)url; +- (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url; +- (void)tableViewIsScrolling; + +@end + +@interface ChatConversationTableView : UICheckBoxTableView { + @private + LinphoneChatRoom *chatRoom; + MSList *messageList; +} + +@property(nonatomic, strong) id chatRoomDelegate; + +- (void)addChatEntry:(LinphoneChatMessage *)chat; +- (void)scrollToBottom:(BOOL)animated; +- (void)scrollToLastUnread:(BOOL)animated; +- (void)updateChatEntry:(LinphoneChatMessage *)chat; +- (void)setChatRoom:(LinphoneChatRoom *)room; + +@end diff --git a/Classes/ChatConversationTableView.m b/Classes/ChatConversationTableView.m new file mode 100644 index 000000000..03f181b68 --- /dev/null +++ b/Classes/ChatConversationTableView.m @@ -0,0 +1,228 @@ +/* ChatRoomTableViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "LinphoneManager.h" +#import "ChatConversationTableView.h" +#import "UIChatBubbleTextCell.h" +#import "UIChatBubblePhotoCell.h" +#import "PhoneMainView.h" + +@implementation ChatConversationTableView + +#pragma mark - Lifecycle Functions + +- (void)dealloc { + [self clearMessageList]; +} + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + self.tableView.accessibilityIdentifier = @"ChatRoom list"; + // this should not be needed, we should only load messages when setting the chat room + // [self reloadData]; +} + +#pragma mark - + +- (void)clearMessageList { + if (messageList) { + ms_list_free_with_data(messageList, (void (*)(void *))linphone_chat_message_unref); + messageList = nil; + } +} + +- (void)updateData { + if (!chatRoom) + return; + [self clearMessageList]; + messageList = linphone_chat_room_get_history(chatRoom, 0); + + // also append transient upload messages because they are not in history yet! + for (FileTransferDelegate *ftd in [[LinphoneManager instance] fileTransferDelegates]) { + const LinphoneAddress *ftd_peer = + linphone_chat_room_get_peer_address(linphone_chat_message_get_chat_room(ftd.message)); + const LinphoneAddress *peer = linphone_chat_room_get_peer_address(chatRoom); + if (linphone_address_equal(ftd_peer, peer) && linphone_chat_message_is_outgoing(ftd.message)) { + LOGI(@"Appending transient upload message %p", ftd.message); + messageList = ms_list_append(messageList, linphone_chat_message_ref(ftd.message)); + } + } +} + +- (void)reloadData { + [self updateData]; + [self.tableView reloadData]; + [self scrollToLastUnread:false]; +} + +- (void)addChatEntry:(LinphoneChatMessage *)chat { + + messageList = ms_list_append(messageList, linphone_chat_message_ref(chat)); + int pos = ms_list_size(messageList) - 1; + + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:pos inSection:0]; + [self.tableView beginUpdates]; + [self.tableView insertRowsAtIndexPaths:@[ indexPath ] withRowAnimation:UITableViewRowAnimationFade]; + [self.tableView endUpdates]; +} + +- (void)updateChatEntry:(LinphoneChatMessage *)chat { + NSInteger index = ms_list_index(messageList, chat); + if (index < 0) { + LOGW(@"chat entry doesn't exist"); + return; + } + [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:index inSection:0]] + withRowAnimation:FALSE]; // just reload + return; +} + +- (void)scrollToBottom:(BOOL)animated { + [self.tableView reloadData]; + int count = ms_list_size(messageList); + if (count) { + [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(count - 1) inSection:0] + atScrollPosition:UITableViewScrollPositionBottom + animated:YES]; + } +} + +- (void)debugMessages { + if (!messageList) { + LOGE(@"No data to debug"); + return; + } + MSList *item = messageList; + int count = 0; + while (item) { + LinphoneChatMessage *msg = (LinphoneChatMessage *)item->data; + LOGI(@"Message %d: %s", count++, linphone_chat_message_get_text(msg)); + item = item->next; + } +} + +- (void)scrollToLastUnread:(BOOL)animated { + if (messageList == nil || chatRoom == nil) { + return; + } + + int index = -1; + int count = ms_list_size(messageList); + // Find first unread & set all entry read + for (int i = 0; i < count; ++i) { + int read = linphone_chat_message_is_read(ms_list_nth_data(messageList, i)); + if (read == 0) { + if (index == -1) + index = i; + } + } + if (index == -1) { + index = count - 1; + } + + linphone_chat_room_mark_as_read(chatRoom); + TabBarView *tab = (TabBarView *)[PhoneMainView.instance.mainViewController + getCachedController:NSStringFromClass(TabBarView.class)]; + [tab update:YES]; + + // Scroll to unread + if (index >= 0) { + [self.tableView.layer removeAllAnimations]; + [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] + atScrollPosition:UITableViewScrollPositionTop + animated:animated]; + } +} + +#pragma mark - Property Functions + +- (void)setChatRoom:(LinphoneChatRoom *)room { + chatRoom = room; + [self reloadData]; +} + +#pragma mark - UITableViewDataSource Functions + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return ms_list_size(messageList); +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + NSString *kCellId = nil; + LinphoneChatMessage *chat = ms_list_nth_data(messageList, (int)[indexPath row]); + if (linphone_chat_message_get_file_transfer_information(chat) || + linphone_chat_message_get_external_body_url(chat)) { + kCellId = NSStringFromClass(UIChatBubblePhotoCell.class); + } else { + kCellId = NSStringFromClass(UIChatBubbleTextCell.class); + } + UIChatBubbleTextCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + if (cell == nil) { + cell = [[NSClassFromString(kCellId) alloc] initWithIdentifier:kCellId]; + } + [cell setChatMessage:chat]; + if (chat) { + [cell update]; + } + [cell setChatRoomDelegate:_chatRoomDelegate]; + [super accessoryForCell:cell atPath:indexPath]; + return cell; +} + +#pragma mark - UITableViewDelegate Functions + +- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { + [_chatRoomDelegate tableViewIsScrolling]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + LinphoneChatMessage *chat = ms_list_nth_data(messageList, (int)[indexPath row]); + return [UIChatBubbleTextCell ViewHeightForMessage:chat withWidth:self.view.frame.size.width].height; +} + +- (void)tableView:(UITableView *)tableView + commitEditingStyle:(UITableViewCellEditingStyle)editingStyle + forRowAtIndexPath:(NSIndexPath *)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + [tableView beginUpdates]; + LinphoneChatMessage *chat = ms_list_nth_data(messageList, (int)[indexPath row]); + linphone_chat_room_delete_message(chatRoom, chat); + messageList = ms_list_remove(messageList, chat); + + [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] + withRowAnimation:UITableViewRowAnimationBottom]; + [tableView endUpdates]; + } +} + +- (void)removeSelectionUsing:(void (^)(NSIndexPath *))remover { + [super removeSelectionUsing:^(NSIndexPath *indexPath) { + LinphoneChatMessage *chat = ms_list_nth_data(messageList, (int)[indexPath row]); + linphone_chat_room_delete_message(chatRoom, chat); + messageList = ms_list_remove(messageList, chat); + }]; +} + +@end diff --git a/Classes/ChatConversationView.h b/Classes/ChatConversationView.h new file mode 100644 index 000000000..cf28ebac1 --- /dev/null +++ b/Classes/ChatConversationView.h @@ -0,0 +1,70 @@ +/* ChatRoomViewController.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import + +#import "UIToggleButton.h" +#import "UICompositeView.h" +#import "ChatConversationTableView.h" +#import "ImagePickerView.h" +#import "OrderedDictionary.h" +#import "UIRoundedImageView.h" +#import "UIBackToCallButton.h" +#import "Utils/HPGrowingTextView/HPGrowingTextView.h" + +#include "linphone/linphonecore.h" + +@interface ChatConversationView + : TPMultiLayoutViewController { + LinphoneChatRoom *chatRoom; + OrderedDictionary *imageQualities; + BOOL scrollOnGrowingEnabled; + BOOL composingVisible; +} + +@property(weak, nonatomic) IBOutlet UIIconButton *backButton; +@property(nonatomic, strong) IBOutlet ChatConversationTableView *tableController; +@property(weak, nonatomic) IBOutlet HPGrowingTextView *messageField; +@property(weak, nonatomic) IBOutlet UIView *topBar; +@property(nonatomic, strong) IBOutlet UIButton *sendButton; +@property(nonatomic, strong) IBOutlet UILabel *addressLabel; +@property(nonatomic, strong) IBOutlet UIView *chatView; +@property(nonatomic, strong) IBOutlet UIView *messageView; +@property(nonatomic, strong) IBOutlet UITapGestureRecognizer *listTapGestureRecognizer; +@property(nonatomic, strong) IBOutlet UISwipeGestureRecognizer *listSwipeGestureRecognizer; +@property(strong, nonatomic) IBOutlet UILabel *composeLabel; +@property(strong, nonatomic) IBOutlet UIView *composeIndicatorView; +@property(nonatomic, strong) IBOutlet UIButton *pictureButton; +@property(weak, nonatomic) IBOutlet UIIconButton *callButton; +@property(weak, nonatomic) IBOutlet UIBackToCallButton *backToCallButton; + +- (IBAction)onBackClick:(id)event; +- (IBAction)onEditClick:(id)event; +- (IBAction)onMessageChange:(id)sender; +- (IBAction)onSendClick:(id)event; +- (IBAction)onPictureClick:(id)event; +- (IBAction)onListTap:(id)sender; +- (IBAction)onCallClick:(id)sender; +- (IBAction)onDeleteClick:(id)sender; +- (IBAction)onEditionChangeClick:(id)sender; + +- (void)setChatRoom:(LinphoneChatRoom *)room; + +@end diff --git a/Classes/ChatConversationView.m b/Classes/ChatConversationView.m new file mode 100644 index 000000000..35af6e569 --- /dev/null +++ b/Classes/ChatConversationView.m @@ -0,0 +1,696 @@ +/* ChatRoomViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "ChatConversationView.h" +#import "PhoneMainView.h" +#import "Utils.h" +#import "FileTransferDelegate.h" +#import "UIChatBubbleTextCell.h" + +@implementation ChatConversationView + +#pragma mark - Lifecycle Functions + +- (id)init { + self = [super initWithNibName:NSStringFromClass(self.class) bundle:[NSBundle mainBundle]]; + if (self != nil) { + scrollOnGrowingEnabled = TRUE; + chatRoom = NULL; + imageQualities = [[OrderedDictionary alloc] + initWithObjectsAndKeys:[NSNumber numberWithFloat:0.9], NSLocalizedString(@"Maximum", nil), + [NSNumber numberWithFloat:0.5], NSLocalizedString(@"Average", nil), + [NSNumber numberWithFloat:0.0], NSLocalizedString(@"Minimum", nil), nil]; + composingVisible = TRUE; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:TabBarView.class + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:NO + fragmentWith:ChatsListView.class]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - ViewController Functions + +- (void)viewDidLoad { + [super viewDidLoad]; + + // if we use fragments, remove back button + if (IPAD) { + _backButton.hidden = YES; + _backButton.alpha = 0; + } + + _messageField.minNumberOfLines = 1; + _messageField.maxNumberOfLines = ([LinphoneManager runningOnIpad]) ? 10 : 3; + _messageField.delegate = self; + _messageField.font = [UIFont systemFontOfSize:18.0f]; + _messageField.contentInset = UIEdgeInsetsMake(-15, 0, 0, 0); + // _messageField.internalTextView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, 10); + [_tableController setChatRoomDelegate:self]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationWillEnterForeground:) + name:UIApplicationDidBecomeActiveNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWillShow:) + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWillHide:) + name:UIKeyboardWillHideNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(textReceivedEvent:) + name:kLinphoneMessageReceived + object:nil]; + [[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(callUpdateEvent:) + name:kLinphoneCallUpdate + object:nil]; + + [_backToCallButton update]; + + if (_tableController.isEditing) { + [_tableController setEditing:NO]; + } + [[_tableController tableView] reloadData]; + + BOOL fileSharingEnabled = linphone_core_get_file_transfer_server([LinphoneManager getLc]) != NULL; + [_pictureButton setEnabled:fileSharingEnabled]; + + [self callUpdateEvent:nil]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + [_messageField resignFirstResponder]; + + [self setComposingVisible:FALSE withDelay:0]; // will hide the "user is composing.." message + + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { + [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; + // force offset recomputing + composingVisible = !composingVisible; + [self setComposingVisible:!composingVisible withDelay:0]; + [_backToCallButton update]; + [_tableController scrollToBottom:true]; +} + +#pragma mark - + +- (void)setChatRoom:(LinphoneChatRoom *)room { + chatRoom = room; + [_messageField setText:@""]; + [_tableController setChatRoom:room]; + + if (chatRoom != NULL) { + _chatView.hidden = NO; + [self update]; + linphone_chat_room_mark_as_read(chatRoom); + [self setComposingVisible:linphone_chat_room_is_remote_composing(chatRoom) withDelay:0]; + TabBarView *tab = (TabBarView *)[PhoneMainView.instance.mainViewController + getCachedController:NSStringFromClass(TabBarView.class)]; + [tab update:YES]; + } else { + _chatView.hidden = YES; + } +} + +- (void)applicationWillEnterForeground:(NSNotification *)notif { + if (chatRoom != nil) { + linphone_chat_room_mark_as_read(chatRoom); + TabBarView *tab = (TabBarView *)[PhoneMainView.instance.mainViewController + getCachedController:NSStringFromClass(TabBarView.class)]; + [tab update:YES]; + } +} + +- (void)callUpdateEvent:(NSNotification *)notif { + _callButton.hidden = + (_tableController.isEditing || linphone_core_get_current_call([LinphoneManager getLc]) != NULL); +} + +- (void)update { + if (chatRoom == NULL) { + LOGW(@"Cannot update chat room header: null contact"); + return; + } + + const LinphoneAddress *addr = linphone_chat_room_get_peer_address(chatRoom); + if (addr == NULL) { + [PhoneMainView.instance popCurrentView]; + UIAlertView *error = [[UIAlertView alloc] + initWithTitle:NSLocalizedString(@"Invalid SIP address", nil) + message:NSLocalizedString(@"Either configure a SIP proxy server from settings prior to send a " + @"message or use a valid SIP address (I.E sip:john@example.net)", + nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Continue", nil) + otherButtonTitles:nil]; + [error show]; + return; + } + [ContactDisplay setDisplayNameLabel:_addressLabel forAddress:addr]; + _addressLabel.accessibilityValue = _addressLabel.text; + _composeLabel.text = [NSString stringWithFormat:NSLocalizedString(@"%@ is composing...", nil), _addressLabel.text]; +} + +- (BOOL)sendMessage:(NSString *)message withExterlBodyUrl:(NSURL *)externalUrl withInternalURL:(NSURL *)internalUrl { + if (chatRoom == NULL) { + LOGW(@"Cannot send message: No chatroom"); + return FALSE; + } + + LinphoneChatMessage *msg = linphone_chat_room_create_message(chatRoom, [message UTF8String]); + if (externalUrl) { + linphone_chat_message_set_external_body_url(msg, [[externalUrl absoluteString] UTF8String]); + } + + if (internalUrl) { + // internal url is saved in the appdata for display and later save + [LinphoneManager setValueInMessageAppData:[internalUrl absoluteString] forKey:@"localimage" inMessage:msg]; + } + + linphone_chat_room_send_chat_message(chatRoom, msg); + [_tableController addChatEntry:msg]; + [_tableController scrollToBottom:true]; + + return TRUE; +} + +- (void)saveAndSend:(UIImage *)image url:(NSURL *)url { + // photo from Camera, must be saved first + if (url == nil) { + [[LinphoneManager instance] + .photoLibrary + writeImageToSavedPhotosAlbum:image.CGImage + orientation:(ALAssetOrientation)[image imageOrientation] + completionBlock:^(NSURL *assetURL, NSError *error) { + if (error) { + LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]); + + UIAlertView *errorAlert = [[UIAlertView alloc] + initWithTitle:NSLocalizedString(@"Transfer error", nil) + message:NSLocalizedString(@"Cannot write image to photo library", nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Ok", nil) + otherButtonTitles:nil, nil]; + [errorAlert show]; + } else { + LOGI(@"Image saved to [%@]", [assetURL absoluteString]); + [self startImageUpload:image url:assetURL]; + } + }]; + } else { + [self startImageUpload:image url:url]; + } +} + +- (void)chooseImageQuality:(UIImage *)image url:(NSURL *)url { + DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Choose the image size", nil)]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + for (NSString *key in [imageQualities allKeys]) { + NSNumber *number = [imageQualities objectForKey:key]; + NSData *data = UIImageJPEGRepresentation(image, [number floatValue]); + NSNumber *size = [NSNumber numberWithInteger:[data length]]; + + NSString *text = [NSString stringWithFormat:@"%@ (%@)", key, [size toHumanReadableSize]]; + [sheet addButtonWithTitle:text + block:^() { + [self saveAndSend:[UIImage imageWithData:data] url:url]; + }]; + } + [sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; + dispatch_async(dispatch_get_main_queue(), ^{ + [sheet showInView:PhoneMainView.instance.view]; + }); + }); +} + +- (void)setComposingVisible:(BOOL)visible withDelay:(CGFloat)delay { + + if (composingVisible == visible) + return; + + CGRect keyboardFrame = [_messageView frame]; + CGRect newComposingFrame = [_composeIndicatorView frame]; + CGRect newTableFrame = [_tableController.tableView frame]; + + if (visible) { + // pull up the composing frame and shrink the table view + newTableFrame.size.height -= newComposingFrame.size.height; + newComposingFrame.origin.y = keyboardFrame.origin.y - newComposingFrame.size.height; + } else { + // pull down the composing frame and widen the tableview + newTableFrame.size.height += newComposingFrame.size.height; + newComposingFrame.origin.y = keyboardFrame.origin.y; + } + composingVisible = visible; + [UIView animateWithDuration:delay + animations:^{ + _tableController.tableView.frame = newTableFrame; + _composeIndicatorView.frame = newComposingFrame; + } + completion:^(BOOL finished) { + [_tableController scrollToBottom:TRUE]; + }]; +} + +#pragma mark - Event Functions + +- (void)textReceivedEvent:(NSNotification *)notif { + LinphoneAddress *from = [[[notif userInfo] objectForKey:@"from_address"] pointerValue]; + LinphoneChatRoom *room = [[notif.userInfo objectForKey:@"room"] pointerValue]; + LinphoneChatMessage *chat = [[notif.userInfo objectForKey:@"message"] pointerValue]; + + if (from == NULL || chat == NULL) { + return; + } + char *fromStr = linphone_address_as_string_uri_only(from); + const LinphoneAddress *cr_from = linphone_chat_room_get_peer_address(chatRoom); + char *cr_from_string = linphone_address_as_string_uri_only(cr_from); + + if (fromStr && cr_from_string) { + + if (strcasecmp(cr_from_string, fromStr) == 0) { + if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) { + linphone_chat_room_mark_as_read(room); + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneMessageReceived object:self]; + } + [_tableController addChatEntry:chat]; + [_tableController scrollToLastUnread:TRUE]; + } + } + ms_free(fromStr); + ms_free(cr_from_string); +} + +- (void)textComposeEvent:(NSNotification *)notif { + LinphoneChatRoom *room = [[[notif userInfo] objectForKey:@"room"] pointerValue]; + if (room && room == chatRoom) { + BOOL composing = linphone_chat_room_is_remote_composing(room); + [self setComposingVisible:composing withDelay:0.3]; + } +} + +#pragma mark - UITextFieldDelegate Functions + +- (BOOL)growingTextViewShouldBeginEditing:(HPGrowingTextView *)growingTextView { + if (_tableController.isEditing) { + [_tableController setEditing:NO]; + } + [_listTapGestureRecognizer setEnabled:TRUE]; + return TRUE; +} + +- (BOOL)growingTextViewShouldEndEditing:(HPGrowingTextView *)growingTextView { + [_listTapGestureRecognizer setEnabled:FALSE]; + return TRUE; +} + +- (void)growingTextChanged:(HPGrowingTextView *)growingTextView text:(NSString *)text { + if ([text length] > 0 && chatRoom) + linphone_chat_room_compose(chatRoom); +} + +- (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height { + int diff = height - growingTextView.bounds.size.height; + + if (diff != 0) { + CGRect messageRect = [_messageView frame]; + messageRect.origin.y -= diff; + messageRect.size.height += diff; + [_messageView setFrame:messageRect]; + + // Always stay at bottom + if (scrollOnGrowingEnabled) { + CGRect tableFrame = [_tableController.view frame]; + CGPoint contentPt = [_tableController.tableView contentOffset]; + contentPt.y += diff; + if (contentPt.y + tableFrame.size.height > _tableController.tableView.contentSize.height) + contentPt.y += diff; + [_tableController.tableView setContentOffset:contentPt animated:FALSE]; + } + + CGRect tableRect = [_tableController.view frame]; + tableRect.size.height -= diff; + [_tableController.view setFrame:tableRect]; + + // if we're showing the compose message, update it position + if (![_composeLabel isHidden]) { + CGRect frame = [_composeLabel frame]; + frame.origin.y -= diff; + [_composeLabel setFrame:frame]; + } + } +} +/* +#pragma mark - UITextFieldDelegate Functions + +- (BOOL)textViewShouldBeginEditing:(UITextView *)textView { + if (_tableController.isEditing) { + [_tableController setEditing:NO]; + } + [_listTapGestureRecognizer setEnabled:TRUE]; + return TRUE; +} + +- (BOOL)textViewShouldEndEditing:(UITextView *)textView { + [_listTapGestureRecognizer setEnabled:FALSE]; + return TRUE; +} + +- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { + if ([text isEqualToString:@"\n"]) { + [_listTapGestureRecognizer setEnabled:FALSE]; + [self onSendClick:nil]; + textView.text = @""; + return NO; + } + return YES; +} + +- (void)textViewDidChange:(UITextView *)textView { + if ([textView.text length] > 0) { + linphone_chat_room_compose(chatRoom); + } +} + +- (void)textViewDidEndEditing:(UITextView *)textView { + [_listTapGestureRecognizer setEnabled:FALSE]; + [textView resignFirstResponder]; +} +*/ +/* + - (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height { + int diff = height - growingTextView.bounds.size.height; + + if (diff != 0) { + CGRect messageRect = [_messageView frame]; + messageRect.origin.y -= diff; + messageRect.size.height += diff; + [_messageView setFrame:messageRect]; + + // Always stay at bottom + if (scrollOnGrowingEnabled) { + CGRect tableFrame = [_tableController.view frame]; + CGPoint contentPt = [_tableController.tableView contentOffset]; + contentPt.y += diff; + if (contentPt.y + tableFrame.size.height > _tableController.tableView.contentSize.height) + contentPt.y += diff; + [_tableController.tableView setContentOffset:contentPt animated:FALSE]; + } + + CGRect tableRect = [_tableController.view frame]; + tableRect.size.height -= diff; + [_tableController.view setFrame:tableRect]; + + // if we're showing the compose message, update it position + if (![_composeLabel isHidden]) { + CGRect frame = [_composeLabel frame]; + frame.origin.y -= diff; + [_composeLabel setFrame:frame]; + } + } +}*/ + +#pragma mark - Action Functions + +- (IBAction)onBackClick:(id)event { + [_tableController setChatRoom:NULL]; + [PhoneMainView.instance popToView:ChatsListView.compositeViewDescription]; +} + +- (IBAction)onEditClick:(id)event { + [_tableController setEditing:![_tableController isEditing] animated:TRUE]; + [_messageField resignFirstResponder]; +} + +- (IBAction)onSendClick:(id)event { + if ([self sendMessage:[_messageField text] withExterlBodyUrl:nil withInternalURL:nil]) { + scrollOnGrowingEnabled = FALSE; + [_messageField setText:@""]; + scrollOnGrowingEnabled = TRUE; + [self onMessageChange:nil]; + } +} + +- (IBAction)onListTap:(id)sender { + [_messageField resignFirstResponder]; +} + +- (IBAction)onDeleteClick:(id)sender { + NSString *msg = [NSString stringWithFormat:NSLocalizedString(@"Do you want to delete selected messages?", nil)]; + [UIConfirmationDialog ShowWithMessage:msg + cancelMessage:nil + confirmMessage:nil + onCancelClick:^() { + [self onEditionChangeClick:nil]; + } + onConfirmationClick:^() { + [_tableController removeSelectionUsing:nil]; + [_tableController loadData]; + [self onEditionChangeClick:nil]; + }]; +} + +- (IBAction)onEditionChangeClick:(id)sender { + _backButton.hidden = _callButton.hidden = _tableController.isEditing; + [_backToCallButton update]; +} + +- (IBAction)onCallClick:(id)sender { + NSString *displayName = [FastAddressBook displayNameForAddress:linphone_chat_room_get_peer_address(chatRoom)]; + // Go to dialer view + DialerView *view = VIEW(DialerView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; + char *uri = linphone_address_as_string(linphone_chat_room_get_peer_address(chatRoom)); + [view call:[NSString stringWithUTF8String:uri] displayName:displayName]; + ms_free(uri); +} + +- (IBAction)onListSwipe:(id)sender { + [self onBackClick:sender]; +} + +- (IBAction)onMessageChange:(id)sender { + if ([[_messageField text] length] > 0) { + [_sendButton setEnabled:TRUE]; + } else { + [_sendButton setEnabled:FALSE]; + } +} + +- (IBAction)onPictureClick:(id)event { + [_messageField resignFirstResponder]; + [ImagePickerView SelectImageFromDevice:self atPosition:_pictureButton inView:self.view]; +} + +#pragma mark ChatRoomDelegate + +- (BOOL)startImageUpload:(UIImage *)image url:(NSURL *)url { + FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init]; + [fileTransfer upload:image withURL:url forChatRoom:chatRoom]; + [_tableController addChatEntry:linphone_chat_message_ref(fileTransfer.message)]; + [_tableController scrollToBottom:true]; + return TRUE; +} + +- (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url { + [self sendMessage:message withExterlBodyUrl:[NSURL URLWithString:url] withInternalURL:nil]; +} + +#pragma mark ImagePickerDelegate + +- (void)imagePickerDelegateImage:(UIImage *)image info:(NSDictionary *)info { + // Dismiss popover on iPad + if (IPAD) { + [VIEW(ImagePickerView).popoverController dismissPopoverAnimated:TRUE]; + } + + NSURL *url = [info valueForKey:UIImagePickerControllerReferenceURL]; + [self chooseImageQuality:image url:url]; +} + +- (void)tableViewIsScrolling { + // if user is scrolling in table view, we should hide the keyboard + if ([_messageField isFirstResponder]) { + [_messageField resignFirstResponder]; + } +} + +#pragma mark - Keyboard Event Functions + +- (void)keyboardWillHide:(NSNotification *)notif { + NSTimeInterval duration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + [UIView animateWithDuration:duration + delay:0 + options:UIViewAnimationOptionBeginFromCurrentState + animations:^{ + CGFloat composeIndicatorCompensation = composingVisible ? _composeIndicatorView.frame.size.height : 0.0f; + + // Show TabBar and status bar and also top bar + + // somehow, it breaks rotation if we put that in the block above when rotating portrait -> landscape + // if (!UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { + [PhoneMainView.instance showTabBar:YES]; + // } + [PhoneMainView.instance showStatusBar:YES]; + [PhoneMainView.instance fullScreen:NO]; + _topBar.alpha = 1.0; + + // Resize chat view + { + CGRect chatFrame = [_chatView frame]; + chatFrame.origin.y = _topBar.frame.origin.y + _topBar.frame.size.height; + chatFrame.size.height = [[self view] frame].size.height - chatFrame.origin.y; + [_chatView setFrame:chatFrame]; + } + + // Resize & Move table view + { + CGRect tableFrame = [_tableController.view frame]; + 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 { + NSTimeInterval duration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + + [UIView animateWithDuration:duration + delay:0 + options:UIViewAnimationOptionBeginFromCurrentState + animations:^{ + CGFloat composeIndicatorCompensation = composingVisible ? _composeIndicatorView.frame.size.height : 0.0f; + + CGRect endFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; + + if (([[UIDevice currentDevice].systemVersion floatValue] < 8) && + UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) { + int width = endFrame.size.height; + endFrame.size.height = endFrame.size.width; + endFrame.size.width = width; + } + + // Hide TabBar and status bar and also top bar + if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { + [PhoneMainView.instance showTabBar:NO]; + } + [PhoneMainView.instance showStatusBar:NO]; + [PhoneMainView.instance fullScreen:YES]; + _topBar.alpha = 0.0; + + // 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 = [_chatView frame]; + chatFrame.origin.y = 0; + chatFrame.size.height = viewFrame.size.height - chatFrame.origin.y + diff; + [_chatView setFrame:chatFrame]; + } + + // Resize & Move table view + { + CGRect tableFrame = _tableController.view.frame; + 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 diff --git a/Classes/ChatRoomTableViewController.h b/Classes/ChatRoomTableViewController.h deleted file mode 100644 index 38fc39114..000000000 --- a/Classes/ChatRoomTableViewController.h +++ /dev/null @@ -1,46 +0,0 @@ -/* ChatRoomTableViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#import -#include "linphone/linphonecore.h" - -@protocol ChatRoomDelegate - -- (BOOL)chatRoomStartImageDownload:(NSURL*)url userInfo:(id)userInfo; -- (BOOL)chatRoomStartImageUpload:(UIImage*)image url:(NSURL*)url; -- (void)resendChat:(NSString*)message withExternalUrl:(NSString*)url; - -@end - -@interface ChatRoomTableViewController : UITableViewController { -@private - LinphoneChatRoom* chatRoom; - MSList *messageList; -} - -@property (nonatomic, retain) id chatRoomDelegate; - -- (void)addChatEntry:(LinphoneChatMessage*)chat; -- (void)scrollToBottom:(BOOL)animated; -- (void)scrollToLastUnread:(BOOL)animated; -- (void)updateChatEntry:(LinphoneChatMessage*)chat; -- (void)setChatRoom:(LinphoneChatRoom*)room; - -@end diff --git a/Classes/ChatRoomTableViewController.m b/Classes/ChatRoomTableViewController.m deleted file mode 100644 index 2780d723f..000000000 --- a/Classes/ChatRoomTableViewController.m +++ /dev/null @@ -1,212 +0,0 @@ -/* ChatRoomTableViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "LinphoneManager.h" -#import "ChatRoomTableViewController.h" -#import "UIChatRoomCell.h" -#import "Utils.h" -#import "PhoneMainView.h" - -#import - -@implementation ChatRoomTableViewController - -@synthesize chatRoomDelegate; - -#pragma mark - Lifecycle Functions - -- (void)dealloc { - [chatRoomDelegate release]; - [self clearMessageList]; - - [super dealloc]; -} - -#pragma mark - ViewController Functions - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [TUNinePatchCache flushCache]; // Clear cache -// [self clearMessageList]; -// chatRoom = NULL; -} -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - self.tableView.accessibilityIdentifier = @"Chat list"; - [self reloadData]; -} - -#pragma mark - - -- (void)clearMessageList { - if (messageList){ - ms_list_free_with_data(messageList, (void(*)(void*))linphone_chat_message_unref); - messageList = nil; - } -} - -- (void)updateData { - if( !chatRoom ) return; - [self clearMessageList]; - self->messageList = linphone_chat_room_get_history(chatRoom, 0); -} - -- (void)reloadData { - [self updateData]; - [self.tableView reloadData]; - [self scrollToLastUnread:false]; -} - -- (void)addChatEntry:(LinphoneChatMessage*)chat { - - messageList = ms_list_append(messageList, linphone_chat_message_ref(chat)); - int pos = ms_list_size(messageList) - 1; - - [self.tableView beginUpdates]; - [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:pos inSection:0]] withRowAnimation:UITableViewRowAnimationFade]; - [self.tableView endUpdates]; -} - -- (void)updateChatEntry:(LinphoneChatMessage*)chat { - NSInteger index = ms_list_index(self->messageList, chat); - if (index<0) { - [LinphoneLogger logc:LinphoneLoggerWarning format:"chat entry doesn't exist"]; - return; - } - [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:FALSE]; //just reload - return; -} - -- (void)scrollToBottom:(BOOL)animated { - [self.tableView reloadData]; - int count = ms_list_size(messageList); - if( count ){ - [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(count - 1) inSection:0] - atScrollPosition:UITableViewScrollPositionBottom - animated:YES]; - } -} - -- (void)debugMessages { - if( !messageList ){ - NSLog(@"No data to debug"); - return; - } - MSList*item = self->messageList; - int count = 0; - while (item) { - LinphoneChatMessage* msg = (LinphoneChatMessage*)item->data; - NSLog(@"Message %d: %s", count++, linphone_chat_message_get_text(msg)); - item = item->next; - } -} - -- (void)scrollToLastUnread:(BOOL)animated { - if(messageList == nil || chatRoom == nil) { - return; - } - - int index = -1; - int count = ms_list_size(messageList); - // Find first unread & set all entry read - for(int i = 0; i = 0) { - [self.tableView.layer removeAllAnimations]; - [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] - atScrollPosition:UITableViewScrollPositionTop - animated:animated]; - } -} - -#pragma mark - Property Functions - -- (void)setChatRoom:(LinphoneChatRoom*)room { - chatRoom = room; - [self reloadData]; -} - -#pragma mark - UITableViewDataSource Functions - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return ms_list_size(self->messageList); -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - static NSString *kCellId = @"UIChatRoomCell"; - UIChatRoomCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; - if (cell == nil) { - cell = [[[UIChatRoomCell alloc] initWithIdentifier:kCellId] autorelease]; - } - - LinphoneChatMessage* chat = ms_list_nth_data(self->messageList, (int)[indexPath row]); - [cell setChatMessage:chat]; - [cell setChatRoomDelegate:chatRoomDelegate]; - return cell; -} - - -#pragma mark - UITableViewDelegate Functions - -- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { - if(editingStyle == UITableViewCellEditingStyleDelete) { - [tableView beginUpdates]; - LinphoneChatMessage *chat = ms_list_nth_data(self->messageList, (int)[indexPath row]); - if( chat ){ - - linphone_chat_room_delete_message(chatRoom, chat); - messageList = ms_list_remove(messageList, chat); - - [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationBottom]; - } - [tableView endUpdates]; - - } -} - -- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { - // Detemine if it's in editing mode - if (self.editing) { - return UITableViewCellEditingStyleDelete; - } - return UITableViewCellEditingStyleNone; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - LinphoneChatMessage* message = ms_list_nth_data(self->messageList, (int)[indexPath row]); - return [UIChatRoomCell height:message width:[self.view frame].size.width]; -} - -@end diff --git a/Classes/ChatRoomViewController.h b/Classes/ChatRoomViewController.h deleted file mode 100644 index 6748d383f..000000000 --- a/Classes/ChatRoomViewController.h +++ /dev/null @@ -1,72 +0,0 @@ -/* ChatRoomViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UIToggleButton.h" -#import "UICompositeViewController.h" -#import "ChatRoomTableViewController.h" -#import "HPGrowingTextView.h" -#import "ImagePickerViewController.h" -#import "ImageSharing.h" -#import "OrderedDictionary.h" - -#include "linphone/linphonecore.h" - -@interface ChatRoomViewController : UIViewController { - LinphoneChatRoom *chatRoom; - ImageSharing *imageSharing; - OrderedDictionary *imageQualities; - BOOL scrollOnGrowingEnabled; - BOOL composingVisible; -} - -@property (nonatomic, retain) IBOutlet ChatRoomTableViewController* tableController; -@property (nonatomic, retain) IBOutlet UIToggleButton *editButton; -@property (nonatomic, retain) IBOutlet HPGrowingTextView* messageField; -@property (nonatomic, retain) IBOutlet UIButton* sendButton; -@property (nonatomic, retain) IBOutlet UILabel *addressLabel; -@property (nonatomic, retain) IBOutlet UIImageView *avatarImage; -@property (nonatomic, retain) IBOutlet UIView *headerView; -@property (nonatomic, retain) IBOutlet UIView *chatView; -@property (nonatomic, retain) IBOutlet UIView *messageView; -@property (nonatomic, retain) IBOutlet UIImageView *messageBackgroundImage; -@property (nonatomic, retain) IBOutlet UIImageView *transferBackgroundImage; -@property (nonatomic, retain) IBOutlet UITapGestureRecognizer *listTapGestureRecognizer; -@property (nonatomic, retain) IBOutlet UISwipeGestureRecognizer *listSwipeGestureRecognizer; -@property (retain, nonatomic) IBOutlet UILabel *composeLabel; -@property (retain, nonatomic) IBOutlet UIView *composeIndicatorView; - -@property (nonatomic, retain) IBOutlet UIButton* pictureButton; -@property (nonatomic, retain) IBOutlet UIButton* cancelTransferButton; -@property (nonatomic, retain) IBOutlet UIProgressView* imageTransferProgressBar; -@property (nonatomic, retain) IBOutlet UIView* transferView; -@property (nonatomic, retain) IBOutlet UIView* waitView; - -- (IBAction)onBackClick:(id)event; -- (IBAction)onEditClick:(id)event; -- (IBAction)onMessageChange:(id)sender; -- (IBAction)onSendClick:(id)event; -- (IBAction)onPictureClick:(id)event; -- (IBAction)onTransferCancelClick:(id)event; -- (IBAction)onListTap:(id)sender; - -- (void)setChatRoom:(LinphoneChatRoom*)room; - -@end diff --git a/Classes/ChatRoomViewController.m b/Classes/ChatRoomViewController.m deleted file mode 100644 index 458aa7e01..000000000 --- a/Classes/ChatRoomViewController.m +++ /dev/null @@ -1,838 +0,0 @@ -/* ChatRoomViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "ChatRoomViewController.h" -#import "PhoneMainView.h" -#import "DTActionSheet.h" -#import "UILinphone.h" - -#import -#import -#import "Utils.h" - -@implementation ChatRoomViewController - -@synthesize tableController; -@synthesize sendButton; -@synthesize messageField; -@synthesize editButton; -@synthesize addressLabel; -@synthesize composeLabel; -@synthesize composeIndicatorView; -@synthesize avatarImage; -@synthesize headerView; -@synthesize chatView; -@synthesize messageView; -@synthesize messageBackgroundImage; -@synthesize transferBackgroundImage; -@synthesize listTapGestureRecognizer; -@synthesize listSwipeGestureRecognizer; -@synthesize pictureButton; -@synthesize imageTransferProgressBar; -@synthesize cancelTransferButton; -@synthesize transferView; -@synthesize waitView; - -#pragma mark - Lifecycle Functions - -- (id)init { - self = [super initWithNibName:@"ChatRoomViewController" bundle:[NSBundle mainBundle]]; - if (self != nil) { - self->scrollOnGrowingEnabled = TRUE; - self->chatRoom = NULL; - self->imageSharing = NULL; - self->listTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onListTap:)]; - self.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), - [NSNumber numberWithFloat:0.0], NSLocalizedString(@"Minimum", nil), nil]; - self->composingVisible = TRUE; - } - return self; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [tableController release]; - [messageField release]; - [sendButton release]; - [editButton release]; - [addressLabel release]; - [avatarImage release]; - [headerView release]; - [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]; -} - - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"ChatRoom" - content:@"ChatRoomViewController" - stateBar:nil - stateBarEnabled:false - tabBar:/*@"UIMainBar"*/nil - tabBarEnabled:false /*to keep room for chat*/ - fullscreen:false - landscapeMode:true - portraitMode:true]; - } - return compositeDescription; -} - - -#pragma mark - ViewController Functions - -- (void)viewDidLoad { - [super viewDidLoad]; - [tableController setChatRoomDelegate:self]; - - // Set selected+over background: IB lack ! - [editButton setBackgroundImage:[UIImage imageNamed:@"chat_ok_over.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStates:editButton]; - - messageField.minNumberOfLines = 1; - messageField.maxNumberOfLines = ([LinphoneManager runningOnIpad])?10:3; - messageField.delegate = self; - messageField.font = [UIFont systemFontOfSize:18.0f]; - messageField.contentInset = UIEdgeInsetsMake(0, -5, -2, -5); - messageField.internalTextView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, 10); - messageField.backgroundColor = [UIColor clearColor]; - [sendButton setEnabled:FALSE]; - - [tableController.tableView addGestureRecognizer:listTapGestureRecognizer]; - [listTapGestureRecognizer setEnabled:FALSE]; - - 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]; -} - - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(applicationWillEnterForeground:) - name:UIApplicationDidBecomeActiveNotification - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(keyboardWillShow:) - name:UIKeyboardWillShowNotification - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(keyboardWillHide:) - name:UIKeyboardWillHideNotification - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(textReceivedEvent:) - name:kLinphoneTextReceived - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(onMessageChange:) - name:UITextViewTextDidChangeNotification - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(textComposeEvent:) - name:kLinphoneTextComposeEvent - object:nil]; - if([tableController isEditing]) - [tableController setEditing:FALSE animated:FALSE]; - [editButton setOff]; - [[tableController tableView] reloadData]; - - [messageBackgroundImage setImage:[TUNinePatchCache imageOfSize:[messageBackgroundImage bounds].size - forNinePatchNamed:@"chat_message_background"]]; - - BOOL fileSharingEnabled = [[LinphoneManager instance] lpConfigStringForKey:@"sharing_server_preference"] != NULL - && [[[LinphoneManager instance] lpConfigStringForKey:@"sharing_server_preference"] length]>0; - [pictureButton setEnabled:fileSharingEnabled]; - [waitView setHidden:TRUE]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - - if(imageSharing) { - [imageSharing cancel]; - } - - [messageField resignFirstResponder]; - - [self setComposingVisible:FALSE withDelay:0]; // will hide the "user is composing.." message - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIApplicationDidBecomeActiveNotification - object:nil]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIKeyboardWillShowNotification - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIKeyboardWillHideNotification - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneTextReceived - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UITextViewTextDidChangeNotification - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneTextComposeEvent - object:nil]; -} - -- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { - [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; - [messageBackgroundImage setImage:[TUNinePatchCache imageOfSize:[messageBackgroundImage bounds].size - forNinePatchNamed:@"chat_message_background"]]; - [tableController scrollToBottom:true]; -} - -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; - -} - --(void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - [TUNinePatchCache flushCache]; // will remove any images cache (freeing any cached but unused images) -} - - -#pragma mark - - -- (void)setChatRoom:(LinphoneChatRoom *)room { - self->chatRoom = room; - [messageField setText:@""]; - [tableController setChatRoom:room]; - [self update]; - linphone_chat_room_mark_as_read(chatRoom); - [self setComposingVisible:linphone_chat_room_is_remote_composing(chatRoom) withDelay:0]; - [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self]; -} - -- (void)applicationWillEnterForeground:(NSNotification*)notif { - if(chatRoom != nil) { - linphone_chat_room_mark_as_read(chatRoom); - [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self]; - } -} - -- (void)update { - if(chatRoom == NULL) { - [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); - if (linphoneAddress == NULL) { - [[PhoneMainView instance] popCurrentView]; - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid SIP address",nil) - message:NSLocalizedString(@"Either configure a SIP proxy server from settings prior to send a message or use a valid SIP address (I.E sip:john@example.net)",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; - return; - } - char *tmp = linphone_address_as_string_uri_only(linphoneAddress); - NSString *normalizedSipAddress = [NSString stringWithUTF8String:tmp]; - ms_free(tmp); - - ABRecordRef acontact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress]; - if(acontact != nil) { - displayName = [FastAddressBook getContactDisplayName:acontact]; - image = [FastAddressBook getContactImage:acontact thumbnail:true]; - } - - // Display name - if(displayName == nil) { - const char* username = linphone_address_get_username(linphoneAddress); - char* address = linphone_address_as_string(linphoneAddress); - displayName = [NSString stringWithUTF8String:username?:address]; - ms_free(address); - } - [addressLabel setText:displayName]; - [addressLabel setAccessibilityValue: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 - 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(chatRoom == NULL) { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot send message: No chatroom"]; - return FALSE; - } - - LinphoneChatMessage* msg = linphone_chat_room_create_message(chatRoom, [message UTF8String]); - if(externalUrl) { - linphone_chat_message_set_external_body_url(msg, [[externalUrl absoluteString] UTF8String]); - } - - linphone_chat_room_send_message2(chatRoom, msg, message_status, self); - - if ( internalUrl ) { - // internal url is saved in the appdata for display and later save - [LinphoneManager setValueInMessageAppData:[internalUrl absoluteString] forKey:@"localimage" inMessage:msg]; - } - - [tableController addChatEntry:msg]; - [tableController scrollToBottom:true]; - return TRUE; -} - -- (void)saveAndSend:(UIImage*)image url:(NSURL*)url { - if(url == nil) { - [waitView setHidden:FALSE]; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [[LinphoneManager instance].photoLibrary - writeImageToSavedPhotosAlbum:image.CGImage - orientation:(ALAssetOrientation)[image imageOrientation] - completionBlock:^(NSURL *assetURL, NSError *error){ - dispatch_async(dispatch_get_main_queue(), ^{ - [waitView setHidden:TRUE]; - if (error) { - [LinphoneLogger log:LinphoneLoggerError format:@"Cannot save image data downloaded [%@]", [error localizedDescription]]; - - UIAlertView* errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transfer error", nil) - message:NSLocalizedString(@"Cannot write image to photo library", nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Ok",nil) - otherButtonTitles:nil ,nil]; - [errorAlert show]; - [errorAlert release]; - return; - } - [LinphoneLogger log:LinphoneLoggerLog format:@"Image saved to [%@]", [assetURL absoluteString]]; - [self chatRoomStartImageUpload:image url:assetURL]; - }); - }]; - }); - } else { - [self chatRoomStartImageUpload:image url:url]; - } -} - -- (void)chooseImageQuality:(UIImage*)image url:(NSURL*)url { - [waitView setHidden:FALSE]; - - DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Choose the image size", nil)]; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - //UIImage *image = [original_image normalizedImage]; - for(NSString *key in [imageQualities allKeys]) { - NSNumber *number = [imageQualities objectForKey:key]; - NSData *data = UIImageJPEGRepresentation(image, [number floatValue]); - NSNumber *size = [NSNumber numberWithInteger:[data length]]; - - NSString *text = [NSString stringWithFormat:@"%@ (%@)", key, [size toHumanReadableSize]]; - [sheet addButtonWithTitle:text block:^(){ - [self saveAndSend:[UIImage imageWithData:data] url:url]; - }]; - } - [sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; - dispatch_async(dispatch_get_main_queue(), ^{ - [waitView setHidden:TRUE]; - [sheet showInView:[PhoneMainView instance].view]; - }); - }); -} - -- (void)setComposingVisible:(BOOL)visible withDelay:(CGFloat)delay { - - if( composingVisible == visible ) return; - - CGRect keyboardFrame = [self.messageView frame]; - CGRect newComposingFrame = [self.composeIndicatorView frame]; - CGRect newTableFrame = [self.tableController.tableView frame]; - - if( visible ){ - [composeLabel setText:[NSString stringWithFormat:NSLocalizedString(@"%@ is composing...", @""), [addressLabel text]]]; - // pull up the composing frame and shrink the table view - - newTableFrame.size.height -= newComposingFrame.size.height; - newComposingFrame.origin.y = keyboardFrame.origin.y - newComposingFrame.size.height; - } else { - // pull down the composing frame and widen the tableview - 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) { - [self.tableController scrollToBottom:TRUE]; - }]; -} - - -#pragma mark - Event Functions - -- (void)textReceivedEvent:(NSNotification *)notif { - LinphoneAddress * from = [[[notif userInfo] objectForKey:@"from_address"] pointerValue]; - LinphoneChatRoom* room = [[notif.userInfo objectForKey:@"room"] pointerValue]; - LinphoneChatMessage* chat = [[notif.userInfo objectForKey:@"message"] pointerValue]; - - if(from == NULL || chat == NULL) { - return; - } - char *fromStr = linphone_address_as_string_uri_only(from); - const LinphoneAddress* cr_from = linphone_chat_room_get_peer_address(chatRoom); - char* cr_from_string = linphone_address_as_string_uri_only(cr_from); - - if(fromStr && cr_from_string ) { - - if(strcasecmp(cr_from_string, fromStr) == 0) { - if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) { - linphone_chat_room_mark_as_read(room); - [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self]; - } - [tableController addChatEntry:chat]; - [tableController scrollToLastUnread:TRUE]; - } - } - ms_free(fromStr); - ms_free(cr_from_string); -} - -- (void)textComposeEvent:(NSNotification*)notif { - LinphoneChatRoom* room = [[[notif userInfo] objectForKey:@"room"] pointerValue]; - if( room && room == chatRoom ){ - BOOL composing = linphone_chat_room_is_remote_composing(room); - [self setComposingVisible:composing withDelay:0.3]; - } -} - -#pragma mark - UITextFieldDelegate Functions - -- (BOOL)growingTextViewShouldBeginEditing:(HPGrowingTextView *)growingTextView { - if(editButton.selected) { - [tableController setEditing:FALSE animated:TRUE]; - [editButton setOff]; - } - [listTapGestureRecognizer setEnabled:TRUE]; - return TRUE; -} - -- (BOOL)growingTextViewShouldEndEditing:(HPGrowingTextView *)growingTextView { - [listTapGestureRecognizer setEnabled:FALSE]; - return TRUE; -} - -- (void)growingTextChanged:(HPGrowingTextView *)growingTextView text:(NSString *)text { - if( [text length] > 0 && chatRoom ) - linphone_chat_room_compose(chatRoom); -} - -- (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height { - int diff = height - growingTextView.bounds.size.height; - - if(diff != 0) { - CGRect messageRect = [messageView frame]; - messageRect.origin.y -= diff; - messageRect.size.height += diff; - [messageView setFrame:messageRect]; - - // Always stay at bottom - if(scrollOnGrowingEnabled) { - CGRect tableFrame = [tableController.view frame]; - CGPoint contentPt = [tableController.tableView contentOffset]; - contentPt.y += diff; - if(contentPt.y + tableFrame.size.height > tableController.tableView.contentSize.height) - contentPt.y += diff; - [tableController.tableView setContentOffset:contentPt animated:FALSE]; - } - - CGRect tableRect = [tableController.view frame]; - tableRect.size.height -= diff; - [tableController.view setFrame:tableRect]; - - [messageBackgroundImage setImage:[TUNinePatchCache imageOfSize:[messageBackgroundImage bounds].size - forNinePatchNamed:@"chat_message_background"]]; - // if we're showing the compose message, update it position - if ( ![composeLabel isHidden] ) { - CGRect frame = [composeLabel frame]; - frame.origin.y -= diff; - [composeLabel setFrame:frame]; - } - } -} - - -#pragma mark - Action Functions - -- (IBAction)onBackClick:(id)event { - [self.tableController setChatRoom:NULL]; - [[PhoneMainView instance] popCurrentView]; -} - -- (IBAction)onEditClick:(id)event { - [tableController setEditing:![tableController isEditing] animated:TRUE]; - [messageField resignFirstResponder]; -} - -- (IBAction)onSendClick:(id)event { - if([self sendMessage:[messageField text] withExterlBodyUrl:nil withInternalURL:nil]) { - scrollOnGrowingEnabled = FALSE; - [messageField setText:@""]; - scrollOnGrowingEnabled = TRUE; - [self onMessageChange:nil]; - } -} - -- (IBAction)onListTap:(id)sender { - [messageField resignFirstResponder]; -} -- (IBAction)onListSwipe:(id)sender { - [self onBackClick:sender]; -} - -- (IBAction)onMessageChange:(id)sender { - if([[messageField text] length] > 0) { - [sendButton setEnabled:TRUE]; - } else { - [sendButton setEnabled:FALSE]; - } -} - -- (IBAction)onPictureClick:(id)event { - [messageField resignFirstResponder]; - - void (^block)(UIImagePickerControllerSourceType) = ^(UIImagePickerControllerSourceType type) { - UICompositeViewDescription *description = [ImagePickerViewController compositeViewDescription]; - ImagePickerViewController *controller; - if([LinphoneManager runningOnIpad]) { - controller = DYNAMIC_CAST([[PhoneMainView instance].mainViewController getCachedController:description.content], ImagePickerViewController); - } else { - controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:description push:TRUE], ImagePickerViewController); - } - if(controller != nil) { - controller.sourceType = type; - - // Displays a control that allows the user to choose picture or - // movie capture, if both are available: - controller.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage]; - - // Hides the controls for moving & scaling pictures, or for - // trimming movies. To instead show the controls, use YES. - controller.allowsEditing = NO; - controller.imagePickerDelegate = self; - - if([LinphoneManager runningOnIpad]) { - CGRect rect = [self.messageView convertRect:[pictureButton frame] toView:self.view]; - [controller.popoverController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:FALSE]; - } - } - }; - - DTActionSheet *sheet = [[[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Select picture source",nil)] autorelease]; - if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { - [sheet addButtonWithTitle:NSLocalizedString(@"Camera",nil) block:^(){ - block(UIImagePickerControllerSourceTypeCamera); - }]; - } - if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { - [sheet addButtonWithTitle:NSLocalizedString(@"Photo library",nil) block:^(){ - block(UIImagePickerControllerSourceTypePhotoLibrary); - }]; - } - [sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel",nil) block:nil]; - - [sheet showInView:[PhoneMainView instance].view]; -} - -- (IBAction)onTransferCancelClick:(id)event { - if(imageSharing) { - [imageSharing cancel]; - } -} - - -#pragma mark ChatRoomDelegate - -- (BOOL)chatRoomStartImageDownload:(NSURL*)url userInfo:(id)userInfo { - if(imageSharing == nil) { - imageSharing = [ImageSharing newImageSharingDownload:url delegate:self userInfo:userInfo]; - [messageView setHidden:TRUE]; - [transferView setHidden:FALSE]; - return TRUE; - } - return FALSE; -} - -- (BOOL)chatRoomStartImageUpload:(UIImage*)image url:(NSURL*)url{ - if(imageSharing == nil) { - NSString *urlString = [[LinphoneManager instance] lpConfigStringForKey:@"sharing_server_preference"]; - imageSharing = [ImageSharing newImageSharingUpload:[NSURL URLWithString:urlString] image:image delegate:self userInfo:url]; - [messageView setHidden:TRUE]; - [transferView setHidden:FALSE]; - return TRUE; - } - return FALSE; -} - -- (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url { - [self sendMessage:message withExterlBodyUrl:[NSURL URLWithString:url] withInternalURL:nil]; -} - -#pragma mark ImageSharingDelegate - -- (void)imageSharingProgress:(ImageSharing*)aimageSharing progress:(float)progress { - [imageTransferProgressBar setProgress:progress]; -} - -- (void)imageSharingAborted:(ImageSharing*)aimageSharing { - [messageView setHidden:FALSE]; - [transferView setHidden:TRUE]; - [imageSharing release]; - imageSharing = nil; -} - -- (void)imageSharingError:(ImageSharing*)aimageSharing error:(NSError *)error { - [messageView setHidden:FALSE]; - [transferView setHidden:TRUE]; - NSString *url = [aimageSharing.connection.currentRequest.URL absoluteString]; - if (aimageSharing.upload) { - [LinphoneLogger log:LinphoneLoggerError format:@"Cannot upload file to server [%@] because [%@]", url, [error localizedDescription]]; - UIAlertView* errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transfer error", nil) - message:NSLocalizedString(@"Cannot transfer file to remote contact", nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Ok",nil) - otherButtonTitles:nil ,nil]; - [errorAlert show]; - [errorAlert release]; - } else { - [LinphoneLogger log:LinphoneLoggerError format:@"Cannot download file from [%@] because [%@]", url, [error localizedDescription]]; - UIAlertView* errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transfer error", nil) - message:NSLocalizedString(@"Cannot transfer file from remote contact", nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue", nil) - otherButtonTitles:nil, nil]; - [errorAlert show]; - [errorAlert release]; - } - imageSharing = nil; -} - -- (void)imageSharingUploadDone:(ImageSharing*)aimageSharing url:(NSURL*)url{ - [self sendMessage:nil withExterlBodyUrl:url withInternalURL:[aimageSharing userInfo] ]; - - [messageView setHidden:FALSE]; - [transferView setHidden:TRUE]; - imageSharing = nil; -} - -- (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] - completionBlock:^(NSURL *assetURL, NSError *error){ - if (error) { - [LinphoneLogger log:LinphoneLoggerError format:@"Cannot save image data downloaded [%@]", [error localizedDescription]]; - - UIAlertView* errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transfer error", nil) - message:NSLocalizedString(@"Cannot write image to photo library", nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Ok",nil) - otherButtonTitles:nil ,nil]; - [errorAlert show]; - [errorAlert release]; - return; - } - [LinphoneLogger log:LinphoneLoggerLog format:@"Image saved to [%@]", [assetURL absoluteString]]; - [LinphoneManager setValueInMessageAppData:[assetURL absoluteString] forKey:@"localimage" inMessage:chat]; - [tableController updateChatEntry:chat]; - }]; - imageSharing = nil; -} - - -#pragma mark ImagePickerDelegate - -- (void)imagePickerDelegateImage:(UIImage*)image info:(NSDictionary *)info { - // Dismiss popover on iPad - if([LinphoneManager runningOnIpad]) { - UICompositeViewDescription *description = [ImagePickerViewController compositeViewDescription]; - ImagePickerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance].mainViewController getCachedController:description.content], ImagePickerViewController); - if(controller != nil) { - [controller.popoverController dismissPopoverAnimated:TRUE]; - } - } - - NSURL *url = [info valueForKey:UIImagePickerControllerReferenceURL]; - [self chooseImageQuality:image url:url]; -} - - -#pragma mark - Keyboard Event Functions - -- (void)keyboardWillHide:(NSNotification *)notif { - NSTimeInterval duration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; - [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 { - NSTimeInterval duration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; - CGFloat composeIndicatorCompensation = composingVisible ? composeIndicatorView.frame.size.height : 0.0f; - - [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)) { - int width = endFrame.size.height; - endFrame.size.height = endFrame.size.width; - endFrame.size.width = width; - } - - // Resize chat view - { - CGRect viewFrame = [[self view] frame]; - CGRect rect = [PhoneMainView instance].view.bounds; - CGPoint pos = {viewFrame.size.width, viewFrame.size.height}; - CGPoint gPos = [self.view convertPoint:pos toView:[UIApplication sharedApplication].keyWindow.rootViewController.view]; // Bypass IOS bug on landscape mode - float diff = (rect.size.height - gPos.y - endFrame.size.height); - if(diff > 0) diff = 0; - CGRect chatFrame = [[self chatView] frame]; - chatFrame.size.height = viewFrame.size.height - chatFrame.origin.y + diff; - [[self chatView] setFrame:chatFrame]; - } - - // Move header view - { - CGRect headerFrame = [headerView frame]; - headerFrame.origin.y = -headerFrame.size.height; - [headerView setFrame:headerFrame]; - [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 diff --git a/Classes/ChatTableViewController.h b/Classes/ChatTableViewController.h deleted file mode 100644 index 3cc3d9e71..000000000 --- a/Classes/ChatTableViewController.h +++ /dev/null @@ -1,27 +0,0 @@ -/* ChatTableViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#include "linphone/linphonecore.h" - -@interface ChatTableViewController : UITableViewController { -} - -- (void)loadData; -@end diff --git a/Classes/ChatTableViewController.m b/Classes/ChatTableViewController.m deleted file mode 100644 index 429209d86..000000000 --- a/Classes/ChatTableViewController.m +++ /dev/null @@ -1,170 +0,0 @@ -/* ChatTableViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "ChatTableViewController.h" -#import "UIChatCell.h" - -#import "linphone/linphonecore.h" -#import "PhoneMainView.h" -#import "UACellBackgroundView.h" -#import "UILinphone.h" -#import "Utils.h" - -@implementation ChatTableViewController { - @private - MSList* data; -} - - -#pragma mark - Lifecycle Functions - -- (void)dealloc { - [super dealloc]; -} - -#pragma mark - ViewController Functions - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - self.tableView.accessibilityIdentifier = @"ChatRoom list"; - [self loadData]; -} - - -#pragma mark - - -static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRoom *elem){ - 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); - time_t old = linphone_chat_message_get_time(last_elem_message); - if ( new < old ) return 1; - else if ( new > old) return -1; - } - return 0; -} - -- (MSList*)sortChatRooms { - MSList* sorted = nil; - MSList* unsorted = linphone_core_get_chat_rooms([LinphoneManager getLc]); - MSList* iter = unsorted; - - while (iter) { - // 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]; -} - -#pragma mark - UITableViewDataSource Functions - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return ms_list_size(data); -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - static NSString *kCellId = @"UIChatCell"; - UIChatCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; - if (cell == nil) { - cell = [[[UIChatCell alloc] initWithIdentifier:kCellId] autorelease]; - - // Background View - UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease]; - cell.selectedBackgroundView = selectedBackgroundView; - [selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR]; - } - - [cell setChatRoom:(LinphoneChatRoom*)ms_list_nth_data(data, (int)[indexPath row])]; - - return cell; -} - - -#pragma mark - UITableViewDelegate Functions - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [tableView deselectRowAtIndexPath:indexPath animated:NO]; - 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); - if(controller != nil) { - [controller setChatRoom:chatRoom]; - } -} - -- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { - // Detemine if it's in editing mode - if (self.editing) { - return UITableViewCellEditingStyleDelete; - } - return UITableViewCellEditingStyleNone; -} - -- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { - if(editingStyle == UITableViewCellEditingStyleDelete) { - [tableView beginUpdates]; - - LinphoneChatRoom *chatRoom = (LinphoneChatRoom*)ms_list_nth_data(data, (int)[indexPath row]); - linphone_chat_room_delete_history(chatRoom); - 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]; - } -} - -@end diff --git a/Classes/ChatViewController.h b/Classes/ChatViewController.h deleted file mode 100644 index 1ac291235..000000000 --- a/Classes/ChatViewController.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ChatViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UIToggleButton.h" - -#import "ChatTableViewController.h" -#import "UICompositeViewController.h" - -@interface ChatViewController : UIViewController { -} - -@property (nonatomic, retain) IBOutlet ChatTableViewController* tableController; -@property (nonatomic, retain) IBOutlet UIToggleButton *editButton; -@property (nonatomic, retain) IBOutlet UITextField *addressField; - -- (IBAction)onAddClick:(id) event; -- (IBAction)onEditClick:(id) event; - -@end diff --git a/Classes/ChatViewController.m b/Classes/ChatViewController.m deleted file mode 100644 index 437717dbb..000000000 --- a/Classes/ChatViewController.m +++ /dev/null @@ -1,156 +0,0 @@ -/* ChatViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "ChatViewController.h" -#import "PhoneMainView.h" - -@implementation ChatViewController - -@synthesize tableController; -@synthesize editButton; -@synthesize addressField; - -#pragma mark - Lifecycle Functions - -- (id)init { - return [super initWithNibName:@"ChatViewController" bundle:[NSBundle mainBundle]]; -} - - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [tableController release]; - [editButton release]; - [addressField release]; - - [super dealloc]; -} - -#pragma mark - ViewController Functions - -- (void)viewDidLoad { - [super viewDidLoad]; - - // Set selected+over background: IB lack ! - [editButton setBackgroundImage:[UIImage imageNamed:@"chat_ok_over.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStates:editButton]; - - [tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4 - [tableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4 -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(textReceivedEvent:) - name:kLinphoneTextReceived - object:nil]; - if([tableController isEditing]) - [tableController setEditing:FALSE animated:FALSE]; - [editButton setOff]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneTextReceived - object:nil]; -} - - -#pragma mark - Event Functions - -- (void)textReceivedEvent:(NSNotification *)notif { - [tableController loadData]; -} - - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"Chat" - content:@"ChatViewController" - stateBar:nil - stateBarEnabled:false - tabBar: @"UIMainBar" - tabBarEnabled:true - fullscreen:false - landscapeMode:[LinphoneManager runningOnIpad] - portraitMode:true]; - } - return compositeDescription; -} - - -#pragma mark - Action Functions - --(void) startChatRoom { - //Push ChatRoom - LinphoneChatRoom* room = linphone_core_get_or_create_chat_room([LinphoneManager getLc], [addressField.text UTF8String]); - if( room != nil ){ - ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController); - if(controller != nil) { - LinphoneChatRoom* room = linphone_core_get_or_create_chat_room([LinphoneManager getLc], [addressField.text UTF8String]); - [controller setChatRoom:room]; - } - } else { - UIAlertView* alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid address", nil) - message:@"Please specify the entire SIP address for the chat" - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Cancel", nil) - otherButtonTitles:nil]; - [alert show]; - [alert release]; - } - addressField.text = @""; - -} -- (IBAction)onAddClick:(id)event { - if ([[addressField text ]length] == 0) { // if no address is manually set, lauch address book - [ContactSelection setSelectionMode:ContactSelectionModeMessage]; - [ContactSelection setAddAddress:nil]; - [ContactSelection setSipFilter: [LinphoneManager instance].contactFilter]; - [ContactSelection enableEmailFilter:FALSE]; - [ContactSelection setNameOrEmailFilter:nil]; - [[PhoneMainView instance] changeCurrentView:[ContactsViewController compositeViewDescription] push:TRUE]; - } else { - [self startChatRoom]; - } -} - -- (IBAction)onEditClick:(id)event { - [tableController setEditing:![tableController isEditing] animated:TRUE]; -} - -#pragma mark - UITextFieldDelegate Functions - -- (BOOL)textFieldShouldReturn:(UITextField *)textField { - [addressField resignFirstResponder]; - if ([[addressField text ]length]> 0) - [self startChatRoom]; - return YES; -} -@end diff --git a/Classes/LinphoneUI/UILinphoneTextField.h b/Classes/ChatsListTableView.h similarity index 77% rename from Classes/LinphoneUI/UILinphoneTextField.h rename to Classes/ChatsListTableView.h index a6445665e..9754a4f99 100644 --- a/Classes/LinphoneUI/UILinphoneTextField.h +++ b/Classes/ChatsListTableView.h @@ -1,4 +1,4 @@ -/* UILinphoneTextField.h +/* ChatTableViewController.h * * Copyright (C) 2012 Belledonne Comunications, Grenoble, France * @@ -10,7 +10,7 @@ * 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. + * 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 @@ -18,12 +18,10 @@ */ #import -#import +#include "linphone/linphonecore.h" +#include "UICheckBoxTableView.h" -@interface UILinphoneTextField : UITextField { - -} - -@property (retain, nonatomic) IBOutlet TUNinePatch *backgroundNinePatch; +@interface ChatsListTableView : UICheckBoxTableView +- (void)loadData; @end diff --git a/Classes/ChatsListTableView.m b/Classes/ChatsListTableView.m new file mode 100644 index 000000000..fdb622216 --- /dev/null +++ b/Classes/ChatsListTableView.m @@ -0,0 +1,219 @@ +/* ChatTableViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "ChatsListTableView.h" +#import "UIChatCell.h" + +#import "FileTransferDelegate.h" + +#import "linphone/linphonecore.h" +#import "PhoneMainView.h" +#import "Utils.h" + +@implementation ChatsListTableView { + MSList *data; +} + +#pragma mark - Lifecycle Functions + +- (instancetype)init { + self = super.init; + if (self) { + data = nil; + } + return self; +} + +- (void)dealloc { + if (data != nil) { + ms_list_free_with_data(data, chatTable_free_chatrooms); + } +} + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + self.tableView.accessibilityIdentifier = @"Chat list"; + [self loadData]; +} + +#pragma mark - + +static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRoom *elem) { + 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); + time_t old = linphone_chat_message_get_time(last_elem_message); + if (new < old) + return 1; + else if (new > old) + return -1; + } + return 0; +} + +- (MSList *)sortChatRooms { + MSList *sorted = nil; + const MSList *unsorted = linphone_core_get_chat_rooms([LinphoneManager getLc]); + const MSList *iter = unsorted; + + while (iter) { + // store last message in user data + LinphoneChatRoom *chat_room = iter->data; + MSList *history = linphone_chat_room_get_history(iter->data, 1); + LinphoneChatMessage *last_msg = NULL; + if (history) { + last_msg = linphone_chat_message_ref(history->data); + ms_list_free(history); + } + linphone_chat_room_set_user_data(chat_room, last_msg); + sorted = + ms_list_insert_sorted(sorted, linphone_chat_room_ref(chat_room), (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(lastMsg); + 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]; + [super loadData]; + + if (IPAD) { + // reset conversation view since in fragment mode, conversations are relative to current data + // select first conversation if any + if ([self totalNumberOfItems] > 0) { + ChatConversationView *view = VIEW(ChatConversationView); + [view setChatRoom:(LinphoneChatRoom *)ms_list_nth_data(data, 0)]; + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; + } else { + [PhoneMainView.instance changeCurrentView:ChatConversationCreateView.compositeViewDescription]; + } + } +} + +#pragma mark - UITableViewDataSource Functions + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return ms_list_size(data); +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *kCellId = @"UIChatCell"; + UIChatCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + if (cell == nil) { + cell = [[UIChatCell alloc] initWithIdentifier:kCellId]; + } + + [cell setChatRoom:(LinphoneChatRoom *)ms_list_nth_data(data, (int)[indexPath row])]; + [super accessoryForCell:cell atPath:indexPath]; + return cell; +} + +#pragma mark - UITableViewDelegate Functions + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [super tableView:tableView didSelectRowAtIndexPath:indexPath]; + if (![self isEditing]) { + LinphoneChatRoom *chatRoom = (LinphoneChatRoom *)ms_list_nth_data(data, (int)[indexPath row]); + ChatConversationView *view = VIEW(ChatConversationView); + [view setChatRoom:chatRoom]; + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE]; + } +} + +- (void)tableView:(UITableView *)tableView + commitEditingStyle:(UITableViewCellEditingStyle)editingStyle + forRowAtIndexPath:(NSIndexPath *)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + [tableView beginUpdates]; + + LinphoneChatRoom *chatRoom = (LinphoneChatRoom *)ms_list_nth_data(data, (int)[indexPath row]); + LinphoneChatMessage *last_msg = linphone_chat_room_get_user_data(chatRoom); + if (last_msg) { + linphone_chat_message_unref(last_msg); + linphone_chat_room_set_user_data(chatRoom, NULL); + } + + FileTransferDelegate *ftdToDelete = nil; + for (FileTransferDelegate *ftd in [[LinphoneManager instance] fileTransferDelegates]) { + if (linphone_chat_message_get_chat_room(ftd.message) == chatRoom) { + ftdToDelete = ftd; + break; + } + } + [ftdToDelete cancel]; + + linphone_core_delete_chat_room(linphone_chat_room_get_core(chatRoom), chatRoom); + data = ms_list_remove(data, chatRoom); + + // will force a call to [self loadData] + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneMessageReceived object:self]; + + [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] + withRowAnimation:UITableViewRowAnimationFade]; + [tableView endUpdates]; + } +} + +- (void)removeSelectionUsing:(void (^)(NSIndexPath *))remover { + [super removeSelectionUsing:^(NSIndexPath *indexPath) { + LinphoneChatRoom *chatRoom = (LinphoneChatRoom *)ms_list_nth_data(data, (int)[indexPath row]); + LinphoneChatMessage *last_msg = linphone_chat_room_get_user_data(chatRoom); + if (last_msg) { + linphone_chat_message_unref(last_msg); + linphone_chat_room_set_user_data(chatRoom, NULL); + } + + FileTransferDelegate *ftdToDelete = nil; + for (FileTransferDelegate *ftd in [[LinphoneManager instance] fileTransferDelegates]) { + if (linphone_chat_message_get_chat_room(ftd.message) == chatRoom) { + ftdToDelete = ftd; + break; + } + } + [ftdToDelete cancel]; + + linphone_core_delete_chat_room(linphone_chat_room_get_core(chatRoom), chatRoom); + data = ms_list_remove(data, chatRoom); + + // will force a call to [self loadData] + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneMessageReceived object:self]; + }]; +} + +@end diff --git a/Classes/ChatsListView.h b/Classes/ChatsListView.h new file mode 100644 index 000000000..4021f21bb --- /dev/null +++ b/Classes/ChatsListView.h @@ -0,0 +1,39 @@ +/* ChatViewController.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import + +#import "UIToggleButton.h" + +#import "ChatsListTableView.h" +#import "UICompositeView.h" +#import "UIBackToCallButton.h" + +@interface ChatsListView : UIViewController { +} + +@property(nonatomic, strong) IBOutlet ChatsListTableView *tableController; +@property(weak, nonatomic) IBOutlet UIButton *addButton; +@property(weak, nonatomic) IBOutlet UIBackToCallButton *backToCallButton; + +- (IBAction)onAddClick:(id)event; +- (IBAction)onEditionChangeClick:(id)sender; +- (IBAction)onDeleteClick:(id)sender; + +@end diff --git a/Classes/ChatsListView.m b/Classes/ChatsListView.m new file mode 100644 index 000000000..3660a62e0 --- /dev/null +++ b/Classes/ChatsListView.m @@ -0,0 +1,99 @@ +/* ChatViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "ChatsListView.h" +#import "PhoneMainView.h" + +#import "ChatConversationCreateView.h" +@implementation ChatsListView + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(textReceivedEvent:) + name:kLinphoneMessageReceived + object:nil]; + [_backToCallButton update]; + [self setEditing:NO]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneMessageReceived object:nil]; +} + +#pragma mark - Event Functions + +- (void)textReceivedEvent:(NSNotification *)notif { + [_tableController loadData]; +} + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:TabBarView.class + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:YES + fragmentWith:ChatConversationCreateView.class]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - Action Functions + +- (IBAction)onAddClick:(id)event { + ChatConversationCreateView *view = VIEW(ChatConversationCreateView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:YES]; +} + +- (IBAction)onEditionChangeClick:(id)sender { + _addButton.hidden = self.tableController.isEditing; + [_backToCallButton update]; +} + +- (IBAction)onDeleteClick:(id)sender { + NSString *msg = + [NSString stringWithFormat:NSLocalizedString(@"Do you want to delete selected conversations?", nil)]; + [UIConfirmationDialog ShowWithMessage:msg + cancelMessage:nil + confirmMessage:nil + onCancelClick:^() { + [self onEditionChangeClick:nil]; + } + onConfirmationClick:^() { + [_tableController removeSelectionUsing:nil]; + [_tableController loadData]; + [self onEditionChangeClick:nil]; + }]; +} + +@end diff --git a/Classes/ContactDetailsDelegate.h b/Classes/ContactDetailsDelegate.h index c251079ee..c1043f25e 100644 --- a/Classes/ContactDetailsDelegate.h +++ b/Classes/ContactDetailsDelegate.h @@ -19,7 +19,6 @@ @protocol ContactDetailsDelegate -- (void)onRemove:(id)event; - (void)onModification:(id)event; @end \ No newline at end of file diff --git a/Classes/ContactDetailsLabelViewController.h b/Classes/ContactDetailsLabelViewController.h deleted file mode 100644 index b03ecb175..000000000 --- a/Classes/ContactDetailsLabelViewController.h +++ /dev/null @@ -1,39 +0,0 @@ -/* ContactDetailsLabelViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#import "UICompositeViewController.h" - -@protocol ContactDetailsLabelViewDelegate - -- (void)changeContactDetailsLabel:(NSString*)label; - -@end - -@interface ContactDetailsLabelViewController : UIViewController { -} - -@property (nonatomic, copy) NSString *selectedData; -@property (nonatomic, retain) NSDictionary *dataList; -@property (nonatomic, retain) IBOutlet UITableView *tableView; -@property (nonatomic, retain) id delegate; - -- (IBAction)onBackClick:(id)event; - -@end diff --git a/Classes/ContactDetailsLabelViewController.m b/Classes/ContactDetailsLabelViewController.m deleted file mode 100644 index d7c3374da..000000000 --- a/Classes/ContactDetailsLabelViewController.m +++ /dev/null @@ -1,150 +0,0 @@ -/* ContactDetailsLabelViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "ContactDetailsLabelViewController.h" - -#import "UACellBackgroundView.h" -#import "UILinphone.h" -#import "PhoneMainView.h" - -@implementation ContactDetailsLabelViewController - -@synthesize dataList; -@synthesize tableView; -@synthesize selectedData; -@synthesize delegate; - - -#pragma mark - Lifecycle Functions - -- (void)dealloc { - [selectedData release]; - [dataList release]; - [tableView release]; - [delegate release]; - - [super dealloc]; -} - - -#pragma mark - ViewController Functions - -- (void)viewDidLoad { - [super viewDidLoad]; - [tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4 - [tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4 -} - - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"ContactDetailsLabel" - content:@"ContactDetailsLabelViewController" - stateBar:nil - stateBarEnabled:false - tabBar:@"UIMainBar" - tabBarEnabled:true - fullscreen:false - landscapeMode:[LinphoneManager runningOnIpad] - portraitMode:true]; - } - return compositeDescription; -} - - -#pragma mark - - -- (void)dismiss { - if([[[PhoneMainView instance] currentView] equal:[ContactDetailsLabelViewController compositeViewDescription]]) { - [[PhoneMainView instance] popCurrentView]; - } -} - - -#pragma mark - Property Functions - -- (void)setDataList:(NSDictionary *)adatalist { - if([dataList isEqualToDictionary:adatalist]) { - return; - } - [dataList release]; - dataList = [adatalist retain]; - [tableView reloadData]; -} - - -- (void)setSelectedData:(NSString *)aselectedData { - if (selectedData != nil) { - [selectedData release]; - } - selectedData = [[NSString alloc] initWithString:aselectedData]; - [tableView reloadData]; -} - - -#pragma mark - UITableViewDataSource Functions - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return [dataList count]; -} - -- (UITableViewCell *)tableView:(UITableView *)atableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - static NSString *kCellId = @"ContactDetailsLabelCell"; - UITableViewCell *cell = [atableView dequeueReusableCellWithIdentifier:kCellId]; - if (cell == nil) { - cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kCellId] autorelease]; - - // Background View - UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease]; - cell.selectedBackgroundView = selectedBackgroundView; - [selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR]; - } - NSString* key = [[dataList allKeys] objectAtIndex:[indexPath row]]; - [cell.textLabel setText:[dataList objectForKey:key]]; - if ([key compare:selectedData]==0) { - [cell setAccessoryType:UITableViewCellAccessoryCheckmark]; - } else { - [cell setAccessoryType:UITableViewCellAccessoryNone]; - } - return cell; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - NSString* key = [[dataList allKeys] objectAtIndex:[indexPath row]]; - [self setSelectedData:key]; - [delegate changeContactDetailsLabel:key]; - [self dismiss]; -} - - -#pragma mark - Action Functions - -- (IBAction)onBackClick:(id)event { - [self dismiss]; -} - -@end diff --git a/Classes/ContactDetailsTableView.h b/Classes/ContactDetailsTableView.h new file mode 100644 index 000000000..72777fc20 --- /dev/null +++ b/Classes/ContactDetailsTableView.h @@ -0,0 +1,51 @@ +/* ContactDetailsTableViewController.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import +#import + +#import "ContactDetailsDelegate.h" + +typedef enum _ContactSections { + ContactSections_None = 0, // first section is empty because we cannot set header for first section + ContactSections_First_Name, + ContactSections_Last_Name, + ContactSections_Sip, + ContactSections_Number, + ContactSections_Email, + ContactSections_MAX +} ContactSections; + +@interface ContactDetailsTableView : UITableViewController { + @private + NSMutableArray *dataCache; + NSMutableArray *labelArray; + NSIndexPath *editingIndexPath; +} + +@property(nonatomic, assign, setter=setContact:) ABRecordRef contact; +@property(nonatomic, strong) IBOutlet id contactDetailsDelegate; + +- (BOOL)isValid; +- (void)addPhoneField:(NSString *)number; +- (void)addSipField:(NSString *)address; +- (void)addEmailField:(NSString *)address; +- (void)setContact:(ABRecordRef)contact; + +@end diff --git a/Classes/ContactDetailsTableView.m b/Classes/ContactDetailsTableView.m new file mode 100644 index 000000000..98e77d04a --- /dev/null +++ b/Classes/ContactDetailsTableView.m @@ -0,0 +1,833 @@ +/* ContactDetailsTableViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "ContactDetailsTableView.h" +#import "PhoneMainView.h" +#import "UIContactDetailsCell.h" +#import "Utils.h" +#import "OrderedDictionary.h" +#import "FastAddressBook.h" + +@interface Entry : NSObject + +@property(assign) ABMultiValueIdentifier identifier; + +@end + +@implementation Entry + +@synthesize identifier; + +#pragma mark - Lifecycle Functions + +- (id)initWithData:(ABMultiValueIdentifier)aidentifier { + self = [super init]; + if (self != NULL) { + [self setIdentifier:aidentifier]; + } + return self; +} + +@end + +@implementation ContactDetailsTableView + +@synthesize contactDetailsDelegate; +@synthesize contact; + +#pragma mark - Lifecycle Functions + +- (void)initContactDetailsTableViewController { + dataCache = [[NSMutableArray alloc] init]; + + // pre-fill the data-cache with empty arrays + for (int i = ContactSections_Number; i < ContactSections_MAX; i++) { + [dataCache addObject:@[]]; + } + + labelArray = [[NSMutableArray alloc] + initWithObjects:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"], + [NSString stringWithString:(NSString *)kABPersonPhoneMobileLabel], + [NSString stringWithString:(NSString *)kABPersonPhoneIPhoneLabel], + [NSString stringWithString:(NSString *)kABPersonPhoneMainLabel], nil]; + editingIndexPath = nil; +} + +- (id)init { + self = [super init]; + if (self) { + [self initContactDetailsTableViewController]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + [self initContactDetailsTableViewController]; + } + return self; +} + +- (void)dealloc { + if (contact != nil && ABRecordGetRecordID(contact) == kABRecordInvalidID) { + CFRelease(contact); + } +} + +#pragma mark - + +- (void)updateModification { + [contactDetailsDelegate onModification:nil]; +} + +- (NSMutableArray *)getSectionData:(NSInteger)section { + if (section == ContactSections_Number) { + return [dataCache objectAtIndex:0]; + } else if (section == ContactSections_Sip) { + return [dataCache objectAtIndex:1]; + } else if (section == ContactSections_Email) { + if ([[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"] == true) { + return [dataCache objectAtIndex:2]; + } else { + return nil; + } + } + return nil; +} + +- (ABPropertyID)propertyIDForSection:(ContactSections)section { + switch (section) { + case ContactSections_First_Name: + return kABPersonFirstNameProperty; + case ContactSections_Last_Name: + return kABPersonLastNameProperty; + case ContactSections_Sip: + return kABPersonInstantMessageProperty; + case ContactSections_Number: + return kABPersonPhoneProperty; + case ContactSections_Email: + return kABPersonEmailProperty; + default: + return kABInvalidPropertyType; + } +} + +- (NSDictionary *)getLocalizedLabels { + OrderedDictionary *dict = [[OrderedDictionary alloc] initWithCapacity:[labelArray count]]; + for (NSString *str in labelArray) { + [dict setObject:[FastAddressBook localizedLabel:str] forKey:str]; + } + return dict; +} + +- (void)loadData { + [dataCache removeAllObjects]; + + if (contact == NULL) + return; + + LOGI(@"Load data from contact %p", contact); + // Phone numbers + { + ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty); + NSMutableArray *subArray = [NSMutableArray array]; + if (lMap) { + for (int i = 0; i < ABMultiValueGetCount(lMap); ++i) { + ABMultiValueIdentifier identifier = ABMultiValueGetIdentifierAtIndex(lMap, i); + Entry *entry = [[Entry alloc] initWithData:identifier]; + [subArray addObject:entry]; + } + CFRelease(lMap); + } + [dataCache addObject:subArray]; + } + + // SIP (IM) + { + ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty); + NSMutableArray *subArray = [NSMutableArray array]; + if (lMap) { + for (int i = 0; i < ABMultiValueGetCount(lMap); ++i) { + ABMultiValueIdentifier identifier = ABMultiValueGetIdentifierAtIndex(lMap, i); + CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, i); + BOOL add = false; + if (CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) { + if (CFStringCompare((CFStringRef)[LinphoneManager instance].contactSipField, + CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey), + kCFCompareCaseInsensitive) == 0) { + add = true; + } + } else { + // check domain + LinphoneAddress *address = linphone_address_new( + [(NSString *)CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey) UTF8String]); + if (address) { + if ([[ContactSelection getSipFilter] compare:@"*" options:NSCaseInsensitiveSearch] == + NSOrderedSame) { + add = true; + } else { + NSString *domain = [NSString stringWithCString:linphone_address_get_domain(address) + encoding:[NSString defaultCStringEncoding]]; + add = [domain compare:[ContactSelection getSipFilter] options:NSCaseInsensitiveSearch] == + NSOrderedSame; + } + linphone_address_destroy(address); + } else { + add = false; + } + } + if (add) { + Entry *entry = [[Entry alloc] initWithData:identifier]; + [subArray addObject:entry]; + } + CFRelease(lDict); + } + CFRelease(lMap); + } + [dataCache addObject:subArray]; + } + + // Email + if ([[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"] == true) { + ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonEmailProperty); + NSMutableArray *subArray = [NSMutableArray array]; + if (lMap) { + for (int i = 0; i < ABMultiValueGetCount(lMap); ++i) { + ABMultiValueIdentifier identifier = ABMultiValueGetIdentifierAtIndex(lMap, i); + CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, i); + Entry *entry = [[Entry alloc] initWithData:identifier]; + [subArray addObject:entry]; + CFRelease(lDict); + } + CFRelease(lMap); + } + [dataCache addObject:subArray]; + } + + if (contactDetailsDelegate != nil) { + [contactDetailsDelegate onModification:nil]; + } + [self.tableView reloadData]; +} + +- (Entry *)setOrCreateSipContactEntry:(Entry *)entry withValue:(NSString *)value { + ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty); + ABMutableMultiValueRef lMap; + if (lcMap != NULL) { + lMap = ABMultiValueCreateMutableCopy(lcMap); + CFRelease(lcMap); + } else { + lMap = ABMultiValueCreateMutable(kABStringPropertyType); + } + ABMultiValueIdentifier index; + CFErrorRef error = NULL; + + NSDictionary *lDict = @{ + (NSString *) kABPersonInstantMessageUsernameKey : value, (NSString *) + kABPersonInstantMessageServiceKey : [LinphoneManager instance].contactSipField + }; + + if (entry) { + index = (int)ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); + ABMultiValueReplaceValueAtIndex(lMap, (__bridge CFTypeRef)(lDict), index); + } else { + CFStringRef label = (__bridge CFStringRef)[labelArray objectAtIndex:0]; + ABMultiValueAddValueAndLabel(lMap, (__bridge CFTypeRef)lDict, label, &index); + } + + if (!ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, &error)) { + LOGI(@"Can't set contact with value [%@] cause [%@]", value, [(__bridge NSError *)error localizedDescription]); + CFRelease(lMap); + } else { + if (entry == nil) { + entry = [[Entry alloc] initWithData:index]; + } + CFRelease(lMap); + + /*check if message type is kept or not*/ + lcMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty); + lMap = ABMultiValueCreateMutableCopy(lcMap); + CFRelease(lcMap); + index = (int)ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); + lDict = CFBridgingRelease(ABMultiValueCopyValueAtIndex(lMap, index)); + + if ([lDict objectForKey:(__bridge NSString *)kABPersonInstantMessageServiceKey] == nil) { + /*too bad probably a gtalk number, storing uri*/ + NSString *username = [lDict objectForKey:(NSString *)kABPersonInstantMessageUsernameKey]; + LinphoneAddress *address = linphone_core_interpret_url([LinphoneManager getLc], [username UTF8String]); + if (address) { + char *uri = linphone_address_as_string_uri_only(address); + NSDictionary *dict2 = @{ + (NSString *) kABPersonInstantMessageUsernameKey : + [NSString stringWithCString:uri encoding:[NSString defaultCStringEncoding]], + (NSString *) + kABPersonInstantMessageServiceKey : [LinphoneManager instance].contactSipField + }; + + ABMultiValueReplaceValueAtIndex(lMap, (__bridge CFTypeRef)(dict2), index); + + if (!ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, &error)) { + LOGI(@"Can't set contact with value [%@] cause [%@]", value, + [(__bridge NSError *)error localizedDescription]); + } + linphone_address_destroy(address); + ms_free(uri); + } + } + CFRelease(lMap); + } + + return entry; +} + +- (void)setSipContactEntry:(Entry *)entry withValue:(NSString *)value { + [self setOrCreateSipContactEntry:entry withValue:value]; +} +- (void)addEntry:(UITableView *)tableview section:(NSInteger)section animated:(BOOL)animated { + [self addEntry:tableview section:section animated:animated value:@""]; +} + +- (void)addEntry:(UITableView *)tableview section:(NSInteger)section animated:(BOOL)animated value:(NSString *)value { + NSMutableArray *sectionArray = [self getSectionData:section]; + NSUInteger count = [sectionArray count]; + CFErrorRef error = NULL; + bool added = TRUE; + if (section == ContactSections_Number) { + ABMultiValueIdentifier identifier; + ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonPhoneProperty); + ABMutableMultiValueRef lMap; + if (lcMap != NULL) { + lMap = ABMultiValueCreateMutableCopy(lcMap); + CFRelease(lcMap); + } else { + lMap = ABMultiValueCreateMutable(kABStringPropertyType); + } + CFStringRef label = (__bridge CFStringRef)[labelArray objectAtIndex:0]; + if (!ABMultiValueAddValueAndLabel(lMap, (__bridge CFTypeRef)(value), label, &identifier)) { + added = false; + } + + if (added && ABRecordSetValue(contact, kABPersonPhoneProperty, lMap, &error)) { + Entry *entry = [[Entry alloc] initWithData:identifier]; + [sectionArray addObject:entry]; + } else { + added = false; + LOGI(@"Can't add entry: %@", [(__bridge NSError *)error localizedDescription]); + } + CFRelease(lMap); + } else if (section == ContactSections_Sip) { + Entry *entry = [self setOrCreateSipContactEntry:nil withValue:value]; + if (entry) { + [sectionArray addObject:entry]; + added = true; + } else { + added = false; + LOGE(@"Can't add entry for value: %@", value); + } + } else if (section == ContactSections_Email) { + ABMultiValueIdentifier identifier; + ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonEmailProperty); + ABMutableMultiValueRef lMap; + if (lcMap != NULL) { + lMap = ABMultiValueCreateMutableCopy(lcMap); + CFRelease(lcMap); + } else { + lMap = ABMultiValueCreateMutable(kABStringPropertyType); + } + CFStringRef label = (__bridge CFStringRef)[labelArray objectAtIndex:0]; + if (!ABMultiValueAddValueAndLabel(lMap, (__bridge CFTypeRef)(value), label, &identifier)) { + added = false; + } + + if (added && ABRecordSetValue(contact, kABPersonEmailProperty, lMap, &error)) { + Entry *entry = [[Entry alloc] initWithData:identifier]; + [sectionArray addObject:entry]; + } else { + added = false; + LOGI(@"Can't add entry: %@", [(__bridge NSError *)error localizedDescription]); + } + CFRelease(lMap); + } + + if (added && animated) { + // Update accessory + if (count > 0) { + [tableview reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:count - 1 + inSection:section]] + withRowAnimation:FALSE]; + } + [tableview + insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:count inSection:section]] + withRowAnimation:UITableViewRowAnimationFade]; + } + if (contactDetailsDelegate != nil) { + [contactDetailsDelegate onModification:nil]; + } +} + +- (void)removeEmptyEntry:(UITableView *)tableview section:(NSInteger)section animated:(BOOL)animated { + NSMutableArray *sectionDict = [self getSectionData:section]; + NSInteger i = [sectionDict count]; + for (NSInteger row = i - 1; row >= 0; row--) { + Entry *entry = [sectionDict objectAtIndex:row]; + + 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 = nil; + NSString *value = nil; + if (property == kABPersonInstantMessageProperty) { + // when we query the instanteMsg property we get a dictionary instead of a value + toRelease = valueRef; + value = CFDictionaryGetValue(valueRef, kABPersonInstantMessageUsernameKey); + } else { + value = CFBridgingRelease(valueRef); + } + + if (value.length == 0) { + [self removeEntry:tableview path:[NSIndexPath indexPathForRow:row inSection:section] animated:animated]; + } + if (toRelease != nil) { + CFRelease(toRelease); + } + + CFRelease(lMap); + } + } + if (contactDetailsDelegate != nil) { + [contactDetailsDelegate onModification:nil]; + } +} + +- (void)removeEntry:(UITableView *)tableview path:(NSIndexPath *)indexPath animated:(BOOL)animated { + NSMutableArray *sectionArray = [self getSectionData:[indexPath section]]; + Entry *entry = [sectionArray objectAtIndex:[indexPath row]]; + ABPropertyID property = [self propertyIDForSection:(ContactSections)indexPath.section]; + + if (property != kABInvalidPropertyType) { + ABMultiValueRef lcMap = ABRecordCopyValue(contact, property); + ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap); + CFRelease(lcMap); + NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); + ABMultiValueRemoveValueAndLabelAtIndex(lMap, index); + ABRecordSetValue(contact, property, lMap, nil); + CFRelease(lMap); + } + + [sectionArray removeObjectAtIndex:[indexPath row]]; + + NSArray *tagInsertIndexPath = [NSArray arrayWithObject:indexPath]; + if (animated) { + [tableview deleteRowsAtIndexPaths:tagInsertIndexPath withRowAnimation:UITableViewRowAnimationFade]; + } +} + +#pragma mark - Property Functions + +- (void)setContact:(ABRecordRef)acontact { + if (acontact == contact) + return; + + if (contact != nil && ABRecordGetRecordID(contact) == kABRecordInvalidID) { + CFRelease(contact); + } + contact = acontact; + [self loadData]; +} + +- (void)addPhoneField:(NSString *)number { + ContactSections i = 0; + while (i != ContactSections_MAX && i != ContactSections_Number) + ++i; + [self addEntry:[self tableView] section:i animated:FALSE value:number]; +} + +- (void)addSipField:(NSString *)address { + ContactSections i = 0; + while (i != ContactSections_MAX && i != ContactSections_Sip) + ++i; + [self addEntry:[self tableView] section:i animated:FALSE value:address]; +} + +- (void)addEmailField:(NSString *)address { + ContactSections i = 0; + while (i != ContactSections_MAX && i != ContactSections_Email) + ++i; + [self addEntry:[self tableView] section:i animated:FALSE value:address]; +} + +#pragma mark - UITableViewDataSource Functions + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return ContactSections_MAX; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + if (section == ContactSections_First_Name || section == ContactSections_Last_Name) { + return (self.tableView.isEditing) ? 1 : 0 /*no first and last name when not editting */; + } else { + return [[self getSectionData:section] count]; + } +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *kCellId = @"UIContactDetailsCell"; + UIContactDetailsCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + if (cell == nil) { + cell = [[UIContactDetailsCell alloc] initWithIdentifier:kCellId]; + [cell.editTextfield setDelegate:self]; + } + + NSMutableArray *sectionDict = [self getSectionData:[indexPath section]]; + Entry *entry = [sectionDict objectAtIndex:[indexPath row]]; + + NSString *value = @""; + [cell hideDeleteButton:NO]; + if (indexPath.section == ContactSections_First_Name) { + value = (NSString *)CFBridgingRelease( + ABRecordCopyValue(contact, [self propertyIDForSection:ContactSections_First_Name])); + [cell hideDeleteButton:YES]; + } else if (indexPath.section == ContactSections_Last_Name) { + value = (NSString *)CFBridgingRelease( + ABRecordCopyValue(contact, [self propertyIDForSection:ContactSections_Last_Name])); + [cell hideDeleteButton:YES]; + } else if ([indexPath section] == ContactSections_Number) { + ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty); + NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); + NSString *valueRef = CFBridgingRelease(ABMultiValueCopyValueAtIndex(lMap, index)); + if (valueRef != NULL) { + value = [FastAddressBook localizedLabel:valueRef]; + } + CFRelease(lMap); + } else if ([indexPath section] == ContactSections_Sip) { + ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty); + NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); + CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, index); + value = (NSString *)(CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey)); + if (value != NULL) { + LinphoneAddress *addr = NULL; + if ([[LinphoneManager instance] lpConfigBoolForKey:@"contact_display_username_only"] && + (addr = linphone_address_new([value UTF8String]))) { + if (linphone_address_get_username(addr)) { + value = [NSString stringWithCString:linphone_address_get_username(addr) + encoding:[NSString defaultCStringEncoding]]; + } + } + if (addr) + linphone_address_destroy(addr); + } + CFRelease(lDict); + CFRelease(lMap); + } else if ([indexPath section] == ContactSections_Email) { + ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonEmailProperty); + NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); + NSString *valueRef = CFBridgingRelease(ABMultiValueCopyValueAtIndex(lMap, index)); + if (valueRef != NULL) { + value = [FastAddressBook localizedLabel:valueRef]; + } + CFRelease(lMap); + } + [cell setAddress:value]; + if ([indexPath section] == ContactSections_Number) { + [cell.editTextfield setKeyboardType:UIKeyboardTypePhonePad]; + } else if ([indexPath section] == ContactSections_Sip) { + [cell.editTextfield setKeyboardType:UIKeyboardTypeASCIICapable]; + } else if ([indexPath section] == ContactSections_Email) { + [cell.editTextfield setKeyboardType:UIKeyboardTypeASCIICapable]; + } else { + [cell.editTextfield setKeyboardType:UIKeyboardTypeDefault]; + } + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [tableView deselectRowAtIndexPath:indexPath animated:NO]; + NSMutableArray *sectionDict = [self getSectionData:[indexPath section]]; + Entry *entry = [sectionDict objectAtIndex:[indexPath row]]; + if ([self isEditing]) { + NSString *key = nil; + ABPropertyID property = [self propertyIDForSection:(ContactSections)indexPath.section]; + + if (property != kABInvalidPropertyType && property != kABPersonFirstNameProperty && + property != kABPersonLastNameProperty) { + ABMultiValueRef lMap = ABRecordCopyValue(contact, property); + NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); + NSString *labelRef = CFBridgingRelease(ABMultiValueCopyLabelAtIndex(lMap, index)); + if (labelRef != NULL) { + key = (NSString *)(labelRef); + } + CFRelease(lMap); + } + if (key != nil) { + editingIndexPath = indexPath; + } + } +} + +- (void)tableView:(UITableView *)tableView + commitEditingStyle:(UITableViewCellEditingStyle)editingStyle + forRowAtIndexPath:(NSIndexPath *)indexPath { + [LinphoneUtils findAndResignFirstResponder:[self tableView]]; + if (editingStyle == UITableViewCellEditingStyleInsert) { + [tableView beginUpdates]; + [self addEntry:tableView section:[indexPath section] animated:TRUE]; + [tableView endUpdates]; + } else if (editingStyle == UITableViewCellEditingStyleDelete) { + [tableView beginUpdates]; + [self removeEntry:tableView path:indexPath animated:TRUE]; + [tableView endUpdates]; + } +} + +#pragma mark - UITableViewDelegate Functions + +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + [super setEditing:editing animated:animated]; + BOOL showEmails = [[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"]; + if (editing) { + // add phone/SIP/email entries so that the user can add new data + for (int section = 0; section < [self numberOfSectionsInTableView:[self tableView]]; ++section) { + if (section == ContactSections_Number || section == ContactSections_Sip || + (showEmails && section == ContactSections_Email)) { + [self addEntry:self.tableView section:section animated:animated]; + } + } + } else { + [LinphoneUtils findAndResignFirstResponder:[self tableView]]; + // remove empty phone numbers + for (int section = 0; section < [self numberOfSectionsInTableView:[self tableView]]; ++section) { + // remove phony entries that were not filled by the user + if (section == ContactSections_Number || section == ContactSections_Sip || + (showEmails && section == ContactSections_Email)) { + + [self removeEmptyEntry:self.tableView section:section animated:animated]; + if ([[self getSectionData:section] count] == 0 && animated) { // the section is empty -> remove titles + [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] + withRowAnimation:UITableViewRowAnimationFade]; + } + } + } + } + [self loadData]; + if (contactDetailsDelegate != nil) { + [contactDetailsDelegate onModification:nil]; + } +} + +- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView + editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { + return UITableViewCellEditingStyleNone; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { + NSString *text = nil; + BOOL canAddEntry = self.tableView.isEditing; + NSString *addEntryName = nil; + if (section == ContactSections_First_Name && self.tableView.isEditing) { + text = NSLocalizedString(@"First name", nil); + canAddEntry = NO; + } else if (section == ContactSections_Last_Name && self.tableView.isEditing) { + text = NSLocalizedString(@"Last name", nil); + canAddEntry = NO; + } else if ([self getSectionData:section].count > 0 || self.tableView.isEditing) { + if (section == ContactSections_Number) { + text = NSLocalizedString(@"Phone numbers", nil); + addEntryName = NSLocalizedString(@"Add new phone number", nil); + } else if (section == ContactSections_Sip) { + text = NSLocalizedString(@"SIP addresses", nil); + addEntryName = NSLocalizedString(@"Add new SIP address", nil); + } else if (section == ContactSections_Email && + [LinphoneManager.instance lpConfigBoolForKey:@"show_contacts_emails_preference"]) { + text = NSLocalizedString(@"Email addresses", nil); + addEntryName = NSLocalizedString(@"Add new email", nil); + } + } + + if (!text) { + return nil; + } + + CGRect frame = CGRectMake(0, 0, tableView.frame.size.width, 30); + UIView *tempView = [[UIView alloc] initWithFrame:frame]; + tempView.backgroundColor = [UIColor whiteColor]; + + UILabel *tempLabel = [[UILabel alloc] initWithFrame:frame]; + tempLabel.backgroundColor = [UIColor clearColor]; + tempLabel.textColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_E.png"]]; + tempLabel.text = text.uppercaseString; + tempLabel.textAlignment = NSTextAlignmentCenter; + tempLabel.font = [UIFont systemFontOfSize:15]; + tempLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + [tempView addSubview:tempLabel]; + + if (canAddEntry) { + frame.origin.x = tableView.frame.size.width / 2 - 28; + UIIconButton *tempAddButton = [[UIIconButton alloc] initWithFrame:frame]; + [tempAddButton setImage:[UIImage imageNamed:@"add_field_default.png"] forState:UIControlStateNormal]; + [tempAddButton setImage:[UIImage imageNamed:@"add_field_over.png"] forState:UIControlStateHighlighted]; + [tempAddButton setImage:[UIImage imageNamed:@"add_field_over.png"] forState:UIControlStateSelected]; + [tempAddButton addTarget:self action:@selector(onAddClick:) forControlEvents:UIControlEventTouchUpInside]; + tempAddButton.tag = section; + tempAddButton.accessibilityLabel = addEntryName; + tempAddButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; + [tempView addSubview:tempAddButton]; + } + + return tempView; +} + +- (void)onAddClick:(id)sender { + NSInteger section = ((UIButton *)sender).tag; + UITableView *tableView = VIEW(ContactDetailsView).tableController.tableView; + NSInteger count = [self.tableView numberOfRowsInSection:section]; + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:count inSection:section]; + [tableView.dataSource tableView:tableView + commitEditingStyle:UITableViewCellEditingStyleInsert + forRowAtIndexPath:indexPath]; +} + +#pragma mark - ContactDetailsLabelDelegate Functions + +- (void)changeContactDetailsLabel:(NSString *)value { + if (value != nil) { + 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); + NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); + ABMultiValueReplaceLabelAtIndex(lMap, (__bridge CFStringRef)(value), index); + ABRecordSetValue(contact, kABPersonPhoneProperty, lMap, nil); + CFRelease(lMap); + } + + [self.tableView beginUpdates]; + [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:editingIndexPath] withRowAnimation:FALSE]; + [self.tableView reloadSectionIndexTitles]; + [self.tableView endUpdates]; + } + editingIndexPath = nil; +} + +#pragma mark - UITextFieldDelegate Functions + +- (BOOL)textField:(UITextField *)textField + shouldChangeCharactersInRange:(NSRange)range + replacementString:(NSString *)string { + if (contactDetailsDelegate != nil) { + [self performSelector:@selector(updateModification) withObject:nil afterDelay:0]; + } + return YES; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + [textField resignFirstResponder]; + return YES; +} + +- (BOOL)textFieldShouldEndEditing:(UITextField *)textField { + UIView *view = [textField superview]; + + // Find TableViewCell + while (view != nil && ![view isKindOfClass:[UIContactDetailsCell class]]) + view = [view superview]; + if (view != nil) { + UIContactDetailsCell *cell = (UIContactDetailsCell *)view; + NSIndexPath *path = [self.tableView indexPathForCell:cell]; + NSMutableArray *sectionDict = [self getSectionData:[path section]]; + Entry *entry = [sectionDict objectAtIndex:[path row]]; + ContactSections sect = (ContactSections)[path section]; + + ABPropertyID property = [self propertyIDForSection:sect]; + NSString *value = [textField text]; + + switch (sect) { + case ContactSections_First_Name: + case ContactSections_Last_Name: { + // [cell.detailTextLabel setText:[textField text]]; + CFErrorRef error = NULL; + ABRecordSetValue(contact, property, (__bridge CFTypeRef)([textField text]), (CFErrorRef *)&error); + if (error != NULL) { + LOGE(@"Error when saving property %i in contact %p: Fail(%@)", property, contact, + [(__bridge NSError *)error localizedDescription]); + } + break; + } + case ContactSections_Sip: + [self setSipContactEntry:entry withValue:value]; + break; + case ContactSections_Email: + case ContactSections_Number: { + ABMultiValueRef lcMap = ABRecordCopyValue(contact, property); + ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap); + CFRelease(lcMap); + NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); + ABMultiValueReplaceValueAtIndex(lMap, (__bridge CFStringRef)value, index); + ABRecordSetValue(contact, property, lMap, nil); + CFRelease(lMap); + break; + } + case ContactSections_MAX: + case ContactSections_None: + break; + } + cell.editTextfield.text = value; + } else { + LOGE(@"Not valid UIEditableTableViewCell"); + } + if (contactDetailsDelegate != nil) { + [self performSelector:@selector(updateModification) withObject:nil afterDelay:0]; + } + return TRUE; +} +- (BOOL)isValid { + NSString *firstName = (NSString *)CFBridgingRelease( + ABRecordCopyValue(contact, [self propertyIDForSection:ContactSections_First_Name])); + NSString *lastName = (NSString *)CFBridgingRelease( + ABRecordCopyValue(contact, [self propertyIDForSection:ContactSections_Last_Name])); + return firstName.length > 0 || lastName.length > 0; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + if (tableView.isEditing) { + return 44; + } else { + return 88; + } +} +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { + return 1e-5; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { + if (section == 0 || (!self.tableView.isEditing && + (section == ContactSections_First_Name || section == ContactSections_Last_Name))) { + return 1e-5; + } + return [self tableView:tableView viewForHeaderInSection:section].frame.size.height; +} + +@end diff --git a/Classes/ContactDetailsTableViewController.h b/Classes/ContactDetailsTableViewController.h deleted file mode 100644 index c51db7bab..000000000 --- a/Classes/ContactDetailsTableViewController.h +++ /dev/null @@ -1,54 +0,0 @@ -/* ContactDetailsTableViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#import - -#import "ContactDetailsDelegate.h" -#import "ContactDetailsLabelViewController.h" -#import "UIContactDetailsHeader.h" -#import "UIContactDetailsFooter.h" - - -typedef enum _ContactSections { - ContactSections_None = 0, - ContactSections_Number, - ContactSections_Sip, - ContactSections_Email, - ContactSections_MAX -} ContactSections_e; - -@interface ContactDetailsTableViewController : UITableViewController { -@private - NSMutableArray *dataCache; - NSMutableArray *labelArray; - NSIndexPath *editingIndexPath; -} - -@property (nonatomic, assign) ABRecordRef contact; -@property (nonatomic, retain) IBOutlet id contactDetailsDelegate; -@property (nonatomic, retain) IBOutlet UIContactDetailsHeader *headerController; -@property (nonatomic, retain) IBOutlet UIContactDetailsFooter *footerController; - -- (BOOL)isValid; -- (void)addPhoneField:(NSString*)number; -- (void)addSipField:(NSString*)address; -- (void)addEmailField:(NSString*)address; - -@end diff --git a/Classes/ContactDetailsTableViewController.m b/Classes/ContactDetailsTableViewController.m deleted file mode 100644 index a85bd9cad..000000000 --- a/Classes/ContactDetailsTableViewController.m +++ /dev/null @@ -1,889 +0,0 @@ -/* ContactDetailsTableViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "ContactDetailsTableViewController.h" -#import "PhoneMainView.h" -#import "UIEditableTableViewCell.h" -#import "UACellBackgroundView.h" -#import "UILinphone.h" -#import "OrderedDictionary.h" -#import "FastAddressBook.h" -#import "Utils.h" - -@interface Entry : NSObject - -@property (assign) ABMultiValueIdentifier identifier; - -@end - -@implementation Entry - -@synthesize identifier; - -#pragma mark - Lifecycle Functions - -- (id)initWithData:(ABMultiValueIdentifier)aidentifier { - self = [super init]; - if (self != NULL) { - [self setIdentifier:aidentifier]; - } - return self; -} - -- (void)dealloc { - [super dealloc]; -} - -@end - - -@implementation ContactDetailsTableViewController - -static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSections_None, ContactSections_Number, ContactSections_Sip, ContactSections_Email}; - -@synthesize footerController; -@synthesize headerController; -@synthesize contactDetailsDelegate; -@synthesize contact; - -#pragma mark - Lifecycle Functions - -- (void)initContactDetailsTableViewController { - dataCache = [[NSMutableArray alloc] init]; - - // pre-fill the data-cache with empty arrays - for(int i=ContactSections_Number; i< ContactSections_MAX; i++){ - [dataCache addObject:@[]]; - } - - labelArray = [[NSMutableArray alloc] initWithObjects: - [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"], - [NSString stringWithString:(NSString*)kABPersonPhoneMobileLabel], - [NSString stringWithString:(NSString*)kABPersonPhoneIPhoneLabel], - [NSString stringWithString:(NSString*)kABPersonPhoneMainLabel], nil]; - editingIndexPath = nil; -} - -- (id)init { - self = [super init]; - if (self) { - [self initContactDetailsTableViewController]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { - [self initContactDetailsTableViewController]; - } - return self; -} - -- (void)dealloc { - if(contact != nil && ABRecordGetRecordID(contact) == kABRecordInvalidID) { - CFRelease(contact); - } - if(editingIndexPath != nil) { - [editingIndexPath release]; - } - [labelArray release]; - [dataCache release]; - - [super dealloc]; -} - - -#pragma mark - ViewController Functions - -- (void)viewDidLoad { - [super viewDidLoad]; - [headerController view]; // Force view load - [footerController view]; // Force view load - - self.tableView.accessibilityIdentifier = @"Contact numbers table"; -} - -- (void)viewDidDisappear:(BOOL)animated { - [super viewDidDisappear:animated]; -} - - -#pragma mark - - -- (BOOL)isValid { - return [headerController isValid]; -} - -- (void)updateModification { - [contactDetailsDelegate onModification:nil]; -} - -- (NSMutableArray*)getSectionData:(NSInteger)section { - if(contactSections[section] == ContactSections_Number) { - return [dataCache objectAtIndex:0]; - } else if(contactSections[section] == ContactSections_Sip) { - return [dataCache objectAtIndex:1]; - } else if(contactSections[section] == ContactSections_Email) { - if ([[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"] == true) { - return [dataCache objectAtIndex:2]; - } else { - return nil; - } - } - 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]; - CFRelease(lLocalizedLabel); - return retStr; -} - -- (NSDictionary*)getLocalizedLabels { - OrderedDictionary *dict = [[OrderedDictionary alloc] initWithCapacity:[labelArray count]]; - for(NSString *str in labelArray) { - [dict setObject:[ContactDetailsTableViewController localizeLabel:str] forKey:str]; - } - return [dict autorelease]; -} - -- (void)loadData { - [dataCache removeAllObjects]; - - if(contact == NULL) - return; - - [LinphoneLogger logc:LinphoneLoggerLog format:"Load data from contact %p", contact]; - // Phone numbers - { - ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty); - NSMutableArray *subArray = [NSMutableArray array]; - if(lMap) { - for(int i = 0; i < ABMultiValueGetCount(lMap); ++i) { - ABMultiValueIdentifier identifier = ABMultiValueGetIdentifierAtIndex(lMap, i); - Entry *entry = [[Entry alloc] initWithData:identifier]; - [subArray addObject: entry]; - [entry release]; - } - CFRelease(lMap); - } - [dataCache addObject:subArray]; - } - - // SIP (IM) - { - ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty); - NSMutableArray *subArray = [NSMutableArray array]; - if(lMap) { - for(int i = 0; i < ABMultiValueGetCount(lMap); ++i) { - ABMultiValueIdentifier identifier = ABMultiValueGetIdentifierAtIndex(lMap, i); - CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, i); - BOOL add = false; - if(CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) { - if(CFStringCompare((CFStringRef)[LinphoneManager instance].contactSipField, CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey), kCFCompareCaseInsensitive) == 0) { - add = true; - } - } else { - //check domain - LinphoneAddress* address = linphone_address_new([(NSString*)CFDictionaryGetValue(lDict,kABPersonInstantMessageUsernameKey) UTF8String]); - if (address) { - if ([[ContactSelection getSipFilter] compare:@"*" options:NSCaseInsensitiveSearch] == NSOrderedSame) { - add = true; - } else { - NSString* domain = [NSString stringWithCString:linphone_address_get_domain(address) - encoding:[NSString defaultCStringEncoding]]; - add = [domain compare:[ContactSelection getSipFilter] options:NSCaseInsensitiveSearch] == NSOrderedSame; - } - linphone_address_destroy(address); - } else { - add = false; - } - } - if(add) { - Entry *entry = [[Entry alloc] initWithData:identifier]; - [subArray addObject: entry]; - [entry release]; - } - CFRelease(lDict); - } - CFRelease(lMap); - } - [dataCache addObject:subArray]; - } - - // Email - if ([[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"] == true) - { - ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonEmailProperty); - NSMutableArray *subArray = [NSMutableArray array]; - if(lMap) { - for(int i = 0; i < ABMultiValueGetCount(lMap); ++i) { - ABMultiValueIdentifier identifier = ABMultiValueGetIdentifierAtIndex(lMap, i); - CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, i); - Entry *entry = [[Entry alloc] initWithData:identifier]; - [subArray addObject: entry]; - [entry release]; - CFRelease(lDict); - } - CFRelease(lMap); - } - [dataCache addObject:subArray]; - } - - if(contactDetailsDelegate != nil) { - [contactDetailsDelegate onModification:nil]; - } - [self.tableView reloadData]; -} - --(Entry *) setOrCreateSipContactEntry:(Entry *)entry withValue:(NSString*)value { - ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty); - ABMutableMultiValueRef lMap; - if(lcMap != NULL) { - lMap = ABMultiValueCreateMutableCopy(lcMap); - CFRelease(lcMap); - } else { - lMap = ABMultiValueCreateMutable(kABStringPropertyType); - } - ABMultiValueIdentifier index; - NSError* error = NULL; - - CFStringRef keys[] = { kABPersonInstantMessageUsernameKey, kABPersonInstantMessageServiceKey}; - CFTypeRef values[] = { [value copy], [LinphoneManager instance].contactSipField }; - CFDictionaryRef lDict = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 2, NULL, NULL); - if (entry) { - index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); - ABMultiValueReplaceValueAtIndex(lMap, lDict, index); - } else { - CFStringRef label = (CFStringRef)[labelArray objectAtIndex:0]; - ABMultiValueAddValueAndLabel(lMap, lDict, label, &index); - } - - if (!ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, (CFErrorRef*)&error)) { - [LinphoneLogger log:LinphoneLoggerLog format:@"Can't set contact with value [%@] cause [%@]", value,[error localizedDescription]]; - CFRelease(lMap); - } else { - if (entry == nil) { - entry = [[[Entry alloc] initWithData:index] autorelease]; - } - CFRelease(lDict); - CFRelease(lMap); - - /*check if message type is kept or not*/ - lcMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty); - lMap = ABMultiValueCreateMutableCopy(lcMap); - CFRelease(lcMap); - index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); - lDict = ABMultiValueCopyValueAtIndex(lMap,index); - if(!CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) { - /*too bad probably a gtalk number, storing uri*/ - NSString* username = CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey); - LinphoneAddress* address = linphone_core_interpret_url([LinphoneManager getLc] - ,[username UTF8String]); - if(address){ - char* uri = linphone_address_as_string_uri_only(address); - CFStringRef keys[] = { kABPersonInstantMessageUsernameKey, kABPersonInstantMessageServiceKey}; - CFTypeRef values[] = { [NSString stringWithCString:uri encoding:[NSString defaultCStringEncoding]], [LinphoneManager instance].contactSipField }; - CFDictionaryRef lDict2 = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 2, NULL, NULL); - ABMultiValueReplaceValueAtIndex(lMap, lDict2, index); - if (!ABRecordSetValue(contact, kABPersonInstantMessageProperty, lMap, (CFErrorRef*)&error)) { - [LinphoneLogger log:LinphoneLoggerLog format:@"Can't set contact with value [%@] cause [%@]", value,[error localizedDescription]]; - } - CFRelease(lDict2); - linphone_address_destroy(address); - ms_free(uri); - } - } - CFRelease(lMap); - } - CFRelease(lDict); - - return entry; -} - --(void) setSipContactEntry:(Entry *)entry withValue:(NSString*)value { - [self setOrCreateSipContactEntry:entry withValue:value]; -} -- (void)addEntry:(UITableView*)tableview section:(NSInteger)section animated:(BOOL)animated { - [self addEntry:tableview section:section animated:animated value:@""]; -} - -- (void)addEntry:(UITableView*)tableview section:(NSInteger)section animated:(BOOL)animated value:(NSString *)value{ - NSMutableArray *sectionArray = [self getSectionData:section]; - NSUInteger count = [sectionArray count]; - NSError* error = NULL; - bool added = TRUE; - if(contactSections[section] == ContactSections_Number) { - ABMultiValueIdentifier identifier; - ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonPhoneProperty); - ABMutableMultiValueRef lMap; - if(lcMap != NULL) { - lMap = ABMultiValueCreateMutableCopy(lcMap); - CFRelease(lcMap); - } else { - lMap = ABMultiValueCreateMutable(kABStringPropertyType); - } - CFStringRef label = (CFStringRef)[labelArray objectAtIndex:0]; - if(!ABMultiValueAddValueAndLabel(lMap, [[value copy] autorelease], label, &identifier)) { - added = false; - } - - if(added && ABRecordSetValue(contact, kABPersonPhoneProperty, lMap, (CFErrorRef*)&error)) { - Entry *entry = [[Entry alloc] initWithData:identifier]; - [sectionArray addObject:entry]; - [entry release]; - } else { - added = false; - [LinphoneLogger log:LinphoneLoggerLog format:@"Can't add entry: %@", [error localizedDescription]]; - } - CFRelease(lMap); - } else if(contactSections[section] == ContactSections_Sip) { - Entry *entry = [self setOrCreateSipContactEntry:nil withValue:value]; - if (entry) { - [sectionArray addObject:entry]; - added=true; - } else { - added=false; - [LinphoneLogger log:LinphoneLoggerError format:@"Can't add entry for value: %@", value]; - } - } else if(contactSections[section] == ContactSections_Email) { - ABMultiValueIdentifier identifier; - ABMultiValueRef lcMap = ABRecordCopyValue(contact, kABPersonEmailProperty); - ABMutableMultiValueRef lMap; - if(lcMap != NULL) { - lMap = ABMultiValueCreateMutableCopy(lcMap); - CFRelease(lcMap); - } else { - lMap = ABMultiValueCreateMutable(kABStringPropertyType); - } - CFStringRef label = (CFStringRef)[labelArray objectAtIndex:0]; - if(!ABMultiValueAddValueAndLabel(lMap, [[value copy] autorelease], label, &identifier)) { - added = false; - } - - if(added && ABRecordSetValue(contact, kABPersonEmailProperty, lMap, (CFErrorRef*)&error)) { - Entry *entry = [[Entry alloc] initWithData:identifier]; - [sectionArray addObject:entry]; - [entry release]; - } else { - added = false; - [LinphoneLogger log:LinphoneLoggerLog format:@"Can't add entry: %@", [error localizedDescription]]; - } - CFRelease(lMap); - } - - if (added && animated) { - // Update accessory - if (count > 0) { - [tableview reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:count -1 inSection:section]] withRowAnimation:FALSE]; - } - [tableview insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:count inSection:section]] withRowAnimation:UITableViewRowAnimationFade]; - } - if(contactDetailsDelegate != nil) { - [contactDetailsDelegate onModification:nil]; - } -} - -- (void)removeEmptyEntry:(UITableView*)tableview section:(NSInteger)section animated:(BOOL)animated { - NSMutableArray *sectionDict = [self getSectionData:section]; - NSInteger row = [sectionDict count] - 1; - if(row >= 0) { - Entry *entry = [sectionDict objectAtIndex:row]; - - 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(toRelease); - CFRelease(lMap); - - } - } - if(contactDetailsDelegate != nil) { - [contactDetailsDelegate onModification:nil]; - } -} - -- (void)removeEntry:(UITableView*)tableview path:(NSIndexPath*)indexPath animated:(BOOL)animated { - NSMutableArray *sectionArray = [self getSectionData:[indexPath section]]; - Entry *entry = [sectionArray objectAtIndex:[indexPath row]]; - ABPropertyID property = [self propertyIDForSection:contactSections[indexPath.section]]; - - if( property != kABInvalidPropertyType ){ - ABMultiValueRef lcMap = ABRecordCopyValue(contact, property); - ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap); - CFRelease(lcMap); - NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); - ABMultiValueRemoveValueAndLabelAtIndex(lMap, index); - ABRecordSetValue(contact, property, lMap, nil); - CFRelease(lMap); - } - - [sectionArray removeObjectAtIndex:[indexPath row]]; - - NSArray *tagInsertIndexPath = [NSArray arrayWithObject:indexPath]; - if (animated) { - [tableview deleteRowsAtIndexPaths:tagInsertIndexPath withRowAnimation:UITableViewRowAnimationFade]; - } -} - - -#pragma mark - Property Functions - -- (void)setContact:(ABRecordRef)acontact { - if(contact != nil && ABRecordGetRecordID(contact) == kABRecordInvalidID) { - CFRelease(contact); - } - contact = acontact; - [self loadData]; - [headerController setContact:contact]; -} - -- (void)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; - [self addEntry:[self tableView] section:i animated:FALSE value:address]; -} - -- (void)addEmailField:(NSString*)address { - int i = 0; - while(i < ContactSections_MAX && contactSections[i] != ContactSections_Email) ++i; - [self addEntry:[self tableView] section:i animated:FALSE value:address]; -} - - -#pragma mark - UITableViewDataSource Functions - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return ContactSections_MAX; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return [[self getSectionData:section] count]; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - static NSString *kCellId = @"ContactDetailsCell"; - UIEditableTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; - if (cell == nil) { - cell = [[[UIEditableTableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:kCellId] autorelease]; - [cell.detailTextField setDelegate:self]; - [cell.detailTextField setAutocapitalizationType:UITextAutocapitalizationTypeNone]; - [cell.detailTextField setAutocorrectionType:UITextAutocorrectionTypeNo]; - [cell setBackgroundColor:[UIColor whiteColor]]; - - // Background View - UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease]; - cell.selectedBackgroundView = selectedBackgroundView; - [selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR]; - } - - NSMutableArray *sectionDict = [self getSectionData:[indexPath section]]; - Entry *entry = [sectionDict objectAtIndex:[indexPath row]]; - - NSString *value = @""; - // default label is our app name - NSString *label = [ContactDetailsTableViewController localizeLabel:[labelArray objectAtIndex:0]]; - - if(contactSections[[indexPath section]] == ContactSections_Number) { - ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty); - NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); - CFStringRef labelRef = ABMultiValueCopyLabelAtIndex(lMap, index); - if(labelRef != NULL) { - label = [ContactDetailsTableViewController localizeLabel:(NSString*) labelRef]; - CFRelease(labelRef); - } - CFStringRef valueRef = ABMultiValueCopyValueAtIndex(lMap, index); - if(valueRef != NULL) { - value = [ContactDetailsTableViewController localizeLabel:(NSString*) valueRef]; - CFRelease(valueRef); - } - CFRelease(lMap); - } else if(contactSections[[indexPath section]] == ContactSections_Sip) { - ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty); - NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); - CFStringRef labelRef = ABMultiValueCopyLabelAtIndex(lMap, index); - if(labelRef != NULL) { - label = [ContactDetailsTableViewController localizeLabel:(NSString*) labelRef]; - CFRelease(labelRef); - } - CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, index); - CFStringRef valueRef = CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey); - if(valueRef != NULL) { - LinphoneAddress* addr=NULL; - if ([[LinphoneManager instance] lpConfigBoolForKey:@"contact_display_username_only"] - && (addr=linphone_address_new([(NSString *)valueRef UTF8String]))) { - if (linphone_address_get_username(addr)) { - value = [NSString stringWithCString:linphone_address_get_username(addr) - encoding:[NSString defaultCStringEncoding]]; - } /*else value=@""*/ - } else { - value = [NSString stringWithString:(NSString*) valueRef]; - } - if (addr) linphone_address_destroy(addr); - } - CFRelease(lDict); - CFRelease(lMap); - } else if(contactSections[[indexPath section]] == ContactSections_Email) { - ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonEmailProperty); - NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); - CFStringRef labelRef = ABMultiValueCopyLabelAtIndex(lMap, index); - if(labelRef != NULL) { - label = [ContactDetailsTableViewController localizeLabel:(NSString*) labelRef]; - CFRelease(labelRef); - } - CFStringRef valueRef = ABMultiValueCopyValueAtIndex(lMap, index); - if(valueRef != NULL) { - value = [ContactDetailsTableViewController localizeLabel:(NSString*) valueRef]; - CFRelease(valueRef); - } - CFRelease(lMap); - } - [cell.textLabel setText:label]; - [cell.detailTextLabel setText:value]; - [cell.detailTextField setText:value]; - if (contactSections[[indexPath section]] == ContactSections_Number) { - [cell.detailTextField setKeyboardType:UIKeyboardTypePhonePad]; - [cell.detailTextField setPlaceholder:NSLocalizedString(@"Phone number", nil)]; - } else if(contactSections[[indexPath section]] == ContactSections_Sip){ - [cell.detailTextField setKeyboardType:UIKeyboardTypeASCIICapable]; - [cell.detailTextField setPlaceholder:NSLocalizedString(@"SIP address", nil)]; - } else if(contactSections[[indexPath section]] == ContactSections_Email) { - [cell.detailTextField setKeyboardType:UIKeyboardTypeASCIICapable]; - [cell.detailTextField setPlaceholder:NSLocalizedString(@"Email address", nil)]; - } - return cell; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [tableView deselectRowAtIndexPath:indexPath animated:NO]; - NSMutableArray *sectionDict = [self getSectionData:[indexPath section]]; - Entry *entry = [sectionDict objectAtIndex:[indexPath row]]; - if (![self isEditing]) { - NSString *dest=NULL;; - if(contactSections[[indexPath section]] == ContactSections_Number) { - ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonPhoneProperty); - NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); - CFStringRef valueRef = ABMultiValueCopyValueAtIndex(lMap, index); - if(valueRef != NULL) { - dest = [ContactDetailsTableViewController localizeLabel:(NSString*) valueRef]; - CFRelease(valueRef); - } - CFRelease(lMap); - } else if(contactSections[[indexPath section]] == ContactSections_Sip) { - ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonInstantMessageProperty); - NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); - CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(lMap, index); - CFStringRef valueRef = CFDictionaryGetValue(lDict, kABPersonInstantMessageUsernameKey); - dest = [FastAddressBook normalizeSipURI:[NSString stringWithString:(NSString*) valueRef]]; - CFRelease(lDict); - CFRelease(lMap); - } else if(contactSections[[indexPath section]] == ContactSections_Email) { - ABMultiValueRef lMap = ABRecordCopyValue(contact, kABPersonEmailProperty); - NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); - CFStringRef valueRef = ABMultiValueCopyValueAtIndex(lMap, index); - if(valueRef != NULL) { - dest = [FastAddressBook normalizeSipURI:[NSString stringWithString:(NSString*) valueRef]]; - CFRelease(valueRef); - } - CFRelease(lMap); - } - if(dest != nil) { - NSString *displayName = [FastAddressBook getContactDisplayName:contact]; - if([ContactSelection getSelectionMode] != ContactSelectionModeMessage) { - // Go to dialer view - DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController); - if(controller != nil) { - [controller call:dest displayName:displayName]; - } - } else { - // Go to Chat room view - [[PhoneMainView instance] popToView:[ChatViewController compositeViewDescription]]; // Got to Chat and push ChatRoom - ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController); - if(controller != nil) { - LinphoneChatRoom* room = linphone_core_get_or_create_chat_room([LinphoneManager getLc], [dest UTF8String]); - [controller setChatRoom:room]; - } - } - } - } else { - NSString *key = nil; - 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); - } - CFRelease(lMap); - } - if(key != nil) { - if(editingIndexPath != nil) { - [editingIndexPath release]; - } - editingIndexPath = [indexPath copy]; - ContactDetailsLabelViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsLabelViewController compositeViewDescription] push:TRUE], ContactDetailsLabelViewController); - if(controller != nil) { - [controller setDataList:[self getLocalizedLabels]]; - [controller setSelectedData:key]; - [controller setDelegate:self]; - } - } - } -} - -- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { - [LinphoneUtils findAndResignFirstResponder:[self tableView]]; - if (editingStyle == UITableViewCellEditingStyleInsert) { - [tableView beginUpdates]; - [self addEntry:tableView section:[indexPath section] animated:TRUE]; - [tableView endUpdates]; - } else if (editingStyle == UITableViewCellEditingStyleDelete) { - [tableView beginUpdates]; - [self removeEntry:tableView path:indexPath animated:TRUE]; - [tableView endUpdates]; - } -} - -#pragma mark - UITableViewDelegate Functions - -- (void)setEditing:(BOOL)editing animated:(BOOL)animated { - bool_t showEmails = [[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"]; - // Resign keyboard - if(!editing) { - [LinphoneUtils findAndResignFirstResponder:[self tableView]]; - } - - [headerController setEditing:editing animated:animated]; - [footerController setEditing:editing animated:animated]; - - if(animated) { - [self.tableView beginUpdates]; - } - if(editing) { - // add phony entries so that the user can add new data - for (int section = 0; section < [self numberOfSectionsInTableView:[self tableView]]; ++section) { - if(contactSections[section] == ContactSections_Number || - contactSections[section] == ContactSections_Sip || - (showEmails && contactSections[section] == ContactSections_Email)) { - [self addEntry:self.tableView section:section animated:animated]; - } - } - } else { - for (int section = 0; section < [self numberOfSectionsInTableView:[self tableView]]; ++section) { - // remove phony entries that were not filled by the user - if(contactSections[section] == ContactSections_Number || - contactSections[section] == ContactSections_Sip || - (showEmails && contactSections[section] == ContactSections_Email)) { - - [self removeEmptyEntry:self.tableView section:section animated:animated]; - if( [[self getSectionData:section] count] == 0 && animated ) { // the section is empty -> remove titles - [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] - withRowAnimation:UITableViewRowAnimationFade]; - } - } - } - } - if(animated) { - [self.tableView endUpdates]; - } - - [super setEditing:editing animated:animated]; - if(contactDetailsDelegate != nil) { - [contactDetailsDelegate onModification:nil]; - } -} - -- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { - NSInteger last_index = [[self getSectionData:[indexPath section]] count] - 1; - if (indexPath.row == last_index) { - return UITableViewCellEditingStyleInsert; - } - return UITableViewCellEditingStyleDelete; -} - -- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { - if(section == ContactSections_None) { - return [headerController view]; - } else { - return nil; - } -} - -- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { - if(section == (ContactSections_MAX - 1)) { - if(ABRecordGetRecordID(contact) != kABRecordInvalidID) { - return [footerController view]; - } - } - return nil; -} - -- (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - if( [[self getSectionData:section] count] == 0) return nil; - - if(contactSections[section] == ContactSections_Number) { - return NSLocalizedString(@"Phone numbers", nil); - } else if(contactSections[section] == ContactSections_Sip) { - return NSLocalizedString(@"SIP addresses", nil); - } else if(contactSections[section] == ContactSections_Email) { - return NSLocalizedString(@"Email addresses", nil); - } - return nil; -} - -- (NSString*)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { - return nil; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { - if(section == ContactSections_None) { - return [UIContactDetailsHeader height:[headerController isEditing]]; - } else { - // Hide section if nothing in it - if([[self getSectionData:section] count] > 0) - return 22; - else - return 0.000001f; // Hack UITableView = 0 - } -} - -- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { - if(section == (ContactSections_MAX - 1)) { - if(ABRecordGetRecordID(contact) != kABRecordInvalidID) { - return [UIContactDetailsFooter height:[footerController isEditing]]; - } else { - return 0.000001f; // Hack UITableView = 0 - } - } else if(section == ContactSections_None) { - return 0.000001f; // Hack UITableView = 0 - } - return 10.0f; -} - - -#pragma mark - ContactDetailsLabelDelegate Functions - -- (void)changeContactDetailsLabel:(NSString *)value { - if(value != nil) { - 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); - NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); - ABMultiValueReplaceLabelAtIndex(lMap, (CFStringRef)(value), index); - ABRecordSetValue(contact, kABPersonPhoneProperty, lMap, nil); - CFRelease(lMap); - } - - [self.tableView beginUpdates]; - [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject: editingIndexPath] withRowAnimation:FALSE]; - [self.tableView reloadSectionIndexTitles]; - [self.tableView endUpdates]; - } - [editingIndexPath release]; - editingIndexPath = nil; -} - - -#pragma mark - UITextFieldDelegate Functions - -- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { - if(contactDetailsDelegate != nil) { - [self performSelector:@selector(updateModification) withObject:nil afterDelay:0]; - } - return YES; -} - -- (BOOL)textFieldShouldReturn:(UITextField *)textField { - [textField resignFirstResponder]; - return YES; -} - -- (BOOL)textFieldShouldEndEditing:(UITextField *)textField { - UIView *view = [textField superview]; - // Find TableViewCell - while(view != nil && ![view isKindOfClass:[UIEditableTableViewCell class]]) view = [view superview]; - if(view != nil) { - UIEditableTableViewCell *cell = (UIEditableTableViewCell*)view; - NSIndexPath *path = [self.tableView indexPathForCell:cell]; - NSMutableArray *sectionDict = [self getSectionData:[path section]]; - Entry *entry = [sectionDict objectAtIndex:[path row]]; - ContactSections_e sect = contactSections[[path section]]; - - ABPropertyID property = [self propertyIDForSection:sect]; - NSString *value = [textField text]; - - if(sect == ContactSections_Sip) { - [self setSipContactEntry:entry withValue:value]; - } else if( property != kABInvalidPropertyType ){ - ABMultiValueRef lcMap = ABRecordCopyValue(contact, property); - ABMutableMultiValueRef lMap = ABMultiValueCreateMutableCopy(lcMap); - CFRelease(lcMap); - NSInteger index = ABMultiValueGetIndexForIdentifier(lMap, [entry identifier]); - ABMultiValueReplaceValueAtIndex(lMap, (CFStringRef)value, index); - ABRecordSetValue(contact, property, lMap, nil); - CFRelease(lMap); - } - - [cell.detailTextLabel setText:value]; - } else { - [LinphoneLogger logc:LinphoneLoggerError format:"Not valid UIEditableTableViewCell"]; - } - if(contactDetailsDelegate != nil) { - [self performSelector:@selector(updateModification) withObject:nil afterDelay:0]; - } - return TRUE; -} - -@end diff --git a/Classes/ContactDetailsView.h b/Classes/ContactDetailsView.h new file mode 100644 index 000000000..4927ee42f --- /dev/null +++ b/Classes/ContactDetailsView.h @@ -0,0 +1,57 @@ +/* ContactDetailsViewController.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import +#import + +#import "UICompositeView.h" +#import "UIToggleButton.h" +#import "ContactDetailsTableView.h" +#import "UIRoundedImageView.h" +#import "ImagePickerView.h" + +@interface ContactDetailsView + : TPMultiLayoutViewController { + ABAddressBookRef addressBook; + BOOL inhibUpdate; +} + +@property(nonatomic, assign, setter=setContact:) ABRecordRef contact; +@property(nonatomic, strong) IBOutlet ContactDetailsTableView *tableController; +@property(nonatomic, strong) IBOutlet UIToggleButton *editButton; +@property(nonatomic, strong) IBOutlet UIButton *backButton; +@property(nonatomic, strong) IBOutlet UIButton *cancelButton; +@property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage; +@property(weak, nonatomic) IBOutlet UILabel *nameLabel; +@property(weak, nonatomic) IBOutlet UIToggleButton *deleteButton; +@property(weak, nonatomic) IBOutlet UIView *contentView; +@property(weak, nonatomic) IBOutlet UILabel *emptyLabel; + +- (IBAction)onBackClick:(id)event; +- (IBAction)onCancelClick:(id)event; +- (IBAction)onEditClick:(id)event; +- (IBAction)onDeleteClick:(id)sender; +- (IBAction)onAvatarClick:(id)sender; + +- (void)newContact; +- (void)newContact:(NSString *)address; +- (void)editContact:(ABRecordRef)contact; +- (void)editContact:(ABRecordRef)contact address:(NSString *)address; +- (void)setContact:(ABRecordRef)contact; +@end diff --git a/Classes/ContactDetailsView.m b/Classes/ContactDetailsView.m new file mode 100644 index 000000000..24c25748c --- /dev/null +++ b/Classes/ContactDetailsView.m @@ -0,0 +1,341 @@ +/* ContactDetailsViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "ContactDetailsView.h" +#import "PhoneMainView.h" + +@implementation ContactDetailsView + +static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void *context); + +#pragma mark - Lifecycle Functions + +- (id)init { + self = [super initWithNibName:NSStringFromClass(self.class) bundle:[NSBundle mainBundle]]; + if (self != nil) { + inhibUpdate = FALSE; + addressBook = ABAddressBookCreateWithOptions(nil, nil); + ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, (__bridge void *)(self)); + } + return self; +} + +- (void)dealloc { + ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, (__bridge void *)(self)); + CFRelease(addressBook); +} + +#pragma mark - + +- (void)resetData { + if (self.isEditing) { + [self setEditing:FALSE]; + } + if (_contact == NULL) { + ABAddressBookRevert(addressBook); + return; + } + + LOGI(@"Reset data to contact %p", _contact); + ABRecordID recordID = ABRecordGetRecordID(_contact); + ABAddressBookRevert(addressBook); + _contact = ABAddressBookGetPersonWithRecordID(addressBook, recordID); + if (_contact == NULL) { + [PhoneMainView.instance popCurrentView]; + return; + } + [_avatarImage setImage:[FastAddressBook imageForContact:_contact thumbnail:NO] bordered:NO withRoundedRadius:YES]; + [_tableController setContact:_contact]; +} + +static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void *context) { + ContactDetailsView *controller = (__bridge ContactDetailsView *)context; + if (!controller->inhibUpdate && ![[controller tableController] isEditing]) { + [controller resetData]; + } +} + +- (void)removeContact { + if (_contact != NULL) { + inhibUpdate = TRUE; + [[[LinphoneManager instance] fastAddressBook] removeContact:_contact]; + inhibUpdate = FALSE; + } +} + +- (void)saveData { + if (_contact == NULL) { + [PhoneMainView.instance popCurrentView]; + return; + } + + // Add contact to book + CFErrorRef error = NULL; + if (ABRecordGetRecordID(_contact) == kABRecordInvalidID) { + ABAddressBookAddRecord(addressBook, _contact, (CFErrorRef *)&error); + if (error != NULL) { + LOGE(@"Add contact %p: Fail(%@)", _contact, [(__bridge NSError *)error localizedDescription]); + } else { + LOGI(@"Add contact %p: Success!", _contact); + } + } + + // Save address book + error = NULL; + inhibUpdate = TRUE; + ABAddressBookSave(addressBook, (CFErrorRef *)&error); + inhibUpdate = FALSE; + if (error != NULL) { + LOGE(@"Save AddressBook: Fail(%@)", [(__bridge NSError *)error localizedDescription]); + } else { + LOGI(@"Save AddressBook: Success!"); + } + [[LinphoneManager instance].fastAddressBook reload]; +} + +- (void)selectContact:(ABRecordRef)acontact andReload:(BOOL)reload { + _contact = NULL; + [self resetData]; + + _emptyLabel.hidden = (acontact != NULL); + + _contact = acontact; + [_avatarImage setImage:[FastAddressBook imageForContact:_contact thumbnail:NO] bordered:NO withRoundedRadius:YES]; + [ContactDisplay setDisplayNameLabel:_nameLabel forContact:acontact]; + [_tableController setContact:_contact]; + + if (reload) { + [self setEditing:TRUE animated:FALSE]; + [[_tableController tableView] reloadData]; + } +} + +- (void)addCurrentContactContactField:(NSString *)address { + LinphoneAddress *linphoneAddress = linphone_core_interpret_url([LinphoneManager getLc], address.UTF8String); + NSString *username = + linphoneAddress ? [NSString stringWithUTF8String:linphone_address_get_username(linphoneAddress)] : address; + + 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]; + } + if (linphoneAddress) { + linphone_address_destroy(linphoneAddress); + } + [self setEditing:TRUE]; + [[_tableController tableView] reloadData]; +} + +- (void)newContact { + [self selectContact:ABPersonCreate() andReload:YES]; +} + +- (void)newContact:(NSString *)address { + [self selectContact:ABPersonCreate() andReload:NO]; + [self addCurrentContactContactField:address]; +} + +- (void)editContact:(ABRecordRef)acontact { + [self selectContact:ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact)) andReload:YES]; +} + +- (void)editContact:(ABRecordRef)acontact address:(NSString *)address { + [self selectContact:ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact)) andReload:NO]; + [self addCurrentContactContactField:address]; +} + +- (void)setContact:(ABRecordRef)acontact { + [self selectContact:ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact)) andReload:NO]; +} + +#pragma mark - ViewController Functions + +- (void)viewDidLoad { + [super viewDidLoad]; + + // if we use fragments, remove back button + if (IPAD) { + _backButton.hidden = YES; + _backButton.alpha = 0; + } + + [self setContact:NULL]; + + _tableController.tableView.accessibilityIdentifier = @"Contact table"; + + [_editButton setImage:[UIImage imageNamed:@"valid_disabled.png"] + forState:(UIControlStateDisabled | UIControlStateSelected)]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + _editButton.hidden = ([ContactSelection getSelectionMode] != ContactSelectionModeEdit && + [ContactSelection getSelectionMode] != ContactSelectionModeNone); +} + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:TabBarView.class + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:NO + fragmentWith:ContactsListView.class]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - + +- (void)setEditing:(BOOL)editing { + [self setEditing:editing animated:NO]; +} + +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + [super setEditing:editing animated:animated]; + + if (animated) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:1.0]; + } + [_tableController setEditing:editing animated:animated]; + if (editing) { + [_editButton setOn]; + } else { + [_editButton setOff]; + } + _cancelButton.hidden = !editing; + _backButton.hidden = editing; + _nameLabel.hidden = editing; + [ContactDisplay setDisplayNameLabel:_nameLabel forContact:_contact]; + + if ([self viewIsCurrentlyPortrait]) { + CGRect frame = self.contentView.frame; + frame.size.height -= _avatarImage.frame.origin.y + _avatarImage.frame.size.height; + frame.origin.y = _nameLabel.frame.origin.y; + if (!editing) { + frame.origin.y += _nameLabel.frame.size.height; + frame.size.height -= _nameLabel.frame.size.height; + } + + _tableController.tableView.frame = frame; + } + if (animated) { + [UIView commitAnimations]; + } +} + +#pragma mark - Action Functions + +- (IBAction)onCancelClick:(id)event { + [self setEditing:FALSE]; + [self resetData]; +} + +- (IBAction)onBackClick:(id)event { + if ([ContactSelection getSelectionMode] == ContactSelectionModeEdit) { + [ContactSelection setSelectionMode:ContactSelectionModeNone]; + } + + ContactsListView *view = VIEW(ContactsListView); + [PhoneMainView.instance popToView:view.compositeViewDescription]; +} + +- (IBAction)onEditClick:(id)event { + if (_tableController.isEditing) { + if ([_tableController isValid]) { + [self setEditing:FALSE]; + [self saveData]; + } + } else { + [self setEditing:TRUE]; + } +} + +- (IBAction)onDeleteClick:(id)sender { + NSString *msg = NSLocalizedString(@"Do you want to delete selected contact?", nil); + [UIConfirmationDialog ShowWithMessage:msg + cancelMessage:nil + confirmMessage:nil + onCancelClick:nil + onConfirmationClick:^() { + [self setEditing:FALSE]; + [self removeContact]; + [PhoneMainView.instance popCurrentView]; + }]; +} + +- (IBAction)onAvatarClick:(id)sender { + if (_tableController.isEditing) { + [ImagePickerView SelectImageFromDevice:self atPosition:_avatarImage inView:self.view]; + } +} + +- (void)onModification:(id)event { + if (!_tableController.isEditing || [_tableController isValid]) { + [_editButton setEnabled:TRUE]; + } else { + [_editButton setEnabled:FALSE]; + } +} + +#pragma mark - Image picker delegate + +- (void)imagePickerDelegateImage:(UIImage *)image info:(NSDictionary *)info { + // Dismiss popover on iPad + if (IPAD) { + [VIEW(ImagePickerView).popoverController dismissPopoverAnimated:TRUE]; + } + + FastAddressBook *fab = [LinphoneManager instance].fastAddressBook; + CFErrorRef error = NULL; + if (!ABPersonRemoveImageData(_contact, (CFErrorRef *)&error)) { + LOGI(@"Can't remove entry: %@", [(__bridge NSError *)error localizedDescription]); + } + NSData *dataRef = UIImageJPEGRepresentation(image, 0.9f); + CFDataRef cfdata = CFDataCreate(NULL, [dataRef bytes], [dataRef length]); + + [fab saveAddressBook]; + + if (!ABPersonSetImageData(_contact, cfdata, (CFErrorRef *)&error)) { + LOGI(@"Can't add entry: %@", [(__bridge NSError *)error localizedDescription]); + } else { + [fab saveAddressBook]; + } + + CFRelease(cfdata); + + [_avatarImage setImage:[FastAddressBook imageForContact:_contact thumbnail:NO] bordered:NO withRoundedRadius:YES]; +} +@end diff --git a/Classes/ContactDetailsViewController.h b/Classes/ContactDetailsViewController.h deleted file mode 100644 index cc445a0c3..000000000 --- a/Classes/ContactDetailsViewController.h +++ /dev/null @@ -1,47 +0,0 @@ -/* ContactDetailsViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#import - -#import "UICompositeViewController.h" -#import "UIToggleButton.h" -#import "ContactDetailsTableViewController.h" - -@interface ContactDetailsViewController : UIViewController { - ABAddressBookRef addressBook; - BOOL inhibUpdate; -} - -@property (nonatomic, assign) ABRecordRef contact; -@property (nonatomic, retain) IBOutlet ContactDetailsTableViewController *tableController; -@property (nonatomic, retain) IBOutlet UIToggleButton *editButton; -@property (nonatomic, retain) IBOutlet UIButton *backButton; -@property (nonatomic, retain) IBOutlet UIButton *cancelButton; - -- (IBAction)onBackClick:(id)event; -- (IBAction)onCancelClick:(id)event; -- (IBAction)onEditClick:(id)event; - -- (void)newContact; -- (void)newContact:(NSString*)address; -- (void)editContact:(ABRecordRef)contact; -- (void)editContact:(ABRecordRef)contact address:(NSString*)address; - -@end diff --git a/Classes/ContactDetailsViewController.m b/Classes/ContactDetailsViewController.m deleted file mode 100644 index 35f010ae3..000000000 --- a/Classes/ContactDetailsViewController.m +++ /dev/null @@ -1,310 +0,0 @@ -/* ContactDetailsViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "ContactDetailsViewController.h" -#import "PhoneMainView.h" - -@implementation ContactDetailsViewController - -@synthesize tableController; -@synthesize contact; -@synthesize editButton; -@synthesize backButton; -@synthesize cancelButton; - - -static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context); - -#pragma mark - Lifecycle Functions - -- (id)init { - self = [super initWithNibName:@"ContactDetailsViewController" bundle:[NSBundle mainBundle]]; - if(self != nil) { - inhibUpdate = FALSE; - addressBook = ABAddressBookCreateWithOptions(nil, nil); - ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, self); - } - return self; -} - -- (void)dealloc { - ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, self); - CFRelease(addressBook); - [tableController release]; - - [editButton release]; - [backButton release]; - [cancelButton release]; - - [super dealloc]; -} - - -#pragma mark - - -- (void)resetData { - [self disableEdit:FALSE]; - if(contact == NULL) { - ABAddressBookRevert(addressBook); - return; - } - - [LinphoneLogger logc:LinphoneLoggerLog format:"Reset data to contact %p", contact]; - ABRecordID recordID = ABRecordGetRecordID(contact); - ABAddressBookRevert(addressBook); - contact = ABAddressBookGetPersonWithRecordID(addressBook, recordID); - if(contact == NULL) { - [[PhoneMainView instance] popCurrentView]; - return; - } - [tableController setContact:contact]; -} - -static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) { - ContactDetailsViewController* controller = (ContactDetailsViewController*)context; - if(!controller->inhibUpdate && ![[controller tableController] isEditing]) { - [controller resetData]; - } -} - -- (void)removeContact { - if(contact == NULL) { - [[PhoneMainView instance] popCurrentView]; - return; - } - - // Remove contact from book - if(ABRecordGetRecordID(contact) != kABRecordInvalidID) { - NSError* error = NULL; - ABAddressBookRemoveRecord(addressBook, contact, (CFErrorRef*)&error); - if (error != NULL) { - [LinphoneLogger log:LinphoneLoggerError format:@"Remove contact %p: Fail(%@)", contact, [error localizedDescription]]; - } else { - [LinphoneLogger logc:LinphoneLoggerLog format:"Remove contact %p: Success!", contact]; - } - contact = NULL; - - // Save address book - error = NULL; - inhibUpdate = TRUE; - ABAddressBookSave(addressBook, (CFErrorRef*)&error); - inhibUpdate = FALSE; - if (error != NULL) { - [LinphoneLogger log:LinphoneLoggerError format:@"Save AddressBook: Fail(%@)", [error localizedDescription]]; - } else { - [LinphoneLogger logc:LinphoneLoggerLog format:"Save AddressBook: Success!"]; - } - [[LinphoneManager instance].fastAddressBook reload]; - } -} - -- (void)saveData { - if(contact == NULL) { - [[PhoneMainView instance] popCurrentView]; - return; - } - - // Add contact to book - NSError* error = NULL; - if(ABRecordGetRecordID(contact) == kABRecordInvalidID) { - ABAddressBookAddRecord(addressBook, contact, (CFErrorRef*)&error); - if (error != NULL) { - [LinphoneLogger log:LinphoneLoggerError format:@"Add contact %p: Fail(%@)", contact, [error localizedDescription]]; - } else { - [LinphoneLogger logc:LinphoneLoggerLog format:"Add contact %p: Success!", contact]; - } - } - - // Save address book - error = NULL; - inhibUpdate = TRUE; - ABAddressBookSave(addressBook, (CFErrorRef*)&error); - inhibUpdate = FALSE; - if (error != NULL) { - [LinphoneLogger log:LinphoneLoggerError format:@"Save AddressBook: Fail(%@)", [error localizedDescription]]; - } else { - [LinphoneLogger logc:LinphoneLoggerLog format:"Save AddressBook: Success!"]; - } - [[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 { - [self selectContact:ABPersonCreate() andReload:YES]; -} - -- (void)newContact:(NSString*)address { - [self selectContact:ABPersonCreate() andReload:NO]; - [self addCurrentContactContactField:address]; -} - -- (void)editContact:(ABRecordRef)acontact { - [self selectContact:ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact)) andReload:YES]; -} - -- (void)editContact:(ABRecordRef)acontact address:(NSString*)address { - [self selectContact:ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact)) andReload:NO]; - [self addCurrentContactContactField:address]; -} - -- (void)setContact:(ABRecordRef)acontact { - [self selectContact:ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(acontact)) andReload:NO]; -} - -#pragma mark - ViewController Functions - -- (void)viewDidLoad{ - [super viewDidLoad]; - - // Set selected+over background: IB lack ! - [editButton setBackgroundImage:[UIImage imageNamed:@"contact_ok_over.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - // Set selected+disabled background: IB lack ! - [editButton setBackgroundImage:[UIImage imageNamed:@"contact_ok_disabled.png"] - forState:(UIControlStateDisabled | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStates:editButton]; - - [tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4 - [tableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4 -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - if([ContactSelection getSelectionMode] == ContactSelectionModeEdit || - [ContactSelection getSelectionMode] == ContactSelectionModeNone) { - [editButton setHidden:FALSE]; - } else { - [editButton setHidden:TRUE]; - } -} - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"ContactDetails" - content:@"ContactDetailsViewController" - stateBar:nil - stateBarEnabled:false - tabBar:@"UIMainBar" - tabBarEnabled:true - fullscreen:false - landscapeMode:[LinphoneManager runningOnIpad] - portraitMode:true]; - } - return compositeDescription; -} - - -#pragma mark - - -- (void)enableEdit:(BOOL)animated { - if(![tableController isEditing]) { - [tableController setEditing:TRUE animated:animated]; - } - [editButton setOn]; - [cancelButton setHidden:FALSE]; - [backButton setHidden:TRUE]; -} - -- (void)disableEdit:(BOOL)animated { - if([tableController isEditing]) { - [tableController setEditing:FALSE animated:animated]; - } - [editButton setOff]; - [cancelButton setHidden:TRUE]; - [backButton setHidden:FALSE]; -} - - -#pragma mark - Action Functions - -- (IBAction)onCancelClick:(id)event { - [self disableEdit:TRUE]; - [self resetData]; -} - -- (IBAction)onBackClick:(id)event { - if([ContactSelection getSelectionMode] == ContactSelectionModeEdit) { - [ContactSelection setSelectionMode:ContactSelectionModeNone]; - } - [[PhoneMainView instance] popCurrentView]; -} - -- (IBAction)onEditClick:(id)event { - if([tableController isEditing]) { - if([tableController isValid]) { - [self disableEdit:TRUE]; - [self saveData]; - } - } else { - [self enableEdit:TRUE]; - } -} - -- (void)onRemove:(id)event { - [self disableEdit:FALSE]; - [self removeContact]; - [[PhoneMainView instance] popCurrentView]; -} - -- (void)onModification:(id)event { - if(![tableController isEditing] || [tableController isValid]) { - [editButton setEnabled:TRUE]; - } else { - [editButton setEnabled:FALSE]; - } -} - -@end diff --git a/Classes/LinphoneUI/UILinphoneButton.h b/Classes/ContactsListTableView.h similarity index 68% rename from Classes/LinphoneUI/UILinphoneButton.h rename to Classes/ContactsListTableView.h index 7b390c40d..135479ec2 100644 --- a/Classes/LinphoneUI/UILinphoneButton.h +++ b/Classes/ContactsListTableView.h @@ -1,4 +1,4 @@ -/* UILinphoneButton.h +/* ContactsTableViewController.h * * Copyright (C) 2012 Belledonne Comunications, Grenoble, France * @@ -10,7 +10,7 @@ * 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. + * 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 @@ -18,13 +18,20 @@ */ #import -#import +#import -@interface UILinphoneButton : UIButton { - +#import "UICheckBoxTableView.h" + +#import "OrderedDictionary.h" + +@interface ContactsListTableView : UICheckBoxTableView { + @private + OrderedDictionary *addressBookMap; + NSMutableDictionary *avatarMap; + + ABAddressBookRef addressBook; } -@property (retain, nonatomic) IBOutlet TUNinePatch *backgroundNinePatch; -@property (retain, nonatomic) IBOutlet TUNinePatch *backgroundOverNinePatch; +- (void)loadData; @end diff --git a/Classes/ContactsListTableView.m b/Classes/ContactsListTableView.m new file mode 100644 index 000000000..9396d6915 --- /dev/null +++ b/Classes/ContactsListTableView.m @@ -0,0 +1,280 @@ +/* ContactsTableViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "ContactsListTableView.h" +#import "UIContactCell.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" +#import "Utils.h" + +@implementation ContactsListTableView + +static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void *context); + +#pragma mark - Lifecycle Functions + +- (void)initContactsTableViewController { + addressBookMap = [[OrderedDictionary alloc] init]; + avatarMap = [[NSMutableDictionary alloc] init]; + + addressBook = ABAddressBookCreateWithOptions(nil, nil); + + ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, (__bridge void *)(self)); +} + +- (id)init { + self = [super init]; + if (self) { + [self initContactsTableViewController]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + [self initContactsTableViewController]; + } + return self; +} + +- (void)dealloc { + ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, (__bridge void *)(self)); + CFRelease(addressBook); +} + +#pragma mark - + +static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) { + if (!fuzzy_word || !sentence) { + return fuzzy_word == sentence; + } + const char *c = fuzzy_word; + const char *within_sentence = sentence; + for (; c != NULL && *c != '\0' && within_sentence != NULL; ++c) { + within_sentence = strchr(within_sentence, *c); + // Could not find c character in sentence. Abort. + if (within_sentence == NULL) { + break; + } + // since strchr returns the index of the matched char, move forward + within_sentence++; + } + + // If the whole fuzzy was found, returns 0. Otherwise returns number of characters left. + return (int)(within_sentence != NULL ? 0 : fuzzy_word + strlen(fuzzy_word) - c); +} + +- (NSString *)displayNameForContact:(ABRecordRef)person { + NSString *name = [FastAddressBook displayNameForContact:person]; + if (name != nil && [name length] > 0 && ![name isEqualToString:NSLocalizedString(@"Unknown", nil)]) { + // Add the contact only if it fuzzy match filter too (if any) + if ([ContactSelection getNameOrEmailFilter] == nil || + (ms_strcmpfuz([[[ContactSelection getNameOrEmailFilter] lowercaseString] UTF8String], + [[name lowercaseString] UTF8String]) == 0)) { + + // Sort contacts by first letter. We need to translate the name to ASCII first, because of UTF-8 + // issues. For instance expected order would be: Alberta(A tilde) before ASylvano. + NSData *name2ASCIIdata = [name dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; + NSString *name2ASCII = [[NSString alloc] initWithData:name2ASCIIdata encoding:NSASCIIStringEncoding]; + return name2ASCII; + } + } + return nil; +} + +- (void)loadData { + LOGI(@"Load contact list"); + @synchronized(addressBookMap) { + + // Reset Address book + [addressBookMap removeAllObjects]; + + NSArray *lContacts = (NSArray *)CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook)); + for (id lPerson in lContacts) { + BOOL add = true; + ABRecordRef person = (__bridge ABRecordRef)lPerson; + + // Do not add the contact directly if we set some filter + if ([ContactSelection getSipFilter] || [ContactSelection emailFilterEnabled]) { + add = false; + } + if ([FastAddressBook contactHasValidSipDomain:person]) { + add = true; + } + if (!add && [ContactSelection emailFilterEnabled]) { + ABMultiValueRef personEmailAddresses = ABRecordCopyValue(person, kABPersonEmailProperty); + // Add this contact if it has an email + add = (ABMultiValueGetCount(personEmailAddresses) > 0); + + CFRelease(personEmailAddresses); + } + + NSString *name = [self displayNameForContact:person]; + if (add && name != nil) { + NSString *firstChar = [[name substringToIndex:1] uppercaseString]; + + // Put in correct subDic + if ([firstChar characterAtIndex:0] < 'A' || [firstChar characterAtIndex:0] > 'Z') { + firstChar = @"#"; + } + OrderedDictionary *subDic = [addressBookMap objectForKey:firstChar]; + if (subDic == nil) { + subDic = [[OrderedDictionary alloc] init]; + [addressBookMap insertObject:subDic forKey:firstChar selector:@selector(caseInsensitiveCompare:)]; + } + [subDic insertObject:lPerson forKey:name selector:@selector(caseInsensitiveCompare:)]; + } + } + } + [super loadData]; + if (IPAD) { + // reset details view since in fragment mode, details are relative to current data + // select first contact if any + ABRecordRef contact = ([self totalNumberOfItems] > 0) + ? [self contactForIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]] + : nil; + ContactDetailsView *view = VIEW(ContactDetailsView); + [view setContact:contact]; + } +} + +static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void *context) { + ContactsListTableView *controller = (__bridge ContactsListTableView *)context; + ABAddressBookRevert(addressBook); + [controller->avatarMap removeAllObjects]; + [controller loadData]; +} + +#pragma mark - UITableViewDataSource Functions + +- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { + return [addressBookMap allKeys]; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return [addressBookMap count]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return [(OrderedDictionary *)[addressBookMap objectForKey:[addressBookMap keyAtIndex:section]] count]; +} + +- (ABRecordRef)contactForIndexPath:(NSIndexPath *)indexPath { + + OrderedDictionary *subDic = [addressBookMap objectForKey:[addressBookMap keyAtIndex:[indexPath section]]]; + NSString *key = [[subDic allKeys] objectAtIndex:[indexPath row]]; + return (__bridge ABRecordRef)([subDic objectForKey:key]); +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + NSString *kCellId = NSStringFromClass(UIContactCell.class); + UIContactCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + if (cell == nil) { + cell = [[UIContactCell alloc] initWithIdentifier:kCellId]; + } + ABRecordRef contact = [self contactForIndexPath:indexPath]; + + // Cached avatar + UIImage *image = [avatarMap objectForKey:[NSNumber numberWithInt:ABRecordGetRecordID(contact)]]; + if (image == nil) { + image = [FastAddressBook imageForContact:contact thumbnail:true]; + [avatarMap setObject:image forKey:[NSNumber numberWithInt:ABRecordGetRecordID(contact)]]; + } + [cell.avatarImage setImage:image bordered:NO withRoundedRadius:YES]; + [cell setContact:contact]; + [super accessoryForCell:cell atPath:indexPath]; + + return cell; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { + CGRect frame = CGRectMake(0, 0, tableView.frame.size.width, tableView.sectionHeaderHeight); + UIView *tempView = [[UIView alloc] initWithFrame:frame]; + tempView.backgroundColor = [UIColor whiteColor]; + + UILabel *tempLabel = [[UILabel alloc] initWithFrame:frame]; + tempLabel.backgroundColor = [UIColor clearColor]; + tempLabel.textColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_A.png"]]; + tempLabel.text = [addressBookMap keyAtIndex:section]; + tempLabel.textAlignment = NSTextAlignmentCenter; + tempLabel.font = [UIFont boldSystemFontOfSize:17]; + tempLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + [tempView addSubview:tempLabel]; + + return tempView; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [super tableView:tableView didSelectRowAtIndexPath:indexPath]; + if (![self isEditing]) { + OrderedDictionary *subDic = [addressBookMap objectForKey:[addressBookMap keyAtIndex:[indexPath section]]]; + ABRecordRef lPerson = (__bridge ABRecordRef)([subDic objectForKey:[subDic keyAtIndex:[indexPath row]]]); + + // Go to Contact details view + ContactDetailsView *view = VIEW(ContactDetailsView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE]; + if ([ContactSelection getSelectionMode] != ContactSelectionModeEdit) { + [view setContact:lPerson]; + } else { + [view editContact:lPerson address:[ContactSelection getAddAddress]]; + } + } +} + +- (void)tableView:(UITableView *)tableView + commitEditingStyle:(UITableViewCellEditingStyle)editingStyle + forRowAtIndexPath:(NSIndexPath *)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, (__bridge void *)(self)); + [tableView beginUpdates]; + OrderedDictionary *subDic = [addressBookMap objectForKey:[addressBookMap keyAtIndex:[indexPath section]]]; + NSString *key = [[subDic allKeys] objectAtIndex:[indexPath row]]; + ABRecordRef contact = (__bridge ABRecordRef)([subDic objectForKey:key]); + NSString *firstChar = [[self displayNameForContact:contact] substringToIndex:1]; + [[addressBookMap objectForKey:firstChar] removeObjectForKey:[self displayNameForContact:contact]]; + if ([tableView numberOfRowsInSection:indexPath.section] == 1) { + [addressBookMap removeObjectForKey:firstChar]; + [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] + withRowAnimation:UITableViewRowAnimationFade]; + } + [[[LinphoneManager instance] fastAddressBook] removeContact:contact]; + [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] + withRowAnimation:UITableViewRowAnimationFade]; + [tableView endUpdates]; + ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, (__bridge void *)(self)); + } +} + +- (void)removeSelectionUsing:(void (^)(NSIndexPath *))remover { + [super removeSelectionUsing:^(NSIndexPath *indexPath) { + ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, (__bridge void *)(self)); + OrderedDictionary *subDic = [addressBookMap objectForKey:[addressBookMap keyAtIndex:[indexPath section]]]; + NSString *key = [[subDic allKeys] objectAtIndex:[indexPath row]]; + ABRecordRef contact = (__bridge ABRecordRef)([subDic objectForKey:key]); + NSString *firstChar = [[self displayNameForContact:contact] substringToIndex:1]; + [[addressBookMap objectForKey:firstChar] removeObjectForKey:[self displayNameForContact:contact]]; + if ([self.tableView numberOfRowsInSection:indexPath.section] == 1) { + [addressBookMap removeObjectForKey:firstChar]; + } + [[[LinphoneManager instance] fastAddressBook] removeContact:contact]; + }]; +} + +@end diff --git a/Classes/ContactsViewController.h b/Classes/ContactsListView.h similarity index 61% rename from Classes/ContactsViewController.h rename to Classes/ContactsListView.h index 6e726ab41..e16499907 100644 --- a/Classes/ContactsViewController.h +++ b/Classes/ContactsListView.h @@ -20,34 +20,30 @@ #import #import -#import "UICompositeViewController.h" -#import "ContactsTableViewController.h" +#import "UICompositeView.h" +#import "ContactsListTableView.h" +#import "UIIconButton.h" -typedef enum _ContactSelectionMode { - ContactSelectionModeNone, - ContactSelectionModeEdit, - ContactSelectionModePhone, - ContactSelectionModeMessage -} ContactSelectionMode; +typedef enum _ContactSelectionMode { ContactSelectionModeNone, ContactSelectionModeEdit } ContactSelectionMode; @interface ContactSelection : NSObject { } + (void)setSelectionMode:(ContactSelectionMode)selectionMode; + (ContactSelectionMode)getSelectionMode; -+ (void)setAddAddress:(NSString*)address; -+ (NSString*)getAddAddress; ++ (void)setAddAddress:(NSString *)address; ++ (NSString *)getAddAddress; /*! * Filters contacts by SIP domain. * @param domain SIP domain to filter. Use @"*" or nil to disable it. */ -+ (void)setSipFilter:(NSString*) domain; ++ (void)setSipFilter:(NSString *)domain; /*! * Weither contacts are filtered by SIP domain or not. * @return the filter used, or nil if none. */ -+ (NSString*)getSipFilter; ++ (NSString *)getSipFilter; /*! * Weither always keep contacts with an email address or not. @@ -65,33 +61,32 @@ typedef enum _ContactSelectionMode { * Filters contacts by name and/or email fuzzy matching pattern. * @param fuzzyName fuzzy word to match. Use nil to disable it. */ -+ (void)setNameOrEmailFilter:(NSString*)fuzzyName; ++ (void)setNameOrEmailFilter:(NSString *)fuzzyName; /*! * Weither contacts are filtered by name and/or email. * @return the filter used, or nil if none. */ -+ (NSString*)getNameOrEmailFilter; ++ (NSString *)getNameOrEmailFilter; @end -@interface ContactsViewController : UIViewController { - BOOL use_systemView; -} +@interface ContactsListView + : UIViewController -@property (nonatomic, retain) IBOutlet ContactsTableViewController* tableController; -@property (nonatomic, retain) IBOutlet UITableView *tableView; -@property (nonatomic, retain) IBOutlet UINavigationController* sysViewController; -@property (retain, nonatomic) IBOutlet UIView *toolBar; -@property (nonatomic, retain) IBOutlet UIButton* allButton; -@property (nonatomic, retain) IBOutlet UIButton* linphoneButton; -@property (nonatomic, retain) IBOutlet UIButton *backButton; -@property (nonatomic, retain) IBOutlet UIButton *addButton; -@property (retain, nonatomic) IBOutlet UISearchBar *searchBar; +@property(strong, nonatomic) IBOutlet ContactsListTableView *tableController; +@property(strong, nonatomic) IBOutlet UIView *topBar; +@property(nonatomic, strong) IBOutlet UIButton *allButton; +@property(nonatomic, strong) IBOutlet UIButton *linphoneButton; +@property(nonatomic, strong) IBOutlet UIButton *addButton; +@property(strong, nonatomic) IBOutlet UISearchBar *searchBar; +@property(weak, nonatomic) IBOutlet UIIconButton *deleteButton; +@property(weak, nonatomic) IBOutlet UIImageView *selectedButtonImage; - (IBAction)onAllClick:(id)event; - (IBAction)onLinphoneClick:(id)event; - (IBAction)onAddContactClick:(id)event; -- (IBAction)onBackClick:(id)event; +- (IBAction)onDeleteClick:(id)sender; +- (IBAction)onEditionChangeClick:(id)sender; @end diff --git a/Classes/ContactsListView.m b/Classes/ContactsListView.m new file mode 100644 index 000000000..f027b671b --- /dev/null +++ b/Classes/ContactsListView.m @@ -0,0 +1,279 @@ +/* ContactsViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "PhoneMainView.h" +#import + +@implementation ContactSelection + +static ContactSelectionMode sSelectionMode = ContactSelectionModeNone; +static NSString *sAddAddress = nil; +static NSString *sSipFilter = nil; +static BOOL sEnableEmailFilter = FALSE; +static NSString *sNameOrEmailFilter; + ++ (void)setSelectionMode:(ContactSelectionMode)selectionMode { + sSelectionMode = selectionMode; +} + ++ (ContactSelectionMode)getSelectionMode { + return sSelectionMode; +} + ++ (void)setAddAddress:(NSString *)address { + if (sAddAddress != nil) { + sAddAddress = nil; + } + if (address != nil) { + sAddAddress = address; + } +} + ++ (NSString *)getAddAddress { + return sAddAddress; +} + ++ (void)setSipFilter:(NSString *)domain { + sSipFilter = domain; +} + ++ (NSString *)getSipFilter { + return sSipFilter; +} + ++ (void)enableEmailFilter:(BOOL)enable { + sEnableEmailFilter = enable; +} + ++ (BOOL)emailFilterEnabled { + return sEnableEmailFilter; +} + ++ (void)setNameOrEmailFilter:(NSString *)fuzzyName { + sNameOrEmailFilter = fuzzyName; +} + ++ (NSString *)getNameOrEmailFilter { + return sNameOrEmailFilter; +} + +@end + +@implementation ContactsListView + +@synthesize tableController; +@synthesize allButton; +@synthesize linphoneButton; +@synthesize addButton; +@synthesize topBar; + +typedef enum { ContactsAll, ContactsLinphone, ContactsMAX } ContactsCategory; + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:TabBarView.class + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:YES + fragmentWith:ContactDetailsView.class]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + _searchBar.showsCancelButton = (_searchBar.text.length > 0); + + if (tableController.isEditing) { + tableController.editing = NO; + } + [self update]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + if (![FastAddressBook isAuthorized]) { + UIAlertView *error = [[UIAlertView alloc] + initWithTitle:NSLocalizedString(@"Address book", nil) + message:NSLocalizedString(@"You must authorize the application to have access to address book.\n" + "Toggle the application in Settings > Privacy > Contacts", + nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Continue", nil) + otherButtonTitles:nil]; + [error show]; + [PhoneMainView.instance changeCurrentView:DialerView.compositeViewDescription]; + } +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self changeView:ContactsAll]; +} + +#pragma mark - + +- (void)changeView:(ContactsCategory)view { + CGRect frame = _selectedButtonImage.frame; + if (view == ContactsAll) { + frame.origin.x = allButton.frame.origin.x; + [ContactSelection setSipFilter:nil]; + [ContactSelection enableEmailFilter:FALSE]; + [tableController loadData]; + allButton.selected = TRUE; + linphoneButton.selected = FALSE; + } else { + frame.origin.x = linphoneButton.frame.origin.x; + [ContactSelection setSipFilter:LinphoneManager.instance.contactFilter]; + [ContactSelection enableEmailFilter:FALSE]; + [tableController loadData]; + linphoneButton.selected = TRUE; + allButton.selected = FALSE; + } + _selectedButtonImage.frame = frame; +} + +- (void)refreshButtons { + [addButton setHidden:FALSE]; + [self changeView:[ContactSelection getSipFilter] ? ContactsLinphone : ContactsAll]; +} + +- (void)update { + [self refreshButtons]; + [tableController loadData]; +} + +#pragma mark - Action Functions + +- (IBAction)onAllClick:(id)event { + [self changeView:ContactsAll]; +} + +- (IBAction)onLinphoneClick:(id)event { + [self changeView:ContactsLinphone]; +} + +- (IBAction)onAddContactClick:(id)event { + // Go to Contact details view + ContactDetailsView *view = VIEW(ContactDetailsView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE]; + if ([ContactSelection getAddAddress] == nil) { + [view newContact]; + } else { + [view newContact:[ContactSelection getAddAddress]]; + } +} + +- (IBAction)onDeleteClick:(id)sender { + NSString *msg = [NSString stringWithFormat:NSLocalizedString(@"Do you want to delete selected contacts?", nil)]; + [UIConfirmationDialog ShowWithMessage:msg + cancelMessage:nil + confirmMessage:nil + onCancelClick:^() { + [self onEditionChangeClick:nil]; + } + onConfirmationClick:^() { + [tableController removeSelectionUsing:nil]; + [tableController loadData]; + }]; +} + +- (IBAction)onEditionChangeClick:(id)sender { + allButton.hidden = linphoneButton.hidden = _selectedButtonImage.hidden = addButton.hidden = + self.tableController.isEditing; +} + +- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { + searchBar.text = @""; + [self searchBar:searchBar textDidChange:@""]; + [searchBar resignFirstResponder]; +} + +#pragma mark - Rotation handling + +//- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { +// [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; +// // the searchbar overlaps the subview in most rotation cases, we have to re-layout the view manually: +// [self relayoutTableView]; +//} + +#pragma mark - ABPeoplePickerDelegate + +- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker { + [PhoneMainView.instance popCurrentView]; + return; +} + +- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker + shouldContinueAfterSelectingPerson:(ABRecordRef)person { + return true; +} + +- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker + shouldContinueAfterSelectingPerson:(ABRecordRef)person + property:(ABPropertyID)property + identifier:(ABMultiValueIdentifier)identifier { + + CFTypeRef multiValue = ABRecordCopyValue(person, property); + CFIndex valueIdx = ABMultiValueGetIndexForIdentifier(multiValue, identifier); + NSString *phoneNumber = (NSString *)CFBridgingRelease(ABMultiValueCopyValueAtIndex(multiValue, valueIdx)); + // Go to dialer view + DialerView *view = VIEW(DialerView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; + [view call:phoneNumber displayName:(NSString *)CFBridgingRelease(ABRecordCopyCompositeName(person))]; + CFRelease(multiValue); + 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]; +} + +@end diff --git a/Classes/ContactsTableViewController.h b/Classes/ContactsTableViewController.h deleted file mode 100644 index d1cbd99a0..000000000 --- a/Classes/ContactsTableViewController.h +++ /dev/null @@ -1,35 +0,0 @@ -/* ContactsTableViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#import - -#import "OrderedDictionary.h" - -@interface ContactsTableViewController : UITableViewController { - @private - OrderedDictionary* addressBookMap; - NSMutableDictionary* avatarMap; - - ABAddressBookRef addressBook; -} - -- (void)loadData; - -@end diff --git a/Classes/ContactsTableViewController.m b/Classes/ContactsTableViewController.m deleted file mode 100644 index 79675a18d..000000000 --- a/Classes/ContactsTableViewController.m +++ /dev/null @@ -1,314 +0,0 @@ -/* ContactsTableViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "ContactsTableViewController.h" -#import "UIContactCell.h" -#import "LinphoneManager.h" -#import "PhoneMainView.h" -#import "UACellBackgroundView.h" -#import "UILinphone.h" -#import "Utils.h" - -@implementation ContactsTableViewController - -static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context); - - -#pragma mark - Lifecycle Functions - -- (void)initContactsTableViewController { - addressBookMap = [[OrderedDictionary alloc] init]; - avatarMap = [[NSMutableDictionary alloc] init]; - - addressBook = ABAddressBookCreateWithOptions(nil, nil); - - ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, self); -} - -- (id)init { - self = [super init]; - if (self) { - [self initContactsTableViewController]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { - [self initContactsTableViewController]; - } - return self; -} - -- (void)dealloc { - ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, self); - CFRelease(addressBook); - [addressBookMap release]; - [avatarMap release]; - [super dealloc]; -} - - -#pragma mark - - -- (BOOL)contactHasValidSipDomain:(ABRecordRef)person { - // Check if one of the contact' sip URI matches the expected SIP filter - ABMultiValueRef personSipAddresses = ABRecordCopyValue(person, kABPersonInstantMessageProperty); - BOOL match = false; - NSString * filter = [ContactSelection getSipFilter]; - - for(int i = 0; i < ABMultiValueGetCount(personSipAddresses) && !match; ++i) { - CFDictionaryRef lDict = ABMultiValueCopyValueAtIndex(personSipAddresses, i); - if(CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) { - CFStringRef serviceKey = CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey); - - if (CFStringCompare((CFStringRef)[LinphoneManager instance].contactSipField, serviceKey, kCFCompareCaseInsensitive) == 0) { - match = true; - } - } else { - //check domain - LinphoneAddress* address = linphone_address_new([(NSString*)CFDictionaryGetValue(lDict,kABPersonInstantMessageUsernameKey) UTF8String]); - - if (address) { - 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; - } - } - linphone_address_destroy(address); - } - } - CFRelease(lDict); - } - CFRelease(personSipAddresses); - return match; -} - -static int ms_strcmpfuz(const char * fuzzy_word, const char * sentence) { - if (! fuzzy_word || !sentence) { - return fuzzy_word == sentence; - } - const char * c = fuzzy_word; - const char * within_sentence = sentence; - for (; c != NULL && *c != '\0' && within_sentence != NULL; ++c) { - within_sentence = strchr(within_sentence, *c); - // Could not find c character in sentence. Abort. - if (within_sentence == NULL) { - break; - } - // since strchr returns the index of the matched char, move forward - within_sentence++; - } - - // If the whole fuzzy was found, returns 0. Otherwise returns number of characters left. - return (int)(within_sentence != NULL ? 0 : fuzzy_word + strlen(fuzzy_word) - c); -} - -- (void)loadData { - [LinphoneLogger logc:LinphoneLoggerLog format:"Load contact list"]; - @synchronized (addressBookMap) { - - // Reset Address book - [addressBookMap removeAllObjects]; - - NSArray *lContacts = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); - for (id lPerson in lContacts) { - BOOL add = true; - ABRecordRef person = (ABRecordRef)lPerson; - - // Do not add the contact directly if we set some filter - if([ContactSelection getSipFilter] || [ContactSelection emailFilterEnabled]) { - add = false; - } - if([ContactSelection getSipFilter] && [self contactHasValidSipDomain:person]) { - add = true; - } - if (!add && [ContactSelection emailFilterEnabled]) { - ABMultiValueRef personEmailAddresses = ABRecordCopyValue(person, kABPersonEmailProperty); - // Add this contact if it has an email - add = (ABMultiValueGetCount(personEmailAddresses) > 0); - - CFRelease(personEmailAddresses); - } - - if(add) { - CFStringRef lFirstName = ABRecordCopyValue(person, kABPersonFirstNameProperty); - CFStringRef lLocalizedFirstName = (lFirstName != nil)? ABAddressBookCopyLocalizedLabel(lFirstName): nil; - CFStringRef lLastName = ABRecordCopyValue(person, kABPersonLastNameProperty); - CFStringRef lLocalizedLastName = (lLastName != nil)? ABAddressBookCopyLocalizedLabel(lLastName): nil; - CFStringRef lOrganization = ABRecordCopyValue(person, kABPersonOrganizationProperty); - CFStringRef lLocalizedlOrganization = (lOrganization != nil)? ABAddressBookCopyLocalizedLabel(lOrganization): nil; - NSString *name = nil; - if(lLocalizedFirstName != nil && lLocalizedLastName != nil) { - name=[NSString stringWithFormat:@"%@ %@", [(NSString *)lLocalizedFirstName retain], [(NSString *)lLocalizedLastName retain]]; - } else if(lLocalizedLastName != nil) { - name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedLastName retain]]; - } else if(lLocalizedFirstName != nil) { - name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedFirstName retain]]; - } else if(lLocalizedlOrganization != nil) { - name=[NSString stringWithFormat:@"%@",[(NSString *)lLocalizedlOrganization retain]]; - } - - if(name != nil && [name length] > 0) { - // Add the contact only if it fuzzy match filter too (if any) - if ([ContactSelection getNameOrEmailFilter] == nil || - (ms_strcmpfuz([[[ContactSelection getNameOrEmailFilter] lowercaseString] UTF8String], [[name lowercaseString] UTF8String]) == 0)) { - - //Sort contacts by first letter. We need to translate the name to ASCII first, because of UTF-8 issues. For instance - // we expect order: Alberta(A tilde) before ASylvano. - NSData *name2ASCIIdata = [name dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; - NSString *name2ASCII = [[[NSString alloc] initWithData:name2ASCIIdata encoding:NSASCIIStringEncoding] autorelease]; - NSString *firstChar = [[name2ASCII substringToIndex:1] uppercaseString]; - - // Put in correct subDic - if([firstChar characterAtIndex:0] < 'A' || [firstChar characterAtIndex:0] > 'Z') { - firstChar = @"#"; - } - OrderedDictionary *subDic =[addressBookMap objectForKey: firstChar]; - if(subDic == nil) { - subDic = [[[OrderedDictionary alloc] init] autorelease]; - [addressBookMap insertObject:subDic forKey:firstChar selector:@selector(caseInsensitiveCompare:)]; - } - [subDic insertObject:lPerson forKey:name2ASCII selector:@selector(caseInsensitiveCompare:)]; - } - } - if(lLocalizedlOrganization != nil) - CFRelease(lLocalizedlOrganization); - if(lOrganization != nil) - CFRelease(lOrganization); - if(lLocalizedLastName != nil) - CFRelease(lLocalizedLastName); - if(lLastName != nil) - CFRelease(lLastName); - if(lLocalizedFirstName != nil) - CFRelease(lLocalizedFirstName); - if(lFirstName != nil) - CFRelease(lFirstName); - } - } - if (lContacts) - CFRelease(lContacts); - } - [self.tableView reloadData]; -} - -static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context) { - ContactsTableViewController* controller = (ContactsTableViewController*)context; - ABAddressBookRevert(addressBook); - [controller->avatarMap removeAllObjects]; - [controller loadData]; -} - -#pragma mark - ViewController Functions - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; -} - - -#pragma mark - UITableViewDataSource Functions - -- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { - return [addressBookMap allKeys]; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return [addressBookMap count]; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return [(OrderedDictionary *)[addressBookMap objectForKey: [addressBookMap keyAtIndex: section]] count]; - -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - static NSString *kCellId = @"UIContactCell"; - UIContactCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; - if (cell == nil) { - cell = [[[UIContactCell alloc] initWithIdentifier:kCellId] autorelease]; - - // Background View - UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease]; - cell.selectedBackgroundView = selectedBackgroundView; - [selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR]; - } - OrderedDictionary *subDic = [addressBookMap objectForKey: [addressBookMap keyAtIndex: [indexPath section]]]; - - NSString *key = [[subDic allKeys] objectAtIndex:[indexPath row]]; - ABRecordRef contact = [subDic objectForKey:key]; - - // Cached avatar - UIImage *image = nil; - id data = [avatarMap objectForKey:[NSNumber numberWithInt: ABRecordGetRecordID(contact)]]; - if(data == nil) { - image = [FastAddressBook getContactImage:contact thumbnail:true]; - if(image != nil) { - [avatarMap setObject:image forKey:[NSNumber numberWithInt: ABRecordGetRecordID(contact)]]; - } else { - [avatarMap setObject:[NSNull null] forKey:[NSNumber numberWithInt: ABRecordGetRecordID(contact)]]; - } - } else if(data != [NSNull null]) { - image = data; - } - if(image == nil) { - image = [UIImage imageNamed:@"avatar_unknown_small.png"]; - } - [[cell avatarImage] setImage:image]; - - [cell setContact: contact]; - return cell; -} - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - return [addressBookMap keyAtIndex: section]; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - OrderedDictionary *subDic = [addressBookMap objectForKey: [addressBookMap keyAtIndex: [indexPath section]]]; - ABRecordRef lPerson = [subDic objectForKey: [subDic keyAtIndex:[indexPath row]]]; - - // Go to Contact details view - ContactDetailsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsViewController compositeViewDescription] push:TRUE], ContactDetailsViewController); - if(controller != nil) { - if([ContactSelection getSelectionMode] != ContactSelectionModeEdit) { - [controller setContact:lPerson]; - } else { - [controller editContact:lPerson address:[ContactSelection getAddAddress]]; - } - } -} - - -#pragma mark - UITableViewDelegate Functions - -- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { - // Detemine if it's in editing mode - if (self.editing) { - return UITableViewCellEditingStyleDelete; - } - return UITableViewCellEditingStyleNone; -} - -@end diff --git a/Classes/ContactsViewController.m b/Classes/ContactsViewController.m deleted file mode 100644 index 60f8541de..000000000 --- a/Classes/ContactsViewController.m +++ /dev/null @@ -1,394 +0,0 @@ -/* ContactsViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "ContactsViewController.h" -#import "PhoneMainView.h" -#import "Utils.h" - -#import - -@implementation ContactSelection - -static ContactSelectionMode sSelectionMode = ContactSelectionModeNone; -static NSString* sAddAddress = nil; -static NSString* sSipFilter = nil; -static BOOL sEnableEmailFilter = FALSE; -static NSString* sNameOrEmailFilter; - -+ (void)setSelectionMode:(ContactSelectionMode)selectionMode { - sSelectionMode = selectionMode; -} - -+ (ContactSelectionMode)getSelectionMode { - return sSelectionMode; -} - -+ (void)setAddAddress:(NSString*)address { - if(sAddAddress != nil) { - [sAddAddress release]; - sAddAddress= nil; - } - if(address != nil) { - sAddAddress = [address retain]; - } -} - -+ (NSString*)getAddAddress { - return sAddAddress; -} - -+ (void)setSipFilter:(NSString*)domain { - [sSipFilter release]; - sSipFilter = [domain retain]; -} - -+ (NSString*)getSipFilter { - return sSipFilter; -} - -+ (void)enableEmailFilter:(BOOL)enable { - sEnableEmailFilter = enable; -} - -+ (BOOL)emailFilterEnabled { - return sEnableEmailFilter; -} - -+ (void)setNameOrEmailFilter:(NSString*)fuzzyName { - [sNameOrEmailFilter release]; - sNameOrEmailFilter = [fuzzyName retain]; -} - -+ (NSString*)getNameOrEmailFilter { - return sNameOrEmailFilter; -} - - -@end - -@implementation ContactsViewController - -@synthesize tableController; -@synthesize tableView; - -@synthesize sysViewController; - -@synthesize allButton; -@synthesize linphoneButton; -@synthesize backButton; -@synthesize addButton; -@synthesize toolBar; - -typedef enum _HistoryView { - History_All, - History_Linphone, - History_Search, - History_MAX -} HistoryView; - - -#pragma mark - Lifecycle Functions - -- (id)init { - return [super initWithNibName:@"ContactsViewController" bundle:[NSBundle mainBundle]]; -} - -- (void)dealloc { - [tableController release]; - [tableView release]; - - [allButton release]; - [linphoneButton release]; - [backButton release]; - [addButton release]; - - [_searchBar release]; - [super dealloc]; -} - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"Contacts" - content:@"ContactsViewController" - stateBar:nil - stateBarEnabled:false - tabBar:@"UIMainBar" - tabBarEnabled:true - fullscreen:false - landscapeMode:[LinphoneManager runningOnIpad] - portraitMode:true]; - } - return compositeDescription; -} - - -#pragma mark - ViewController Functions - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; -} - -- (void)relayoutTableView { - CGRect subViewFrame= self.view.frame; - // let the toolBar be visible - subViewFrame.origin.y += self.toolBar.frame.size.height; - subViewFrame.size.height -= self.toolBar.frame.size.height; - [UIView animateWithDuration:0.2 animations:^{ - self.tableView.frame = subViewFrame; - }]; -} - -- (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]; - picker.peoplePickerDelegate = self; - picker.view.frame = self.view.frame; - - [self.view addSubview:picker.view]; - - self.sysViewController = picker; - self.searchBar.hidden = TRUE; - - } else if( !use_system && !self.tableController ){ - - - self.tableController = [[[ContactsTableViewController alloc] init] autorelease]; - self.tableView = [[[UITableView alloc] init] autorelease]; - - self.tableController.view = self.tableView; - - [self relayoutTableView]; - - self.tableView.dataSource = self.tableController; - self.tableView.delegate = self.tableController; - - self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | - UIViewAutoresizingFlexibleWidth | - UIViewAutoresizingFlexibleTopMargin | - UIViewAutoresizingFlexibleBottomMargin | - UIViewAutoresizingFlexibleLeftMargin | - UIViewAutoresizingFlexibleRightMargin; - - [self.view addSubview:tableView]; - [self update]; - } -} - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - if(![FastAddressBook isAuthorized]) { - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Address book",nil) - message:NSLocalizedString(@"You must authorize the application to have access to address book.\n" - "Toggle the application in Settings > Privacy > Contacts",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; - [[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]]; - } -} - -- (void)viewDidDisappear:(BOOL)animated { - [super viewDidDisappear:animated]; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - [self changeView:History_All]; - - // Set selected+over background: IB lack ! - [linphoneButton setBackgroundImage:[UIImage imageNamed:@"contacts_linphone_selected.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [linphoneButton setTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"] - forState:UIControlStateNormal]; - - [LinphoneUtils buttonFixStates:linphoneButton]; - - // Set selected+over background: IB lack ! - [allButton setBackgroundImage:[UIImage imageNamed:@"contacts_all_selected.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStates:allButton]; - - [tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4 - [tableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4 -} - - -#pragma mark - - -- (void)changeView:(HistoryView)view { - if(view == History_All) { - [ContactSelection setSipFilter:nil]; - [ContactSelection enableEmailFilter:FALSE]; - [tableController loadData]; - allButton.selected = TRUE; - } else { - allButton.selected = FALSE; - } - - if(view == History_Linphone) { - [ContactSelection setSipFilter:[LinphoneManager instance].contactFilter]; - [ContactSelection enableEmailFilter:FALSE]; - [tableController loadData]; - linphoneButton.selected = TRUE; - } else { - linphoneButton.selected = FALSE; - } -} - -- (void)update { - switch ([ContactSelection getSelectionMode]) { - case ContactSelectionModePhone: - case ContactSelectionModeMessage: - [addButton setHidden:TRUE]; - [backButton setHidden:FALSE]; - break; - default: - [addButton setHidden:FALSE]; - [backButton setHidden:TRUE]; - break; - } - if([ContactSelection getSipFilter]) { - allButton.selected = FALSE; - linphoneButton.selected = TRUE; - } else { - allButton.selected = TRUE; - linphoneButton.selected = FALSE; - } - [tableController loadData]; -} - - -#pragma mark - Action Functions - -- (IBAction)onAllClick:(id)event { - [self changeView: History_All]; -} - -- (IBAction)onLinphoneClick:(id)event { - [self changeView: History_Linphone]; -} - -- (IBAction)onAddContactClick:(id)event { - // Go to Contact details view - ContactDetailsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsViewController compositeViewDescription] push:TRUE], ContactDetailsViewController); - if(controller != nil) { - if([ContactSelection getAddAddress] == nil) { - [controller newContact]; - } else { - [controller newContact:[ContactSelection getAddAddress]]; - } - } -} - -- (IBAction)onBackClick:(id)event { - [[PhoneMainView instance] popCurrentView]; -} - - -- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { - [self searchBar:searchBar textDidChange:nil]; - [searchBar resignFirstResponder]; -} - -#pragma mark - Rotation handling - -- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { - [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; - // the searchbar overlaps the subview in most rotation cases, we have to re-layout the view manually: - [self relayoutTableView]; -} - - -#pragma mark - ABPeoplePickerDelegate - --(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker -{ - [[PhoneMainView instance] popCurrentView]; - return; -} - -- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker - shouldContinueAfterSelectingPerson:(ABRecordRef)person { - return true; - -} - -- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker - shouldContinueAfterSelectingPerson:(ABRecordRef)person - property:(ABPropertyID)property - identifier:(ABMultiValueIdentifier)identifier { - - CFTypeRef multiValue = ABRecordCopyValue(person, property); - CFIndex valueIdx = ABMultiValueGetIndexForIdentifier(multiValue,identifier); - NSString *phoneNumber = (NSString *)ABMultiValueCopyValueAtIndex(multiValue, valueIdx); - // Go to dialer view - DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController); - if(controller != nil) { - [controller call:phoneNumber displayName:[(NSString*)ABRecordCopyCompositeName(person) autorelease]]; - } - [phoneNumber release]; - CFRelease(multiValue); - 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]; -} -@end diff --git a/Classes/DialerView.h b/Classes/DialerView.h new file mode 100644 index 000000000..c9321d6b7 --- /dev/null +++ b/Classes/DialerView.h @@ -0,0 +1,68 @@ +/* DialerViewController.h + * + * Copyright (C) 2009 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import + +#import "UICompositeView.h" + +#import "UICamSwitch.h" +#import "UICallButton.h" +#import "UITransferButton.h" +#import "UIDigitButton.h" + +@interface DialerView + : TPMultiLayoutViewController { +} + +- (void)setAddress:(NSString *)address; +- (void)call:(NSString *)address displayName:(NSString *)displayName; +- (void)call:(NSString *)address; + +@property(nonatomic, assign) BOOL transferMode; + +@property(nonatomic, strong) IBOutlet UITextField *addressField; +@property(nonatomic, strong) IBOutlet UIButton *addContactButton; +@property(nonatomic, strong) IBOutlet UICallButton *callButton; +@property(nonatomic, strong) IBOutlet UICallButton *addCallButton; +@property(nonatomic, strong) IBOutlet UITransferButton *transferButton; +@property(nonatomic, strong) IBOutlet UIButton *backButton; +@property(weak, nonatomic) IBOutlet UIIconButton *backspaceButton; + +@property(nonatomic, strong) IBOutlet UIDigitButton *oneButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *twoButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *threeButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *fourButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *fiveButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *sixButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *sevenButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *eightButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *nineButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *starButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *zeroButton; +@property(nonatomic, strong) IBOutlet UIDigitButton *hashButton; +@property(nonatomic, strong) IBOutlet UIView *backgroundView; +@property(nonatomic, strong) IBOutlet UIView *videoPreview; +@property(nonatomic, strong) IBOutlet UICamSwitch *videoCameraSwitch; + +- (IBAction)onAddContactClick:(id)event; +- (IBAction)onBackClick:(id)event; +- (IBAction)onAddressChange:(id)sender; +- (IBAction)onBackspaceClick:(id)sender; + +@end diff --git a/Classes/DialerView.m b/Classes/DialerView.m new file mode 100644 index 000000000..de83c6fbe --- /dev/null +++ b/Classes/DialerView.m @@ -0,0 +1,435 @@ +/* DialerViewController.h + * + * Copyright (C) 2009 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import +#import + +#import "LinphoneManager.h" +#import "PhoneMainView.h" + +@implementation DialerView + +@synthesize transferMode; + +@synthesize addressField; +@synthesize addContactButton; +@synthesize backButton; +@synthesize addCallButton; +@synthesize transferButton; +@synthesize callButton; +@synthesize backspaceButton; + +@synthesize oneButton; +@synthesize twoButton; +@synthesize threeButton; +@synthesize fourButton; +@synthesize fiveButton; +@synthesize sixButton; +@synthesize sevenButton; +@synthesize eightButton; +@synthesize nineButton; +@synthesize starButton; +@synthesize zeroButton; +@synthesize hashButton; + +@synthesize backgroundView; +@synthesize videoPreview; +@synthesize videoCameraSwitch; + +#pragma mark - Lifecycle Functions + +- (id)init { + self = [super initWithNibName:NSStringFromClass(self.class) bundle:[NSBundle mainBundle]]; + if (self) { + transferMode = FALSE; + } + return self; +} + +- (void)dealloc { + // Remove all observers + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:TabBarView.class + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:YES + fragmentWith:nil]; + compositeDescription.darkBackground = true; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + // Set observer + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(callUpdateEvent:) + name:kLinphoneCallUpdate + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(coreUpdateEvent:) + name:kLinphoneCoreUpdate + object:nil]; + + // technically not needed, but older versions of linphone had this button + // disabled by default. In this case, updating by pushing a new version with + // xcode would result in the callbutton being disabled all the time. + // We force it enabled anyway now. + [callButton setEnabled:TRUE]; + + // Update on show + LinphoneManager *mgr = [LinphoneManager instance]; + LinphoneCore *lc = [LinphoneManager getLc]; + LinphoneCall *call = linphone_core_get_current_call(lc); + LinphoneCallState state = (call != NULL) ? linphone_call_get_state(call) : 0; + [self callUpdate:call state:state]; + + if (IPAD) { + BOOL videoEnabled = linphone_core_video_display_enabled(lc); + BOOL previewPref = [mgr lpConfigBoolForKey:@"preview_preference"]; + + if (videoEnabled && previewPref) { + linphone_core_set_native_preview_window_id(lc, (__bridge void *)(videoPreview)); + + if (!linphone_core_video_preview_enabled(lc)) { + linphone_core_enable_video_preview(lc, TRUE); + } + + [backgroundView setHidden:FALSE]; + [videoCameraSwitch setHidden:FALSE]; + } else { + linphone_core_set_native_preview_window_id(lc, NULL); + linphone_core_enable_video_preview(lc, FALSE); + [backgroundView setHidden:TRUE]; + [videoCameraSwitch setHidden:TRUE]; + } + } + [addressField setText:@""]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + [zeroButton setDigit:'0']; + [oneButton setDigit:'1']; + [twoButton setDigit:'2']; + [threeButton setDigit:'3']; + [fourButton setDigit:'4']; + [fiveButton setDigit:'5']; + [sixButton setDigit:'6']; + [sevenButton setDigit:'7']; + [eightButton setDigit:'8']; + [nineButton setDigit:'9']; + [starButton setDigit:'*']; + [hashButton setDigit:'#']; + + [addressField setAdjustsFontSizeToFitWidth:TRUE]; // Not put it in IB: issue with placeholder size + + UILongPressGestureRecognizer *backspaceLongGesture = + [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onBackspaceLongClick:)]; + [backspaceButton addGestureRecognizer:backspaceLongGesture]; + + UILongPressGestureRecognizer *zeroLongGesture = + [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onZeroLongClick:)]; + [zeroButton addGestureRecognizer:zeroLongGesture]; + + UILongPressGestureRecognizer *oneLongGesture = + [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onOneLongClick:)]; + [oneButton addGestureRecognizer:oneLongGesture]; + + if (IPAD) { + if ([LinphoneManager instance].frontCamId != nil) { + // only show camera switch button if we have more than 1 camera + [videoCameraSwitch setHidden:FALSE]; + } + } +} + +- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation + duration:(NSTimeInterval)duration { + [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; + switch (toInterfaceOrientation) { + case UIInterfaceOrientationPortrait: + [videoPreview setTransform:CGAffineTransformMakeRotation(0)]; + break; + case UIInterfaceOrientationPortraitUpsideDown: + [videoPreview setTransform:CGAffineTransformMakeRotation(M_PI)]; + break; + case UIInterfaceOrientationLandscapeLeft: + [videoPreview setTransform:CGAffineTransformMakeRotation(M_PI / 2)]; + break; + case UIInterfaceOrientationLandscapeRight: + [videoPreview setTransform:CGAffineTransformMakeRotation(-M_PI / 2)]; + break; + default: + break; + } + CGRect frame = self.view.frame; + frame.origin = CGPointMake(0, 0); + videoPreview.frame = frame; +} + +#pragma mark - Event Functions + +- (void)callUpdateEvent:(NSNotification *)notif { + LinphoneCall *call = [[notif.userInfo objectForKey:@"call"] pointerValue]; + LinphoneCallState state = [[notif.userInfo objectForKey:@"state"] intValue]; + [self callUpdate:call state:state]; +} + +- (void)coreUpdateEvent:(NSNotification *)notif { + if (IPAD) { + LinphoneCore *lc = [LinphoneManager getLc]; + if (linphone_core_video_display_enabled(lc) && linphone_core_video_preview_enabled(lc)) { + linphone_core_set_native_preview_window_id(lc, (__bridge void *)(videoPreview)); + [backgroundView setHidden:FALSE]; + [videoCameraSwitch setHidden:FALSE]; + } else { + linphone_core_set_native_preview_window_id(lc, NULL); + [backgroundView setHidden:TRUE]; + [videoCameraSwitch setHidden:TRUE]; + } + } +} + +#pragma mark - Debug Functions +- (void)presentMailViewWithTitle:(NSString *)subject forRecipients:(NSArray *)recipients attachLogs:(BOOL)attachLogs { + if ([MFMailComposeViewController canSendMail]) { + MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init]; + if (controller) { + controller.mailComposeDelegate = self; + [controller setSubject:subject]; + [controller setToRecipients:recipients]; + + if (attachLogs) { + char *filepath = linphone_core_compress_log_collection(); + if (filepath == NULL) { + LOGE(@"Cannot sent logs: file is NULL"); + return; + } + + NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; + NSString *filename = [appName stringByAppendingString:@".gz"]; + NSString *mimeType = @"text/plain"; + + if ([filename hasSuffix:@".gz"]) { + mimeType = @"application/gzip"; + filename = [appName stringByAppendingString:@".gz"]; + } else { + LOGE(@"Unknown extension type: %@, cancelling email", filename); + return; + } + [controller setMessageBody:NSLocalizedString(@"Application logs", nil) isHTML:NO]; + [controller addAttachmentData:[NSData dataWithContentsOfFile:[NSString stringWithUTF8String:filepath]] + mimeType:mimeType + fileName:filename]; + + ms_free(filepath); + } + self.modalPresentationStyle = UIModalPresentationPageSheet; + [self.view.window.rootViewController presentViewController:controller + animated:TRUE + completion:^{ + }]; + } + + } else { + UIAlertView *alert = + [[UIAlertView alloc] initWithTitle:subject + message:NSLocalizedString(@"Error: no mail account configured", nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"OK", nil) + otherButtonTitles:nil]; + [alert show]; + } +} + +- (BOOL)displayDebugPopup:(NSString *)address { + LinphoneManager *mgr = [LinphoneManager instance]; + NSString *debugAddress = [mgr lpConfigStringForKey:@"debug_popup_magic" withDefault:@""]; + if (![debugAddress isEqualToString:@""] && [address isEqualToString:debugAddress]) { + + DTAlertView *alertView = [[DTAlertView alloc] initWithTitle:NSLocalizedString(@"Debug", nil) + message:NSLocalizedString(@"Choose an action", nil)]; + + [alertView addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; + + [alertView + addButtonWithTitle:NSLocalizedString(@"Send logs", nil) + block:^{ + NSString *appName = + [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; + NSString *logsAddress = + [mgr lpConfigStringForKey:@"debug_popup_email" withDefault:@"linphone-ios@linphone.org"]; + [self presentMailViewWithTitle:appName forRecipients:@[ logsAddress ] attachLogs:true]; + }]; + + BOOL debugEnabled = [[LinphoneManager instance] lpConfigBoolForKey:@"debugenable_preference"]; + NSString *actionLog = + (debugEnabled ? NSLocalizedString(@"Disable logs", nil) : NSLocalizedString(@"Enable logs", nil)); + [alertView addButtonWithTitle:actionLog + block:^{ + // enable / disable + BOOL enableDebug = ![mgr lpConfigBoolForKey:@"debugenable_preference"]; + [mgr lpConfigSetBool:enableDebug forKey:@"debugenable_preference"]; + [mgr setLogsEnabled:enableDebug]; + }]; + + [alertView show]; + return true; + } + return false; +} + +#pragma mark - + +- (void)callUpdate:(LinphoneCall *)call state:(LinphoneCallState)state { + LinphoneCore *lc = [LinphoneManager getLc]; + BOOL callInProgress = (linphone_core_get_calls_nb(lc) > 0); + addCallButton.hidden = (!callInProgress || transferMode); + transferButton.hidden = (!callInProgress || !transferMode); + addContactButton.hidden = callButton.hidden = callInProgress; + backButton.hidden = !callInProgress; + [callButton updateVideoPolicy]; +} + +- (void)setAddress:(NSString *)address { + [addressField setText:address]; +} + +- (void)setTransferMode:(BOOL)atransferMode { + transferMode = atransferMode; + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); + LinphoneCallState state = (call != NULL) ? linphone_call_get_state(call) : 0; + [self callUpdate:call state:state]; +} + +- (void)call:(NSString *)address { + LinphoneAddress *addr = linphone_address_new(address.UTF8String); + NSString *displayName = addr ? [FastAddressBook displayNameForAddress:addr] : nil; + if (addr) + linphone_address_destroy(addr); + [self call:address displayName:displayName]; +} + +- (void)call:(NSString *)address displayName:(NSString *)displayName { + [[LinphoneManager instance] call:address displayName:displayName transfer:transferMode]; +} + +#pragma mark - UITextFieldDelegate Functions + +- (BOOL)textField:(UITextField *)textField + shouldChangeCharactersInRange:(NSRange)range + replacementString:(NSString *)string { + //[textField performSelector:@selector() withObject:nil afterDelay:0]; + return YES; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + if (textField == addressField) { + [addressField resignFirstResponder]; + } + return YES; +} + +#pragma mark - MFComposeMailDelegate + +- (void)mailComposeController:(MFMailComposeViewController *)controller + didFinishWithResult:(MFMailComposeResult)result + error:(NSError *)error { + [controller dismissViewControllerAnimated:TRUE + completion:^{ + }]; + [self.navigationController setNavigationBarHidden:TRUE animated:FALSE]; +} + +#pragma mark - Action Functions + +- (IBAction)onAddContactClick:(id)event { + [ContactSelection setSelectionMode:ContactSelectionModeEdit]; + [ContactSelection setAddAddress:[addressField text]]; + [ContactSelection setSipFilter:nil]; + [ContactSelection setNameOrEmailFilter:nil]; + [ContactSelection enableEmailFilter:FALSE]; + ContactsListView *view = VIEW(ContactsListView); + [PhoneMainView.instance changeCurrentView:view.class.compositeViewDescription push:TRUE]; +} + +- (IBAction)onBackClick:(id)event { + [PhoneMainView.instance changeCurrentView:CallView.compositeViewDescription]; +} + +- (IBAction)onAddressChange:(id)sender { + if ([self displayDebugPopup:self.addressField.text]) { + self.addressField.text = @""; + } + addContactButton.enabled = backspaceButton.enabled = addCallButton.enabled = transferButton.enabled = + ([[addressField text] length] > 0); +} + +- (IBAction)onBackspaceClick:(id)sender { + if ([addressField.text length] > 0) { + [addressField setText:[addressField.text substringToIndex:[addressField.text length] - 1]]; + } +} + +- (void)onBackspaceLongClick:(id)sender { + [addressField setText:@""]; +} + +- (void)onZeroLongClick:(id)sender { + // replace last character with a '+' + NSString *newAddress = + [[self.addressField.text substringToIndex:[self.addressField.text length] - 1] stringByAppendingString:@"+"]; + [self.addressField setText:newAddress]; +} + +- (void)onOneLongClick:(id)sender { + LinphoneManager *lm = [LinphoneManager instance]; + NSString *voiceMail = [lm lpConfigStringForKey:@"voice_mail_uri"]; + if (voiceMail != nil) { + [lm call:voiceMail displayName:NSLocalizedString(@"Voice mail", nil) transfer:FALSE]; + } else { + LOGE(@"Cannot call voice mail because URI not set!"); + } +} +@end diff --git a/Classes/DialerViewController.h b/Classes/DialerViewController.h deleted file mode 100644 index d97d612df..000000000 --- a/Classes/DialerViewController.h +++ /dev/null @@ -1,67 +0,0 @@ -/* DialerViewController.h - * - * Copyright (C) 2009 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UICompositeViewController.h" - -#import "UIEraseButton.h" -#import "UICamSwitch.h" -#import "UICallButton.h" -#import "UITransferButton.h" -#import "UIDigitButton.h" - -@interface DialerViewController : UIViewController { -} - -- (void)setAddress:(NSString*)address; -- (void)call:(NSString*)address displayName:(NSString *)displayName; -- (void)call:(NSString*)address; - -@property (nonatomic, assign) BOOL transferMode; - -@property (nonatomic, retain) IBOutlet UITextField* addressField; -@property (nonatomic, retain) IBOutlet UIButton* addContactButton; -@property (nonatomic, retain) IBOutlet UICallButton* callButton; -@property (nonatomic, retain) IBOutlet UICallButton* addCallButton; -@property (nonatomic, retain) IBOutlet UITransferButton* transferButton; -@property (nonatomic, retain) IBOutlet UIButton* backButton; -@property (nonatomic, retain) IBOutlet UIEraseButton* eraseButton; - -@property (nonatomic, retain) IBOutlet UIDigitButton* oneButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* twoButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* threeButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* fourButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* fiveButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* sixButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* sevenButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* eightButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* nineButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* starButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* zeroButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* sharpButton; -@property (nonatomic, retain) IBOutlet UIView* backgroundView; -@property (nonatomic, retain) IBOutlet UIView* videoPreview; -@property (nonatomic, retain) IBOutlet UICamSwitch* videoCameraSwitch; - -- (IBAction)onAddContactClick: (id) event; -- (IBAction)onBackClick: (id) event; -- (IBAction)onAddressChange: (id)sender; - -@end diff --git a/Classes/DialerViewController.m b/Classes/DialerViewController.m deleted file mode 100644 index c9480b922..000000000 --- a/Classes/DialerViewController.m +++ /dev/null @@ -1,469 +0,0 @@ -/* DialerViewController.h - * - * Copyright (C) 2009 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#import - -#import "DialerViewController.h" -#import "IncallViewController.h" -#import "DTAlertView.h" -#import "LinphoneManager.h" -#import "PhoneMainView.h" -#import "Utils.h" - -#include "linphone/linphonecore.h" - - -@implementation DialerViewController - -@synthesize transferMode; - -@synthesize addressField; -@synthesize addContactButton; -@synthesize backButton; -@synthesize addCallButton; -@synthesize transferButton; -@synthesize callButton; -@synthesize eraseButton; - -@synthesize oneButton; -@synthesize twoButton; -@synthesize threeButton; -@synthesize fourButton; -@synthesize fiveButton; -@synthesize sixButton; -@synthesize sevenButton; -@synthesize eightButton; -@synthesize nineButton; -@synthesize starButton; -@synthesize zeroButton; -@synthesize sharpButton; - -@synthesize backgroundView; -@synthesize videoPreview; -@synthesize videoCameraSwitch; - -#pragma mark - Lifecycle Functions - -- (id)init { - self = [super initWithNibName:@"DialerViewController" bundle:[NSBundle mainBundle]]; - if(self) { - self->transferMode = FALSE; - } - return self; -} - -- (void)dealloc { - [addressField release]; - [addContactButton release]; - [backButton release]; - [eraseButton release]; - [callButton release]; - [addCallButton release]; - [transferButton release]; - - [oneButton release]; - [twoButton release]; - [threeButton release]; - [fourButton release]; - [fiveButton release]; - [sixButton release]; - [sevenButton release]; - [eightButton release]; - [nineButton release]; - [starButton release]; - [zeroButton release]; - [sharpButton release]; - - [videoPreview release]; - [videoCameraSwitch release]; - - // Remove all observers - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [super dealloc]; -} - - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"Dialer" - content:@"DialerViewController" - stateBar:@"UIStateBar" - stateBarEnabled:true - tabBar:@"UIMainBar" - tabBarEnabled:true - fullscreen:false - landscapeMode:[LinphoneManager runningOnIpad] - portraitMode:true]; - compositeDescription.darkBackground = true; - } - return compositeDescription; -} - - -#pragma mark - ViewController Functions - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - // Set observer - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(callUpdateEvent:) - name:kLinphoneCallUpdate - object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(coreUpdateEvent:) - name:kLinphoneCoreUpdate - object:nil]; - - // technically not needed, but older versions of linphone had this button - // disabled by default. In this case, updating by pushing a new version with - // xcode would result in the callbutton being disabled all the time. - // We force it enabled anyway now. - [callButton setEnabled:TRUE]; - - // Update on show - LinphoneManager *mgr = [LinphoneManager instance]; - LinphoneCore* lc = [LinphoneManager getLc]; - LinphoneCall* call = linphone_core_get_current_call(lc); - LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0; - [self callUpdate:call state:state]; - - if([LinphoneManager runningOnIpad]) { - BOOL videoEnabled = linphone_core_video_enabled(lc); - BOOL previewPref = [mgr lpConfigBoolForKey:@"preview_preference"]; - - if( videoEnabled && previewPref ) { - linphone_core_set_native_preview_window_id(lc, (unsigned long)videoPreview); - - if( !linphone_core_video_preview_enabled(lc)){ - linphone_core_enable_video_preview(lc, TRUE); - } - - [backgroundView setHidden:FALSE]; - [videoCameraSwitch setHidden:FALSE]; - } else { - linphone_core_set_native_preview_window_id(lc, (unsigned long)NULL); - linphone_core_enable_video_preview(lc, FALSE); - [backgroundView setHidden:TRUE]; - [videoCameraSwitch setHidden:TRUE]; - } - } - - [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]; - } -#endif - -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - - // Remove observer - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneCallUpdate - object:nil]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneCoreUpdate - object:nil]; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - [zeroButton setDigit:'0']; - [oneButton setDigit:'1']; - [twoButton setDigit:'2']; - [threeButton setDigit:'3']; - [fourButton setDigit:'4']; - [fiveButton setDigit:'5']; - [sixButton setDigit:'6']; - [sevenButton setDigit:'7']; - [eightButton setDigit:'8']; - [nineButton setDigit:'9']; - [starButton setDigit:'*']; - [sharpButton setDigit:'#']; - - [addressField setAdjustsFontSizeToFitWidth:TRUE]; // Not put it in IB: issue with placeholder size - - if([LinphoneManager runningOnIpad]) { - if ([LinphoneManager instance].frontCamId != nil) { - // only show camera switch button if we have more than 1 camera - [videoCameraSwitch setHidden:FALSE]; - } - } -} - -- (void)viewDidUnload { - [super viewDidUnload]; -} - -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; - CGRect frame = [videoPreview frame]; - switch (toInterfaceOrientation) { - case UIInterfaceOrientationPortrait: - [videoPreview setTransform: CGAffineTransformMakeRotation(0)]; - break; - case UIInterfaceOrientationPortraitUpsideDown: - [videoPreview setTransform: CGAffineTransformMakeRotation(M_PI)]; - break; - case UIInterfaceOrientationLandscapeLeft: - [videoPreview setTransform: CGAffineTransformMakeRotation(M_PI / 2)]; - break; - case UIInterfaceOrientationLandscapeRight: - [videoPreview setTransform: CGAffineTransformMakeRotation(-M_PI / 2)]; - break; - default: - break; - } - [videoPreview setFrame:frame]; -} - - -#pragma mark - Event Functions - -- (void)callUpdateEvent:(NSNotification*)notif { - LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue]; - LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue]; - [self callUpdate:call state:state]; -} - -- (void)coreUpdateEvent:(NSNotification*)notif { - if([LinphoneManager runningOnIpad]) { - LinphoneCore* lc = [LinphoneManager getLc]; - if(linphone_core_video_enabled(lc) && linphone_core_video_preview_enabled(lc)) { - linphone_core_set_native_preview_window_id(lc, (unsigned long)videoPreview); - [backgroundView setHidden:FALSE]; - [videoCameraSwitch setHidden:FALSE]; - } else { - linphone_core_set_native_preview_window_id(lc, (unsigned long)NULL); - [backgroundView setHidden:TRUE]; - [videoCameraSwitch setHidden:TRUE]; - } - } -} - -#pragma mark - Debug Functions --(void)presentMailViewWithTitle:(NSString*)subject forRecipients:(NSArray*)recipients attachLogs:(BOOL)attachLogs { - if( [MFMailComposeViewController canSendMail] ){ - MFMailComposeViewController* controller = [[MFMailComposeViewController alloc] init]; - if( controller ){ - controller.mailComposeDelegate = self; - [controller setSubject:subject]; - [controller setToRecipients:recipients]; - - if( attachLogs ){ - char * filepath = linphone_core_compress_log_collection([LinphoneManager getLc]); - if (filepath == NULL) { - Linphone_err(@"Cannot sent logs: file is NULL"); - return; - } - NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; - NSString *filename = [appName stringByAppendingString:@".gz"]; - NSString *mimeType = @"text/plain"; - - if ([filename hasSuffix:@".gz"]) { - mimeType = @"application/gzip"; - filename = [appName stringByAppendingString:@".gz"]; - } else { - Linphone_err(@"Unknown extension type: %@, cancelling email", filename); - return; - } - [controller setMessageBody:NSLocalizedString(@"Application logs", nil) isHTML:NO]; - [controller addAttachmentData:[NSData dataWithContentsOfFile:[NSString stringWithUTF8String:filepath]] mimeType:mimeType fileName:filename]; - - ms_free(filepath); - - } - self.modalPresentationStyle = UIModalPresentationPageSheet; - [self.view.window.rootViewController presentViewController:controller animated:TRUE completion:^{}]; - [controller release]; - } - - } else { - UIAlertView* alert = [[UIAlertView alloc] initWithTitle:subject - message:NSLocalizedString(@"Error: no mail account configured", nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"OK", nil) - otherButtonTitles: nil]; - [alert show]; - [alert release]; - } -} - - -- (BOOL)displayDebugPopup:(NSString*)address { - LinphoneManager* mgr = [LinphoneManager instance]; - NSString* debugAddress = [mgr lpConfigStringForKey:@"debug_popup_magic" withDefault:@""]; - if( ![debugAddress isEqualToString:@""] && [address isEqualToString:debugAddress]){ - - - DTAlertView* alertView = [[DTAlertView alloc] initWithTitle:NSLocalizedString(@"Debug", nil) - message:NSLocalizedString(@"Choose an action", nil)]; - - [alertView addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; - - [alertView addButtonWithTitle:NSLocalizedString(@"Send logs", nil) block:^{ - NSString* appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; - NSString* logsAddress = [mgr lpConfigStringForKey:@"debug_popup_email" withDefault:@"linphone-ios@linphone.org"]; - [self presentMailViewWithTitle:appName forRecipients:@[logsAddress] attachLogs:true]; - }]; - - BOOL debugEnabled = [[LinphoneManager instance] lpConfigBoolForKey:@"debugenable_preference"]; - NSString* actionLog = (debugEnabled ? NSLocalizedString(@"Disable logs", nil) : NSLocalizedString(@"Enable logs", nil)); - [alertView addButtonWithTitle:actionLog block:^{ - // enable / disable - BOOL enableDebug = ![mgr lpConfigBoolForKey:@"debugenable_preference"]; - [mgr lpConfigSetBool:enableDebug forKey:@"debugenable_preference"]; - [mgr setLogsEnabled:enableDebug]; - }]; - - [alertView show]; - [alertView release]; - return true; - } - return false; -} - - -#pragma mark - - -- (void)callUpdate:(LinphoneCall*)call state:(LinphoneCallState)state { - LinphoneCore *lc = [LinphoneManager getLc]; - if(linphone_core_get_calls_nb(lc) > 0) { - if(transferMode) { - [addCallButton setHidden:true]; - [transferButton setHidden:false]; - } else { - [addCallButton setHidden:false]; - [transferButton setHidden:true]; - } - [callButton setHidden:true]; - [backButton setHidden:false]; - [addContactButton setHidden:true]; - } else { - [addCallButton setHidden:true]; - [callButton setHidden:false]; - [backButton setHidden:true]; - [addContactButton setHidden:false]; - [transferButton setHidden:true]; - } -} - -- (void)setAddress:(NSString*) address { - [addressField setText:address]; -} - -- (void)setTransferMode:(BOOL)atransferMode { - transferMode = atransferMode; - LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); - LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0; - [self callUpdate:call state:state]; -} - -- (void)call:(NSString*)address { - NSString *displayName = nil; - ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:address]; - if(contact) { - displayName = [FastAddressBook getContactDisplayName:contact]; - } - [self call:address displayName:displayName]; -} - -- (void)call:(NSString*)address displayName:(NSString *)displayName { - [[LinphoneManager instance] call:address displayName:displayName transfer:transferMode]; -} - - -#pragma mark - UITextFieldDelegate Functions - -- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { - //[textField performSelector:@selector() withObject:nil afterDelay:0]; - return YES; -} - -- (BOOL)textFieldShouldReturn:(UITextField *)textField { - if (textField == addressField) { - [addressField resignFirstResponder]; - } - return YES; -} - -#pragma mark - MFComposeMailDelegate - --(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error { - [controller dismissViewControllerAnimated:TRUE completion:^{}]; - [self.navigationController setNavigationBarHidden:TRUE animated:FALSE]; -} - - -#pragma mark - Action Functions - -- (IBAction)onAddContactClick: (id) event { - [ContactSelection setSelectionMode:ContactSelectionModeEdit]; - [ContactSelection setAddAddress:[addressField text]]; - [ContactSelection setSipFilter:nil]; - [ContactSelection setNameOrEmailFilter:nil]; - [ContactSelection enableEmailFilter:FALSE]; - ContactsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactsViewController compositeViewDescription] push:TRUE], ContactsViewController); - if(controller != nil) { - - } -} - -- (IBAction)onBackClick: (id) event { - [[PhoneMainView instance] changeCurrentView:[InCallViewController compositeViewDescription]]; -} - -- (IBAction)onAddressChange: (id)sender { - if( [self displayDebugPopup:self.addressField.text] ){ - self.addressField.text = @""; - } - if([[addressField text] length] > 0) { - [addContactButton setEnabled:TRUE]; - [eraseButton setEnabled:TRUE]; - [addCallButton setEnabled:TRUE]; - [transferButton setEnabled:TRUE]; - } else { - [addContactButton setEnabled:FALSE]; - [eraseButton setEnabled:FALSE]; - [addCallButton setEnabled:FALSE]; - [transferButton setEnabled:FALSE]; - } -} - -@end diff --git a/Classes/LinphoneUI/UIDigitButtonLongPlus.m b/Classes/FirstLoginView.h similarity index 52% rename from Classes/LinphoneUI/UIDigitButtonLongPlus.m rename to Classes/FirstLoginView.h index 2b2ffbbf6..25d54de97 100644 --- a/Classes/LinphoneUI/UIDigitButtonLongPlus.m +++ b/Classes/FirstLoginView.h @@ -1,4 +1,4 @@ -/* UIDigitButton.m +/* FirstLoginViewController.h * * Copyright (C) 2011 Belledonne Comunications, Grenoble, France * @@ -17,18 +17,23 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#import "UIDigitButtonLongPlus.h" +#import -@implementation UIDigitButtonLongPlus +#import "UICompositeView.h" +#import "UIAssistantTextField.h" -#pragma mark - UILongTouchButtonDelegate Functions - -- (void)onRepeatTouch { +@interface FirstLoginView : UIViewController { + LinphoneAccountCreator *account_creator; } -- (void)onLongTouch { - NSString* newAddress = [[self.addressField.text substringToIndex: [self.addressField.text length]-1] stringByAppendingString:@"+"]; - [self.addressField setText:newAddress]; -} +- (IBAction)onLoginClick:(id)sender; +- (IBAction)onSiteClick:(id)sender; + +@property(nonatomic, strong) IBOutlet UIButton *loginButton; +@property(nonatomic, strong) IBOutlet UIButton *siteButton; +@property(nonatomic, strong) IBOutlet UIAssistantTextField *usernameField; +@property(nonatomic, strong) IBOutlet UIAssistantTextField *passwordField; +@property(nonatomic, strong) IBOutlet UIView *waitView; +@property(weak, nonatomic) IBOutlet UIAssistantTextField *domainField; @end diff --git a/Classes/FirstLoginView.m b/Classes/FirstLoginView.m new file mode 100644 index 000000000..cd2473341 --- /dev/null +++ b/Classes/FirstLoginView.m @@ -0,0 +1,203 @@ +/* FirstLoginViewController.m + * + * Copyright (C) 2011 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "FirstLoginView.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" +#import "Utils/XMLRPCHelper.h" + +@implementation FirstLoginView + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:nil + tabBar:nil + sideMenu:nil + fullscreen:false + isLeftFragment:NO + fragmentWith:nil]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + // Set observer + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(registrationUpdateEvent:) + name:kLinphoneRegistrationUpdate + object:nil]; + + [_usernameField setText:[[LinphoneManager instance] lpConfigStringForKey:@"assistant_username"]]; + [_passwordField setText:[[LinphoneManager instance] lpConfigStringForKey:@"assistant_password"]]; + + // Update on show + const MSList *list = linphone_core_get_proxy_config_list([LinphoneManager getLc]); + if (list != NULL) { + LinphoneProxyConfig *config = (LinphoneProxyConfig *)list->data; + if (config) { + [self registrationUpdate:linphone_proxy_config_get_state(config)]; + } + } + + [_usernameField showError:[AssistantView errorForStatus:LinphoneAccountCreatorUsernameInvalid] + when:^BOOL(NSString *inputEntry) { + LinphoneAccountCreatorStatus s = + linphone_account_creator_set_username(account_creator, inputEntry.UTF8String); + _usernameField.errorLabel.text = [AssistantView errorForStatus:s]; + return s != LinphoneAccountCreatorOK; + }]; + + [_passwordField showError:[AssistantView errorForStatus:LinphoneAccountCreatorPasswordTooShort] + when:^BOOL(NSString *inputEntry) { + LinphoneAccountCreatorStatus s = + linphone_account_creator_set_password(account_creator, inputEntry.UTF8String); + _passwordField.errorLabel.text = [AssistantView errorForStatus:s]; + return s != LinphoneAccountCreatorOK; + }]; + + [_domainField showError:[AssistantView errorForStatus:LinphoneAccountCreatorDomainInvalid] + when:^BOOL(NSString *inputEntry) { + LinphoneAccountCreatorStatus s = + linphone_account_creator_set_domain(account_creator, inputEntry.UTF8String); + _domainField.errorLabel.text = [AssistantView errorForStatus:s]; + return s != LinphoneAccountCreatorOK; + }]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + // Remove observer + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneRegistrationUpdate object:nil]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + NSString *siteUrl = [[LinphoneManager instance] lpConfigStringForKey:@"first_login_view_url"]; + if (siteUrl == nil) { + siteUrl = @"http://www.linphone.org"; + } + [_siteButton setTitle:siteUrl forState:UIControlStateNormal]; + account_creator = linphone_account_creator_new([LinphoneManager getLc], siteUrl.UTF8String); +} + +- (void)shouldEnableNextButton { + BOOL invalidInputs = NO; + for (UIAssistantTextField *field in @[ _usernameField, _passwordField, _domainField ]) { + invalidInputs |= (field.isInvalid || field.lastText.length == 0); + } + _loginButton.enabled = !invalidInputs; +} + +#pragma mark - Event Functions + +- (void)registrationUpdateEvent:(NSNotification *)notif { + [self registrationUpdate:[[notif.userInfo objectForKey:@"state"] intValue]]; +} + +- (void)registrationUpdate:(LinphoneRegistrationState)state { + switch (state) { + case LinphoneRegistrationOk: { + [[LinphoneManager instance] lpConfigSetBool:FALSE forKey:@"enable_first_login_view_preference"]; + [_waitView setHidden:true]; + [PhoneMainView.instance changeCurrentView:DialerView.compositeViewDescription]; + break; + } + case LinphoneRegistrationNone: + case LinphoneRegistrationCleared: { + [_waitView setHidden:true]; + break; + } + case LinphoneRegistrationFailed: { + [_waitView setHidden:true]; + + // erase uername passwd + [[LinphoneManager instance] lpConfigSetString:nil forKey:@"assistant_username"]; + [[LinphoneManager instance] lpConfigSetString:nil forKey:@"assistant_password"]; + break; + } + case LinphoneRegistrationProgress: { + [_waitView setHidden:false]; + break; + } + default: + break; + } +} + +#pragma mark - Action Functions + +- (void)onSiteClick:(id)sender { + NSURL *url = [NSURL URLWithString:_siteButton.titleLabel.text]; + [[UIApplication sharedApplication] openURL:url]; + return; +} + +- (void)onLoginClick:(id)sender { + _waitView.hidden = NO; + [XMLRPCHelper GetProvisioningURL:_usernameField.text + password:_passwordField.text + domain:_domainField.text + OnSuccess:^(NSString *url) { + if (url) { + linphone_core_set_provisioning_uri([LinphoneManager getLc], url.UTF8String); + [[LinphoneManager instance] resetLinphoneCore]; + } else { + _waitView.hidden = YES; + } + }]; +} + +#pragma mark - UITextFieldDelegate Functions + +- (BOOL)textFieldShouldReturn:(UITextField *)theTextField { + // When the user presses return, take focus away from the text field so that the keyboard is dismissed. + [theTextField resignFirstResponder]; + return YES; +} + +- (void)textFieldDidEndEditing:(UITextField *)textField { + UIAssistantTextField *atf = (UIAssistantTextField *)textField; + [atf textFieldDidEndEditing:atf]; +} + +- (BOOL)textField:(UITextField *)textField + shouldChangeCharactersInRange:(NSRange)range + replacementString:(NSString *)string { + UIAssistantTextField *atf = (UIAssistantTextField *)textField; + [atf textField:atf shouldChangeCharactersInRange:range replacementString:string]; + [self shouldEnableNextButton]; + return YES; +} + +@end diff --git a/Classes/FirstLoginViewController.h b/Classes/FirstLoginViewController.h deleted file mode 100644 index 44e022547..000000000 --- a/Classes/FirstLoginViewController.h +++ /dev/null @@ -1,36 +0,0 @@ -/* FirstLoginViewController.h - * - * Copyright (C) 2011 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UICompositeViewController.h" - -@interface FirstLoginViewController : UIViewController { -} - -- (IBAction)onLoginClick:(id)sender; -- (IBAction)onSiteClick:(id)sender; - -@property (nonatomic, retain) IBOutlet UIButton* loginButton; -@property (nonatomic, retain) IBOutlet UIButton* siteButton; -@property (nonatomic, retain) IBOutlet UITextField* usernameField; -@property (nonatomic, retain) IBOutlet UITextField* passwordField; -@property (nonatomic, retain) IBOutlet UIView* waitView; - -@end diff --git a/Classes/FirstLoginViewController.m b/Classes/FirstLoginViewController.m deleted file mode 100644 index cfd5cf754..000000000 --- a/Classes/FirstLoginViewController.m +++ /dev/null @@ -1,207 +0,0 @@ -/* FirstLoginViewController.m - * - * Copyright (C) 2011 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU 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 "FirstLoginViewController.h" -#import "LinphoneManager.h" -#import "PhoneMainView.h" - -@implementation FirstLoginViewController - -@synthesize loginButton; -@synthesize siteButton; -@synthesize usernameField; -@synthesize passwordField; -@synthesize waitView; - -#pragma mark - Lifecycle Functions - -- (id)init { - return [super initWithNibName:@"FirstLoginViewController" bundle:[NSBundle mainBundle]]; -} - -- (void)dealloc { - [loginButton release]; - [siteButton release]; - [usernameField release]; - [passwordField release]; - [waitView release]; - - // Remove all observer - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [super dealloc]; -} - - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"FirstLogin" - content:@"FirstLoginViewController" - stateBar:nil - stateBarEnabled:false - tabBar:nil - tabBarEnabled:false - fullscreen:false - landscapeMode:false - portraitMode:true]; - } - return compositeDescription; -} - -#pragma mark - ViewController Functions - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - // Set observer - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(registrationUpdateEvent:) - name:kLinphoneRegistrationUpdate - object:nil]; - - - [usernameField setText:[[LinphoneManager instance] lpConfigStringForKey:@"wizard_username"]]; - [passwordField setText:[[LinphoneManager instance] lpConfigStringForKey:@"wizard_password"]]; - - // Update on show - const MSList* list = linphone_core_get_proxy_config_list([LinphoneManager getLc]); - if(list != NULL) { - LinphoneProxyConfig *config = (LinphoneProxyConfig*) list->data; - if(config) { - [self registrationUpdate:linphone_proxy_config_get_state(config)]; - } - } -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - - // Remove observer - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneRegistrationUpdate - object:nil]; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - NSString* siteUrl = [[LinphoneManager instance] lpConfigStringForKey:@"first_login_view_url"]; - if (siteUrl==nil) { - siteUrl=@"http://www.linphone.org"; - } - [siteButton setTitle:siteUrl forState:UIControlStateNormal]; -} - -#pragma mark - Event Functions - -- (void)registrationUpdateEvent:(NSNotification*)notif { - [self registrationUpdate:[[notif.userInfo objectForKey: @"state"] intValue]]; -} - - -#pragma mark - - -- (void)registrationUpdate:(LinphoneRegistrationState)state { - switch (state) { - case LinphoneRegistrationOk: { - [[LinphoneManager instance] lpConfigSetBool:FALSE forKey:@"enable_first_login_view_preference"]; - [waitView setHidden:true]; - [[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]]; - break; - } - case LinphoneRegistrationNone: - case LinphoneRegistrationCleared: { - [waitView setHidden:true]; - break; - } - case LinphoneRegistrationFailed: { - [waitView setHidden:true]; - - //erase uername passwd - [[LinphoneManager instance] lpConfigSetString:nil forKey:@"wizard_username"]; - [[LinphoneManager instance] lpConfigSetString:nil forKey:@"wizard_password"]; - break; - } - case LinphoneRegistrationProgress: { - [waitView setHidden:false]; - break; - } - default: break; - } -} - -#pragma mark - Action Functions - -- (void)onSiteClick:(id)sender { - NSURL *url = [NSURL URLWithString:siteButton.titleLabel.text]; - [[UIApplication sharedApplication] openURL:url]; - return; -} - -- (void)onLoginClick:(id)sender { - NSString* errorMessage=nil; - if ([usernameField.text length]==0 ) { - errorMessage=NSLocalizedString(@"Enter your username",nil); - } else if ([passwordField.text length]==0 ) { - errorMessage=NSLocalizedString(@"Enter your password",nil); - } - - if (errorMessage != nil) { - UIAlertView* error=nil; - error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Alert",nil) - message:errorMessage - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; - } else { - linphone_core_clear_all_auth_info([LinphoneManager getLc]); - linphone_core_clear_proxy_config([LinphoneManager getLc]); - LinphoneProxyConfig* proxyCfg = linphone_core_create_proxy_config([LinphoneManager getLc]); - /*default domain is supposed to be preset from linphonerc*/ - NSString* identity = [NSString stringWithFormat:@"sip:%@@%s",usernameField.text, linphone_proxy_config_get_addr(proxyCfg)]; - linphone_proxy_config_set_identity(proxyCfg,[identity UTF8String]); - LinphoneAuthInfo* auth_info =linphone_auth_info_new([usernameField.text UTF8String] - ,[usernameField.text UTF8String] - ,[passwordField.text UTF8String] - ,NULL - ,NULL - ,linphone_proxy_config_get_domain(proxyCfg)); - linphone_core_add_auth_info([LinphoneManager getLc], auth_info); - linphone_core_add_proxy_config([LinphoneManager getLc], proxyCfg); - linphone_core_set_default_proxy_config([LinphoneManager getLc], proxyCfg); - [self.waitView setHidden:false]; - }; -} - - -#pragma mark - UITextFieldDelegate Functions - -- (BOOL)textFieldShouldReturn:(UITextField *)theTextField { - // When the user presses return, take focus away from the text field so that the keyboard is dismissed. - [theTextField resignFirstResponder]; - return YES; -} - -@end diff --git a/Classes/HistoryDetailsTableView.h b/Classes/HistoryDetailsTableView.h new file mode 100644 index 000000000..025561893 --- /dev/null +++ b/Classes/HistoryDetailsTableView.h @@ -0,0 +1,19 @@ +// +// HistoryDetailsTableViewController.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 27/07/15. +// +// + +#import + +#import "linphone/linphonecore.h" + +@interface HistoryDetailsTableView : UITableViewController { + @private + NSMutableArray *callLogs; +} +- (void)loadDataForAddress:(const LinphoneAddress *)peer; + +@end diff --git a/Classes/HistoryDetailsTableView.m b/Classes/HistoryDetailsTableView.m new file mode 100644 index 000000000..998b26949 --- /dev/null +++ b/Classes/HistoryDetailsTableView.m @@ -0,0 +1,88 @@ +// +// HistoryDetailsTableViewController.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 27/07/15. +// +// + +#import "HistoryDetailsTableView.h" +#import "LinphoneManager.h" +#import "Utils.h" + +@implementation HistoryDetailsTableView + +- (void)loadDataForAddress:(const LinphoneAddress *)peer { + if (callLogs == nil) { + callLogs = [[NSMutableArray alloc] init]; + } else { + [callLogs removeAllObjects]; + } + + if (peer) { + const MSList *logs = linphone_core_get_call_history_for_address([LinphoneManager getLc], peer); + while (logs != NULL) { + LinphoneCallLog *log = (LinphoneCallLog *)logs->data; + if (linphone_address_weak_equal(linphone_call_log_get_remote_address(log), peer)) { + [callLogs addObject:[NSValue valueWithPointer:log]]; + } + logs = ms_list_next(logs); + } + } + [[self tableView] reloadData]; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return [callLogs count]; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { + CGRect frame = CGRectMake(0, 0, tableView.frame.size.width, 44); + UIView *tempView = [[UIView alloc] initWithFrame:frame]; + tempView.backgroundColor = [UIColor whiteColor]; + + UILabel *tempLabel = [[UILabel alloc] initWithFrame:frame]; + tempLabel.backgroundColor = [UIColor clearColor]; + tempLabel.textColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_E.png"]]; + tempLabel.text = NSLocalizedString(@"Calls", nil); + tempLabel.textAlignment = NSTextAlignmentCenter; + tempLabel.font = [UIFont boldSystemFontOfSize:17]; + tempLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + [tempView addSubview:tempLabel]; + + return tempView; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *kCellId = @"UITableViewCell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + if (cell == nil) { + cell = [[UITableViewCell alloc] init]; + } + + LinphoneCallLog *log = [[callLogs objectAtIndex:[indexPath row]] pointerValue]; + int duration = linphone_call_log_get_duration(log); + time_t callTime = linphone_call_log_get_start_date(log); + cell.textLabel.textAlignment = NSTextAlignmentCenter; + [cell.textLabel + setText:[NSString stringWithFormat:@"%@ - %@", + [LinphoneUtils timeToString:callTime withFormat:LinphoneDateHistoryDetails], + [LinphoneUtils durationToString:duration]]]; + BOOL outgoing = (linphone_call_log_get_dir(log) == LinphoneCallOutgoing); + + if (linphone_call_log_get_status(log) == LinphoneCallMissed) { + cell.imageView.image = [UIImage imageNamed:@"call_missed.png"]; + } else if (outgoing) { + cell.imageView.image = [UIImage imageNamed:@"call_outgoing.png"]; + } else { + cell.imageView.image = [UIImage imageNamed:@"call_incoming.png"]; + } + + return cell; +} + +@end diff --git a/Classes/HistoryDetailsView.h b/Classes/HistoryDetailsView.h new file mode 100644 index 000000000..355d53b56 --- /dev/null +++ b/Classes/HistoryDetailsView.h @@ -0,0 +1,48 @@ +/* HistoryDetailsViewController.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import +#include "linphone/linphonecore.h" + +#import +#import "UICompositeView.h" +#import "HistoryDetailsTableView.h" +#import "UIRoundedImageView.h" + +@interface HistoryDetailsView : TPMultiLayoutViewController { + @private + LinphoneCallLog *callLog; +} +@property(weak, nonatomic) IBOutlet UIButton *backButton; +@property(weak, nonatomic) IBOutlet UILabel *contactLabel; +@property(nonatomic, strong) IBOutlet UIRoundedImageView *avatarImage; +@property(nonatomic, strong) IBOutlet UILabel *addressLabel; +@property(nonatomic, strong) IBOutlet UIButton *addContactButton; +@property(nonatomic, copy, setter=setCallLogId:) NSString *callLogId; +@property(weak, nonatomic) IBOutlet UIView *headerView; +@property(strong, nonatomic) IBOutlet HistoryDetailsTableView *tableView; +@property(weak, nonatomic) IBOutlet UILabel *emptyLabel; + +- (IBAction)onBackClick:(id)event; +- (IBAction)onAddContactClick:(id)event; +- (IBAction)onCallClick:(id)event; +- (IBAction)onChatClick:(id)event; +- (void)setCallLogId:(NSString *)acallLogId; + +@end diff --git a/Classes/HistoryDetailsView.m b/Classes/HistoryDetailsView.m new file mode 100644 index 000000000..02216d51c --- /dev/null +++ b/Classes/HistoryDetailsView.m @@ -0,0 +1,191 @@ +/* HistoryDetailsViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "HistoryDetailsView.h" +#import "PhoneMainView.h" +#import "FastAddressBook.h" + +@implementation HistoryDetailsView + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:TabBarView.class + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:NO + fragmentWith:HistoryListView.class]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - Property Functions + +- (void)setCallLogId:(NSString *)acallLogId { + _callLogId = [acallLogId copy]; + [self update]; +} + +#pragma mark - ViewController Functions + +- (void)viewDidLoad { + [super viewDidLoad]; + + // if we use fragments, remove back button + if (IPAD) { + _backButton.hidden = YES; + _backButton.alpha = 0; + } + + UITapGestureRecognizer *headerTapGesture = + [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onContactClick:)]; + [_headerView addGestureRecognizer:headerTapGesture]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + [self update]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(update) + name:kLinphoneAddressBookUpdate + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(coreUpdateEvent:) + name:kLinphoneCoreUpdate + object:nil]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +#pragma mark - Event Functions + +- (void)coreUpdateEvent:(NSNotification *)notif { + [self update]; +} + +#pragma mark - + +- (void)update { + // Look for the call log + callLog = NULL; + if (_callLogId) { + const MSList *list = linphone_core_get_call_logs([LinphoneManager getLc]); + while (list != NULL) { + LinphoneCallLog *log = (LinphoneCallLog *)list->data; + const char *cid = linphone_call_log_get_call_id(log); + if (cid != NULL && [_callLogId isEqualToString:[NSString stringWithUTF8String:cid]]) { + callLog = log; + break; + } + list = list->next; + } + } + + // Pop if callLog is null + if (callLog == NULL) { + _emptyLabel.hidden = NO; + _addContactButton.hidden = YES; + return; + } + _emptyLabel.hidden = YES; + + LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog); + _addContactButton.hidden = ([FastAddressBook getContactWithAddress:addr] != nil); + [ContactDisplay setDisplayNameLabel:_contactLabel forAddress:addr]; + [_avatarImage setImage:[FastAddressBook imageForAddress:addr thumbnail:NO] bordered:NO withRoundedRadius:YES]; + char *addrURI = linphone_address_as_string_uri_only(addr); + _addressLabel.text = [NSString stringWithUTF8String:addrURI]; + ms_free(addrURI); + + [_tableView loadDataForAddress:(callLog ? linphone_call_log_get_remote_address(callLog) : NULL)]; +} + +#pragma mark - Action Functions + +- (IBAction)onBackClick:(id)event { + HistoryListView *view = VIEW(HistoryListView); + [PhoneMainView.instance popToView:view.compositeViewDescription]; +} + +- (IBAction)onContactClick:(id)event { + LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog); + ABRecordRef contact = [FastAddressBook getContactWithAddress:addr]; + if (contact) { + ContactDetailsView *view = VIEW(ContactDetailsView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE]; + [ContactSelection setSelectionMode:ContactSelectionModeNone]; + [view setContact:contact]; + } +} + +- (IBAction)onAddContactClick:(id)event { + LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog); + char *lAddress = linphone_address_as_string_uri_only(addr); + if (lAddress != NULL) { + [ContactSelection setAddAddress:[NSString stringWithUTF8String:lAddress]]; + [ContactSelection setSelectionMode:ContactSelectionModeEdit]; + + [ContactSelection setSipFilter:nil]; + [ContactSelection enableEmailFilter:FALSE]; + [ContactSelection setNameOrEmailFilter:nil]; + [PhoneMainView.instance changeCurrentView:ContactsListView.compositeViewDescription push:TRUE]; + ms_free(lAddress); + } +} + +- (IBAction)onCallClick:(id)event { + LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog); + char *lAddress = linphone_address_as_string_uri_only(addr); + if (lAddress == NULL) + return; + NSString *displayName = [FastAddressBook displayNameForAddress:addr]; + + DialerView *view = VIEW(DialerView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; + [view call:[NSString stringWithUTF8String:lAddress] displayName:displayName]; + ms_free(lAddress); +} + +- (IBAction)onChatClick:(id)event { + const LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog); + if (addr == NULL) + return; + [PhoneMainView.instance changeCurrentView:ChatsListView.compositeViewDescription]; + ChatConversationView *view = VIEW(ChatConversationView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE]; + LinphoneChatRoom *room = linphone_core_get_chat_room([LinphoneManager getLc], addr); + [view setChatRoom:room]; +} + +@end diff --git a/Classes/HistoryDetailsViewController.h b/Classes/HistoryDetailsViewController.h deleted file mode 100644 index 132b1310e..000000000 --- a/Classes/HistoryDetailsViewController.h +++ /dev/null @@ -1,53 +0,0 @@ -/* HistoryDetailsViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#include "linphone/linphonecore.h" - -#import -#import "UICompositeViewController.h" - -@interface HistoryDetailsViewController : UIViewController { - @private - ABRecordRef contact; - LinphoneCallLog *callLog; - NSDateFormatter *dateFormatter; -} -@property (nonatomic, retain) IBOutlet UIImageView *avatarImage; -@property (nonatomic, retain) IBOutlet UILabel *addressLabel; -@property (nonatomic, retain) IBOutlet UILabel *dateLabel; -@property (nonatomic, retain) IBOutlet UILabel *dateHeaderLabel; -@property (nonatomic, retain) IBOutlet UILabel *durationLabel; -@property (nonatomic, retain) IBOutlet UILabel *durationHeaderLabel; -@property (nonatomic, retain) IBOutlet UILabel *typeLabel; -@property (nonatomic, retain) IBOutlet UILabel *typeHeaderLabel; -@property (nonatomic, retain) IBOutlet UILabel *plainAddressLabel; -@property (nonatomic, retain) IBOutlet UILabel *plainAddressHeaderLabel; -@property (nonatomic, retain) IBOutlet UIButton *callButton; -@property (nonatomic, retain) IBOutlet UIButton *messageButton; -@property (nonatomic, retain) IBOutlet UIButton *addContactButton; -@property (nonatomic, assign) NSString *callLogId; - -- (IBAction)onBackClick:(id)event; -- (IBAction)onContactClick:(id)event; -- (IBAction)onAddContactClick:(id)event; -- (IBAction)onCallClick:(id)event; -- (IBAction)onMessageClick:(id)event; - -@end diff --git a/Classes/HistoryDetailsViewController.m b/Classes/HistoryDetailsViewController.m deleted file mode 100644 index d9261bd7c..000000000 --- a/Classes/HistoryDetailsViewController.m +++ /dev/null @@ -1,397 +0,0 @@ -/* HistoryDetailsViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "HistoryDetailsViewController.h" -#import "PhoneMainView.h" -#import "FastAddressBook.h" -#import "Utils.h" - -@implementation HistoryDetailsViewController - -@synthesize callLogId; -@synthesize avatarImage; -@synthesize addressLabel; -@synthesize dateLabel; -@synthesize dateHeaderLabel; -@synthesize durationLabel; -@synthesize durationHeaderLabel; -@synthesize typeLabel; -@synthesize typeHeaderLabel; -@synthesize plainAddressLabel; -@synthesize plainAddressHeaderLabel; -@synthesize callButton; -@synthesize messageButton; -@synthesize addContactButton; - -#pragma mark - LifeCycle Functions - -- (id)init { - self = [super initWithNibName:@"HistoryDetailsViewController" bundle:[NSBundle mainBundle]]; - if(self != nil) { - dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setTimeStyle:NSDateFormatterMediumStyle]; - [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; - NSLocale *locale = [NSLocale currentLocale]; - [dateFormatter setLocale:locale]; - } - return self; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [dateFormatter release]; - [callLogId release]; - - [avatarImage release]; - [addressLabel release]; - [dateLabel release]; - [dateHeaderLabel release]; - [durationLabel release]; - [durationHeaderLabel release]; - [typeLabel release]; - [typeHeaderLabel release]; - [plainAddressLabel release]; - [plainAddressHeaderLabel release]; - [callButton release]; - [messageButton release]; - [addContactButton release]; - - [super dealloc]; -} - - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"HistoryDetails" - content:@"HistoryDetailsViewController" - stateBar:nil - stateBarEnabled:false - tabBar:@"UIMainBar" - tabBarEnabled:true - fullscreen:false - landscapeMode:[LinphoneManager runningOnIpad] - portraitMode:true]; - } - return compositeDescription; -} - - -#pragma mark - Property Functions - -- (void)setCallLogId:(NSString *)acallLogId { - self->callLogId = [acallLogId copy]; - [self update]; -} - - -#pragma mark - ViewController Functions - -- (void)viewDidLoad { - [super viewDidLoad]; - [HistoryDetailsViewController adaptSize:dateHeaderLabel field:dateLabel]; - [HistoryDetailsViewController adaptSize:durationHeaderLabel field:durationLabel]; - [HistoryDetailsViewController adaptSize:typeHeaderLabel field:typeLabel]; - [HistoryDetailsViewController adaptSize:plainAddressHeaderLabel field:plainAddressLabel]; - [addContactButton.titleLabel setAdjustsFontSizeToFitWidth:TRUE]; // Auto shrink: IB lack! - [callButton.titleLabel setAdjustsFontSizeToFitWidth:TRUE]; // Auto shrink: IB lack! - [messageButton.titleLabel setAdjustsFontSizeToFitWidth:TRUE]; // Auto shrink: IB lack! -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - BOOL use_system = [[LinphoneManager instance] lpConfigBoolForKey:@"use_system_contacts"]; - if( use_system ){ - [addContactButton setHidden:TRUE]; - } - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(update) - name:kLinphoneAddressBookUpdate - object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(coreUpdateEvent:) - name:kLinphoneCoreUpdate - object:nil]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneAddressBookUpdate - object:nil]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneCoreUpdate - object:nil]; -} - - -#pragma mark - Event Functions - -- (void)coreUpdateEvent:(NSNotification*)notif { - [self update]; -} - - -#pragma mark - - -+ (void)adaptSize:(UILabel*)label field:(UIView*)field { - // - // Adapt size - // - CGRect labelFrame = [label frame]; - CGRect fieldFrame = [field frame]; - - fieldFrame.origin.x -= labelFrame.size.width; - - // Compute firstName size - CGSize contraints; - contraints.height = [label frame].size.height; - contraints.width = ([field frame].size.width + [field frame].origin.x) - [label frame].origin.x; - CGSize firstNameSize = [[label text] sizeWithFont:[label font] constrainedToSize: contraints]; - labelFrame.size.width = firstNameSize.width; - - // Compute lastName size & position - fieldFrame.origin.x += labelFrame.size.width; - fieldFrame.size.width = (contraints.width + [label frame].origin.x) - fieldFrame.origin.x; - - [label setFrame: labelFrame]; - [field setFrame: fieldFrame]; -} - -- (void)update { - - // Look for the call log - callLog = NULL; - const MSList *list = linphone_core_get_call_logs([LinphoneManager getLc]); - while(list != NULL) { - LinphoneCallLog *log = (LinphoneCallLog *)list->data; - const char *cid = linphone_call_log_get_call_id(log); - if(cid != NULL && [callLogId isEqualToString:[NSString stringWithUTF8String:cid]]) { - callLog = log; - break; - } - list = list->next; - } - - // Pop if callLog is null - if(callLog == NULL) { - [[PhoneMainView instance] popCurrentView]; - return; - } - - LinphoneAddress* addr =linphone_call_log_get_remote_address(callLog); - - UIImage *image = nil; - NSString* address = nil; - if(addr != NULL) { - BOOL useLinphoneAddress = true; - // contact name - char* lAddress = linphone_address_as_string_uri_only(addr); - if(lAddress) { - NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:lAddress]]; - contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress]; - if(contact) { - image = [FastAddressBook getContactImage:contact thumbnail:true]; - address = [FastAddressBook getContactDisplayName:contact]; - useLinphoneAddress = false; - } - ms_free(lAddress); - } - if(useLinphoneAddress) { - const char* lDisplayName = linphone_address_get_display_name(addr); - const char* lUserName = linphone_address_get_username(addr); - if (lDisplayName) - address = [NSString stringWithUTF8String:lDisplayName]; - else if(lUserName) - address = [NSString stringWithUTF8String:lUserName]; - } - } - - // Set Image - if(image == nil) { - image = [UIImage imageNamed:@"avatar_unknown.png"]; - } - [avatarImage setImage:image]; - - // Set Address - if(address == nil) { - address = NSLocalizedString(@"Unknown", nil); - } - [addressLabel setText:address]; - - // Hide/Show add button - BOOL use_system = [[LinphoneManager instance] lpConfigBoolForKey:@"use_system_contacts"]; - if(contact) { - [addContactButton setHidden:TRUE]; - } else if (!use_system) { - [addContactButton setHidden:FALSE]; - } - - // State - NSMutableString *state = [NSMutableString string]; - if (linphone_call_log_get_dir(callLog) == LinphoneCallIncoming) { - [state setString:NSLocalizedString(@"Incoming call", nil)]; - } else { - [state setString:NSLocalizedString(@"Outgoing call", nil)]; - } - switch (linphone_call_log_get_status(callLog)) { - case LinphoneCallSuccess: - break; - case LinphoneCallAborted: - [state appendString:NSLocalizedString(@" (Aborted)", nil)]; - break; - case LinphoneCallMissed: - [state appendString:NSLocalizedString(@" (Missed)", nil)]; - break; - case LinphoneCallDeclined: - [state appendString:NSLocalizedString(@" (Declined)", nil)]; - break; - } - [typeLabel setText:state]; - - // Date - NSDate *startData = [NSDate dateWithTimeIntervalSince1970:linphone_call_log_get_start_date(callLog)]; - [dateLabel setText:[dateFormatter stringFromDate:startData]]; - - // Duration - int duration = linphone_call_log_get_duration(callLog); - [durationLabel setText:[NSString stringWithFormat:@"%02i:%02i", (duration/60), duration - 60 * (duration / 60), nil]]; - - // contact name - [plainAddressLabel setText:@""]; - if (addr != NULL) { - if ([[LinphoneManager instance] lpConfigBoolForKey:@"contact_display_username_only"]) { - [plainAddressLabel setText:[NSString stringWithUTF8String:linphone_address_get_username(addr)?linphone_address_get_username(addr):""]]; - } else { - char* lAddress = linphone_address_as_string_uri_only(addr); - if(lAddress != NULL) { - [plainAddressLabel setText:[NSString stringWithUTF8String:lAddress]]; - ms_free(lAddress); - } - } - } - - if (addr != NULL) { - [callButton setHidden:FALSE]; - [messageButton setHidden:FALSE]; - } else { - [callButton setHidden:TRUE]; - [messageButton setHidden:TRUE]; - } - -} - - -#pragma mark - Action Functions - -- (IBAction)onBackClick:(id)event { - [[PhoneMainView instance] popCurrentView]; -} - -- (IBAction)onContactClick:(id)event { - if(contact) { - ContactDetailsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsViewController compositeViewDescription] push:TRUE], ContactDetailsViewController); - if(controller != nil) { - [ContactSelection setSelectionMode:ContactSelectionModeNone]; - [controller setContact:contact]; - } - } -} - -- (IBAction)onAddContactClick:(id)event { - LinphoneAddress* addr; - - addr=linphone_call_log_get_remote_address(callLog); - if (addr != NULL) { - char* lAddress = linphone_address_as_string_uri_only(addr); - if(lAddress != NULL) { - [ContactSelection setAddAddress:[NSString stringWithUTF8String:lAddress]]; - [ContactSelection setSelectionMode:ContactSelectionModeEdit]; - - [ContactSelection setSipFilter:nil]; - [ContactSelection enableEmailFilter:FALSE]; - [ContactSelection setNameOrEmailFilter:nil]; - ContactsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactsViewController compositeViewDescription] push:TRUE], ContactsViewController); - if(controller != nil) { - } - ms_free(lAddress); - } - } -} - -- (IBAction)onCallClick:(id)event { - LinphoneAddress* addr; - addr=linphone_call_log_get_remote_address(callLog); - - char* lAddress = linphone_address_as_string_uri_only(addr); - if(lAddress == NULL) - return; - - NSString *displayName = nil; - if(contact != nil) { - displayName = [FastAddressBook getContactDisplayName:contact]; - } else { - const char* lDisplayName = linphone_address_get_display_name(addr); - const char* lUserName = linphone_address_get_username(addr); - if (lDisplayName) - displayName = [NSString stringWithUTF8String:lDisplayName]; - else if(lUserName) - displayName = [NSString stringWithUTF8String:lUserName]; - } - - - DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController); - if(controller != nil) { - if(displayName != nil) { - [controller call:[NSString stringWithUTF8String:lAddress] displayName:displayName]; - } else { - [controller call:[NSString stringWithUTF8String:lAddress]]; - } - } - ms_free(lAddress); -} - -- (IBAction)onMessageClick:(id)event { - LinphoneAddress* addr; - addr=linphone_call_log_get_remote_address(callLog); - - char* lAddress = linphone_address_as_string_uri_only(addr); - if(lAddress == NULL) - return; - - // Go to ChatRoom view - [[PhoneMainView instance] changeCurrentView:[ChatViewController compositeViewDescription]]; - ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController); - if(controller != nil) { - LinphoneChatRoom* room = linphone_core_get_or_create_chat_room([LinphoneManager getLc], lAddress); - [controller setChatRoom:room]; - } - ms_free(lAddress); -} - -@end diff --git a/Classes/LinphoneUI/UIDigitButtonLongPlus.h b/Classes/HistoryListTableView.h similarity index 68% rename from Classes/LinphoneUI/UIDigitButtonLongPlus.h rename to Classes/HistoryListTableView.h index f1cf5b3c9..1285997be 100644 --- a/Classes/LinphoneUI/UIDigitButtonLongPlus.h +++ b/Classes/HistoryListTableView.h @@ -1,7 +1,6 @@ - -/* UIDigitButton.h +/* HistoryTableViewController.h * - * Copyright (C) 2011 Belledonne Comunications, Grenoble, France + * Copyright (C) 2009 Belledonne Comunications, Grenoble, France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,10 +19,14 @@ #import -#import "UIDigitButton.h" +#import "UICheckBoxTableView.h" - -@interface UIDigitButtonLongPlus : UIDigitButton { +@interface HistoryListTableView : UICheckBoxTableView { } +@property(nonatomic, assign) BOOL missedFilter; + +@property(strong, nonatomic) NSMutableDictionary *sections; +@property(strong, nonatomic) NSMutableArray *sortedDays; + @end diff --git a/Classes/HistoryListTableView.m b/Classes/HistoryListTableView.m new file mode 100644 index 000000000..d65cd98d1 --- /dev/null +++ b/Classes/HistoryListTableView.m @@ -0,0 +1,289 @@ +/* HistoryTableViewController.m + * + * Copyright (C) 2009 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "HistoryListTableView.h" +#import "UIHistoryCell.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" +#import "Utils.h" + +@implementation HistoryListTableView + +@synthesize missedFilter; + +#pragma mark - Lifecycle Functions + +- (void)initHistoryTableViewController { + missedFilter = false; +} + +- (id)init { + self = [super init]; + if (self) { + [self initHistoryTableViewController]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + [self initHistoryTableViewController]; + } + return self; +} + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(loadData) + name:kLinphoneAddressBookUpdate + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(coreUpdateEvent:) + name:kLinphoneCoreUpdate + object:nil]; + [self loadData]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneAddressBookUpdate object:nil]; + + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneCoreUpdate object:nil]; +} + +#pragma mark - Event Functions + +- (void)coreUpdateEvent:(NSNotification *)notif { + // Invalid all pointers + [self loadData]; +} + +#pragma mark - Property Functions + +- (void)setMissedFilter:(BOOL)amissedFilter { + if (missedFilter == amissedFilter) { + return; + } + missedFilter = amissedFilter; + [self loadData]; +} + +#pragma mark - UITableViewDataSource Functions + +- (NSDate *)dateAtBeginningOfDayForDate:(NSDate *)inputDate { + NSCalendar *calendar = [NSCalendar currentCalendar]; + NSTimeZone *timeZone = [NSTimeZone systemTimeZone]; + [calendar setTimeZone:timeZone]; + NSDateComponents *dateComps = + [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:inputDate]; + + dateComps.hour = dateComps.minute = dateComps.second = 0; + return [calendar dateFromComponents:dateComps]; +} + +- (void)loadData { + for (id day in self.sections.allKeys) { + for (id log in self.sections[day]) { + linphone_call_log_unref([log pointerValue]); + } + } + + const MSList *logs = linphone_core_get_call_logs([LinphoneManager getLc]); + self.sections = [NSMutableDictionary dictionary]; + while (logs != NULL) { + LinphoneCallLog *log = (LinphoneCallLog *)logs->data; + if (!missedFilter || linphone_call_log_get_status(log) == LinphoneCallMissed) { + NSDate *startDate = [self + dateAtBeginningOfDayForDate:[NSDate + dateWithTimeIntervalSince1970:linphone_call_log_get_start_date(log)]]; + NSMutableArray *eventsOnThisDay = [self.sections objectForKey:startDate]; + if (eventsOnThisDay == nil) { + eventsOnThisDay = [NSMutableArray array]; + [self.sections setObject:eventsOnThisDay forKey:startDate]; + } + + linphone_call_log_set_user_data(log, NULL); + + // if this contact was already the previous entry, do not add it twice + LinphoneCallLog *prev = [eventsOnThisDay lastObject] ? [[eventsOnThisDay lastObject] pointerValue] : NULL; + if (prev && linphone_address_weak_equal(linphone_call_log_get_remote_address(prev), + linphone_call_log_get_remote_address(log))) { + MSList *list = linphone_call_log_get_user_data(prev); + list = ms_list_append(list, log); + linphone_call_log_set_user_data(prev, list); + } else { + [eventsOnThisDay addObject:[NSValue valueWithPointer:linphone_call_log_ref(log)]]; + } + } + logs = ms_list_next(logs); + } + + [self computeSections]; + + [super loadData]; + + if (IPAD) { + // reset details view since in fragment mode, details are relative to current data + // select first log if any + NSString *callId = nil; + if ([self totalNumberOfItems] > 0) { + id logId = [_sections objectForKey:_sortedDays[0]][0]; + LinphoneCallLog *log = [logId pointerValue]; + callId = [NSString stringWithUTF8String:linphone_call_log_get_call_id(log) ?: ""]; + } + HistoryDetailsView *view = VIEW(HistoryDetailsView); + [view setCallLogId:callId]; + } +} + +- (void)computeSections { + NSArray *unsortedDays = [self.sections allKeys]; + _sortedDays = [[NSMutableArray alloc] + initWithArray:[unsortedDays sortedArrayUsingComparator:^NSComparisonResult(NSDate *d1, NSDate *d2) { + return [d2 compare:d1]; // reverse order + }]]; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return _sortedDays.count; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + NSArray *logs = [_sections objectForKey:_sortedDays[section]]; + return logs.count; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { + CGRect frame = CGRectMake(0, 0, tableView.frame.size.width, 44); + UIView *tempView = [[UIView alloc] initWithFrame:frame]; + tempView.backgroundColor = [UIColor whiteColor]; + + UILabel *tempLabel = [[UILabel alloc] initWithFrame:frame]; + tempLabel.backgroundColor = [UIColor clearColor]; + tempLabel.textColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_A.png"]]; + NSDate *eventDate = _sortedDays[section]; + NSDate *currentDate = [self dateAtBeginningOfDayForDate:[NSDate date]]; + if ([eventDate isEqualToDate:currentDate]) { + tempLabel.text = NSLocalizedString(@"TODAY", nil); + } else if ([eventDate isEqualToDate:[currentDate dateByAddingTimeInterval:-3600 * 24]]) { + tempLabel.text = NSLocalizedString(@"YESTERDAY", nil); + } else { + tempLabel.text = [LinphoneUtils timeToString:eventDate.timeIntervalSince1970 withFormat:LinphoneDateHistoryList] + .uppercaseString; + } + tempLabel.textAlignment = NSTextAlignmentCenter; + tempLabel.font = [UIFont boldSystemFontOfSize:17]; + tempLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + [tempView addSubview:tempLabel]; + + return tempView; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *kCellId = @"UIHistoryCell"; + UIHistoryCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + if (cell == nil) { + cell = [[UIHistoryCell alloc] initWithIdentifier:kCellId]; + } + + id logId = [_sections objectForKey:_sortedDays[indexPath.section]][indexPath.row]; + LinphoneCallLog *log = [logId pointerValue]; + [cell setCallLog:log]; + [super accessoryForCell:cell atPath:indexPath]; + return cell; +} + +#pragma mark - UITableViewDelegate Functions + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [super tableView:tableView didSelectRowAtIndexPath:indexPath]; + if (![self isEditing]) { + id log = [_sections objectForKey:_sortedDays[indexPath.section]][indexPath.row]; + LinphoneCallLog *callLog = [log pointerValue]; + if (callLog != NULL && linphone_call_log_get_call_id(callLog) != NULL) { + if (IPAD) { + UIHistoryCell *cell = (UIHistoryCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath]; + [cell onDetails:self]; + } else { + LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog); + char *uri = linphone_address_as_string(addr); + DialerView *view = VIEW(DialerView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; + [view call:[NSString stringWithUTF8String:uri] + displayName:[FastAddressBook displayNameForAddress:addr]]; + ms_free(uri); + } + } + } +} + +- (void)tableView:(UITableView *)tableView + commitEditingStyle:(UITableViewCellEditingStyle)editingStyle + forRowAtIndexPath:(NSIndexPath *)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + [tableView beginUpdates]; + id log = [_sections objectForKey:_sortedDays[indexPath.section]][indexPath.row]; + LinphoneCallLog *callLog = [log pointerValue]; + MSList *count = linphone_call_log_get_user_data(callLog); + while (count) { + linphone_core_remove_call_log([LinphoneManager getLc], count->data); + count = count->next; + } + linphone_core_remove_call_log([LinphoneManager getLc], callLog); + linphone_call_log_unref(callLog); + [[_sections objectForKey:_sortedDays[indexPath.section]] removeObject:log]; + if (((NSArray *)[_sections objectForKey:_sortedDays[indexPath.section]]).count == 0) { + [_sections removeObjectForKey:_sortedDays[indexPath.section]]; + [_sortedDays removeObjectAtIndex:indexPath.section]; + [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] + withRowAnimation:UITableViewRowAnimationFade]; + } + + [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] + withRowAnimation:UITableViewRowAnimationFade]; + [tableView endUpdates]; + } +} + +- (void)removeSelectionUsing:(void (^)(NSIndexPath *))remover { + [super removeSelectionUsing:^(NSIndexPath *indexPath) { + id log = [_sections objectForKey:_sortedDays[indexPath.section]][indexPath.row]; + LinphoneCallLog *callLog = [log pointerValue]; + MSList *count = linphone_call_log_get_user_data(callLog); + while (count) { + linphone_core_remove_call_log([LinphoneManager getLc], count->data); + count = count->next; + } + linphone_core_remove_call_log([LinphoneManager getLc], callLog); + linphone_call_log_unref(callLog); + [[_sections objectForKey:_sortedDays[indexPath.section]] removeObject:log]; + if (((NSArray *)[_sections objectForKey:_sortedDays[indexPath.section]]).count == 0) { + [_sections removeObjectForKey:_sortedDays[indexPath.section]]; + [_sortedDays removeObjectAtIndex:indexPath.section]; + } + }]; +} + +@end diff --git a/Classes/HistoryListView.h b/Classes/HistoryListView.h new file mode 100644 index 000000000..d867dbf7b --- /dev/null +++ b/Classes/HistoryListView.h @@ -0,0 +1,40 @@ +/* HistoryViewController.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import + +#import "UICompositeView.h" +#import "HistoryListTableView.h" +#import "UIToggleButton.h" + +@interface HistoryListView : UIViewController { +} + +@property(nonatomic, strong) IBOutlet HistoryListTableView *tableController; + +@property(nonatomic, strong) IBOutlet UIButton *allButton; +@property(nonatomic, strong) IBOutlet UIButton *missedButton; +@property(weak, nonatomic) IBOutlet UIImageView *selectedButtonImage; + +- (IBAction)onAllClick:(id)event; +- (IBAction)onMissedClick:(id)event; +- (IBAction)onDeleteClick:(id)event; +- (IBAction)onEditionChangeClick:(id)sender; + +@end diff --git a/Classes/HistoryListView.m b/Classes/HistoryListView.m new file mode 100644 index 000000000..fa9c6be73 --- /dev/null +++ b/Classes/HistoryListView.m @@ -0,0 +1,113 @@ +/* HistoryViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "HistoryListView.h" +#import "PhoneMainView.h" +#import "LinphoneUI/UIHistoryCell.h" + +@implementation HistoryListView + +typedef enum _HistoryView { History_All, History_Missed, History_MAX } HistoryView; + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:TabBarView.class + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:YES + fragmentWith:HistoryDetailsView.class]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + if ([_tableController isEditing]) { + [_tableController setEditing:FALSE animated:FALSE]; + } + [self changeView:History_All]; + [self onEditionChangeClick:nil]; + + // Reset missed call + linphone_core_reset_missed_calls_count([LinphoneManager getLc]); + // Fake event + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCallUpdate object:self]; +} + +#pragma mark - + +- (void)changeView:(HistoryView)view { + CGRect frame = _selectedButtonImage.frame; + if (view == History_All) { + frame.origin.x = _allButton.frame.origin.x; + _allButton.selected = TRUE; + [_tableController setMissedFilter:FALSE]; + _missedButton.selected = FALSE; + } else { + frame.origin.x = _missedButton.frame.origin.x; + _missedButton.selected = TRUE; + [_tableController setMissedFilter:TRUE]; + _allButton.selected = FALSE; + } + _selectedButtonImage.frame = frame; +} + +#pragma mark - Action Functions + +- (IBAction)onAllClick:(id)event { + [self changeView:History_All]; +} + +- (IBAction)onMissedClick:(id)event { + [self changeView:History_Missed]; +} + +- (IBAction)onDeleteClick:(id)event { + NSString *msg = [NSString stringWithFormat:NSLocalizedString(@"Do you want to delete selected logs?", nil)]; + [UIConfirmationDialog ShowWithMessage:msg + cancelMessage:nil + confirmMessage:nil + onCancelClick:^() { + [self onEditionChangeClick:nil]; + } + onConfirmationClick:^() { + [_tableController removeSelectionUsing:nil]; + [_tableController loadData]; + [self onEditionChangeClick:nil]; + }]; +} + +- (IBAction)onEditionChangeClick:(id)sender { + _allButton.hidden = _missedButton.hidden = _selectedButtonImage.hidden = self.tableController.isEditing; +} + +@end diff --git a/Classes/HistoryTableViewController.h b/Classes/HistoryTableViewController.h deleted file mode 100644 index ee6fe80c2..000000000 --- a/Classes/HistoryTableViewController.h +++ /dev/null @@ -1,30 +0,0 @@ -/* HistoryTableViewController.h - * - * Copyright (C) 2009 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -@interface HistoryTableViewController : UITableViewController { - @private - NSMutableArray *callLogs; -} -- (void)loadData; - -@property (nonatomic, assign) BOOL missedFilter; - -@end diff --git a/Classes/HistoryTableViewController.m b/Classes/HistoryTableViewController.m deleted file mode 100644 index 31b8e9adb..000000000 --- a/Classes/HistoryTableViewController.m +++ /dev/null @@ -1,220 +0,0 @@ -/* HistoryTableViewController.m - * - * Copyright (C) 2009 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "HistoryTableViewController.h" -#import "UIHistoryCell.h" -#import "LinphoneManager.h" -#import "PhoneMainView.h" -#import "UACellBackgroundView.h" -#import "UILinphone.h" -#import "Utils.h" - -@implementation HistoryTableViewController - -@synthesize missedFilter; - -#pragma mark - Lifecycle Functions - -- (void)initHistoryTableViewController { - callLogs = [[NSMutableArray alloc] init]; - missedFilter = false; -} - -- (id)init { - self = [super init]; - if (self) { - [self initHistoryTableViewController]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { - [self initHistoryTableViewController]; - } - return self; -} - -- (void)dealloc { - [callLogs release]; - [super dealloc]; -} - - -#pragma mark - ViewController Functions - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(loadData) - name:kLinphoneAddressBookUpdate - object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(coreUpdateEvent:) - name:kLinphoneCoreUpdate - object:nil]; - [self loadData]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneAddressBookUpdate - object:nil]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneCoreUpdate - object:nil]; - -} - - -#pragma mark - Event Functions - -- (void)coreUpdateEvent:(NSNotification*)notif { - // Invalid all pointers - [self loadData]; -} - - -#pragma mark - Property Functions - -- (void)setMissedFilter:(BOOL)amissedFilter { - if(missedFilter == amissedFilter) { - return; - } - missedFilter = amissedFilter; - [self loadData]; -} - - -#pragma mark - UITableViewDataSource Functions - -- (void)loadData { - [callLogs removeAllObjects]; - const MSList * logs = linphone_core_get_call_logs([LinphoneManager getLc]); - while(logs != NULL) { - LinphoneCallLog* log = (LinphoneCallLog *) logs->data; - if(missedFilter) { - if (linphone_call_log_get_status(log) == LinphoneCallMissed) { - [callLogs addObject:[NSValue valueWithPointer: log]]; - } - } else { - [callLogs addObject:[NSValue valueWithPointer: log]]; - } - logs = ms_list_next(logs); - } - [[self tableView] reloadData]; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return [callLogs count]; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - static NSString *kCellId = @"UIHistoryCell"; - UIHistoryCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; - if (cell == nil) { - cell = [[[UIHistoryCell alloc] initWithIdentifier:kCellId] autorelease]; - // Background View - UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease]; - cell.selectedBackgroundView = selectedBackgroundView; - [selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR]; - } - - LinphoneCallLog *log = [[callLogs objectAtIndex:[indexPath row]] pointerValue]; - [cell setCallLog:log]; - - return cell; -} - - -#pragma mark - UITableViewDelegate Functions - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [tableView deselectRowAtIndexPath:indexPath animated:NO]; - - LinphoneCallLog *callLog = [[callLogs objectAtIndex:[indexPath row]] pointerValue]; - LinphoneAddress* addr; - if (linphone_call_log_get_dir(callLog) == LinphoneCallIncoming) { - addr = linphone_call_log_get_from(callLog); - } else { - addr = linphone_call_log_get_to(callLog); - } - - NSString* displayName = nil; - NSString* address = nil; - if(addr != NULL) { - BOOL useLinphoneAddress = true; - // contact name - char* lAddress = linphone_address_as_string_uri_only(addr); - if(lAddress) { - address = [NSString stringWithUTF8String:lAddress]; - NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:address]; - ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress]; - if(contact) { - displayName = [FastAddressBook getContactDisplayName:contact]; - useLinphoneAddress = false; - } - ms_free(lAddress); - } - if(useLinphoneAddress) { - const char* lDisplayName = linphone_address_get_display_name(addr); - if (lDisplayName) - displayName = [NSString stringWithUTF8String:lDisplayName]; - } - } - - if(address != nil) { - // Go to dialer view - DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController); - if(controller != nil) { - [controller call:address displayName:displayName]; - } - } -} - -- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { - // Detemine if it's in editing mode - if (self.editing) { - return UITableViewCellEditingStyleDelete; - } - return UITableViewCellEditingStyleNone; -} - -- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { - if(editingStyle == UITableViewCellEditingStyleDelete) { - [tableView beginUpdates]; - LinphoneCallLog *callLog = [[callLogs objectAtIndex:[indexPath row]] pointerValue]; - linphone_core_remove_call_log([LinphoneManager getLc], callLog); - [callLogs removeObjectAtIndex:[indexPath row]]; - [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; - [tableView endUpdates]; - } -} - -@end - diff --git a/Classes/HistoryViewController.h b/Classes/HistoryViewController.h deleted file mode 100644 index ad4cb89e3..000000000 --- a/Classes/HistoryViewController.h +++ /dev/null @@ -1,42 +0,0 @@ -/* HistoryViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UICompositeViewController.h" -#import "HistoryTableViewController.h" -#import "UIToggleButton.h" - -@interface HistoryViewController : UIViewController { -} - -@property (nonatomic, retain) IBOutlet HistoryTableViewController* tableController; -@property (nonatomic, retain) IBOutlet UITableView *tableView; - -@property (nonatomic, retain) IBOutlet UIButton* allButton; -@property (nonatomic, retain) IBOutlet UIButton* missedButton; -@property (nonatomic, retain) IBOutlet UIToggleButton* editButton; -@property (nonatomic, retain) IBOutlet UIButton* deleteButton; - -- (IBAction)onAllClick:(id) event; -- (IBAction)onMissedClick:(id) event; -- (IBAction)onEditClick:(id) event; -- (IBAction)onDeleteClick:(id) event; - -@end diff --git a/Classes/HistoryViewController.m b/Classes/HistoryViewController.m deleted file mode 100644 index 2ae130f4d..000000000 --- a/Classes/HistoryViewController.m +++ /dev/null @@ -1,174 +0,0 @@ -/* HistoryViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "HistoryViewController.h" - -@implementation HistoryViewController - -@synthesize tableView; -@synthesize tableController; - -@synthesize allButton; -@synthesize missedButton; -@synthesize editButton; -@synthesize deleteButton; - -typedef enum _HistoryView { - History_All, - History_Missed, - History_MAX -} HistoryView; - - -#pragma mark - Lifecycle Functions - -- (id)init { - return [super initWithNibName:@"HistoryViewController" bundle:[NSBundle mainBundle]]; -} - -- (void)dealloc { - [tableController release]; - [tableView release]; - - [allButton release]; - [missedButton release]; - [editButton release]; - [deleteButton release]; - [super dealloc]; -} - - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"History" - content:@"HistoryViewController" - stateBar:nil - stateBarEnabled:false - tabBar:@"UIMainBar" - tabBarEnabled:true - fullscreen:false - landscapeMode:[LinphoneManager runningOnIpad] - portraitMode:true]; - } - return compositeDescription; -} - - -#pragma mark - ViewController Functions - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - if([tableController isEditing]) { - [tableController setEditing:FALSE animated:FALSE]; - } - [deleteButton setHidden:TRUE]; - [editButton setOff]; - [self changeView: History_All]; - - // Reset missed call - linphone_core_reset_missed_calls_count([LinphoneManager getLc]); - // Fake event - [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCallUpdate object:self]; -} - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - editButton.hidden = ([[tableView dataSource] tableView:tableView numberOfRowsInSection:0] == 0); -} - -- (void)viewDidLoad { - [super viewDidLoad]; - [self changeView: History_All]; - - // Set selected+over background: IB lack ! - [editButton setBackgroundImage:[UIImage imageNamed:@"history_ok_over.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStates:editButton]; - - // Set selected+over background: IB lack ! - [allButton setBackgroundImage:[UIImage imageNamed:@"history_all_selected.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStatesForTabs:allButton]; - - // Set selected+over background: IB lack ! - [missedButton setBackgroundImage:[UIImage imageNamed:@"history_missed_selected.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStatesForTabs:missedButton]; - - [tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4 - [tableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4 -} - - -#pragma mark - - -- (void)changeView: (HistoryView) view { - if(view == History_All) { - allButton.selected = TRUE; - [tableController setMissedFilter:FALSE]; - } else { - allButton.selected = FALSE; - } - - if(view == History_Missed) { - missedButton.selected = TRUE; - [tableController setMissedFilter:TRUE]; - } else { - missedButton.selected = FALSE; - } - - editButton.hidden = ([[tableView dataSource] tableView:tableView numberOfRowsInSection:0] == 0); -} - - -#pragma mark - Action Functions - -- (IBAction)onAllClick:(id) event { - [self changeView: History_All]; -} - -- (IBAction)onMissedClick:(id) event { - [self changeView: History_Missed]; -} - -- (IBAction)onEditClick:(id) event { - [tableController setEditing:![tableController isEditing] animated:TRUE]; - [deleteButton setHidden:![tableController isEditing]]; -} - -- (IBAction)onDeleteClick:(id) event { - linphone_core_clear_call_logs([LinphoneManager getLc]); - [tableController loadData]; - editButton.hidden = ([[tableView dataSource] tableView:tableView numberOfRowsInSection:0] == 0); - if([editButton isSelected]) { - [editButton toggle]; - [self onEditClick:nil]; - } -} - -@end diff --git a/Classes/ImagePickerViewController.h b/Classes/ImagePickerView.h similarity index 57% rename from Classes/ImagePickerViewController.h rename to Classes/ImagePickerView.h index a5941ec42..1f03bb5fd 100644 --- a/Classes/ImagePickerViewController.h +++ b/Classes/ImagePickerView.h @@ -17,23 +17,28 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#import "UICompositeViewController.h" +#import "UICompositeView.h" @protocol ImagePickerDelegate -- (void)imagePickerDelegateImage:(UIImage*)image info:(NSDictionary *)info; +- (void)imagePickerDelegateImage:(UIImage *)image info:(NSDictionary *)info; @end -@interface ImagePickerViewController : UIViewController { - @private - UIImagePickerController *pickerController; +@interface ImagePickerView : UIViewController { + @private + UIImagePickerController *pickerController; } -@property(nonatomic, retain) id imagePickerDelegate; -@property(nonatomic) UIImagePickerControllerSourceType sourceType; -@property(nonatomic,copy) NSArray *mediaTypes; -@property(nonatomic) BOOL allowsEditing; +@property(nonatomic, strong) id imagePickerDelegate; +@property(nonatomic) UIImagePickerControllerSourceType sourceType; +@property(nonatomic, copy) NSArray *mediaTypes; +@property(nonatomic) BOOL allowsEditing; @property(nonatomic, readonly) UIPopoverController *popoverController; ++ (void)SelectImageFromDevice:(id)delegate + atPosition:(UIView *)ipadPopoverPosition + inView:(UIView *)view; + @end diff --git a/Classes/ImagePickerView.m b/Classes/ImagePickerView.m new file mode 100644 index 000000000..bf13f0773 --- /dev/null +++ b/Classes/ImagePickerView.m @@ -0,0 +1,222 @@ +/* ImagePickerViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import + +#import "ImagePickerView.h" +#import "PhoneMainView.h" + +@implementation ImagePickerView + +@synthesize imagePickerDelegate; +@synthesize sourceType; +@synthesize mediaTypes; +@synthesize allowsEditing; +@synthesize popoverController; + +#pragma mark - Lifecycle Functions + +- (id)init { + self = [super init]; + if (self != nil) { + pickerController = [[UIImagePickerController alloc] init]; + if (IPAD) { + popoverController = [[UIPopoverController alloc] initWithContentViewController:pickerController]; + } + } + return self; +} + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:nil + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:NO + fragmentWith:nil]; + compositeDescription.darkBackground = false; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - ViewController Functions + +- (void)viewDidLoad { + [super viewDidLoad]; + + [self.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; + if (popoverController == nil) { + [pickerController.view setFrame:[self.view bounds]]; + [self.view addSubview:[pickerController view]]; + } else { + [popoverController setDelegate:self]; + } + [pickerController setDelegate:self]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + if (popoverController != nil) { + [popoverController presentPopoverFromRect:CGRectZero + inView:self.view + permittedArrowDirections:UIPopoverArrowDirectionAny + animated:FALSE]; + } + [[UIApplication sharedApplication] setStatusBarHidden:NO]; // Fix UIImagePickerController status bar hide + [[UIApplication sharedApplication] + setStatusBarStyle:UIStatusBarStyleDefault]; // Fix UIImagePickerController status bar style change +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + if (popoverController != nil) { + [popoverController dismissPopoverAnimated:NO]; + } +} + +#pragma mark - Property Functions + +- (BOOL)allowsEditing { + return pickerController.allowsEditing; +} + +- (void)setAllowsEditing:(BOOL)aallowsEditing { + pickerController.allowsEditing = aallowsEditing; +} + +- (UIImagePickerControllerSourceType)sourceType { + return pickerController.sourceType; +} + +- (void)setSourceType:(UIImagePickerControllerSourceType)asourceType { + pickerController.sourceType = asourceType; +} + +- (NSArray *)mediaTypes { + return pickerController.mediaTypes; +} + +- (void)setMediaTypes:(NSArray *)amediaTypes { + pickerController.mediaTypes = amediaTypes; +} + +#pragma mark - + +- (void)dismiss { + if ([[PhoneMainView.instance currentView] equal:ImagePickerView.compositeViewDescription]) { + [PhoneMainView.instance popCurrentView]; + } +} + +#pragma mark - UIImagePickerControllerDelegate Functions + +- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { + [self dismiss]; + UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage]; + if (image == nil) { + image = [info objectForKey:UIImagePickerControllerOriginalImage]; + } + if (image != nil && imagePickerDelegate != nil) { + [imagePickerDelegate imagePickerDelegateImage:image info:info]; + } +} + +- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { + [self dismiss]; +} + +- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)apopoverController { + [self dismiss]; + return TRUE; +} + +- (void)navigationController:(UINavigationController *)navigationController + willShowViewController:(UIViewController *)viewController + animated:(BOOL)animated { + + if ([navigationController isKindOfClass:[UIImagePickerController class]]) { + [[UIApplication sharedApplication] setStatusBarHidden:NO]; // Fix UIImagePickerController status bar hide + [[UIApplication sharedApplication] + setStatusBarStyle:UIStatusBarStyleBlackOpaque]; // Fix UIImagePickerController status bar style change + } +} + ++ (void)SelectImageFromDevice:(id)delegate + atPosition:(UIView *)ipadPopoverView + inView:(UIView *)ipadView { + void (^block)(UIImagePickerControllerSourceType) = ^(UIImagePickerControllerSourceType type) { + ImagePickerView *view = VIEW(ImagePickerView); + if (!(IPAD && ipadView && ipadPopoverView)) { + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE]; + } + view.sourceType = type; + + // Displays a control that allows the user to choose picture or + // movie capture, if both are available: + view.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage]; + + // Hides the controls for moving & scaling pictures, or for + // trimming movies. To instead show the controls, use YES. + view.allowsEditing = NO; + view.imagePickerDelegate = delegate; + + if (IPAD && ipadView && ipadPopoverView) { + UIView *iterview = ipadPopoverView; + CGRect ipadPopoverPosition = iterview.frame; + do { + ipadPopoverPosition = + [iterview.superview convertRect:ipadPopoverPosition toView:iterview.superview.superview]; + iterview = iterview.superview; + } while (iterview && iterview.superview != ipadView); + [view.popoverController presentPopoverFromRect:ipadPopoverPosition + inView:ipadView + permittedArrowDirections:UIPopoverArrowDirectionAny + animated:FALSE]; + } + }; + + DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Select picture source", nil)]; + if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { + [sheet addButtonWithTitle:NSLocalizedString(@"Camera", nil) + block:^() { + block(UIImagePickerControllerSourceTypeCamera); + }]; + } + if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { + [sheet addButtonWithTitle:NSLocalizedString(@"Photo library", nil) + block:^() { + block(UIImagePickerControllerSourceTypePhotoLibrary); + }]; + } + [sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; + + [sheet showInView:PhoneMainView.instance.view]; +} + +@end diff --git a/Classes/ImagePickerViewController.m b/Classes/ImagePickerViewController.m deleted file mode 100644 index af021d52d..000000000 --- a/Classes/ImagePickerViewController.m +++ /dev/null @@ -1,177 +0,0 @@ -/* ImagePickerViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "ImagePickerViewController.h" -#import "PhoneMainView.h" -#import "DTActionSheet.h" - - -@implementation ImagePickerViewController - -@synthesize imagePickerDelegate; -@synthesize sourceType; -@synthesize mediaTypes; -@synthesize allowsEditing; -@synthesize popoverController; - - -#pragma mark - Lifecycle Functions - -- (id)init { - self = [super init]; - if (self != nil) { - pickerController = [[UIImagePickerController alloc] init]; - if([LinphoneManager runningOnIpad]) { - popoverController = [[UIPopoverController alloc] initWithContentViewController:pickerController]; - } - } - return self; -} - -- (void)dealloc { - [pickerController release]; - [popoverController release]; - - [super dealloc]; -} - - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"ImagePicker" - content:@"ImagePickerViewController" - stateBar:nil - stateBarEnabled:false - tabBar:nil - tabBarEnabled:false - fullscreen:false - landscapeMode:[LinphoneManager runningOnIpad] - portraitMode:true]; - compositeDescription.darkBackground = false; - } - return compositeDescription; -} - - -#pragma mark - ViewController Functions - -- (void)viewDidLoad { - [super viewDidLoad]; - - [self.view setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; - if(popoverController == nil) { - [pickerController.view setFrame:[self.view bounds]]; - [self.view addSubview:[pickerController view]]; - } else { - [popoverController setDelegate:self]; - } - [pickerController setDelegate:self]; -} - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - if(popoverController != nil) { - [popoverController presentPopoverFromRect:CGRectZero inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:FALSE]; - } - [[UIApplication sharedApplication] setStatusBarHidden:NO]; //Fix UIImagePickerController status bar hide - [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault]; //Fix UIImagePickerController status bar style change -} - - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - if(popoverController != nil) { - [popoverController dismissPopoverAnimated: NO]; - } -} - -#pragma mark - Property Functions - -- (BOOL)allowsEditing { - return pickerController.allowsEditing; -} - -- (void)setAllowsEditing:(BOOL)aallowsEditing { - pickerController.allowsEditing = aallowsEditing; -} - -- (UIImagePickerControllerSourceType)sourceType { - return pickerController.sourceType; -} - -- (void)setSourceType:(UIImagePickerControllerSourceType)asourceType { - pickerController.sourceType = asourceType; -} - -- (NSArray *)mediaTypes { - return pickerController.mediaTypes; -} - -- (void)setMediaTypes:(NSArray *)amediaTypes { - pickerController.mediaTypes = amediaTypes; -} - - -#pragma mark - - -- (void)dismiss { - if([[[PhoneMainView instance] currentView] equal:[ImagePickerViewController compositeViewDescription]]) { - [[PhoneMainView instance] popCurrentView]; - } -} - - -#pragma mark - UIImagePickerControllerDelegate Functions - -- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { - [self dismiss]; - UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage]; - if(image == nil) { - image = [info objectForKey:UIImagePickerControllerOriginalImage]; - } - if(image != nil && imagePickerDelegate != nil) { - [imagePickerDelegate imagePickerDelegateImage:image info:info]; - } -} - -- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { - [self dismiss]; -} - -- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)apopoverController { - [self dismiss]; - return TRUE; -} - -- (void)navigationController:(UINavigationController *)navigationController - willShowViewController:(UIViewController *)viewController - animated:(BOOL)animated { - - if ([navigationController isKindOfClass:[UIImagePickerController class]]) { - [[UIApplication sharedApplication] setStatusBarHidden:NO]; //Fix UIImagePickerController status bar hide - [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque]; //Fix UIImagePickerController status bar style change - } -} - - -@end diff --git a/Classes/ImageSharing.h b/Classes/ImageSharing.h deleted file mode 100644 index 1a59c2828..000000000 --- a/Classes/ImageSharing.h +++ /dev/null @@ -1,52 +0,0 @@ -/* ImageSharing.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -@class ImageSharing; - -@protocol ImageSharingDelegate - -- (void)imageSharingProgress:(ImageSharing*)imageSharing progress:(float)progress; -- (void)imageSharingAborted:(ImageSharing*)imageSharing; -- (void)imageSharingError:(ImageSharing*)imageSharing error:(NSError *)error; -- (void)imageSharingUploadDone:(ImageSharing*)imageSharing url:(NSURL*)url; -- (void)imageSharingDownloadDone:(ImageSharing*)imageSharing image:(UIImage *)image; - -@end - -@interface ImageSharing : NSObject { -@private - NSInteger totalBytesExpectedToRead; - id delegate; - NSInteger statusCode; -} - -+ (id)newImageSharingUpload:(NSURL*)url image:(UIImage*)image delegate:(id)delegate userInfo:(id)userInfo; -+ (id)newImageSharingDownload:(NSURL*)url delegate:(id)delegate userInfo:(id)userInfo; - -- (void)cancel; - -@property (nonatomic, retain) id userInfo; - -@property (nonatomic, readonly) BOOL upload; -@property (nonatomic, readonly) NSMutableData* data; -@property (nonatomic, readonly) NSURLConnection* connection; - -@end diff --git a/Classes/ImageSharing.m b/Classes/ImageSharing.m deleted file mode 100644 index 0b41cfc6c..000000000 --- a/Classes/ImageSharing.m +++ /dev/null @@ -1,187 +0,0 @@ -/* ImageSharing.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "ImageSharing.h" -#import "Utils.h" -#import "LinphoneManager.h" - -@implementation ImageSharing - -@synthesize connection; -@synthesize data; -@synthesize upload; -@synthesize userInfo; - -#pragma mark - Lifecycle Functions - -+ (id)newImageSharingUpload:(NSURL*)url image:(UIImage*)image delegate:(id)delegate userInfo:(id)auserInfo{ - ImageSharing *imgs = [[ImageSharing alloc] init]; - if(imgs != nil) { - imgs.userInfo = auserInfo; - imgs->upload = TRUE; - imgs->delegate = [delegate retain]; - imgs->data = [[NSMutableData alloc] init]; - if(delegate) { - [delegate imageSharingProgress:imgs progress:0]; - } - [imgs uploadImageTo:url image:image]; - } - return imgs; -} - -+ (id)newImageSharingDownload:(NSURL*)url delegate:(id)delegate userInfo:(id)auserInfo{ - ImageSharing *imgs = [[ImageSharing alloc] init]; - if(imgs != nil) { - imgs.userInfo = auserInfo; - imgs->upload = FALSE; - imgs->delegate = [delegate retain]; - imgs->data = [[NSMutableData alloc] init]; - if(delegate) { - [delegate imageSharingProgress:imgs progress:0]; - } - [imgs downloadImageFrom:url]; - } - return imgs; -} - -- (void)dealloc { - [connection release]; - [data release]; - [delegate release]; - [userInfo release]; - [super dealloc]; -} - - -#pragma mark - - -- (void)cancel { - [connection cancel]; - [LinphoneLogger log:LinphoneLoggerLog format:@"File transfer interrupted by user"]; - if(delegate) { - [delegate imageSharingAborted:self]; - } -} - - -- (void)downloadImageFrom:(NSURL*)url { - [LinphoneLogger log:LinphoneLoggerLog format:@"downloading [%@]", [url absoluteString]]; - - NSURLRequest* request = [NSURLRequest requestWithURL:url - cachePolicy:NSURLRequestUseProtocolCachePolicy - timeoutInterval:60.0]; - - connection = [[NSURLConnection alloc] initWithRequest:request delegate: self]; -} - - -- (void)uploadImageTo:(NSURL*)url image:(UIImage*)image { - [LinphoneLogger log:LinphoneLoggerLog format:@"downloading [%@]", [url absoluteString]]; - - // setting up the request object now - NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease]; - [request setURL:url]; - [request setHTTPMethod:@"POST"]; - - /* - add some header info now - we always need a boundary when we post a file - also we need to set the content type - - You might want to generate a random boundary.. this is just the same - as my output from wireshark on a valid html post - */ - NSString *boundary = @"---------------------------14737809831466499882746641449"; - NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary]; - [request addValue:contentType forHTTPHeaderField: @"Content-Type"]; - - /* - now lets create the body of the post - */ - NSMutableData *body = [NSMutableData data]; - NSString *imageName = [NSString stringWithFormat:@"%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]]; - [body appendData:[NSData dataWithData:UIImageJPEGRepresentation(image, 1.0)]]; - [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; - [request setHTTPBody:body]; - - connection = [[NSURLConnection alloc] initWithRequest:(NSURLRequest *)request delegate:self]; -} - - -#pragma mark - NSURLConnectionDelegate - -- (void)connection:(NSURLConnection *)aconnection didFailWithError:(NSError *)error { - if(delegate) { - [delegate imageSharingError:self error:error]; - } - [self release]; -} - -- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { - if(upload && delegate) { - [delegate imageSharingProgress:self progress:(float)totalBytesWritten/(float)totalBytesExpectedToWrite]; - } -} - -- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)adata { - [data appendData:adata]; - if(!upload && delegate) { - [delegate imageSharingProgress:self progress:(float)data.length/(float)totalBytesExpectedToRead]; - } -} - -- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { - NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *) response; - statusCode = httpResponse.statusCode; - [LinphoneLogger log:LinphoneLoggerLog format:@"File transfer status code [%i]", statusCode]; - - if (statusCode == 200 && !upload) { - totalBytesExpectedToRead = (int)[response expectedContentLength]; - } -} - -- (void)connectionDidFinishLoading:(NSURLConnection *)connection { - if(statusCode >= 400) { - NSError *error = [NSError errorWithDomain:@"ImageSharing" code:statusCode userInfo:nil]; - if(delegate) { - [delegate imageSharingError:self error:error]; - } - return; - } - if (upload) { - NSString* imageRemoteUrl = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - [LinphoneLogger log:LinphoneLoggerLog format:@"File can be downloaded from [%@]", imageRemoteUrl]; - if(delegate) { - [delegate imageSharingUploadDone:self url:[NSURL URLWithString:imageRemoteUrl]]; - } - [imageRemoteUrl release]; - } else { - UIImage* image = [UIImage imageWithData:data]; - [LinphoneLogger log:LinphoneLoggerLog format:@"File downloaded"]; - if(delegate) { - [delegate imageSharingDownloadDone:self image:image]; - } - } - [self release]; -} - -@end diff --git a/Classes/LinphoneUI/UITransparentTVCell.m b/Classes/ImageView.h similarity index 60% rename from Classes/LinphoneUI/UITransparentTVCell.m rename to Classes/ImageView.h index b027a3a07..6d960b81c 100644 --- a/Classes/LinphoneUI/UITransparentTVCell.m +++ b/Classes/ImageView.h @@ -1,4 +1,4 @@ -/* UITransparentTVCell.m +/* ImageViewController.h * * Copyright (C) 2012 Belledonne Comunications, Grenoble, France * @@ -17,23 +17,24 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#import "UITransparentTVCell.h" +#import -@implementation UITransparentTVCell +#import "UICompositeView.h" -- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier -{ - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - if (self) { - // Set transparent background - [self setBackgroundColor:[UIColor clearColor]]; - } - return self; -} +@interface UIImageScrollView : UIScrollView -- (void)setSelected:(BOOL)selected animated:(BOOL)animated -{ - [super setSelected:selected animated:animated]; -} +@property(nonatomic, strong) UIImage *image; +@property(readonly) IBOutlet UIImageView *imageView; @end + +@interface ImageView : UIViewController { +} + +@property(nonatomic, strong) IBOutlet UIImageScrollView *scrollView; +@property(nonatomic, strong) UIImage *image; +@property(nonatomic, strong) IBOutlet UIButton *backButton; + +- (IBAction)onBackClick:(id)sender; + +@end \ No newline at end of file diff --git a/Classes/ImageView.m b/Classes/ImageView.m new file mode 100644 index 000000000..83d903ec8 --- /dev/null +++ b/Classes/ImageView.m @@ -0,0 +1,154 @@ +/* ImageViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "ImageView.h" +#import "PhoneMainView.h" + +@implementation UIImageScrollView + +@synthesize image; +@synthesize imageView; + +#pragma mark - Lifecycle Functions + +- (void)initUIImageScrollView { + imageView = [[UIImageView alloc] init]; + self.delegate = self; + [self addSubview:imageView]; +} + +- (id)init { + self = [super init]; + if (self != nil) { + [self initUIImageScrollView]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self != nil) { + [self initUIImageScrollView]; + } + return self; +} + +- (id)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self != nil) { + [self initUIImageScrollView]; + } + return self; +} + +#pragma mark - ViewController Functions + +- (void)layoutSubviews { + [super layoutSubviews]; + // center the image as it becomes smaller than the size of the screen + CGSize boundsSize = self.bounds.size; + CGRect frameToCenter = imageView.frame; + + // center horizontally + if (frameToCenter.size.width < boundsSize.width) + frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2; + else + frameToCenter.origin.x = 0; + + // center vertically + if (frameToCenter.size.height < boundsSize.height) + frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2; + else + frameToCenter.origin.y = 0; + + imageView.frame = frameToCenter; +} + +#pragma mark - Property Functions + +- (void)setImage:(UIImage *)aimage { + self.minimumZoomScale = 0; + self.zoomScale = 1; + + CGRect rect = CGRectMake(0, 0, aimage.size.width, aimage.size.height); + imageView.image = aimage; + imageView.frame = rect; + self.contentSize = rect.size; + [self zoomToRect:rect animated:FALSE]; + self.minimumZoomScale = self.zoomScale; +} + +- (UIImage *)image { + return imageView.image; +} + +#pragma mark - UIScrollViewDelegate Functions + +- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { + return imageView; +} + +@end + +@implementation ImageView + +@synthesize scrollView; +@synthesize backButton; +@synthesize image; + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:nil + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:NO + fragmentWith:nil]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - Property Functions + +- (void)setImage:(UIImage *)aimage { + scrollView.image = aimage; +} + +- (UIImage *)image { + return scrollView.image; +} + +#pragma mark - Action Functions + +- (IBAction)onBackClick:(id)sender { + if ([[PhoneMainView.instance currentView] equal:ImageView.compositeViewDescription]) { + [PhoneMainView.instance popCurrentView]; + } +} + +@end diff --git a/Classes/ImageViewController.h b/Classes/ImageViewController.h deleted file mode 100644 index 69e04bb27..000000000 --- a/Classes/ImageViewController.h +++ /dev/null @@ -1,41 +0,0 @@ -/* ImageViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UICompositeViewController.h" - -@interface UIImageScrollView : UIScrollView - -@property (nonatomic, retain) UIImage *image; -@property (readonly) IBOutlet UIImageView *imageView; - -@end - -@interface ImageViewController : UIViewController { - -} - -@property (nonatomic, retain) IBOutlet UIImageScrollView *scrollView; -@property (nonatomic, retain) UIImage *image; -@property (nonatomic, retain) IBOutlet UIButton *backButton; - -- (IBAction)onBackClick:(id)sender; - -@end \ No newline at end of file diff --git a/Classes/ImageViewController.m b/Classes/ImageViewController.m deleted file mode 100644 index 1f37808bd..000000000 --- a/Classes/ImageViewController.m +++ /dev/null @@ -1,182 +0,0 @@ -/* ImageViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "ImageViewController.h" -#import "PhoneMainView.h" - -@implementation UIImageScrollView - -@synthesize image; -@synthesize imageView; - - -#pragma mark - Lifecycle Functions - -- (void)initUIImageScrollView { - imageView = [[UIImageView alloc] init]; - self.delegate = self; - [self addSubview:imageView]; -} - -- (id)init { - self = [super init]; - if(self != nil) { - [self initUIImageScrollView]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if(self != nil) { - [self initUIImageScrollView]; - } - return self; -} - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if(self != nil) { - [self initUIImageScrollView]; - } - return self; -} - -- (void)dealloc { - [image release]; - [imageView dealloc]; - - [super dealloc]; -} - - -#pragma mark - ViewController Functions - -- (void)layoutSubviews { - [super layoutSubviews]; - // center the image as it becomes smaller than the size of the screen - CGSize boundsSize = self.bounds.size; - CGRect frameToCenter = imageView.frame; - - - // center horizontally - if (frameToCenter.size.width < boundsSize.width) - frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2; - else - frameToCenter.origin.x = 0; - - // center vertically - if (frameToCenter.size.height < boundsSize.height) - frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2; - else - frameToCenter.origin.y = 0; - - - imageView.frame = frameToCenter; -} - - -#pragma mark - Property Functions - -- (void)setImage:(UIImage *)aimage { - self.minimumZoomScale = 0; - self.zoomScale = 1; - - CGRect rect = CGRectMake(0, 0, aimage.size.width, aimage.size.height); - imageView.image = aimage; - imageView.frame = rect; - self.contentSize = rect.size; - [self zoomToRect:rect animated:FALSE]; - self.minimumZoomScale = self.zoomScale; -} - -- (UIImage *)image { - return imageView.image; -} - - -#pragma mark - UIScrollViewDelegate Functions - -- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { - return imageView; -} - -@end - -@implementation ImageViewController - -@synthesize scrollView; -@synthesize backButton; -@synthesize image; - - -#pragma mark - Lifecycle Functions - -- (id)init { - return [super initWithNibName:@"ImageViewController" bundle:[NSBundle mainBundle]]; -} - -- (void)dealloc { - [scrollView release]; - [backButton release]; - - [super dealloc]; -} - - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"ImageView" - content:@"ImageViewController" - stateBar:nil - stateBarEnabled:false - tabBar:nil - tabBarEnabled:false - fullscreen:false - landscapeMode:[LinphoneManager runningOnIpad] - portraitMode:true]; - } - return compositeDescription; -} - - -#pragma mark - Property Functions - -- (void)setImage:(UIImage *)aimage { - scrollView.image = aimage; -} - -- (UIImage *)image { - return scrollView.image; -} - - -#pragma mark - Action Functions - -- (IBAction)onBackClick:(id)sender { - if([[[PhoneMainView instance] currentView] equal:[ImageViewController compositeViewDescription]]) { - [[PhoneMainView instance] popCurrentView]; - } -} - -@end diff --git a/Classes/InAppProductsManager.h b/Classes/InAppProductsManager.h new file mode 100644 index 000000000..61a61b351 --- /dev/null +++ b/Classes/InAppProductsManager.h @@ -0,0 +1,100 @@ +/* InAppProductsManager.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import +#import +#import + +@interface InAppProductsXMLRPCDelegate : NSObject + +@end + +#define kIAPNotReady @"IAPNotReady" // startup status, manager is not ready yet +#define kIAPReady @"IAPReady" // no data +#define kIAPPurchaseTrying @"IAPPurchaseTrying" // data: product_id +#define kIAPPurchaseCancelled @"IAPPurchaseCancelled" // data: product_id +#define kIAPPurchaseFailed @"IAPPurchaseFailed" // data: product_id, error_msg +#define kIAPPurchaseSucceeded @"IAPPurchaseSucceeded" // data: product_id, expires_date +#define kIAPPurchaseExpired @"IAPPurchaseExpired" // data: product_id, expires_date +#define kIAPRestoreFailed @"IAPRestoreFailed" // data: error_msg +#define kIAPRestoreSucceeded @"IAPRestoreSucceeded" // no data +#define kIAPReceiptFailed @"IAPReceiptFailed" // data: error_msg +#define kIAPReceiptSucceeded @"IAPReceiptSucceeded" // no data +typedef NSString *IAPPurchaseNotificationStatus; + +// InAppProductsManager take care of any in app purchase accessible within Linphone +// In order to use it, you must configure your linphonerc configuration correctly, such as: +//[in_app_purchase] +// enabled=1 +// paid_account_id=test.autorenew_7days +// receipt_validation_url=https://www.linphone.org/inapp.php +// products_list=test.autorenew_7days +// Note: in Sandbox mode (test), autorenewal expire time is speed up (see +// http://stackoverflow.com/questions/8815271/what-expiry-date-should-i-see-for-in-app-purchase-in-the-application-sandbox) +// so that 7 days renewal is only 3 minutes and: +// 1 week = 3 minutes +// 1 month = 5 minutes +// 2 months = 10 minutes +// 3 months = 15 minutes +// 6 months = 30 minutes +// 1 year = 1 hour + +@interface InAppProductsManager : NSObject { + NSString *latestReceiptMD5; +} + +@property(nonatomic, strong) IAPPurchaseNotificationStatus status; +@property(nonatomic, strong) NSMutableArray *productsAvailable; +@property(nonatomic, strong) NSMutableArray *productsIDPurchased; + +// TRUE when in app purchase capability is available - not modified during runtime +@property(readonly) BOOL enabled; +// TRUE when manager is correctly set up - must first retrieve products available and validate current receipt on our +// server +@property(readonly) BOOL initialized; +// TRUE if manager is available for usage - will be FALSE if an operation is already in progress or if not initialized +// or not enabled +@property(readonly) BOOL available; + +// TRUE if accountActivate was started but we did not receive response from server yet +@property(readonly) BOOL accountActivationInProgress; + +- (BOOL)isPurchasedWithID:(NSString *)productId; +// Purchase an account. You should not use this if manager is not available yet. +- (BOOL)purchaseAccount:(NSString *)phoneNumber + withPassword:(NSString *)password + andEmail:(NSString *)email + monthly:(BOOL)monthly; +// Purchase a product. You should not use this if manager is not available yet. +- (BOOL)purchaseWitID:(NSString *)productID; +// Activate purchased account. +- (BOOL)activateAccount:(NSString *)phoneNumber; + +// restore user purchases. You should not use this if manager is not available yet. Must be at a user action ONLY. +- (BOOL)restore; +// retrieve purchases on our server. You should not use this if manager is not available yet. +// Warning: on first run, this will open a popup to user to provide iTunes Store credentials +- (BOOL)retrievePurchases; + +// internal API only due to methods conflict +- (void)XMLRPCRequest:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response; +// internal API only due to methods conflict +- (void)XMLRPCRequest:(XMLRPCRequest *)request didFailWithError:(NSError *)error; + +@end diff --git a/Classes/InAppProductsManager.m b/Classes/InAppProductsManager.m new file mode 100644 index 000000000..76cb06fca --- /dev/null +++ b/Classes/InAppProductsManager.m @@ -0,0 +1,545 @@ +/* InAppProductsManager.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "InAppProductsManager.h" + +// In app purchase are not supported by the Simulator +#import +#import +#import +#import + +#import "LinphoneManager.h" + +#import "PhoneMainView.h" + +@interface InAppProductsManager () +@property(strong, nonatomic) NSDate *expirationDate; +@property(strong, nonatomic) NSDictionary *accountCreationData; +// needed because request:didFailWithError method is already used by SKProductsRequestDelegate... +@property(nonatomic, strong) InAppProductsXMLRPCDelegate *xmlrpc; +@end + +@implementation InAppProductsManager + +// LINPHONE_CAPABILITY_INAPP_PURCHASE must be defined in Linphone Build Settings +#if LINPHONE_CAPABILITY_INAPP_PURCHASE && !TARGET_IPHONE_SIMULATOR + +- (instancetype)init { + if ((self = [super init]) != nil) { + _enabled = (([SKPaymentQueue canMakePayments]) && + ([[LinphoneManager instance] lpConfigBoolForKey:@"enabled" inSection:@"in_app_purchase"])); + _initialized = false; + _available = false; + _accountActivationInProgress = false; + if (_enabled) { + self.xmlrpc = [[InAppProductsXMLRPCDelegate alloc] init]; + _status = kIAPNotReady; + [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; + [self loadProducts]; + } + } + return self; +} + +#pragma mark Public API + +- (BOOL)isPurchasedWithID:(NSString *)productID { + if (!_enabled) + return FALSE; + + for (NSString *prod in _productsIDPurchased) { + NSDate *now = [[NSDate alloc] init]; + // since multiple ID represent the same product, we must not check it + if (/*[prod isEqual: productID] &&*/ [self.expirationDate earlierDate:now] == now) { + bool isBought = true; + LOGE(@"%@ is %s bought.", prod, isBought ? "" : "NOT"); + return isBought; + } + } + return false; +} + +- (BOOL)purchaseWitID:(NSString *)productID { + if (!_enabled || !_initialized || !_available) { + NSDictionary *dict = @{ + @"product_id" : productID, + @"error_msg" : NSLocalizedString(@"Cannot purchase anything yet, please try again later.", nil) + }; + [self postNotificationforStatus:kIAPPurchaseFailed withDict:dict]; + return FALSE; + } + SKProduct *prod = [self productIDAvailable:productID]; + if (prod) { + NSDictionary *dict = @{ @"product_id" : productID }; + [self postNotificationforStatus:kIAPPurchaseTrying withDict:dict]; + SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:prod]; + _available = false; + [[SKPaymentQueue defaultQueue] addPayment:payment]; + [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; + return TRUE; + } else { + NSDictionary *dict = @{ @"product_id" : productID, @"error_msg" : @"Product not available" }; + [self postNotificationforStatus:kIAPPurchaseFailed withDict:dict]; + return FALSE; + } +} + +- (BOOL)purchaseAccount:(NSString *)phoneNumber + withPassword:(NSString *)password + andEmail:(NSString *)email + monthly:(BOOL)monthly { + if (phoneNumber) { + NSString *productID = + [[LinphoneManager instance] lpConfigStringForKey:(monthly ? @"paid_account_id_monthly" : @"paid_account_id") + inSection:@"in_app_purchase"]; + self.accountCreationData = @{ @"phoneNumber" : phoneNumber, @"password" : password, @"email" : email }; + + if (![self purchaseWitID:productID]) { + self.accountCreationData = nil; + } + return true; + } + return false; +} + +- (BOOL)activateAccount:(NSString *)phoneNumber { + if (phoneNumber) { + NSString *receiptBase64 = [self getReceipt]; + if (receiptBase64) { + NSURL *URL = [NSURL URLWithString:[[LinphoneManager instance] lpConfigStringForKey:@"receipt_validation_url" + inSection:@"in_app_purchase"]]; + XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithURL:URL]; + // buying for the first time: need to create the account + // if ([transaction.transactionIdentifier + // isEqualToString:transaction.originalTransaction.transactionIdentifier]) { + [request setMethod:@"activate_account" + withParameters:[NSArray arrayWithObjects:@"", phoneNumber, receiptBase64, @"", @"apple", nil]]; + _accountActivationInProgress = YES; + XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager]; + [manager spawnConnectionWithXMLRPCRequest:request delegate:self.xmlrpc]; + LOGI(@"XMLRPC query %@", [request method]); + return true; + } else { + LOGE(@"Trying to activate account but no receipt available yet (probably doing it too soon)"); + } + } + return false; +} + +- (BOOL)restore { + if (!_enabled || !_initialized || !_available) { + NSDictionary *dict = @{ @"error_msg" : NSLocalizedString(@"In apps not ready yet", nil) }; + [self postNotificationforStatus:kIAPRestoreFailed withDict:dict]; + return FALSE; + } + LOGI(@"Restoring user purchases..."); + // force new query of our server + latestReceiptMD5 = nil; + _available = false; + [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; + return TRUE; +} + +- (BOOL)retrievePurchases { + if (!_enabled | !_initialized | !_available) { + NSDictionary *dict = @{ @"error_msg" : NSLocalizedString(@"In apps not ready yet", nil) }; + [self postNotificationforStatus:kIAPRestoreFailed withDict:dict]; + return FALSE; + } else if ([[self getPhoneNumber] length] == 0) { + LOGW(@"Not retrieving purchase since not account configured yet"); + return FALSE; + } else { + _available = false; + [self validateReceipt:nil]; + return TRUE; + } +} + +#pragma mark ProductListLoading + +- (void)loadProducts { + NSArray *list = [[[[LinphoneManager instance] lpConfigStringForKey:@"products_list" inSection:@"in_app_purchase"] + stringByReplacingOccurrencesOfString:@" " + withString:@""] componentsSeparatedByString:@","]; + + _productsIDPurchased = [[NSMutableArray alloc] initWithCapacity:0]; + + SKProductsRequest *productsRequest = + [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithArray:list]]; + productsRequest.delegate = self; + [productsRequest start]; +} + +- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { + _productsAvailable = [NSMutableArray arrayWithArray:response.products]; + + LOGI(@"Found %lu products available", (unsigned long)_productsAvailable.count); + _initialized = true; + if (response.invalidProductIdentifiers.count > 0) { + for (NSString *invalidIdentifier in response.invalidProductIdentifiers) { + LOGW(@"Found product Identifier with invalid ID '%@'", invalidIdentifier); + } + } else { + _available = true; + [self postNotificationforStatus:kIAPReady withDict:nil]; + } +} + +- (void)request:(SKRequest *)request didFailWithError:(NSError *)error { + LOGE(@"Impossible to retrieve list of products: %@", [error localizedDescription]); + // well, let's retry... + [self loadProducts]; +} + +#pragma mark Other + +- (SKProduct *)productIDAvailable:(NSString *)productID { + if (!_enabled || !_initialized) + return nil; + for (SKProduct *product in _productsAvailable) { + if ([product.productIdentifier compare:productID options:NSLiteralSearch] == NSOrderedSame) { + return product; + } + } + return nil; +} + +- (void)requestDidFinish:(SKRequest *)request { + if ([request isKindOfClass:[SKReceiptRefreshRequest class]]) { + NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL]; + if ([[NSFileManager defaultManager] fileExistsAtPath:[receiptUrl path]]) { + LOGI(@"App Receipt exists"); + [self validateReceipt:nil]; + } else { + // This can happen if the user cancels the login screen for the store. + // If we get here it means there is no receipt and an attempt to get it failed because the user cancelled + // the login. + LOGF(@"Receipt request done but there is no receipt"); + } + } +} + +- (NSString *)getReceipt { + NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL]; + // Test whether the receipt is present at the above URL + if (![[NSFileManager defaultManager] fileExistsAtPath:[receiptURL path]]) { + // We are probably in sandbox environment, trying to retrieve it... + return nil; + } + + NSString *receiptBase64 = [[NSData dataWithContentsOfURL:receiptURL] base64EncodedStringWithOptions:0]; + LOGI(@"Found appstore receipt %@", [receiptBase64 md5]); + return receiptBase64; +} + +- (void)validateReceipt:(SKPaymentTransaction *)transaction { + NSString *receiptBase64 = [self getReceipt]; + if (receiptBase64 == nil) { + SKRequest *req = [[SKReceiptRefreshRequest alloc] init]; + LOGI(@"Receipt not found yet, trying to retrieve it..."); + req.delegate = self; + [req start]; + return; + } + // only check the receipt if it has changed + if (latestReceiptMD5 == nil || ![latestReceiptMD5 isEqualToString:[receiptBase64 md5]]) { + // transaction is null when restoring user purchases at application start or if user clicks the "restore" button + // We must validate the receipt on our server + NSURL *URL = [NSURL URLWithString:[[LinphoneManager instance] lpConfigStringForKey:@"receipt_validation_url" + inSection:@"in_app_purchase"]]; + XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithURL:URL]; + // buying for the first time: need to create the account + // if ([transaction.transactionIdentifier + // isEqualToString:transaction.originalTransaction.transactionIdentifier]) { + if (self.accountCreationData.count == 3) { + [request setMethod:@"create_account_from_in_app_purchase" + withParameters:[NSArray arrayWithObjects:@"", [_accountCreationData objectForKey:@"phoneNumber"], + receiptBase64, @"", @"apple", + [_accountCreationData objectForKey:@"email"], nil]]; + self.accountCreationData = nil; + // otherwise simply renewing + } else { + if ([[self getPhoneNumber] length] > 0) { + [request setMethod:@"get_expiration_date" + withParameters:[NSArray + arrayWithObjects:[self getPhoneNumber], receiptBase64, @"", @"apple", nil]]; + } else { + LOGW(@"No SIP URI configured, doing nothing"); + _available = true; + return; + } + } + latestReceiptMD5 = [receiptBase64 md5]; + + XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager]; + [manager spawnConnectionWithXMLRPCRequest:request delegate:self.xmlrpc]; + LOGI(@"XMLRPC query %@", [request method]); + } else { + LOGW(@"Not checking receipt since it has already been done!"); + _available = true; + } +} + +- (NSString *)getPhoneNumber { + NSString *phoneNumber = @""; + LinphoneProxyConfig *config = linphone_core_get_default_proxy_config([LinphoneManager getLc]); + if (config) { + const char *identity = linphone_proxy_config_get_identity(config); + if (identity) { + LinphoneAddress *addr = linphone_address_new(identity); + if (addr) { + phoneNumber = [NSString stringWithUTF8String:linphone_address_get_username(addr)]; + linphone_address_destroy(addr); + } + } + } + return phoneNumber; +} + +- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { + for (SKPaymentTransaction *transaction in transactions) { + switch (transaction.transactionState) { + case SKPaymentTransactionStatePurchasing: + break; + case SKPaymentTransactionStatePurchased: + case SKPaymentTransactionStateRestored: { + if (!_initialized) { + LOGW(@"Pending transactions before end of initialization, not verifying receipt"); + } else { + [self validateReceipt:transaction]; + } + [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; + break; + } + case SKPaymentTransactionStateDeferred: + LOGI(@"Waiting for parent approval..."); + // could do some UI stuff + break; + case SKPaymentTransactionStateFailed: { + _available = true; + [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; + if (transaction.error.code == SKErrorPaymentCancelled) { + LOGI(@"SKPaymentTransactionStateFailed: cancelled"); + NSDictionary *dict = @{ @"product_id" : transaction.payment.productIdentifier }; + [self postNotificationforStatus:kIAPPurchaseCancelled withDict:dict]; + } else { + NSString *errlast = + [NSString stringWithFormat:@"Purchase failed: %@.", transaction.error.localizedDescription]; + LOGE(@"SKPaymentTransactionStateFailed: %@", errlast); + NSDictionary *dict = + @{ @"product_id" : transaction.payment.productIdentifier, + @"error_msg" : errlast }; + [self postNotificationforStatus:kIAPPurchaseFailed withDict:dict]; + } + break; + } + } + } +} + +- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions { + for (SKPaymentTransaction *transaction in transactions) { + LOGD(@"%@ was removed from the payment queue.", transaction.payment.productIdentifier); + } +} + +- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error { + if (error.code != SKErrorPaymentCancelled) { + NSDictionary *dict = @{ @"error_msg" : [error localizedDescription] }; + [self postNotificationforStatus:kIAPRestoreFailed withDict:dict]; + } +} + +- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue { + LOGI(@"All restorable transactions have been processed by the payment queue."); +} + +- (void)postNotificationforStatus:(IAPPurchaseNotificationStatus)status withDict:(NSDictionary *)dict { + _status = status; + LOGI(@"Triggering notification for status %@", status); + [[NSNotificationCenter defaultCenter] postNotificationName:status object:self userInfo:dict]; +} + +- (void)XMLRPCRequest:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response { + if (!_enabled) + return; + + _available = true; + + if ([[request method] isEqualToString:@"activate_account"]) { + _accountActivationInProgress = NO; + } + + LOGI(@"XMLRPC response %@: %@", [request method], [response body]); + NSString *productID = + [[LinphoneManager instance] lpConfigStringForKey:@"paid_account_id" inSection:@"in_app_purchase"]; + + // validation succeeded + if (![response isFault] && [response object] != nil) { + if (([[request method] isEqualToString:@"get_expiration_date"]) || + ([[request method] isEqualToString:@"create_account_from_in_app_purchase"])) { + [_productsIDPurchased removeObject:productID]; + // response object can either be expiration date (long long number or an error string) + double timeinterval = [[response object] doubleValue]; + if (timeinterval != 0.0f) { + self.expirationDate = [NSDate dateWithTimeIntervalSince1970:timeinterval / 1000]; + NSDate *now = [[NSDate alloc] init]; + NSDictionary *dict = @{ @"product_id" : productID, @"expires_date" : self.expirationDate }; + if ([self.expirationDate earlierDate:now] == self.expirationDate) { + LOGW(@"Account has expired"); + [self postNotificationforStatus:kIAPPurchaseExpired withDict:dict]; + } else { + LOGI(@"Account valid until %@", self.expirationDate); + [_productsIDPurchased addObject:productID]; + [self postNotificationforStatus:kIAPPurchaseSucceeded withDict:dict]; + } + } else { + self.expirationDate = nil; + NSString *error = [response object]; + LOGE(@"Failed with error %@", error); + NSString *errorMsg; + if ([error isEqualToString:@"ERROR_ACCOUNT_ALREADY_EXISTS"]) { + errorMsg = NSLocalizedString(@"This account is already registered.", nil); + } else if ([error isEqualToString:@"ERROR_UID_ALREADY_IN_USE"]) { + errorMsg = NSLocalizedString(@"You already own an account.", nil); + } else if ([error isEqualToString:@"ERROR_ACCOUNT_DOESNT_EXIST"]) { + errorMsg = + NSLocalizedString(@"You have already purchased an account but it does not exist anymore.", nil); + } else if ([error isEqualToString:@"ERROR_PURCHASE_CANCELLED"]) { + errorMsg = NSLocalizedString(@"You cancelled your account.", nil); + } else { + errorMsg = [NSString stringWithFormat:NSLocalizedString(@"Unknown error (%@).", nil), error]; + } + NSDictionary *dict = @{ @"product_id" : productID, @"error_msg" : errorMsg }; + [self postNotificationforStatus:kIAPPurchaseFailed withDict:dict]; + } + } + } else { + NSString *errorString = NSLocalizedString(@"Unknown error", nil); + if ([response isFault]) { + errorString = + [NSString stringWithFormat:NSLocalizedString(@"Communication issue (%@)", nil), [response faultString]]; + } else if ([response object] == nil) { + errorString = NSLocalizedString(@"Invalid server response", nil); + } + LOGE(@"Communication issue (%@)", [response faultString]); + UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Communication issue", nil) + message:errorString + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Continue", nil) + otherButtonTitles:nil, nil]; + [errorView show]; + + latestReceiptMD5 = nil; + NSDictionary *dict = @{ @"error_msg" : errorString }; + [self postNotificationforStatus:kIAPPurchaseFailed withDict:dict]; + } +} + +- (void)XMLRPCRequest:(XMLRPCRequest *)request didFailWithError:(NSError *)error { + if (!_enabled) + return; + + _available = true; + + if ([[request method] isEqualToString:@"activate_account"]) { + _accountActivationInProgress = NO; + } + + LOGE(@"Communication issue (%@)", [error localizedDescription]); + NSString *errorString = + [NSString stringWithFormat:NSLocalizedString(@"Communication issue (%@)", nil), [error localizedDescription]]; + UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Communication issue", nil) + message:errorString + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Continue", nil) + otherButtonTitles:nil, nil]; + [errorView show]; + latestReceiptMD5 = nil; + NSDictionary *dict = @{ @"error_msg" : errorString }; + [self postNotificationforStatus:kIAPReceiptFailed withDict:dict]; +} +#else +- (void)postNotificationforStatus:(IAPPurchaseNotificationStatus)status { + _status = status; + [[NSNotificationCenter defaultCenter] postNotificationName:status object:self userInfo:nil]; + LOGE(@"Not supported, triggering %@", status); +} +- (BOOL)purchaseAccount:(NSString *)phoneNumber + withPassword:(NSString *)password + andEmail:(NSString *)email + monthly:(BOOL)monthly { + [self postNotificationforStatus:kIAPPurchaseFailed]; + return false; +} +- (BOOL)restore { + [self postNotificationforStatus:kIAPRestoreFailed]; + return false; +} +- (BOOL)retrievePurchases { + [self postNotificationforStatus:kIAPRestoreFailed]; + return false; +} +- (BOOL)purchaseWitID:(NSString *)productID { + [self postNotificationforStatus:kIAPPurchaseFailed]; + return FALSE; +} +- (BOOL)isPurchasedWithID:(NSString *)productId { + return FALSE; +} + +- (void)XMLRPCRequest:(XMLRPCRequest *)request didFailWithError:(NSError *)error { +} +- (void)XMLRPCRequest:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response { +} +- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { +} +- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { +} +- (BOOL)activateAccount:(NSString *)phoneNumber { + return FALSE; +} +#endif +@end + +@implementation InAppProductsXMLRPCDelegate { + InAppProductsManager *iapm; +} + +#pragma mark - XMLRPCConnectionDelegate Functions + +- (void)request:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response { + [[[LinphoneManager instance] iapManager] XMLRPCRequest:request didReceiveResponse:response]; +} + +- (void)request:(XMLRPCRequest *)request didFailWithError:(NSError *)error { + [[[LinphoneManager instance] iapManager] XMLRPCRequest:request didFailWithError:error]; +} + +- (BOOL)request:(XMLRPCRequest *)request canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { + return FALSE; +} + +- (void)request:(XMLRPCRequest *)request didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { +} + +- (void)request:(XMLRPCRequest *)request didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { +} +@end diff --git a/Classes/InCallTableViewController.h b/Classes/InCallTableViewController.h deleted file mode 100644 index c611b370e..000000000 --- a/Classes/InCallTableViewController.h +++ /dev/null @@ -1,35 +0,0 @@ -/* InCallTableViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UICallCell.h" - -#include "linphone/linphonecore.h" - -@interface InCallTableViewController : UITableViewController { - @private - NSTimer *updateTime; - BOOL minimized; -} - -- (void)minimizeAll; -- (void)maximizeAll; - -@end diff --git a/Classes/InCallTableViewController.m b/Classes/InCallTableViewController.m deleted file mode 100644 index cd47bfd43..000000000 --- a/Classes/InCallTableViewController.m +++ /dev/null @@ -1,331 +0,0 @@ -/* InCallTableViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "InCallTableViewController.h" -#import "UICallCell.h" -#import "UIConferenceHeader.h" -#import "LinphoneManager.h" - - -@implementation InCallTableViewController - -static NSString *const kLinphoneInCallCellData = @"LinphoneInCallCellData"; - -enum TableSection { - ConferenceSection = 0, - CallSection = 1 -}; - -#pragma mark - Lifecycle Functions - -- (void)initInCallTableViewController { - minimized = false; -} - -- (id)init{ - self = [super init]; - if (self) { - [self initInCallTableViewController]; - } - return self; -} - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - [self initInCallTableViewController]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { - [self initInCallTableViewController]; - } - return self; -} - -- (void)dealloc { - [super dealloc]; -} - -#pragma mark - ViewController Functions - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - updateTime = [NSTimer scheduledTimerWithTimeInterval:1 - target:self - selector:@selector(update) - userInfo:nil - repeats:YES]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - if (updateTime != nil) { - [updateTime invalidate]; - updateTime = nil; - } -} - - -#pragma mark - Static Functions - -+ (bool)isInConference:(LinphoneCall*) call { - if (!call) - return false; - return linphone_call_is_in_conference(call); -} - -+ (int)callCount:(LinphoneCore*) lc { - int count = 0; - const MSList* calls = linphone_core_get_calls(lc); - - while (calls != 0) { - if (![InCallTableViewController isInConference:((LinphoneCall*)calls->data)]) { - count++; - } - calls = calls->next; - } - return count; -} - -+ (LinphoneCall*)retrieveCallAtIndex: (NSInteger) index inConference:(bool) conf{ - const MSList* calls = linphone_core_get_calls([LinphoneManager getLc]); - - while (calls != 0) { - if ([InCallTableViewController isInConference:(LinphoneCall*)calls->data] == conf) { - if (index == 0) - break; - index--; - } - calls = calls->next; - } - - if (calls == 0) { - [LinphoneLogger logc:LinphoneLoggerError format:"Cannot find call with index %d (in conf: %d)", index, conf]; - return nil; - } else { - return (LinphoneCall*)calls->data; - } -} - - -#pragma mark - - -- (void)removeCallData:(LinphoneCall*) call { - // Remove data associated with the call - if(call != NULL) { - LinphoneCallAppData* appData = (LinphoneCallAppData*) linphone_call_get_user_pointer(call); - if(appData != NULL) { - [appData->userInfos removeObjectForKey:kLinphoneInCallCellData]; - } - } -} - -- (UICallCellData*)addCallData:(LinphoneCall*) call { - // Handle data associated with the call - UICallCellData * data = nil; - if(call != NULL) { - LinphoneCallAppData* appData = (LinphoneCallAppData*) linphone_call_get_user_pointer(call); - if(appData != NULL) { - data = [appData->userInfos objectForKey:kLinphoneInCallCellData]; - if(data == nil) { - data = [[[UICallCellData alloc] init:call minimized:minimized] autorelease]; - [appData->userInfos setObject:data forKey:kLinphoneInCallCellData]; - } - } - } - return data; -} - -- (UICallCellData*)getCallData:(LinphoneCall*) call { - // Handle data associated with the call - UICallCellData * data = nil; - if(call != NULL) { - LinphoneCallAppData* appData = (LinphoneCallAppData*) linphone_call_get_user_pointer(call); - if(appData != NULL) { - data = [appData->userInfos objectForKey:kLinphoneInCallCellData]; - } - } - return data; -} - -- (void)update { - UITableView *tableView = [self tableView]; - for (int section = 0; section < [tableView numberOfSections]; section++) { - for (int row = 0; row < [tableView numberOfRowsInSection:section]; row++) { - NSIndexPath* cellPath = [NSIndexPath indexPathForRow:row inSection:section]; - UICallCell* cell = (UICallCell*) [tableView cellForRowAtIndexPath:cellPath]; - [cell update]; - } - } -} - -- (void)minimizeAll { - - const MSList *list = linphone_core_get_calls([LinphoneManager getLc]); - minimized = true; - while(list != NULL) { - UICallCellData *data = [self getCallData:(LinphoneCall*)list->data]; - if(data) { - data->minimize = true; - } else { - } - list = list->next; - } - [[self tableView] reloadData]; -} - -- (void)maximizeAll { - const MSList *list = linphone_core_get_calls([LinphoneManager getLc]); - minimized = false; - while(list != NULL) { - UICallCellData *data = [self getCallData:(LinphoneCall*)list->data]; - if(data) { - data->minimize = false; - } - list = list->next; - } - [[self tableView] reloadData]; -} - - -#pragma mark - UITableViewDataSource Functions - -- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - static NSString *kCellId = @"UICallCell"; - UICallCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; - if (cell == nil) { - cell = [[[UICallCell alloc] initWithIdentifier:kCellId] autorelease]; - } - - bool inConference = indexPath.section == ConferenceSection; - - LinphoneCore* lc = [LinphoneManager getLc]; - LinphoneCall* currentCall = linphone_core_get_current_call(lc); - LinphoneCall* call = [InCallTableViewController retrieveCallAtIndex:indexPath.row inConference:inConference]; - [cell setData:[self addCallData:call]]; - - // Update cell - if ([indexPath section] == CallSection && [indexPath row] == 0 && linphone_core_get_conference_size(lc) == 0) { - [cell setFirstCell:true]; - } else { - [cell setFirstCell:false]; - } - [cell setCurrentCall:(currentCall == call)]; - [cell setConferenceCell:inConference]; - [cell update]; - - /*if (linphone_core_get_calls_nb(lc) > 1 || linphone_core_get_conference_size(lc) > 0) { - tableView.scrollEnabled = true; - } else { - tableView.scrollEnabled = false; - }*/ - return cell; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - int count = 0; - - LinphoneCore* lc = [LinphoneManager getLc]; - - if(section == CallSection) { - count = [InCallTableViewController callCount:lc]; - } else { - count = linphone_core_get_conference_size(lc); - if(linphone_core_is_in_conference(lc)) { - count--; - } - } - return count; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 2; -} - -- (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - return @""; -} - -- (NSString*)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { - return @""; -} - - -#pragma mark - UITableViewDelegate Functions - -- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { - if(section == CallSection) { - return [[[UIView alloc] initWithFrame:CGRectZero] autorelease]; - } else if(section == ConferenceSection) { - LinphoneCore* lc = [LinphoneManager getLc]; - if(linphone_core_get_conference_size(lc) > 0){ - UIConferenceHeader *headerController = [[UIConferenceHeader alloc] init]; - [headerController update]; - UIView *headerView = [headerController view]; - [headerController release]; - return headerView; - } else { - return [[[UIView alloc] initWithFrame:CGRectZero] autorelease]; - } - } - return [[[UIView alloc] initWithFrame:CGRectZero] autorelease]; -} - -- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { - return [[[UIView alloc] initWithFrame:CGRectZero] autorelease]; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { - LinphoneCore* lc = [LinphoneManager getLc]; - if(section == CallSection) { - return 0.000001f; // Hack UITableView = 0 - } else if(section == ConferenceSection) { - if(linphone_core_get_conference_size(lc) > 0) { - return [UIConferenceHeader getHeight]; - } - } - return 0.000001f; // Hack UITableView = 0 -} - -- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { - LinphoneCore* lc = [LinphoneManager getLc]; - if(section == CallSection) { - return 0.000001f; // Hack UITableView = 0 - } else if(section == ConferenceSection) { - if(linphone_core_get_conference_size(lc) > 0) { - return 20; - } - } - return 0.000001f; // Hack UITableView = 0 -} - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - bool inConference = indexPath.section == ConferenceSection; - LinphoneCall* call = [InCallTableViewController retrieveCallAtIndex:indexPath.row inConference:inConference]; - UICallCellData* data = [self getCallData:call]; - if(data != nil &&data->minimize) - return [UICallCell getMinimizedHeight]; - return [UICallCell getMaximizedHeight]; -} - -@end diff --git a/Classes/InCallViewController.h b/Classes/InCallViewController.h deleted file mode 100644 index d349c9ea8..000000000 --- a/Classes/InCallViewController.h +++ /dev/null @@ -1,50 +0,0 @@ -/* InCallViewController.h - * - * Copyright (C) 2009 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "VideoZoomHandler.h" -#import "UICamSwitch.h" - -#import "UICompositeViewController.h" -#import "InCallTableViewController.h" - -@class VideoViewController; - -@interface InCallViewController : UIViewController { - @private - UITapGestureRecognizer* singleFingerTap; - NSTimer* hideControlsTimer; - BOOL videoShown; - VideoZoomHandler* videoZoomHandler; -} - -@property (nonatomic, retain) IBOutlet InCallTableViewController* callTableController; -@property (nonatomic, retain) IBOutlet UITableView* callTableView; - -@property (nonatomic, retain) IBOutlet UIView* videoGroup; -@property (nonatomic, retain) IBOutlet UIView* videoView; -#ifdef TEST_VIDEO_VIEW_CHANGE -@property (nonatomic, retain) IBOutlet UIView* testVideoView; -#endif -@property (nonatomic, retain) IBOutlet UIView* videoPreview; -@property (nonatomic, retain) IBOutlet UICamSwitch* videoCameraSwitch; -@property (nonatomic, retain) IBOutlet UIActivityIndicatorView* videoWaitingForFirstImage; - -@end diff --git a/Classes/InCallViewController.m b/Classes/InCallViewController.m deleted file mode 100644 index fda5ce633..000000000 --- a/Classes/InCallViewController.m +++ /dev/null @@ -1,515 +0,0 @@ -/* InCallViewController.h - * - * Copyright (C) 2009 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#import -#import -#import -#import -#import - -#import "IncallViewController.h" -#import "UICallCell.h" -#import "LinphoneManager.h" -#import "PhoneMainView.h" -#import "UILinphone.h" -#import "DTActionSheet.h" - -#include "linphone/linphonecore.h" - - -const NSInteger SECURE_BUTTON_TAG=5; - -@implementation InCallViewController { - BOOL hiddenVolume; -} - -@synthesize callTableController; -@synthesize callTableView; - -@synthesize videoGroup; -@synthesize videoView; -@synthesize videoPreview; -@synthesize videoCameraSwitch; -@synthesize videoWaitingForFirstImage; -#ifdef TEST_VIDEO_VIEW_CHANGE -@synthesize testVideoView; -#endif - - -#pragma mark - Lifecycle Functions - -- (id)init { - self = [super initWithNibName:@"InCallViewController" bundle:[NSBundle mainBundle]]; - if(self != nil) { - self->singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showControls:)]; - self->videoZoomHandler = [[VideoZoomHandler alloc] init]; - } - return self; -} - -- (void)dealloc { - [callTableController release]; - [callTableView release]; - - [videoGroup release]; - [videoView release]; - [videoPreview release]; -#ifdef TEST_VIDEO_VIEW_CHANGE - [testVideoView release]; -#endif - [videoCameraSwitch release]; - - [videoWaitingForFirstImage release]; - - [videoZoomHandler release]; - - [[PhoneMainView instance].view removeGestureRecognizer:singleFingerTap]; - [singleFingerTap release]; - - // Remove all observer - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [super dealloc]; -} - - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"InCall" - content:@"InCallViewController" - stateBar:@"UIStateBar" - stateBarEnabled:true - tabBar:@"UICallBar" - tabBarEnabled:true - fullscreen:false - landscapeMode:true - portraitMode:true]; - compositeDescription.darkBackground = true; - } - return compositeDescription; -} - - -#pragma mark - ViewController Functions - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; - UIDevice *device = [UIDevice currentDevice]; - device.proximityMonitoringEnabled = YES; - - [[PhoneMainView instance] setVolumeHidden:TRUE]; - hiddenVolume = TRUE; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - if (hideControlsTimer != nil) { - [hideControlsTimer invalidate]; - hideControlsTimer = nil; - } - - if( hiddenVolume ) { - [[PhoneMainView instance] setVolumeHidden:FALSE]; - hiddenVolume = FALSE; - } - - // Remove observer - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneCallUpdate - object:nil]; -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - // Set observer - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(callUpdateEvent:) - name:kLinphoneCallUpdate - object:nil]; - - // Update on show - LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); - LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0; - [self callUpdate:call state:state animated:FALSE]; - - // Set windows (warn memory leaks) - linphone_core_set_native_video_window_id([LinphoneManager getLc], (unsigned long)videoView); - linphone_core_set_native_preview_window_id([LinphoneManager getLc], (unsigned long)videoPreview); - - // Enable tap - [singleFingerTap setEnabled:TRUE]; -} - -- (void)viewDidDisappear:(BOOL)animated { - [super viewDidDisappear:animated]; - - [[UIApplication sharedApplication] setIdleTimerDisabled:false]; - UIDevice *device = [UIDevice currentDevice]; - device.proximityMonitoringEnabled = NO; - - [[PhoneMainView instance] fullScreen:false]; - // Disable tap - [singleFingerTap setEnabled:FALSE]; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - [singleFingerTap setNumberOfTapsRequired:1]; - [singleFingerTap setCancelsTouchesInView: FALSE]; - [[PhoneMainView instance].view addGestureRecognizer:singleFingerTap]; - - [videoZoomHandler setup:videoGroup]; - videoGroup.alpha = 0; - - [videoCameraSwitch setPreview:videoPreview]; - - [callTableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4 - [callTableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4 -} - -- (void)viewDidUnload { - [super viewDidUnload]; - [[PhoneMainView instance].view removeGestureRecognizer:singleFingerTap]; -} - -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; -// in mode display_filter_auto_rotate=0, no need to rotate the preview -} - - -#pragma mark - - -- (void)callUpdate:(LinphoneCall *)call state:(LinphoneCallState)state animated:(BOOL)animated { - LinphoneCore *lc = [LinphoneManager getLc]; - - if( hiddenVolume ){ - [[PhoneMainView instance] setVolumeHidden:FALSE]; - hiddenVolume = FALSE; - } - - // Update table - [callTableView reloadData]; - - // Fake call update - if(call == NULL) { - return; - } - - switch (state) { - case LinphoneCallIncomingReceived: - case LinphoneCallOutgoingInit: - { - if(linphone_core_get_calls_nb(lc) > 1) { - [callTableController minimizeAll]; - } - } - case LinphoneCallConnected: - case LinphoneCallStreamsRunning: - { - //check video - if (linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { - [self displayVideoCall:animated]; - } else { - [self displayTableCall:animated]; - const LinphoneCallParams* param = linphone_call_get_current_params(call); - const LinphoneCallAppData* callAppData = linphone_call_get_user_pointer(call); - if(state == LinphoneCallStreamsRunning - && callAppData->videoRequested - && linphone_call_params_low_bandwidth_enabled(param)) { - //too bad video was not enabled because low bandwidth - UIAlertView* alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Low bandwidth", nil) - message:NSLocalizedString(@"Video cannot be activated because of low bandwidth condition, only audio is available", nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue", nil) - otherButtonTitles:nil]; - [alert show]; - [alert release]; - callAppData->videoRequested=FALSE; /*reset field*/ - } - } - break; - } - case LinphoneCallUpdatedByRemote: - { - const LinphoneCallParams* current = linphone_call_get_current_params(call); - const LinphoneCallParams* remote = linphone_call_get_remote_params(call); - - /* remote wants to add video */ - if (linphone_core_video_enabled(lc) && !linphone_call_params_video_enabled(current) && - linphone_call_params_video_enabled(remote) && - !linphone_core_get_video_policy(lc)->automatically_accept) { - linphone_core_defer_call_update(lc, call); - [self displayAskToEnableVideoCall:call]; - } else if (linphone_call_params_video_enabled(current) && !linphone_call_params_video_enabled(remote)) { - [self displayTableCall:animated]; - } - break; - } - case LinphoneCallPausing: - case LinphoneCallPaused: - case LinphoneCallPausedByRemote: - { - [self displayTableCall:animated]; - break; - } - case LinphoneCallEnd: - case LinphoneCallError: - { - if(linphone_core_get_calls_nb(lc) <= 2 && !videoShown) { - [callTableController maximizeAll]; - } - break; - } - default: - break; - } - -} - -- (void)showControls:(id)sender { - if (hideControlsTimer) { - [hideControlsTimer invalidate]; - hideControlsTimer = nil; - } - - if([[[PhoneMainView instance] currentView] equal:[InCallViewController compositeViewDescription]] && videoShown) { - // show controls - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:0.3]; - [[PhoneMainView instance] showTabBar: true]; - [[PhoneMainView instance] showStateBar: true]; - [callTableView setAlpha:1.0]; - [videoCameraSwitch setAlpha:1.0]; - [UIView commitAnimations]; - - // hide controls in 5 sec - hideControlsTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 - target:self - selector:@selector(hideControls:) - userInfo:nil - repeats:NO]; - } -} - -- (void)hideControls:(id)sender { - if (hideControlsTimer) { - [hideControlsTimer invalidate]; - hideControlsTimer = nil; - } - - if([[[PhoneMainView instance] currentView] equal:[InCallViewController compositeViewDescription]] && videoShown) { - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:0.3]; - [videoCameraSwitch setAlpha:0.0]; - [callTableView setAlpha:0.0]; - [UIView commitAnimations]; - - - [[PhoneMainView instance] showTabBar: false]; - [[PhoneMainView instance] showStateBar: false]; - } -} - -#ifdef TEST_VIDEO_VIEW_CHANGE -// Define TEST_VIDEO_VIEW_CHANGE in IncallViewController.h to enable video view switching testing -- (void)_debugChangeVideoView { - static bool normalView = false; - if (normalView) { - linphone_core_set_native_video_window_id([LinphoneManager getLc], (unsigned long)videoView); - } else { - linphone_core_set_native_video_window_id([LinphoneManager getLc], (unsigned long)testVideoView); - } - normalView = !normalView; -} -#endif - -- (void)enableVideoDisplay:(BOOL)animation { - if(videoShown && animation) - return; - - videoShown = true; - - [videoZoomHandler resetZoom]; - - if(animation) { - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:1.0]; - } - - [videoGroup setAlpha:1.0]; - [callTableView setAlpha:0.0]; - - UIEdgeInsets insets = {33, 0, 25, 0}; - [callTableView setContentInset:insets]; - [callTableView setScrollIndicatorInsets:insets]; - [callTableController minimizeAll]; - - if(animation) { - [UIView commitAnimations]; - } - - if(linphone_core_self_view_enabled([LinphoneManager getLc])) { - [videoPreview setHidden:FALSE]; - } else { - [videoPreview setHidden:TRUE]; - } - - if ([LinphoneManager instance].frontCamId != nil) { - // only show camera switch button if we have more than 1 camera - [videoCameraSwitch setHidden:FALSE]; - } - [videoCameraSwitch setAlpha:0.0]; - - [[PhoneMainView instance] fullScreen: true]; - [[PhoneMainView instance] showTabBar: false]; - [[PhoneMainView instance] showStateBar: false]; - -#ifdef TEST_VIDEO_VIEW_CHANGE - [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(_debugChangeVideoView) userInfo:nil repeats:YES]; -#endif - // [self batteryLevelChanged:nil]; - - [videoWaitingForFirstImage setHidden: NO]; - [videoWaitingForFirstImage startAnimating]; - - LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); - //linphone_call_params_get_used_video_codec return 0 if no video stream enabled - if (call != NULL && linphone_call_params_get_used_video_codec(linphone_call_get_current_params(call))) { - linphone_call_set_next_video_frame_decoded_callback(call, hideSpinner, self); - } -} - -- (void)disableVideoDisplay:(BOOL)animation { - if(!videoShown && animation) - return; - - videoShown = false; - if(animation) { - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:1.0]; - } - - [videoGroup setAlpha:0.0]; - [[PhoneMainView instance] showTabBar: true]; - - UIEdgeInsets insets = {10, 0, 25, 0}; - [callTableView setContentInset:insets]; - [callTableView setScrollIndicatorInsets:insets]; - [callTableView setAlpha:1.0]; - if(linphone_core_get_calls_nb([LinphoneManager getLc]) <= 2) { - [callTableController maximizeAll]; - } - - [callTableView setAlpha:1.0]; - [videoCameraSwitch setHidden:TRUE]; - - if(animation) { - [UIView commitAnimations]; - } - - if (hideControlsTimer != nil) { - [hideControlsTimer invalidate]; - hideControlsTimer = nil; - } - - [[PhoneMainView instance] fullScreen:false]; -} - -- (void)displayVideoCall:(BOOL)animated { - [self enableVideoDisplay:animated]; -} - -- (void)displayTableCall:(BOOL)animated { - [self disableVideoDisplay:animated]; -} - - -#pragma mark - Spinner Functions - -- (void)hideSpinnerIndicator: (LinphoneCall*)call { - videoWaitingForFirstImage.hidden = TRUE; -} - -static void hideSpinner(LinphoneCall* call, void* user_data) { - InCallViewController* thiz = (InCallViewController*) user_data; - [thiz hideSpinnerIndicator:call]; -} - - -#pragma mark - Event Functions - -- (void)callUpdateEvent: (NSNotification*) notif { - LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue]; - LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue]; - [self callUpdate:call state:state animated:TRUE]; -} - - -#pragma mark - ActionSheet Functions - -- (void)displayAskToEnableVideoCall:(LinphoneCall*) call { - if (linphone_core_get_video_policy([LinphoneManager getLc])->automatically_accept) - return; - - const char* lUserNameChars = linphone_address_get_username(linphone_call_get_remote_address(call)); - NSString* lUserName = lUserNameChars?[[[NSString alloc] initWithUTF8String:lUserNameChars] autorelease]:NSLocalizedString(@"Unknown",nil); - const char* lDisplayNameChars = linphone_address_get_display_name(linphone_call_get_remote_address(call)); - NSString* lDisplayName = [lDisplayNameChars?[[NSString alloc] initWithUTF8String:lDisplayNameChars]:@"" autorelease]; - - NSString* title = [NSString stringWithFormat : NSLocalizedString(@"'%@' would like to enable video",nil), ([lDisplayName length] > 0)?lDisplayName:lUserName]; - DTActionSheet *sheet = [[[DTActionSheet alloc] initWithTitle:title] autorelease]; - NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(dismissVideoActionSheet:) userInfo:sheet repeats:NO]; - [sheet addButtonWithTitle:NSLocalizedString(@"Accept", nil) block:^() { - [LinphoneLogger logc:LinphoneLoggerLog format:"User accept video proposal"]; - LinphoneCallParams* paramsCopy = linphone_call_params_copy(linphone_call_get_current_params(call)); - linphone_call_params_enable_video(paramsCopy, TRUE); - linphone_core_accept_call_update([LinphoneManager getLc], call, paramsCopy); - linphone_call_params_destroy(paramsCopy); - [timer invalidate]; - }]; - DTActionSheetBlock cancelBlock = ^() { - [LinphoneLogger logc:LinphoneLoggerLog format:"User declined video proposal"]; - LinphoneCallParams* paramsCopy = linphone_call_params_copy(linphone_call_get_current_params(call)); - linphone_core_accept_call_update([LinphoneManager getLc], call, paramsCopy); - linphone_call_params_destroy(paramsCopy); - [timer invalidate]; - }; - [sheet addDestructiveButtonWithTitle:NSLocalizedString(@"Decline", nil) block:cancelBlock]; - if([LinphoneManager runningOnIpad]) { - [sheet addCancelButtonWithTitle:NSLocalizedString(@"Decline", nil) block:cancelBlock]; - } - [sheet showInView:[PhoneMainView instance].view]; -} - -- (void)dismissVideoActionSheet:(NSTimer*)timer { - DTActionSheet *sheet = (DTActionSheet *)timer.userInfo; - [sheet dismissWithClickedButtonIndex:sheet.destructiveButtonIndex animated:TRUE]; -} - - -@end diff --git a/Classes/IncomingCallViewController.h b/Classes/IncomingCallViewController.h deleted file mode 100644 index 269c87a24..000000000 --- a/Classes/IncomingCallViewController.h +++ /dev/null @@ -1,45 +0,0 @@ -/* IncomingCallViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UICompositeViewController.h" -#import "TPMultiLayoutViewController.h" -#include "linphone/linphonecore.h" - -@protocol IncomingCallViewDelegate - -- (void)incomingCallAccepted:(LinphoneCall*)call; -- (void)incomingCallDeclined:(LinphoneCall*)call; -- (void)incomingCallAborted:(LinphoneCall*)call; - -@end - -@interface IncomingCallViewController : TPMultiLayoutViewController { -} - -@property (nonatomic, retain) IBOutlet UILabel* addressLabel; -@property (nonatomic, retain) IBOutlet UIImageView* avatarImage; -@property (nonatomic, assign) LinphoneCall* call; -@property (nonatomic, retain) id delegate; - -- (IBAction)onAcceptClick:(id) event; -- (IBAction)onDeclineClick:(id) event; - -@end diff --git a/Classes/IncomingCallViewController.m b/Classes/IncomingCallViewController.m deleted file mode 100644 index 5c7519c92..000000000 --- a/Classes/IncomingCallViewController.m +++ /dev/null @@ -1,211 +0,0 @@ -/* IncomingCallViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "IncomingCallViewController.h" -#import "LinphoneManager.h" -#import "FastAddressBook.h" -#import "PhoneMainView.h" -#import "UILinphone.h" - -@implementation IncomingCallViewController - -@synthesize addressLabel; -@synthesize avatarImage; -@synthesize call; -@synthesize delegate; - -#pragma mark - Lifecycle Functions - -- (id)init { - return [super initWithNibName:@"IncomingCallViewController" bundle:[NSBundle mainBundle]]; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [avatarImage release]; - [addressLabel release]; - [delegate release]; - [super dealloc]; -} - - -#pragma mark - ViewController Functions - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(callUpdateEvent:) - name:kLinphoneCallUpdate - object:nil]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneCallUpdate - object:nil]; -} - - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"IncomingCall" - content:@"IncomingCallViewController" - stateBar:nil - stateBarEnabled:false - tabBar:nil - tabBarEnabled:false - fullscreen:false - landscapeMode:[LinphoneManager runningOnIpad] - portraitMode:true]; - compositeDescription.darkBackground = true; - } - return compositeDescription; -} - - -#pragma mark - Event Functions - -- (void)callUpdateEvent:(NSNotification*)notif { - LinphoneCall *acall = [[notif.userInfo objectForKey: @"call"] pointerValue]; - LinphoneCallState astate = [[notif.userInfo objectForKey: @"state"] intValue]; - [self callUpdate:acall state:astate]; -} - - -#pragma mark - - -- (void)callUpdate:(LinphoneCall *)acall state:(LinphoneCallState)astate { - if(call == acall && (astate == LinphoneCallEnd || astate == LinphoneCallError)) { - [delegate incomingCallAborted:call]; - [self dismiss]; - } -} - - -- (void)dismiss { - if([[[PhoneMainView instance] currentView] equal:[IncomingCallViewController compositeViewDescription]]) { - [[PhoneMainView instance] popCurrentView]; - } -} - -- (void)update { - [self view]; //Force view load - - [avatarImage setImage:[UIImage imageNamed:@"avatar_unknown.png"]]; - - NSString* address = nil; - const LinphoneAddress* addr = linphone_call_get_remote_address(call); - if (addr != NULL) { - BOOL useLinphoneAddress = true; - // contact name - char* lAddress = linphone_address_as_string_uri_only(addr); - if(lAddress) { - NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:lAddress]]; - ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress]; - if(contact) { - UIImage *tmpImage = [FastAddressBook getContactImage:contact thumbnail:false]; - if(tmpImage != nil) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) { - UIImage *tmpImage2 = [UIImage decodedImageWithImage:tmpImage]; - dispatch_async(dispatch_get_main_queue(), ^{ - avatarImage.image = tmpImage2; - }); - }); - } - address = [FastAddressBook getContactDisplayName:contact]; - useLinphoneAddress = false; - } - ms_free(lAddress); - } - if(useLinphoneAddress) { - const char* lDisplayName = linphone_address_get_display_name(addr); - const char* lUserName = linphone_address_get_username(addr); - if (lDisplayName) - address = [NSString stringWithUTF8String:lDisplayName]; - else if(lUserName) - address = [NSString stringWithUTF8String:lUserName]; - } - } - - // Set Address - if(address == nil) { - address = @"Unknown"; - } - [addressLabel setText:address]; -} - - -#pragma mark - Property Functions - -- (void)setCall:(LinphoneCall*)acall { - call = acall; - [self update]; - [self callUpdate:call state:linphone_call_get_state(call)]; -} - - -#pragma mark - Action Functions - -- (IBAction)onAcceptClick:(id)event { - [self dismiss]; - [delegate incomingCallAccepted:call]; -} - -- (IBAction)onDeclineClick:(id)event { - [self dismiss]; - [delegate incomingCallDeclined:call]; -} - - -#pragma mark - TPMultiLayoutViewController Functions - -- (NSDictionary*)attributesForView:(UIView*)view { - NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; - - [attributes setObject:[NSValue valueWithCGRect:view.frame] forKey:@"frame"]; - [attributes setObject:[NSValue valueWithCGRect:view.bounds] forKey:@"bounds"]; - if([view isKindOfClass:[UIButton class]]) { - UIButton *button = (UIButton *)view; - [LinphoneUtils buttonMultiViewAddAttributes:attributes button:button]; - } - [attributes setObject:[NSNumber numberWithInteger:view.autoresizingMask] forKey:@"autoresizingMask"]; - - return attributes; -} - -- (void)applyAttributes:(NSDictionary*)attributes toView:(UIView*)view { - view.frame = [[attributes objectForKey:@"frame"] CGRectValue]; - view.bounds = [[attributes objectForKey:@"bounds"] CGRectValue]; - if([view isKindOfClass:[UIButton class]]) { - UIButton *button = (UIButton *)view; - [LinphoneUtils buttonMultiViewApplyAttributes:attributes button:button]; - } - view.autoresizingMask = [[attributes objectForKey:@"autoresizingMask"] integerValue]; -} - - -@end diff --git a/Classes/KIF b/Classes/KIF index 6a21291a3..21a137bc8 160000 --- a/Classes/KIF +++ b/Classes/KIF @@ -1 +1 @@ -Subproject commit 6a21291a3b6653304be63eeaca8a0edfeb01d7c6 +Subproject commit 21a137bc8068f9fb738f835c6e285d44fe2ce4dd diff --git a/Classes/LaunchScreen.xib b/Classes/LaunchScreen.xib deleted file mode 100644 index ecd6f3023..000000000 --- a/Classes/LaunchScreen.xib +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 950bcb362..c55dd4db4 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -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 "PhoneMainView.h" #import "linphoneAppDelegate.h" @@ -37,486 +37,483 @@ #pragma mark - Lifecycle Functions - (id)init { - self = [super init]; - if(self != nil) { - self->startedInBackground = FALSE; - } - return self; + self = [super init]; + if (self != nil) { + startedInBackground = FALSE; + } + return self; } -- (void)dealloc { - [super dealloc]; -} +#pragma mark - - -#pragma mark - - - - -- (void)applicationDidEnterBackground:(UIApplication *)application{ - Linphone_log(@"%@", NSStringFromSelector(_cmd)); +- (void)applicationDidEnterBackground:(UIApplication *)application { + LOGI(@"%@", NSStringFromSelector(_cmd)); [[LinphoneManager instance] enterBackgroundMode]; } - (void)applicationWillResignActive:(UIApplication *)application { - Linphone_log(@"%@", NSStringFromSelector(_cmd)); - LinphoneCore* lc = [LinphoneManager getLc]; - LinphoneCall* call = linphone_core_get_current_call(lc); - - if (call){ + LOGI(@"%@", NSStringFromSelector(_cmd)); + LinphoneCore *lc = [LinphoneManager getLc]; + LinphoneCall *call = linphone_core_get_current_call(lc); + + if (call) { /* save call context */ - LinphoneManager* instance = [LinphoneManager instance]; + LinphoneManager *instance = [LinphoneManager instance]; instance->currentCallContextBeforeGoingBackground.call = call; instance->currentCallContextBeforeGoingBackground.cameraIsEnabled = linphone_call_camera_enabled(call); - - const LinphoneCallParams* params = linphone_call_get_current_params(call); + + const LinphoneCallParams *params = linphone_call_get_current_params(call); if (linphone_call_params_video_enabled(params)) { linphone_call_enable_camera(call, false); } } - - if (![[LinphoneManager instance] resignActive]) { - } - + if (![[LinphoneManager instance] resignActive]) { + } } - (void)applicationDidBecomeActive:(UIApplication *)application { - Linphone_log(@"%@", NSStringFromSelector(_cmd)); + LOGI(@"%@", NSStringFromSelector(_cmd)); - if( startedInBackground ){ - startedInBackground = FALSE; - [[PhoneMainView instance] startUp]; - [[PhoneMainView instance] updateStatusBar:nil]; - } - LinphoneManager* instance = [LinphoneManager instance]; - - [instance becomeActive]; - - LinphoneCore* lc = [LinphoneManager getLc]; - LinphoneCall* call = linphone_core_get_current_call(lc); - - if (call){ - if (call == instance->currentCallContextBeforeGoingBackground.call) { - const LinphoneCallParams* params = linphone_call_get_current_params(call); - if (linphone_call_params_video_enabled(params)) { - linphone_call_enable_camera( - call, - instance->currentCallContextBeforeGoingBackground.cameraIsEnabled); - } - instance->currentCallContextBeforeGoingBackground.call = 0; - } else if ( linphone_call_get_state(call) == LinphoneCallIncomingReceived ) { - [[PhoneMainView instance ] displayIncomingCall:call]; - // in this case, the ringing sound comes from the notification. - // To stop it we have to do the iOS7 ring fix... - [self fixRing]; - } - } + if (startedInBackground) { + startedInBackground = FALSE; + [PhoneMainView.instance startUp]; + [PhoneMainView.instance updateStatusBar:nil]; + } + LinphoneManager *instance = [LinphoneManager instance]; + + [instance becomeActive]; + + LinphoneCore *lc = [LinphoneManager getLc]; + LinphoneCall *call = linphone_core_get_current_call(lc); + + if (call) { + if (call == instance->currentCallContextBeforeGoingBackground.call) { + const LinphoneCallParams *params = linphone_call_get_current_params(call); + if (linphone_call_params_video_enabled(params)) { + linphone_call_enable_camera(call, instance->currentCallContextBeforeGoingBackground.cameraIsEnabled); + } + instance->currentCallContextBeforeGoingBackground.call = 0; + } else if (linphone_call_get_state(call) == LinphoneCallIncomingReceived) { + [PhoneMainView.instance displayIncomingCall:call]; + // in this case, the ringing sound comes from the notification. + // To stop it we have to do the iOS7 ring fix... + [self fixRing]; + } + } } -- (UIUserNotificationCategory*)getMessageNotificationCategory { - - 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] 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] autorelease]; - localRingNotifAction.identifier = @"incoming_msg"; - [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextDefault]; - [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextMinimal]; +- (UIUserNotificationCategory *)getMessageNotificationCategory { - return localRingNotifAction; + UIMutableUserNotificationAction *reply = [[UIMutableUserNotificationAction alloc] init]; + reply.identifier = @"reply"; + reply.title = NSLocalizedString(@"Reply", nil); + reply.activationMode = UIUserNotificationActivationModeForeground; + reply.destructive = NO; + reply.authenticationRequired = YES; + + UIMutableUserNotificationAction *mark_read = [[UIMutableUserNotificationAction alloc] init]; + 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]; + localRingNotifAction.identifier = @"incoming_msg"; + [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextDefault]; + [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextMinimal]; + + return localRingNotifAction; } -- (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] autorelease]; - decline.identifier = @"decline"; - decline.title = NSLocalizedString(@"Decline", nil); - decline.activationMode = UIUserNotificationActivationModeBackground; - decline.destructive = YES; - decline.authenticationRequired = NO; - - - NSArray* localRingActions = @[decline, answer]; - - UIMutableUserNotificationCategory* localRingNotifAction = [[[UIMutableUserNotificationCategory alloc] init] autorelease]; - localRingNotifAction.identifier = @"incoming_call"; - [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextDefault]; - [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextMinimal]; +- (UIUserNotificationCategory *)getCallNotificationCategory { + UIMutableUserNotificationAction *answer = [[UIMutableUserNotificationAction alloc] init]; + answer.identifier = @"answer"; + answer.title = NSLocalizedString(@"Answer", nil); + answer.activationMode = UIUserNotificationActivationModeForeground; + answer.destructive = NO; + answer.authenticationRequired = YES; - return localRingNotifAction; + UIMutableUserNotificationAction *decline = [[UIMutableUserNotificationAction alloc] init]; + decline.identifier = @"decline"; + decline.title = NSLocalizedString(@"Decline", nil); + decline.activationMode = UIUserNotificationActivationModeBackground; + decline.destructive = YES; + decline.authenticationRequired = NO; + + NSArray *localRingActions = @[ decline, answer ]; + + UIMutableUserNotificationCategory *localRingNotifAction = [[UIMutableUserNotificationCategory alloc] init]; + 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; + UIApplication *app = [UIApplication sharedApplication]; + UIApplicationState state = app.applicationState; - LinphoneManager* instance = [LinphoneManager instance]; - BOOL background_mode = [instance lpConfigBoolForKey:@"backgroundmode_preference"]; - BOOL start_at_boot = [instance lpConfigBoolForKey:@"start_at_boot_preference"]; - - - if( !instance.isTesting ){ - if( [app respondsToSelector:@selector(registerUserNotificationSettings:)] ){ - /* iOS8 notifications can be actioned! Awesome: */ - UIUserNotificationType notifTypes = UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert; - - NSSet* categories = [NSSet setWithObjects:[self getCallNotificationCategory], [self getMessageNotificationCategory], nil]; - UIUserNotificationSettings* userSettings = [UIUserNotificationSettings settingsForTypes:notifTypes categories:categories]; - [app registerUserNotificationSettings:userSettings]; - [app registerForRemoteNotifications]; - } else { - NSUInteger notifTypes = UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeNewsstandContentAvailability; - [app registerForRemoteNotificationTypes:notifTypes]; - } - } else { - NSLog(@"No remote push for testing"); - } - + LinphoneManager *instance = [LinphoneManager instance]; + BOOL background_mode = [instance lpConfigBoolForKey:@"backgroundmode_preference"]; + BOOL start_at_boot = [instance lpConfigBoolForKey:@"start_at_boot_preference"]; - if (state == UIApplicationStateBackground) - { - // we've been woken up directly to background; - if( !start_at_boot || !background_mode ) { - // autoboot disabled or no background, and no push: do nothing and wait for a real launch + if ([app respondsToSelector:@selector(registerUserNotificationSettings:)]) { + /* iOS8 notifications can be actioned! Awesome: */ + UIUserNotificationType notifTypes = + UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert; + + NSSet *categories = + [NSSet setWithObjects:[self getCallNotificationCategory], [self getMessageNotificationCategory], nil]; + UIUserNotificationSettings *userSettings = + [UIUserNotificationSettings settingsForTypes:notifTypes categories:categories]; + [app registerUserNotificationSettings:userSettings]; + + if (!instance.isTesting) { + [app registerForRemoteNotifications]; + } + } else { + if (!instance.isTesting) { + NSUInteger notifTypes = + UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge; + [app registerForRemoteNotificationTypes:notifTypes]; + } + } + + if (state == UIApplicationStateBackground) { + // we've been woken up directly to background; + if (!start_at_boot || !background_mode) { + // autoboot disabled or no background, and no push: do nothing and wait for a real launch /*output a log with NSLog, because the ortp logging system isn't activated yet at this time*/ NSLog(@"Linphone launch doing nothing because start_at_boot or background_mode are not activated.", NULL); - return YES; - } - - } + return YES; + } + } bgStartId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ - [LinphoneLogger log:LinphoneLoggerWarning format:@"Background task for application launching expired."]; - [[UIApplication sharedApplication] endBackgroundTask:bgStartId]; + LOGW(@"Background task for application launching expired."); + [[UIApplication sharedApplication] endBackgroundTask:bgStartId]; }]; - [[LinphoneManager instance] startLibLinphone]; - // initialize UI - [self.window makeKeyAndVisible]; - [RootViewManager setupWithPortrait:(PhoneMainView*)self.window.rootViewController]; - [[PhoneMainView instance] startUp]; - [[PhoneMainView instance] updateStatusBar:nil]; + [[LinphoneManager instance] startLinphoneCore]; + // 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."]; + NSDictionary *remoteNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; + if (remoteNotif) { + LOGI(@"PushNotification from launch received."); [self processRemoteNotification:remoteNotif]; } - if (bgStartId!=UIBackgroundTaskInvalid) [[UIApplication sharedApplication] endBackgroundTask:bgStartId]; + if (bgStartId != UIBackgroundTaskInvalid) + [[UIApplication sharedApplication] endBackgroundTask:bgStartId]; - return YES; -} - -- (void)applicationWillTerminate:(UIApplication *)application { - Linphone_log(@"%@", NSStringFromSelector(_cmd)); -} - -- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { - NSString *scheme = [[url scheme] lowercaseString]; - 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 - cancelButtonTitle:NSLocalizedString(@"No",nil) - otherButtonTitles:NSLocalizedString(@"Yes",nil),nil]; - confirmation.tag = 1; - [confirmation show]; - [confirmation release]; - } else { - if([[url scheme] isEqualToString:@"sip"]) { - // remove "sip://" from the URI, and do it correctly by taking resourceSpecifier and removing leading and trailing "/" - NSString* sipUri = [[url resourceSpecifier] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"/"]]; - - DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController); - if(controller != nil) { - [controller setAddress:sipUri]; - } - } - } return YES; } -- (void)fixRing{ - if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { - // iOS7 fix for notification sound not stopping. - // see http://stackoverflow.com/questions/19124882/stopping-ios-7-remote-notification-sound - [[UIApplication sharedApplication] setApplicationIconBadgeNumber: 1]; - [[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0]; - } +- (void)applicationWillTerminate:(UIApplication *)application { + LOGI(@"%@", NSStringFromSelector(_cmd)); + + linphone_core_terminate_all_calls([LinphoneManager getLc]); + + // destroyLinphoneCore automatically unregister proxies but if we are using + // remote push notifications, we want to continue receiving them + if ([LinphoneManager instance].pushNotificationToken != nil) { + // trick me! setting network reachable to false will avoid sending unregister + linphone_core_set_network_reachable([LinphoneManager getLc], FALSE); + } + [[LinphoneManager instance] destroyLinphoneCore]; } -- (void)processRemoteNotification:(NSDictionary*)userInfo{ +- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { + NSString *scheme = [[url scheme] lowercaseString]; + 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 + cancelButtonTitle:NSLocalizedString(@"No", nil) + otherButtonTitles:NSLocalizedString(@"Yes", nil), nil]; + confirmation.tag = 1; + [confirmation show]; + } else { + if ([[url scheme] isEqualToString:@"sip"]) { + // remove "sip://" from the URI, and do it correctly by taking resourceSpecifier and removing leading and + // trailing "/" + NSString *sipUri = [[url resourceSpecifier] + stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"/"]]; + [VIEW(DialerView) setAddress:sipUri]; + } + } + return YES; +} + +- (void)fixRing { + if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { + // iOS7 fix for notification sound not stopping. + // see http://stackoverflow.com/questions/19124882/stopping-ios-7-remote-notification-sound + [[UIApplication sharedApplication] setApplicationIconBadgeNumber:1]; + [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; + } +} + +- (void)processRemoteNotification:(NSDictionary *)userInfo { NSDictionary *aps = [userInfo objectForKey:@"aps"]; - - if(aps != nil) { - NSDictionary *alert = [aps objectForKey:@"alert"]; - if(alert != nil) { - NSString *loc_key = [alert objectForKey:@"loc-key"]; + + if (aps != nil) { + NSDictionary *alert = [aps objectForKey:@"alert"]; + if (alert != nil) { + NSString *loc_key = [alert objectForKey:@"loc-key"]; /*if we receive a remote notification, it is probably because our TCP background socket was no more working. As a result, break it and refresh registers in order to make sure to receive incoming INVITE or MESSAGE*/ LinphoneCore *lc = [LinphoneManager getLc]; - if (linphone_core_get_calls(lc)==NULL){ //if there are calls, obviously our TCP socket shall be working + if (linphone_core_get_calls(lc) == NULL) { // if there are calls, obviously our TCP socket shall be working linphone_core_set_network_reachable(lc, FALSE); - [LinphoneManager instance].connectivity=none; /*force connectivity to be discovered again*/ - [[LinphoneManager instance] refreshRegisters]; - if(loc_key != nil) { + [LinphoneManager instance].connectivity = none; /*force connectivity to be discovered again*/ + [[LinphoneManager instance] refreshRegisters]; + if (loc_key != nil) { - NSString* callId = [userInfo objectForKey:@"call-id"]; - if( callId != nil ){ + NSString *callId = [userInfo objectForKey:@"call-id"]; + if (callId != nil) { [[LinphoneManager instance] addPushCallId:callId]; } else { - [LinphoneLogger log:LinphoneLoggerError format:@"PushNotification: does not have call-id yet, fix it !"]; + LOGE(@"PushNotification: does not have call-id yet, fix it !"); } - if( [loc_key isEqualToString:@"IM_MSG"] ) { + if ([loc_key isEqualToString:@"IM_MSG"] || [loc_key isEqualToString:@"IM_FULLMSG"]) { - [[PhoneMainView instance] changeCurrentView:[ChatViewController compositeViewDescription]]; + [PhoneMainView.instance changeCurrentView:ChatsListView.compositeViewDescription]; - } else if( [loc_key isEqualToString:@"IC_MSG"] ) { + } else if ([loc_key isEqualToString:@"IC_MSG"]) { [self fixRing]; - } } } - } - } + } + } } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { - Linphone_log(@"%@ : %@", NSStringFromSelector(_cmd), userInfo); + LOGI(@"%@ : %@", NSStringFromSelector(_cmd), userInfo); [self processRemoteNotification:userInfo]; } -- (LinphoneChatRoom*)findChatRoomForContact:(NSString*)contact { - MSList* rooms = linphone_core_get_chat_rooms([LinphoneManager getLc]); - const char* from = [contact UTF8String]; - while (rooms) { - const LinphoneAddress* room_from_address = linphone_chat_room_get_peer_address((LinphoneChatRoom*)rooms->data); - char* room_from = linphone_address_as_string_uri_only(room_from_address); - if( room_from && strcmp(from, room_from)== 0){ - return rooms->data; - } - rooms = rooms->next; - } - return NULL; +- (LinphoneChatRoom *)findChatRoomForContact:(NSString *)contact { + const MSList *rooms = linphone_core_get_chat_rooms([LinphoneManager getLc]); + const char *from = [contact UTF8String]; + while (rooms) { + const LinphoneAddress *room_from_address = linphone_chat_room_get_peer_address((LinphoneChatRoom *)rooms->data); + char *room_from = linphone_address_as_string_uri_only(room_from_address); + if (room_from && strcmp(from, room_from) == 0) { + return rooms->data; + } + rooms = rooms->next; + } + return NULL; } - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { - Linphone_log(@"%@ - state = %ld", NSStringFromSelector(_cmd), (long)application.applicationState); + LOGI(@"%@ - state = %ld", NSStringFromSelector(_cmd), (long)application.applicationState); - [self fixRing]; + [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"]]; - auto_answer = [[LinphoneManager instance] lpConfigBoolForKey:@"autoanswer_notif_preference"]; - } - if(auto_answer) - { - [[LinphoneManager instance] acceptCallForCallId:[notification.userInfo objectForKey:@"callId"]]; - } - } else if([notification.userInfo objectForKey:@"from_addr"] != nil) { - NSString *remoteContact = (NSString*)[notification.userInfo objectForKey:@"from_addr"]; - // Go to ChatRoom view - [[PhoneMainView instance] changeCurrentView:[ChatViewController compositeViewDescription]]; - LinphoneChatRoom*room = [self findChatRoomForContact:remoteContact]; - ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController); - if(controller != nil && room != nil) { - [controller setChatRoom:room]; - } - } else if([notification.userInfo objectForKey:@"callLog"] != nil) { - NSString *callLog = (NSString*)[notification.userInfo objectForKey:@"callLog"]; - // Go to HistoryDetails view - [[PhoneMainView instance] changeCurrentView:[HistoryViewController compositeViewDescription]]; - HistoryDetailsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[HistoryDetailsViewController compositeViewDescription] push:TRUE], HistoryDetailsViewController); - if(controller != nil) { - [controller setCallLogId:callLog]; - } - } + 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"]]; + auto_answer = [[LinphoneManager instance] lpConfigBoolForKey:@"autoanswer_notif_preference"]; + } + if (auto_answer) { + [[LinphoneManager instance] acceptCallForCallId:[notification.userInfo objectForKey:@"callId"]]; + } + } else if ([notification.userInfo objectForKey:@"from_addr"] != nil) { + NSString *remoteContact = (NSString *)[notification.userInfo objectForKey:@"from_addr"]; + [PhoneMainView.instance changeCurrentView:ChatsListView.compositeViewDescription]; + LinphoneChatRoom *room = [self findChatRoomForContact:remoteContact]; + ChatConversationView *view = VIEW(ChatConversationView); + [view setChatRoom:room]; + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE]; + } else if ([notification.userInfo objectForKey:@"callLog"] != nil) { + NSString *callLog = (NSString *)[notification.userInfo objectForKey:@"callLog"]; + HistoryDetailsView *view = VIEW(HistoryDetailsView); + [view setCallLogId:callLog]; + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE]; + } } -// 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]; +// 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 { + LOGI(@"%@ : %@", NSStringFromSelector(_cmd), userInfo); + LinphoneManager *lm = [LinphoneManager instance]; - // save the completion handler for later execution. - // 2 outcomes: - // - if a new call/message is received, the completion handler will be called with "NEWDATA" - // - if nothing happens for 15 seconds, the completion handler will be called with "NODATA" - lm.silentPushCompletion = completionHandler; - [NSTimer scheduledTimerWithTimeInterval:15.0 target:lm selector:@selector(silentPushFailed:) userInfo:nil repeats:FALSE]; + // save the completion handler for later execution. + // 2 outcomes: + // - if a new call/message is received, the completion handler will be called with "NEWDATA" + // - if nothing happens for 15 seconds, the completion handler will be called with "NODATA" + lm.silentPushCompletion = completionHandler; + [NSTimer scheduledTimerWithTimeInterval:15.0 + target:lm + selector:@selector(silentPushFailed:) + userInfo:nil + repeats:FALSE]; - LinphoneCore *lc=[LinphoneManager getLc]; - // If no call is yet received at this time, then force Linphone to drop the current socket and make new one to register, so that we get + LinphoneCore *lc = [LinphoneManager getLc]; + // If no call is yet received at this time, then force Linphone to drop the current socket and make new one to + // register, so that we get // a better chance to receive the INVITE. - if (linphone_core_get_calls(lc)==NULL){ + if (linphone_core_get_calls(lc) == NULL) { linphone_core_set_network_reachable(lc, FALSE); - lm.connectivity=none; /*force connectivity to be discovered again*/ + lm.connectivity = none; /*force connectivity to be discovered again*/ [lm refreshRegisters]; } } - #pragma mark - PushNotification Functions -- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken { - Linphone_log(@"%@ : %@", NSStringFromSelector(_cmd), deviceToken); - [[LinphoneManager instance] setPushNotificationToken:deviceToken]; +- (void)application:(UIApplication *)application + didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { + LOGI(@"%@ : %@", NSStringFromSelector(_cmd), deviceToken); + [[LinphoneManager instance] setPushNotificationToken:deviceToken]; } -- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error { - Linphone_log(@"%@ : %@", NSStringFromSelector(_cmd), [error localizedDescription]); - [[LinphoneManager instance] setPushNotificationToken:nil]; +- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { + LOGI(@"%@ : %@", NSStringFromSelector(_cmd), [error localizedDescription]); + [[LinphoneManager instance] setPushNotificationToken:nil]; } #pragma mark - User notifications -- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { - Linphone_log(@"%@", NSStringFromSelector(_cmd)); +- (void)application:(UIApplication *)application + didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { + LOGI(@"%@", 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){ +- (void)application:(UIApplication *)application + handleActionWithIdentifier:(NSString *)identifier + forLocalNotification:(UILocalNotification *)notification + completionHandler:(void (^)())completionHandler { + LOGI(@"%@", NSStringFromSelector(_cmd)); + if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) { - LinphoneCore* lc = [LinphoneManager getLc]; - [LinphoneLogger log:LinphoneLoggerLog format:@"%@", NSStringFromSelector(_cmd)]; - if( [notification.category isEqualToString:@"incoming_call"]) { - if( [identifier isEqualToString:@"answer"] ){ - // use the standard handler - [self application:application didReceiveLocalNotification:notification]; - } else if( [identifier isEqualToString:@"decline"] ){ - LinphoneCall* call = linphone_core_get_current_call(lc); - if( call ) linphone_core_decline_call(lc, call, LinphoneReasonDeclined); - } - } else if( [notification.category isEqualToString:@"incoming_msg"] ){ - if( [identifier isEqualToString:@"reply"] ){ - // use the standard handler - [self application:application didReceiveLocalNotification:notification]; - } else if( [identifier isEqualToString:@"mark_read"] ){ - NSString* from = [notification.userInfo objectForKey:@"from_addr"]; - LinphoneChatRoom* room = linphone_core_get_or_create_chat_room(lc, [from UTF8String]); - if( room ){ - linphone_chat_room_mark_as_read(room); - [[PhoneMainView instance] updateApplicationBadgeNumber]; - } - } - } - } - completionHandler(); + LinphoneCore *lc = [LinphoneManager getLc]; + LOGI(@"%@", NSStringFromSelector(_cmd)); + if ([notification.category isEqualToString:@"incoming_call"]) { + if ([identifier isEqualToString:@"answer"]) { + // use the standard handler + [self application:application didReceiveLocalNotification:notification]; + } else if ([identifier isEqualToString:@"decline"]) { + LinphoneCall *call = linphone_core_get_current_call(lc); + if (call) + linphone_core_decline_call(lc, call, LinphoneReasonDeclined); + } + } else if ([notification.category isEqualToString:@"incoming_msg"]) { + if ([identifier isEqualToString:@"reply"]) { + // use the standard handler + [self application:application didReceiveLocalNotification:notification]; + } else if ([identifier isEqualToString:@"mark_read"]) { + NSString *from = [notification.userInfo objectForKey:@"from_addr"]; + LinphoneChatRoom *room = linphone_core_get_chat_room_from_uri(lc, [from UTF8String]); + if (room) { + linphone_chat_room_mark_as_read(room); + TabBarView *tab = (TabBarView *)[PhoneMainView.instance.mainViewController + getCachedController:NSStringFromClass(TabBarView.class)]; + [tab update:YES]; + [PhoneMainView.instance updateApplicationBadgeNumber]; + } + } + } + } + completionHandler(); } -- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler { - Linphone_log(@"%@", NSStringFromSelector(_cmd)); - completionHandler(); +- (void)application:(UIApplication *)application + handleActionWithIdentifier:(NSString *)identifier + forRemoteNotification:(NSDictionary *)userInfo + completionHandler:(void (^)())completionHandler { + LOGI(@"%@", NSStringFromSelector(_cmd)); + completionHandler(); } #pragma mark - Remote configuration Functions (URL Handler) +- (void)ConfigurationStateUpdateEvent:(NSNotification *)notif { + LinphoneConfiguringState state = [[notif.userInfo objectForKey:@"state"] intValue]; + if (state == LinphoneConfiguringSuccessful) { + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneConfiguringStateUpdate object:nil]; + [_waitingIndicator dismissWithClickedButtonIndex:0 animated:true]; -- (void)ConfigurationStateUpdateEvent: (NSNotification*) notif { - LinphoneConfiguringState state = [[notif.userInfo objectForKey: @"state"] intValue]; - if (state == LinphoneConfiguringSuccessful) { - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneConfiguringStateUpdate - object:nil]; - [_waitingIndicator dismissWithClickedButtonIndex:0 animated:true]; - - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Success",nil) - message:NSLocalizedString(@"Remote configuration successfully fetched and applied.",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"OK",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; - [[PhoneMainView instance] startUp]; - } - if (state == LinphoneConfiguringFailed) { - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneConfiguringStateUpdate - object:nil]; - [_waitingIndicator dismissWithClickedButtonIndex:0 animated:true]; - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Failure",nil) - message:NSLocalizedString(@"Failed configuring from the specified URL." ,nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"OK",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; - } + UIAlertView *error = [[UIAlertView alloc] + initWithTitle:NSLocalizedString(@"Success", nil) + message:NSLocalizedString(@"Remote configuration successfully fetched and applied.", nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"OK", nil) + otherButtonTitles:nil]; + [error show]; + [PhoneMainView.instance startUp]; + } + if (state == LinphoneConfiguringFailed) { + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneConfiguringStateUpdate object:nil]; + [_waitingIndicator dismissWithClickedButtonIndex:0 animated:true]; + UIAlertView *error = + [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Failure", nil) + message:NSLocalizedString(@"Failed configuring from the specified URL.", nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"OK", nil) + otherButtonTitles:nil]; + [error show]; + } } - -- (void) showWaitingIndicator { - _waitingIndicator = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Fetching remote configuration...",nil) message:@"" delegate:self cancelButtonTitle:nil otherButtonTitles:nil]; - UIActivityIndicatorView *progress= [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(125, 60, 30, 30)]; - progress.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge; - if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0){ - [_waitingIndicator setValue:progress forKey:@"accessoryView"]; - [progress setColor:[UIColor blackColor]]; - } else { - [_waitingIndicator addSubview:progress]; - } - [progress startAnimating]; - [progress release]; - [_waitingIndicator show]; - +- (void)showWaitingIndicator { + _waitingIndicator = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Fetching remote configuration...", nil) + message:@"" + delegate:self + cancelButtonTitle:nil + otherButtonTitles:nil]; + UIActivityIndicatorView *progress = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(125, 60, 30, 30)]; + progress.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge; + if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) { + [_waitingIndicator setValue:progress forKey:@"accessoryView"]; + [progress setColor:[UIColor blackColor]]; + } else { + [_waitingIndicator addSubview:progress]; + } + [progress startAnimating]; + [_waitingIndicator show]; } - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((alertView.tag == 1) && (buttonIndex==1)) { - [self showWaitingIndicator]; - [self attemptRemoteConfiguration]; - } +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { + if ((alertView.tag == 1) && (buttonIndex == 1)) { + [self showWaitingIndicator]; + [self attemptRemoteConfiguration]; + } } - (void)attemptRemoteConfiguration { - [[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]; - + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(ConfigurationStateUpdateEvent:) + name:kLinphoneConfiguringStateUpdate + object:nil]; + linphone_core_set_provisioning_uri([LinphoneManager getLc], [configURL UTF8String]); + [[LinphoneManager instance] destroyLinphoneCore]; + [[LinphoneManager instance] startLinphoneCore]; } - @end diff --git a/Classes/LinphoneCoreSettingsStore.h b/Classes/LinphoneCoreSettingsStore.h index ee73e33ea..4f2331ffa 100644 --- a/Classes/LinphoneCoreSettingsStore.h +++ b/Classes/LinphoneCoreSettingsStore.h @@ -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 #import "IASKSettingsStore.h" @@ -23,12 +23,13 @@ #import "LinphoneManager.h" @interface LinphoneCoreSettingsStore : IASKAbstractSettingsStore { - @private + @public NSDictionary *dict; NSDictionary *changedDict; } -- (void)synchronizeAccount; - (void)transformLinphoneCoreToKeys; +- (void)transformAccountToKeys:(NSString *)username; +- (void)removeAccount; @end diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m index 16c3289ee..c350defc0 100644 --- a/Classes/LinphoneCoreSettingsStore.m +++ b/Classes/LinphoneCoreSettingsStore.m @@ -18,6 +18,7 @@ */ #import "LinphoneCoreSettingsStore.h" +#import "Utils.h" #include "linphone/lpconfig.h" @@ -27,207 +28,249 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); - (id)init { self = [super init]; - if (self){ + if (self) { dict = [[NSMutableDictionary alloc] init]; changedDict = [[NSMutableDictionary alloc] init]; - [self transformLinphoneCoreToKeys]; } return self; } -- (void)dealloc { - [dict release]; - [changedDict release]; - [super dealloc]; -} - -- (void)transformKeysToLinphoneCore { - //LinphoneCore *lc=[LinphoneManager getLc]; - -} - -- (void)setString:(const char*)value forKey:(NSString*)key { - id obj=Nil; - if (value) obj=[[NSString alloc] initWithCString:value encoding:[NSString defaultCStringEncoding] ]; +- (void)setCString:(const char *)value forKey:(NSString *)key { + id obj = @""; + if (value) + obj = [[NSString alloc] initWithCString:value encoding:[NSString defaultCStringEncoding]]; [self setObject:obj forKey:key]; - [obj release]; } -- (NSString*)stringForKey:(NSString*) key { - return [self objectForKey: key]; +- (NSString *)stringForKey:(NSString *)key { + return [self objectForKey:key]; } -- (void)transformCodecsToKeys: (const MSList *)codecs { - LinphoneCore *lc=[LinphoneManager getLc]; - const MSList *elem=codecs; - for(;elem!=NULL;elem=elem->next){ - PayloadType *pt=(PayloadType*)elem->data; - NSString *pref=[LinphoneManager getPreferenceForCodec:pt->mime_type withRate:pt->clock_rate]; - if (pref){ - bool_t value = linphone_core_payload_type_enabled(lc,pt); - [self setBool:value forKey: pref]; - }else{ - [LinphoneLogger logc:LinphoneLoggerWarning format:"Codec %s/%i supported by core is not shown in iOS app config view.", - pt->mime_type,pt->clock_rate]; +- (void)setObject:(id)value forKey:(NSString *)key { + [dict setValue:value forKey:key]; + [changedDict setValue:[NSNumber numberWithBool:TRUE] forKey:key]; +} + +- (id)objectForKey:(NSString *)key { + return [dict valueForKey:key]; +} + +- (BOOL)valueChangedForKey:(NSString *)key { + return [[changedDict valueForKey:key] boolValue]; +} + ++ (int)validPort:(int)port { + if (port < 0) { + return 0; + } + if (port > 65535) { + return 65535; + } + return port; +} + ++ (BOOL)parsePortRange:(NSString *)text minPort:(int *)minPort maxPort:(int *)maxPort { + NSError *error = nil; + *minPort = -1; + *maxPort = -1; + NSRegularExpression *regex = + [NSRegularExpression regularExpressionWithPattern:@"([0-9]+)(([^0-9]+)([0-9]+))?" options:0 error:&error]; + if (error != NULL) + return FALSE; + NSArray *matches = [regex matchesInString:text options:0 range:NSMakeRange(0, [text length])]; + if ([matches count] == 1) { + NSTextCheckingResult *match = [matches objectAtIndex:0]; + bool range = [match rangeAtIndex:2].length > 0; + if (!range) { + NSRange rangeMinPort = [match rangeAtIndex:1]; + *minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] intValue]]; + *maxPort = *minPort; + return TRUE; + } else { + NSRange rangeMinPort = [match rangeAtIndex:1]; + *minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] intValue]]; + NSRange rangeMaxPort = [match rangeAtIndex:4]; + *maxPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMaxPort] intValue]]; + if (*minPort > *maxPort) { + *minPort = *maxPort; + } + return TRUE; + } + } + return FALSE; +} + +- (void)transformCodecsToKeys:(const MSList *)codecs { + LinphoneCore *lc = [LinphoneManager getLc]; + + const MSList *elem = codecs; + for (; elem != NULL; elem = elem->next) { + PayloadType *pt = (PayloadType *)elem->data; + NSString *pref = [LinphoneManager getPreferenceForCodec:pt->mime_type withRate:pt->clock_rate]; + if (pref) { + bool_t value = linphone_core_payload_type_enabled(lc, pt); + [self setBool:value forKey:pref]; + } else { + LOGW(@"Codec %s/%i supported by core is not shown in iOS app config view.", pt->mime_type, pt->clock_rate); + } + } +} + +- (void)transformAccountToKeys:(NSString *)username { + LinphoneCore *lc = [LinphoneManager getLc]; + const MSList *proxies = linphone_core_get_proxy_config_list(lc); + while (username && proxies && + strcmp(username.UTF8String, + linphone_address_get_username(linphone_proxy_config_get_identity_address(proxies->data))) != 0) { + proxies = proxies->next; + } + LinphoneProxyConfig *proxy = NULL; + + // default values + { + [self setObject:@"" forKey:@"account_mandatory_username_preference"]; + [self setObject:@"" forKey:@"account_mandatory_domain_preference"]; + [self setCString:"" forKey:@"account_display_name_preference"]; + [self setObject:@"" forKey:@"account_proxy_preference"]; + [self setObject:@"udp" forKey:@"account_transport_preference"]; + [self setBool:NO forKey:@"account_outbound_proxy_preference"]; + [self setBool:NO forKey:@"account_avpf_preference"]; + [self setBool:YES forKey:@"account_is_default_preference"]; + [self setBool:YES forKey:@"account_is_enabled_preference"]; + [self setCString:"" forKey:@"account_userid_preference"]; + [self setCString:"" forKey:@"account_mandatory_password_preference"]; + [self setCString:"" forKey:@"ha1_preference"]; + [self setInteger:-1 forKey:@"account_expire_preference"]; + [self setInteger:-1 forKey:@"current_proxy_config_preference"]; + [self setCString:"" forKey:@"account_prefix_preference"]; + [self setBool:NO forKey:@"account_substitute_+_by_00_preference"]; + } + + if (proxies) { + proxy = proxies->data; + // root section + { + const LinphoneAddress *identity_addr = linphone_proxy_config_get_identity_address(proxy); + if (identity_addr) { + const char *server_addr = linphone_proxy_config_get_server_addr(proxy); + LinphoneAddress *proxy_addr = linphone_address_new(server_addr); + int port = linphone_address_get_port(proxy_addr); + + [self setCString:linphone_address_get_username(identity_addr) + forKey:@"account_mandatory_username_preference"]; + [self setCString:linphone_address_get_display_name(identity_addr) + forKey:@"account_display_name_preference"]; + [self setCString:linphone_address_get_domain(identity_addr) + forKey:@"account_mandatory_domain_preference"]; + if (strcmp(linphone_address_get_domain(identity_addr), linphone_address_get_domain(proxy_addr)) != 0 || + port > 0) { + char tmp[256] = {0}; + if (port > 0) { + snprintf(tmp, sizeof(tmp) - 1, "%s:%i", linphone_address_get_domain(proxy_addr), port); + } else + snprintf(tmp, sizeof(tmp) - 1, "%s", linphone_address_get_domain(proxy_addr)); + [self setCString:tmp forKey:@"account_proxy_preference"]; + } + const char *tname = "udp"; + switch (linphone_address_get_transport(proxy_addr)) { + case LinphoneTransportTcp: + tname = "tcp"; + break; + case LinphoneTransportTls: + tname = "tls"; + break; + default: + break; + } + linphone_address_destroy(proxy_addr); + [self setCString:tname forKey:@"account_transport_preference"]; + } + + [self setBool:(linphone_proxy_config_get_route(proxy) != NULL) forKey:@"account_outbound_proxy_preference"]; + [self setBool:linphone_proxy_config_avpf_enabled(proxy) forKey:@"account_avpf_preference"]; + [self setBool:linphone_proxy_config_register_enabled(proxy) forKey:@"account_is_enabled_preference"]; + [self setBool:(linphone_core_get_default_proxy_config(lc) == proxy) + forKey:@"account_is_default_preference"]; + + const LinphoneAuthInfo *ai = linphone_core_find_auth_info( + lc, NULL, [self stringForKey:@"account_mandatory_username_preference"].UTF8String, + [self stringForKey:@"account_mandatory_domain_preference"].UTF8String); + if (ai) { + [self setCString:linphone_auth_info_get_userid(ai) forKey:@"account_userid_preference"]; + [self setCString:linphone_auth_info_get_passwd(ai) forKey:@"account_mandatory_password_preference"]; + // hidden but useful if provisioned + [self setCString:linphone_auth_info_get_ha1(ai) forKey:@"ha1_preference"]; + } + + int idx = ms_list_index(linphone_core_get_proxy_config_list(lc), proxy); + [self setInteger:idx forKey:@"current_proxy_config_preference"]; + + int expires = linphone_proxy_config_get_expires(proxy); + [self setInteger:expires forKey:@"account_expire_preference"]; + } + + // call section + { + const char *dial_prefix = linphone_proxy_config_get_dial_prefix(proxy); + [self setCString:dial_prefix forKey:@"account_prefix_preference"]; + BOOL dial_escape_plus = linphone_proxy_config_get_dial_escape_plus(proxy); + [self setBool:dial_escape_plus forKey:@"account_substitute_+_by_00_preference"]; } } } - (void)transformLinphoneCoreToKeys { - LinphoneCore *lc=[LinphoneManager getLc]; - LinphoneProxyConfig *cfg=NULL; - LpConfig* conf = linphone_core_get_config(lc); - linphone_core_get_default_proxy(lc,&cfg); - if (cfg){ - const char *identity=linphone_proxy_config_get_identity(cfg); - LinphoneAddress *addr=linphone_address_new(identity); - if (addr){ - const char *proxy=linphone_proxy_config_get_addr(cfg); - LinphoneAddress *proxy_addr=linphone_address_new(proxy); - int port=linphone_address_get_port(proxy_addr); - - [self setString: linphone_address_get_username(addr) forKey:@"username_preference"]; - [self setString: linphone_address_get_domain(addr) forKey:@"domain_preference"]; - [self setInteger: linphone_proxy_config_get_expires(cfg) forKey:@"expire_preference"]; - [self setString: linphone_proxy_config_get_dial_prefix(cfg) forKey:@"prefix_preference"]; - if (strcmp(linphone_address_get_domain(addr),linphone_address_get_domain(proxy_addr))!=0 || port>0){ - char tmp[256]={0}; - if (port>0) { - snprintf(tmp,sizeof(tmp)-1,"%s:%i",linphone_address_get_domain(proxy_addr),port); - }else snprintf(tmp,sizeof(tmp)-1,"%s",linphone_address_get_domain(proxy_addr)); - [self setString:tmp forKey:@"proxy_preference"]; - } - - const char* tname = "udp"; - switch (linphone_address_get_transport(proxy_addr)) { - case LinphoneTransportTcp: tname = "tcp"; break; - case LinphoneTransportTls: tname = "tls"; break; - default: break; - } - [self setString:tname forKey:@"transport_preference"]; - - linphone_address_destroy(addr); - linphone_address_destroy(proxy_addr); - - [self setBool:(linphone_proxy_config_get_route(cfg)!=NULL) forKey:@"outbound_proxy_preference"]; - [self setBool:linphone_proxy_config_get_dial_escape_plus(cfg) forKey:@"substitute_+_by_00_preference"]; - [self setBool:linphone_proxy_config_avpf_enabled(cfg) forKey:@"avpf_preference"]; + LinphoneManager *lm = [LinphoneManager instance]; + LinphoneCore *lc = [LinphoneManager getLc]; + // root section + { + const MSList *accounts = linphone_core_get_proxy_config_list([LinphoneManager getLc]); + int count = ms_list_size(accounts); + for (int i = 1; i <= count; i++, accounts = accounts->next) { + NSString *key = [NSString stringWithFormat:@"menu_account_%d", i]; + LinphoneProxyConfig *proxy = (LinphoneProxyConfig *)accounts->data; + [self setCString:linphone_address_get_username(linphone_proxy_config_get_identity_address(proxy)) + forKey:key]; } - } else { - [self setInteger: lp_config_get_int(conf,"default_values","reg_expires", 600) forKey:@"expire_preference"]; - [self setObject:@"" forKey:@"username_preference"]; - [self setObject:@"" forKey:@"domain_preference"]; - [self setObject:@"" forKey:@"proxy_preference"]; - [self setObject:@"" forKey:@"password_preference"]; - [self setBool:FALSE forKey:@"outbound_proxy_preference"]; - [self setString:"udp" forKey:@"transport_preference"]; - [self setBool:FALSE forKey:@"avpf_preference"]; + [self setBool:linphone_core_video_display_enabled(lc) forKey:@"enable_video_preference"]; + [self setBool:[LinphoneManager.instance lpConfigBoolForKey:@"auto_answer"] + forKey:@"enable_auto_answer_preference"]; + [self setBool:[lm lpConfigBoolForKey:@"account_mandatory_advanced_preference"] + forKey:@"account_mandatory_advanced_preference"]; } - [self setBool:lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "pushnotification_preference", 0) forKey:@"pushnotification_preference"]; - { - LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(lc); - if(parsed != NULL) { - [self setString: linphone_address_get_display_name(parsed) forKey:@"primary_displayname_preference"]; - [self setString: linphone_address_get_username(parsed) forKey:@"primary_username_preference"]; - } - linphone_address_destroy(parsed); - } - { - { - int minPort, maxPort; - linphone_core_get_audio_port_range(lc, &minPort, &maxPort); - if(minPort != maxPort) - [self setObject:[NSString stringWithFormat:@"%d-%d", minPort, maxPort] forKey:@"audio_port_preference"]; - else - [self setObject:[NSString stringWithFormat:@"%d", minPort] forKey:@"audio_port_preference"]; - } - { - int minPort, maxPort; - linphone_core_get_video_port_range(lc, &minPort, &maxPort); - if(minPort != maxPort) - [self setObject:[NSString stringWithFormat:@"%d-%d", minPort, maxPort] forKey:@"video_port_preference"]; - else - [self setObject:[NSString stringWithFormat:@"%d", minPort] forKey:@"video_port_preference"]; - } - } - { - [self setInteger: linphone_core_get_upload_bandwidth(lc) forKey:@"upload_bandwidth_preference"]; - [self setInteger: linphone_core_get_download_bandwidth(lc) forKey:@"download_bandwidth_preference"]; - } + // account section + { [self transformAccountToKeys:nil]; } + + // audio section { + [self transformCodecsToKeys:linphone_core_get_audio_codecs(lc)]; [self setFloat:linphone_core_get_playback_gain_db(lc) forKey:@"playback_gain_preference"]; - [self setFloat:linphone_core_get_mic_gain_db(lc) forKey:@"microphone_gain_preference"]; - } - { - int port = lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "port_preference", 5060); - [self setInteger:port forKey:@"port_preference"]; - int random_port_preference = lp_config_get_int(conf,LINPHONERC_APPLICATION_KEY,"random_port_preference", 1); - [self setInteger:random_port_preference forKey:@"random_port_preference"]; - } - { - LinphoneAuthInfo *ai; - const MSList *elem=linphone_core_get_auth_info_list(lc); - if (elem && (ai=(LinphoneAuthInfo*)elem->data)){ - [self setString: linphone_auth_info_get_passwd(ai) forKey:@"password_preference"]; - [self setString: linphone_auth_info_get_ha1(ai) forKey:@"ha1_preference"]; // hidden but useful if provisioned - [self setString:linphone_auth_info_get_userid(ai) forKey:@"userid_preference"]; - } - } - { - [self setString: linphone_core_get_stun_server(lc) forKey:@"stun_preference"]; - [self setBool:linphone_core_get_firewall_policy(lc)==LinphonePolicyUseIce forKey:@"ice_preference"]; + [self setFloat:linphone_core_get_mic_gain_db(lc) forKey:@"microphone_gain_preference"]; + [self setInteger:[lm lpConfigIntForKey:@"codec_bitrate_limit" + inSection:@"audio" + withDefault:kLinphoneAudioVbrCodecDefaultBitrate] + forKey:@"audio_codec_bitrate_limit_preference"]; + [self setInteger:[lm lpConfigIntForKey:@"voiceproc_preference" withDefault:1] forKey:@"voiceproc_preference"]; + [self setInteger:[lm lpConfigIntForKey:@"eq_active" inSection:@"sound" withDefault:0] forKey:@"eq_active"]; } + // video section { - [self transformCodecsToKeys: linphone_core_get_audio_codecs(lc)]; - [self transformCodecsToKeys: linphone_core_get_video_codecs(lc)]; - [self setBool:linphone_core_adaptive_rate_control_enabled(lc) forKey:@"adaptive_rate_control_preference"]; - [self setString:linphone_core_get_adaptive_rate_algorithm(lc) forKey:@"adaptive_rate_algorithm_preference"]; - - [self setInteger:lp_config_get_int(conf, "audio", "codec_bitrate_limit", kLinphoneAudioVbrCodecDefaultBitrate) forKey:@"audio_codec_bitrate_limit_preference"]; - [self setInteger:lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "voiceproc_preference", 1) forKey:@"voiceproc_preference"]; - [self setInteger:lp_config_get_int(conf, "sound", "eq_active", 0) forKey:@"eq_active"]; - } + [self transformCodecsToKeys:linphone_core_get_video_codecs(lc)]; - [self setBool:lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "advanced_account_preference", 0) forKey:@"advanced_account_preference"]; - - { - LinphoneMediaEncryption menc=linphone_core_get_media_encryption(lc); - const char *val; - switch(menc){ - case LinphoneMediaEncryptionSRTP: val="SRTP"; break; - case LinphoneMediaEncryptionZRTP: val="ZRTP"; break; - case LinphoneMediaEncryptionDTLS: val="DTLS"; break; - case LinphoneMediaEncryptionNone: val="None"; break; - } - [self setString:val forKey:@"media_encryption_preference"]; - } - [self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "edge_opt_preference", 0) forKey:@"edge_opt_preference"]; - [self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "enable_first_login_view_preference", 0) forKey:@"enable_first_login_view_preference"]; - [self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "debugenable_preference", 0) forKey:@"debugenable_preference"]; - [self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "animations_preference", 1) forKey:@"animations_preference"]; - [self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "wifi_only_preference", 0) forKey:@"wifi_only_preference"]; - [self setString: lp_config_get_string(conf, LINPHONERC_APPLICATION_KEY, "sharing_server_preference", NULL) forKey:@"sharing_server_preference"]; - [self setBool:lp_config_get_int(conf, "sip", "use_ipv6", 0) forKey:@"use_ipv6"]; - - - [self setBool: lp_config_get_int(conf,LINPHONERC_APPLICATION_KEY,"start_at_boot_preference",1) forKey:@"start_at_boot_preference"]; - [self setBool: lp_config_get_int(conf,LINPHONERC_APPLICATION_KEY,"backgroundmode_preference",1) forKey:@"backgroundmode_preference"]; - [self setBool: lp_config_get_int(conf,LINPHONERC_APPLICATION_KEY,"autoanswer_notif_preference",1) forKey:@"autoanswer_notif_preference"]; - - - { const LinphoneVideoPolicy *pol; - [self setBool: linphone_core_video_enabled(lc) forKey:@"enable_video_preference"]; - pol=linphone_core_get_video_policy(lc); + pol = linphone_core_get_video_policy(lc); [self setBool:(pol->automatically_initiate) forKey:@"start_video_preference"]; [self setBool:(pol->automatically_accept) forKey:@"accept_video_preference"]; [self setBool:linphone_core_self_view_enabled(lc) forKey:@"self_video_preference"]; - BOOL previewEnabled=lp_config_get_int(conf,LINPHONERC_APPLICATION_KEY,"preview_preference",1); + BOOL previewEnabled = [lm lpConfigBoolForKey:@"preview_preference" withDefault:YES]; [self setBool:previewEnabled forKey:@"preview_preference"]; + + const char *preset = linphone_core_get_video_preset(lc); + [self setCString:preset ? preset : "default" forKey:@"video_preset_preference"]; MSVideoSize vsize = linphone_core_get_preferred_video_size(lc); int index; if ((vsize.width == MS_VIDEO_SIZE_720P_W) && (vsize.height == MS_VIDEO_SIZE_720P_H)) { @@ -238,31 +281,116 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); index = 2; } [self setInteger:index forKey:@"video_preferred_size_preference"]; + [self setInteger:linphone_core_get_preferred_framerate(lc) forKey:@"video_preferred_fps_preference"]; + [self setInteger:linphone_core_get_download_bandwidth(lc) forKey:@"download_bandwidth_preference"]; } + + // call section { [self setBool:linphone_core_get_use_info_for_dtmf(lc) forKey:@"sipinfo_dtmf_preference"]; [self setBool:linphone_core_get_use_rfc2833_for_dtmf(lc) forKey:@"rfc_dtmf_preference"]; [self setInteger:linphone_core_get_inc_timeout(lc) forKey:@"incoming_call_timeout_preference"]; [self setInteger:linphone_core_get_in_call_timeout(lc) forKey:@"in_call_timeout_preference"]; + + [self setBool:[lm lpConfigBoolForKey:@"repeat_call_notification"] + forKey:@"repeat_call_notification_preference"]; + NSString *ringtone = ([LinphoneManager bundleFile:[NSString stringWithUTF8String:linphone_core_get_ring(lc)]] + ?: [LinphoneManager bundleFile:@"notes_of_the_optimistic.caf"]) + .lastPathComponent; + [self setObject:ringtone forKey:@"call_ringtone_preference"]; } - // Tunnel - if (linphone_core_tunnel_available()){ + // network section + { + [self setBool:[lm lpConfigBoolForKey:@"edge_opt_preference" withDefault:NO] forKey:@"edge_opt_preference"]; + [self setBool:[lm lpConfigBoolForKey:@"wifi_only_preference" withDefault:NO] forKey:@"wifi_only_preference"]; + [self setCString:linphone_core_get_stun_server(lc) forKey:@"stun_preference"]; + [self setBool:linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce forKey:@"ice_preference"]; + int random_port_preference = [lm lpConfigIntForKey:@"random_port_preference" withDefault:1]; + [self setInteger:random_port_preference forKey:@"random_port_preference"]; + int port = [lm lpConfigIntForKey:@"port_preference" withDefault:5060]; + [self setInteger:port forKey:@"port_preference"]; + { + int minPort, maxPort; + linphone_core_get_audio_port_range(lc, &minPort, &maxPort); + if (minPort != maxPort) + [self setObject:[NSString stringWithFormat:@"%d-%d", minPort, maxPort] forKey:@"audio_port_preference"]; + else + [self setObject:[NSString stringWithFormat:@"%d", minPort] forKey:@"audio_port_preference"]; + } + { + int minPort, maxPort; + linphone_core_get_video_port_range(lc, &minPort, &maxPort); + if (minPort != maxPort) + [self setObject:[NSString stringWithFormat:@"%d-%d", minPort, maxPort] forKey:@"video_port_preference"]; + else + [self setObject:[NSString stringWithFormat:@"%d", minPort] forKey:@"video_port_preference"]; + } + [self setBool:[lm lpConfigBoolForKey:@"use_ipv6" withDefault:NO] forKey:@"use_ipv6"]; + LinphoneMediaEncryption menc = linphone_core_get_media_encryption(lc); + const char *val; + switch (menc) { + case LinphoneMediaEncryptionSRTP: + val = "SRTP"; + break; + case LinphoneMediaEncryptionZRTP: + val = "ZRTP"; + break; + case LinphoneMediaEncryptionDTLS: + val = "DTLS"; + break; + case LinphoneMediaEncryptionNone: + val = "None"; + break; + } + [self setCString:val forKey:@"media_encryption_preference"]; + [self setBool:[lm lpConfigBoolForKey:@"pushnotification_preference" withDefault:NO] + forKey:@"pushnotification_preference"]; + [self setInteger:linphone_core_get_upload_bandwidth(lc) forKey:@"upload_bandwidth_preference"]; + [self setInteger:linphone_core_get_download_bandwidth(lc) forKey:@"download_bandwidth_preference"]; + [self setBool:linphone_core_adaptive_rate_control_enabled(lc) forKey:@"adaptive_rate_control_preference"]; + } + + // tunnel section + if (linphone_core_tunnel_available()) { LinphoneTunnel *tunnel = linphone_core_get_tunnel([LinphoneManager getLc]); - [self setString:lp_config_get_string(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "tunnel_mode_preference", "off") forKey:@"tunnel_mode_preference"]; - const MSList* configs = linphone_tunnel_get_servers(tunnel); - if(configs != NULL) { + [self setObject:[lm lpConfigStringForKey:@"tunnel_mode_preference" withDefault:@"off"] + forKey:@"tunnel_mode_preference"]; + const MSList *configs = linphone_tunnel_get_servers(tunnel); + if (configs != NULL) { LinphoneTunnelConfig *ltc = (LinphoneTunnelConfig *)configs->data; - [self setString:linphone_tunnel_config_get_host(ltc) forKey:@"tunnel_address_preference"]; + [self setCString:linphone_tunnel_config_get_host(ltc) forKey:@"tunnel_address_preference"]; [self setInteger:linphone_tunnel_config_get_port(ltc) forKey:@"tunnel_port_preference"]; } else { - [self setString:"" forKey:@"tunnel_address_preference"]; + [self setCString:"" forKey:@"tunnel_address_preference"]; [self setInteger:443 forKey:@"tunnel_port_preference"]; } } - [changedDict release]; + // advanced section + { + [self setBool:[lm lpConfigBoolForKey:@"debugenable_preference" withDefault:NO] + forKey:@"debugenable_preference"]; + [self setBool:[lm lpConfigBoolForKey:@"animations_preference" withDefault:NO] forKey:@"animations_preference"]; + [self setBool:[lm lpConfigBoolForKey:@"backgroundmode_preference" withDefault:NO] + forKey:@"backgroundmode_preference"]; + [self setBool:[lm lpConfigBoolForKey:@"start_at_boot_preference" withDefault:NO] + forKey:@"start_at_boot_preference"]; + [self setBool:[lm lpConfigBoolForKey:@"autoanswer_notif_preference" withDefault:NO] + forKey:@"autoanswer_notif_preference"]; + [self setBool:[lm lpConfigBoolForKey:@"show_msg_in_notif" withDefault:YES] forKey:@"show_msg_in_notif"]; + [self setBool:[lm lpConfigBoolForKey:@"enable_first_login_view_preference" withDefault:NO] + forKey:@"enable_first_login_view_preference"]; + LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(lc); + if (parsed != NULL) { + [self setCString:linphone_address_get_display_name(parsed) forKey:@"primary_displayname_preference"]; + [self setCString:linphone_address_get_username(parsed) forKey:@"primary_username_preference"]; + } + linphone_address_destroy(parsed); + [self setCString:linphone_core_get_file_transfer_server(lc) forKey:@"file_transfer_server_url_preference"]; + } + changedDict = [[NSMutableDictionary alloc] init]; // Post event @@ -270,339 +398,281 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneLogsUpdate object:self userInfo:eventDic]; } -- (void)setObject:(id)value forKey:(NSString *)key { - [dict setValue:value forKey:key]; - [changedDict setValue:[NSNumber numberWithBool:TRUE] forKey:key]; -} - -- (id)objectForKey:(NSString*)key { - return [dict valueForKey:key]; -} - -- (BOOL)valueChangedForKey:(NSString*)key { - return [[changedDict valueForKey:key] boolValue]; -} - -- (void)alertAccountError:(NSString*)error { - UIAlertView* alertview = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil) +- (void)alertAccountError:(NSString *)error { + UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil) message:error delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", nil) - otherButtonTitles: nil]; + otherButtonTitles:nil]; [alertview show]; - [alertview release]; } -+ (BOOL)hasSipPrefix:(NSString*)str { - return [str hasPrefix:@"sip:"] || [str hasPrefix:@"sips:"]; -} - -- (void)synchronizeAccount { +- (void)synchronizeAccounts { + LOGI(@"Account changed, synchronizing."); + LinphoneManager *lm = [LinphoneManager instance]; LinphoneCore *lc = [LinphoneManager getLc]; - LpConfig* conf = linphone_core_get_config(lc); - LinphoneProxyConfig* proxyCfg = NULL; - BOOL isEditing = FALSE; - NSString* error = nil; + LinphoneProxyConfig *proxyCfg = NULL; + NSString *error = nil; int port_preference = [self integerForKey:@"port_preference"]; BOOL random_port_preference = [self boolForKey:@"random_port_preference"]; - lp_config_set_int(conf, LINPHONERC_APPLICATION_KEY, "random_port_preference", random_port_preference); - if(random_port_preference) { + [lm lpConfigSetInt:random_port_preference forKey:@"random_port_preference"]; + if (random_port_preference) { port_preference = -1; } - LCSipTransports transportValue={ port_preference, port_preference, -1, -1 }; + LCSipTransports transportValue = {port_preference, port_preference, -1, -1}; // will also update the sip_*_port section of the config if (linphone_core_set_sip_transports(lc, &transportValue)) { - [LinphoneLogger logc:LinphoneLoggerError format:"cannot set transport"]; + LOGE(@"cannot set transport"); } port_preference = linphone_core_get_sip_port(lc); [self setInteger:port_preference forKey:@"port_preference"]; // Update back preference - BOOL enable_ipv6 = [self boolForKey:@"use_ipv6"]; - lp_config_set_int(conf, "sip", "use_ipv6", enable_ipv6); - if( linphone_core_ipv6_enabled(lc) != enable_ipv6){ - [LinphoneLogger logc:LinphoneLoggerDebug format:"%@ IPV6", enable_ipv6?@"ENABLING":@"DISABLING"]; + [lm lpConfigSetBool:enable_ipv6 forKey:@"use_ipv6" inSection:@"sip"]; + if (linphone_core_ipv6_enabled(lc) != enable_ipv6) { + LOGD(@"%@ IPV6", enable_ipv6 ? @"ENABLING" : @"DISABLING"); linphone_core_enable_ipv6(lc, enable_ipv6); } + // configure sip account - //configure sip account + // mandatory parameters + NSString *username = [self stringForKey:@"account_mandatory_username_preference"]; + NSString *displayName = [self stringForKey:@"account_display_name_preference"]; + NSString *userID = [self stringForKey:@"account_userid_preference"]; + NSString *domain = [self stringForKey:@"account_mandatory_domain_preference"]; + NSString *transport = [self stringForKey:@"account_transport_preference"]; + NSString *accountHa1 = [self stringForKey:@"ha1_preference"]; + NSString *accountPassword = [self stringForKey:@"account_mandatory_password_preference"]; + BOOL isOutboundProxy = [self boolForKey:@"account_outbound_proxy_preference"]; + BOOL use_avpf = [self boolForKey:@"account_avpf_preference"]; + BOOL is_default = [self boolForKey:@"account_is_default_preference"]; + BOOL is_enabled = [self boolForKey:@"account_is_enabled_preference"]; - //mandatory parameters - NSString* username = [self stringForKey:@"username_preference"]; - NSString* userID = [self stringForKey:@"userid_preference"]; - NSString* domain = [self stringForKey:@"domain_preference"]; - NSString* transport = [self stringForKey:@"transport_preference"]; - NSString* accountHa1 = [self stringForKey:@"ha1_preference"]; - NSString* accountPassword = [self stringForKey:@"password_preference"]; - bool isOutboundProxy = [self boolForKey:@"outbound_proxy_preference"]; - BOOL use_avpf = [self boolForKey:@"avpf_preference"]; + if (username && [username length] > 0 && domain && [domain length] > 0) { + int expire = [self integerForKey:@"account_expire_preference"]; + BOOL isWifiOnly = [self boolForKey:@"wifi_only_preference"]; + BOOL pushnotification = [self boolForKey:@"pushnotification_preference"]; + NSString *prefix = [self stringForKey:@"account_prefix_preference"]; + NSString *proxyAddress = [self stringForKey:@"account_proxy_preference"]; - if (username && [username length] >0 && domain && [domain length]>0) { - int expire = [self integerForKey:@"expire_preference"]; - BOOL isWifiOnly = [self boolForKey:@"wifi_only_preference"]; - BOOL pushnotification = [self boolForKey:@"pushnotification_preference"]; - NSString* prefix = [self stringForKey:@"prefix_preference"]; - NSString* proxyAddress = [self stringForKey:@"proxy_preference"]; + const char *route = NULL; - LinphoneAuthInfo *info = NULL; - const char* route = NULL; + if (isWifiOnly && [LinphoneManager instance].connectivity == wwan) + expire = 0; - if( isWifiOnly && [LinphoneManager instance].connectivity == wwan ) expire = 0; - - if ((!proxyAddress || [proxyAddress length] <1 ) && domain) { + if ((!proxyAddress || [proxyAddress length] < 1) && domain) { proxyAddress = domain; - } - - if( ![LinphoneCoreSettingsStore hasSipPrefix:proxyAddress] ) { - proxyAddress = [NSString stringWithFormat:@"sip:%@",proxyAddress]; } - char* proxy = ms_strdup([proxyAddress cStringUsingEncoding:[NSString defaultCStringEncoding]]); - LinphoneAddress* proxy_addr = linphone_address_new(proxy); + if (![proxyAddress hasPrefix:@"sip:"] && ![proxyAddress hasPrefix:@"sips:"]) { + proxyAddress = [NSString stringWithFormat:@"sip:%@", proxyAddress]; + } - if( proxy_addr ){ + char *proxy = ms_strdup(proxyAddress.UTF8String); + LinphoneAddress *proxy_addr = linphone_address_new(proxy); + + if (proxy_addr) { LinphoneTransportType type = LinphoneTransportUdp; - if ( [transport isEqualToString:@"tcp"] ) type = LinphoneTransportTcp; - else if ( [transport isEqualToString:@"tls"] ) type = LinphoneTransportTls; + if ([transport isEqualToString:@"tcp"]) + type = LinphoneTransportTcp; + else if ([transport isEqualToString:@"tls"]) + type = LinphoneTransportTls; linphone_address_set_transport(proxy_addr, type); ms_free(proxy); proxy = linphone_address_as_string_uri_only(proxy_addr); } - // use proxy as route if outbound_proxy is enabled - route = isOutboundProxy? proxy : NULL; - - //possible valid config detected, try to modify current proxy or create new one if none existing - linphone_core_get_default_proxy(lc, &proxyCfg); - if( proxyCfg == NULL ){ - proxyCfg = linphone_core_create_proxy_config(lc); - } else { - isEditing = TRUE; - linphone_proxy_config_edit(proxyCfg); - } - char normalizedUserName[256]; - LinphoneAddress* linphoneAddress = linphone_address_new("sip:user@domain.com"); - linphone_proxy_config_normalize_number(proxyCfg, [username cStringUsingEncoding:[NSString defaultCStringEncoding]], normalizedUserName, sizeof(normalizedUserName)); + LinphoneAddress *linphoneAddress = linphone_address_new("sip:user@domain.com"); + + proxyCfg = ms_list_nth_data(linphone_core_get_proxy_config_list(lc), + [self integerForKey:@"current_proxy_config_preference"]); + // if account was deleted, it is not present anymore + if (proxyCfg == NULL) { + goto bad_proxy; + } + + linphone_proxy_config_normalize_number(proxyCfg, username.UTF8String, normalizedUserName, + sizeof(normalizedUserName)); linphone_address_set_username(linphoneAddress, normalizedUserName); - linphone_address_set_domain(linphoneAddress, [domain cStringUsingEncoding:[NSString defaultCStringEncoding]]); + linphone_address_set_domain(linphoneAddress, [domain UTF8String]); + linphone_address_set_display_name(linphoneAddress, (displayName.length ? displayName.UTF8String : NULL)); + const char *identity = linphone_address_as_string_uri_only(linphoneAddress); + const char *password = [accountPassword UTF8String]; + const char *ha1 = [accountHa1 UTF8String]; - const char* identity = linphone_address_as_string_uri_only(linphoneAddress); - const char* password = [accountPassword cStringUsingEncoding:[NSString defaultCStringEncoding]]; - const char* ha1 = [accountHa1 cStringUsingEncoding:[NSString defaultCStringEncoding]]; - - - if( linphone_proxy_config_set_identity(proxyCfg, identity) == -1 ) { error = NSLocalizedString(@"Invalid username or domain",nil); goto bad_proxy;} - if( linphone_proxy_config_set_server_addr(proxyCfg, proxy) == -1 ) { error = NSLocalizedString(@"Invalid proxy address", nil); goto bad_proxy; } - if( linphone_proxy_config_set_route(proxyCfg, route) == -1 ) { error = NSLocalizedString(@"Invalid route", nil); goto bad_proxy; } - - if ([prefix length]>0) { - linphone_proxy_config_set_dial_prefix(proxyCfg, [prefix cStringUsingEncoding:[NSString defaultCStringEncoding]]); + if (linphone_proxy_config_set_identity(proxyCfg, identity) == -1) { + error = NSLocalizedString(@"Invalid username or domain", nil); + goto bad_proxy; + } + // use proxy as route if outbound_proxy is enabled + route = isOutboundProxy ? proxy : NULL; + if (linphone_proxy_config_set_server_addr(proxyCfg, proxy) == -1) { + error = NSLocalizedString(@"Invalid proxy address", nil); + goto bad_proxy; + } + if (linphone_proxy_config_set_route(proxyCfg, route) == -1) { + error = NSLocalizedString(@"Invalid route", nil); + goto bad_proxy; } - if ([self objectForKey:@"substitute_+_by_00_preference"]) { - bool substitute_plus_by_00 = [self boolForKey:@"substitute_+_by_00_preference"]; - linphone_proxy_config_set_dial_escape_plus(proxyCfg,substitute_plus_by_00); + if ([prefix length] > 0) { + linphone_proxy_config_set_dial_prefix(proxyCfg, [prefix UTF8String]); } - lp_config_set_int(conf, LINPHONERC_APPLICATION_KEY, "pushnotification_preference", pushnotification); + if ([self objectForKey:@"account_substitute_+_by_00_preference"]) { + bool substitute_plus_by_00 = [self boolForKey:@"account_substitute_+_by_00_preference"]; + linphone_proxy_config_set_dial_escape_plus(proxyCfg, substitute_plus_by_00); + } + + [lm lpConfigSetInt:pushnotification forKey:@"pushnotification_preference"]; [[LinphoneManager instance] configurePushTokenForProxyConfig:proxyCfg]; - linphone_proxy_config_enable_register(proxyCfg, true); + linphone_proxy_config_enable_register(proxyCfg, is_enabled); linphone_proxy_config_enable_avpf(proxyCfg, use_avpf); linphone_proxy_config_set_expires(proxyCfg, expire); - - // setup auth info - LinphoneAddress *from = linphone_address_new(identity); - if (from != 0){ - const char* userid_str = (userID != nil)? [userID UTF8String] : NULL; - info=linphone_auth_info_new(linphone_address_get_username(from),userid_str,password,ha1,NULL,linphone_proxy_config_get_domain(proxyCfg)); - linphone_address_destroy(from); + if (is_default) { + linphone_core_set_default_proxy_config(lc, proxyCfg); + } else if (linphone_core_get_default_proxy_config(lc) == proxyCfg) { + linphone_core_set_default_proxy_config(lc, NULL); } - // We reached here without hitting the goto: the new settings are correct, so replace the previous ones. - - // add auth info - linphone_core_clear_all_auth_info(lc); - if( info ) { linphone_core_add_auth_info(lc,info); } + LinphoneAuthInfo *proxyAi = (LinphoneAuthInfo *)linphone_proxy_config_find_auth_info(proxyCfg); // setup new proxycfg - if( isEditing ){ - linphone_proxy_config_done(proxyCfg); - } else { - // was a new proxy config, add it - linphone_core_add_proxy_config(lc, proxyCfg); - linphone_core_set_default_proxy_config(lc,proxyCfg); + linphone_proxy_config_done(proxyCfg); + + // modify auth info only after finishing editting the proxy config, so that + // UNREGISTER succeed + if (proxyAi) { + linphone_core_remove_auth_info(lc, proxyAi); + } + LinphoneAddress *from = linphone_address_new(identity); + if (from) { + const char *userid_str = (userID != nil) ? [userID UTF8String] : NULL; + LinphoneAuthInfo *info = linphone_auth_info_new( + linphone_address_get_username(from), userid_str, password ? password : NULL, password ? NULL : ha1, + linphone_proxy_config_get_realm(proxyCfg), linphone_proxy_config_get_domain(proxyCfg)); + linphone_address_destroy(from); + linphone_core_add_auth_info(lc, info); + linphone_auth_info_destroy(info); } bad_proxy: - if( linphoneAddress) + if (linphoneAddress) linphone_address_destroy(linphoneAddress); - if( proxy) + if (proxy) ms_free(proxy); - if( info ) - linphone_auth_info_destroy(info); // in case of error, show an alert to the user - if( error != nil ){ - if( isEditing ) linphone_proxy_config_done(proxyCfg); - else linphone_proxy_config_destroy(proxyCfg); + if (error != nil) { + linphone_proxy_config_done(proxyCfg); - [self alertAccountError:error]; + [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil) + message:error + delegate:nil + cancelButtonTitle:NSLocalizedString(@"OK", nil) + otherButtonTitles:nil] show]; } } + // reload address book to prepend proxy config domain to contacts' phone number [[[LinphoneManager instance] fastAddressBook] reload]; } -+ (int)validPort:(int)port { - if(port < 0) { - return 0; - } - if(port > 65535) { - return 65535; - } - return port; -} - -+ (BOOL)parsePortRange:(NSString*)text minPort:(int*)minPort maxPort:(int*)maxPort { - NSError* error = nil; - *minPort = -1; - *maxPort = -1; - NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"([0-9]+)(([^0-9]+)([0-9]+))?" options:0 error:&error]; - if(error != NULL) - return FALSE; - NSArray* matches = [regex matchesInString:text options:0 range:NSMakeRange(0, [text length])]; - if([matches count] == 1) { - NSTextCheckingResult *match = [matches objectAtIndex:0]; - bool range = [match rangeAtIndex:2].length > 0; - if(!range) { - NSRange rangeMinPort = [match rangeAtIndex:1]; - *minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] intValue]]; - *maxPort = *minPort; - return TRUE; - } else { - NSRange rangeMinPort = [match rangeAtIndex:1]; - *minPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMinPort] intValue]]; - NSRange rangeMaxPort = [match rangeAtIndex:4]; - *maxPort = [LinphoneCoreSettingsStore validPort:[[text substringWithRange:rangeMaxPort] intValue]]; - if(*minPort > *maxPort) { - *minPort = *maxPort; - } - return TRUE; - } - } - return FALSE; -} - -- (BOOL)synchronize { - LinphoneCore *lc=[LinphoneManager getLc]; - - BOOL account_changed; - - account_changed=[self valueChangedForKey:@"username_preference"] - || [self valueChangedForKey:@"password_preference"] - || [self valueChangedForKey:@"domain_preference"] - || [self valueChangedForKey:@"expire_preference"] - || [self valueChangedForKey:@"proxy_preference"] - || [self valueChangedForKey:@"outbound_proxy_preference"] - || [self valueChangedForKey:@"transport_preference"] - || [self valueChangedForKey:@"port_preference"] - || [self valueChangedForKey:@"random_port_preference"] - || [self valueChangedForKey:@"prefix_preference"] - || [self valueChangedForKey:@"substitute_+_by_00_preference"] - || [self valueChangedForKey:@"use_ipv6"] - || [self valueChangedForKey:@"avpf_preference"] - || [self valueChangedForKey:@"pushnotification_preference"]; - - if (account_changed) - [self synchronizeAccount]; - - //Configure Codecs - +- (void)synchronizeCodecs:(const MSList *)codecs { + LinphoneCore *lc = [LinphoneManager getLc]; PayloadType *pt; const MSList *elem; - for (elem=linphone_core_get_audio_codecs(lc);elem!=NULL;elem=elem->next){ - pt=(PayloadType*)elem->data; - NSString *pref=[LinphoneManager getPreferenceForCodec:pt->mime_type withRate:pt->clock_rate]; - linphone_core_enable_payload_type(lc,pt,[self boolForKey: pref]); + for (elem = codecs; elem != NULL; elem = elem->next) { + pt = (PayloadType *)elem->data; + NSString *pref = [LinphoneManager getPreferenceForCodec:pt->mime_type withRate:pt->clock_rate]; + linphone_core_enable_payload_type(lc, pt, [self boolForKey:pref]); } +} - for (elem=linphone_core_get_video_codecs(lc);elem!=NULL;elem=elem->next){ - pt=(PayloadType*)elem->data; - NSString *pref=[LinphoneManager getPreferenceForCodec:pt->mime_type withRate:pt->clock_rate]; - linphone_core_enable_payload_type(lc,pt,[self boolForKey: pref]); - } - - LpConfig *config = linphone_core_get_config(lc); - lp_config_set_int(config, "audio", "codec_bitrate_limit", [self integerForKey:@"audio_codec_bitrate_limit_preference"]); - [[LinphoneManager instance] configureVbrCodecs]; - linphone_core_enable_adaptive_rate_control(lc, [self boolForKey:@"adaptive_rate_control_preference"]); - linphone_core_set_adaptive_rate_algorithm(lc, [ - [self stringForKey:@"adaptive_rate_algorithm_preference"] cStringUsingEncoding:[NSString defaultCStringEncoding] - ]); - - // Voice processing - BOOL voice_processing = [self boolForKey:@"voiceproc_preference"]; - lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "voiceproc_preference", voice_processing); - NSString* au_device = @"AU: Audio Unit Receiver"; - if( !voice_processing ){ au_device = @"AU: Audio Unit NoVoiceProc"; } - linphone_core_set_capture_device(lc, [au_device UTF8String]); - linphone_core_set_playback_device(lc, [au_device UTF8String]); - - BOOL equalizer = [self boolForKey:@"eq_active"]; - lp_config_set_int(config, "sound", "eq_active", equalizer); - - linphone_core_set_use_info_for_dtmf(lc, [self boolForKey:@"sipinfo_dtmf_preference"]); - linphone_core_set_use_rfc2833_for_dtmf(lc, [self boolForKey:@"rfc_dtmf_preference"]); - linphone_core_set_inc_timeout(lc, [self integerForKey:@"incoming_call_timeout_preference"]); - linphone_core_set_in_call_timeout(lc, [self integerForKey:@"in_call_timeout_preference"]); - lp_config_set_string(config, "app", "voice_mail_uri", [[self stringForKey:@"voice_mail_uri_preference"] UTF8String]); - - bool enableVideo = [self boolForKey:@"enable_video_preference"]; - linphone_core_enable_video(lc, enableVideo, enableVideo); - - NSString *menc = [self stringForKey:@"media_encryption_preference"]; - if (menc && [menc compare:@"SRTP"] == NSOrderedSame) - linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionSRTP); - else if (menc && [menc compare:@"ZRTP"] == NSOrderedSame) - linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionZRTP); - else if (menc && [menc compare:@"DTLS"] == NSOrderedSame) - linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionDTLS); - else - linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionNone); - - NSString* stun_server = [self stringForKey:@"stun_preference"]; - if ([stun_server length] > 0){ - linphone_core_set_stun_server(lc, [stun_server UTF8String]); - BOOL ice_preference = [self boolForKey:@"ice_preference"]; - if(ice_preference) { - linphone_core_set_firewall_policy(lc, LinphonePolicyUseIce); - } else { - linphone_core_set_firewall_policy(lc, LinphonePolicyUseStun); +- (BOOL)synchronize { + LinphoneManager *lm = [LinphoneManager instance]; + LinphoneCore *lc = [LinphoneManager getLc]; + // root section + { + BOOL account_changed = NO; + for (NSString *key in self->changedDict) { + if ([key hasPrefix:@"account_"] && [self valueChangedForKey:key]) { + account_changed = YES; + break; + } } - } else { - linphone_core_set_stun_server(lc, NULL); - linphone_core_set_firewall_policy(lc, LinphonePolicyNoFirewall); + account_changed |= [self valueChangedForKey:@"port_preference"]; + account_changed |= [self valueChangedForKey:@"random_port_preference"]; + account_changed |= [self valueChangedForKey:@"use_ipv6"]; + account_changed |= [self valueChangedForKey:@"pushnotification_preference"]; + + if (account_changed) + [self synchronizeAccounts]; + + bool enableVideo = [self boolForKey:@"enable_video_preference"]; + linphone_core_enable_video_capture(lc, enableVideo); + linphone_core_enable_video_display(lc, enableVideo); + + bool enableAutoAnswer = [self boolForKey:@"enable_auto_answer_preference"]; + [LinphoneManager.instance lpConfigSetBool:enableAutoAnswer forKey:@"auto_answer"]; } - LinphoneVideoPolicy policy; - policy.automatically_accept = [self boolForKey:@"accept_video_preference"]; - policy.automatically_initiate = [self boolForKey:@"start_video_preference"]; - linphone_core_set_video_policy(lc, &policy); - linphone_core_enable_self_view(lc, [self boolForKey:@"self_video_preference"]); - BOOL preview_preference=[self boolForKey:@"preview_preference"]; - lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "preview_preference", preview_preference); - MSVideoSize vsize; - int bw; - switch ([self integerForKey:@"video_preferred_size_preference"]) { + // audio section + { + [self synchronizeCodecs:linphone_core_get_audio_codecs(lc)]; + + float playback_gain = [self floatForKey:@"playback_gain_preference"]; + linphone_core_set_playback_gain_db(lc, playback_gain); + + float mic_gain = [self floatForKey:@"microphone_gain_preference"]; + linphone_core_set_mic_gain_db(lc, mic_gain); + + [lm lpConfigSetInt:[self integerForKey:@"audio_codec_bitrate_limit_preference"] + forKey:@"codec_bitrate_limit" + inSection:@"audio"]; + + BOOL voice_processing = [self boolForKey:@"voiceproc_preference"]; + [lm lpConfigSetInt:voice_processing forKey:@"voiceproc_preference"]; + + BOOL equalizer = [self boolForKey:@"eq_active"]; + [lm lpConfigSetBool:equalizer forKey:@"eq_active" inSection:@"sound"]; + + [[LinphoneManager instance] configureVbrCodecs]; + + NSString *au_device = @"AU: Audio Unit Receiver"; + if (!voice_processing) { + au_device = @"AU: Audio Unit NoVoiceProc"; + } + linphone_core_set_capture_device(lc, [au_device UTF8String]); + linphone_core_set_playback_device(lc, [au_device UTF8String]); + } + + // video section + { + [self synchronizeCodecs:linphone_core_get_video_codecs(lc)]; + + LinphoneVideoPolicy policy; + policy.automatically_initiate = [self boolForKey:@"start_video_preference"]; + policy.automatically_accept = [self boolForKey:@"accept_video_preference"]; + linphone_core_set_video_policy(lc, &policy); + linphone_core_enable_self_view(lc, [self boolForKey:@"self_video_preference"]); + BOOL preview_preference = [self boolForKey:@"preview_preference"]; + [lm lpConfigSetInt:preview_preference forKey:@"preview_preference"]; + + NSString *videoPreset = [self stringForKey:@"video_preset_preference"]; + linphone_core_set_video_preset(lc, [videoPreset UTF8String]); + int bw; + MSVideoSize vsize; + switch ([self integerForKey:@"video_preferred_size_preference"]) { case 0: MS_VIDEO_SIZE_ASSIGN(vsize, 720P); // 128 = margin for audio, the BW includes both video and audio @@ -612,134 +682,167 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); MS_VIDEO_SIZE_ASSIGN(vsize, VGA); // no margin for VGA or QVGA, because video encoders can encode the // target resulution in less than the asked bandwidth - bw = 512; + bw = 660; break; case 2: default: MS_VIDEO_SIZE_ASSIGN(vsize, QVGA); bw = 380; break; - } - linphone_core_set_preferred_video_size(lc, vsize); - [self setInteger: bw forKey:@"upload_bandwidth_preference"]; - [self setInteger: bw forKey:@"download_bandwidth_preference"]; - - // Primary contact - NSString* displayname = [self stringForKey:@"primary_displayname_preference"]; - NSString* username = [self stringForKey:@"primary_username_preference"]; - LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(lc); - if(parsed != NULL) { - linphone_address_set_display_name(parsed,[displayname cStringUsingEncoding:[NSString defaultCStringEncoding]]); - linphone_address_set_username(parsed,[username cStringUsingEncoding:[NSString defaultCStringEncoding]]); - char *contact = linphone_address_as_string(parsed); - linphone_core_set_primary_contact(lc, contact); - ms_free(contact); - linphone_address_destroy(parsed); + } + linphone_core_set_preferred_video_size(lc, vsize); + if (![videoPreset isEqualToString:@"custom"]) { + [self setInteger:0 forKey:@"video_preferred_fps_preference"]; + [self setInteger:bw forKey:@"download_bandwidth_preference"]; + } + linphone_core_set_preferred_framerate(lc, [self integerForKey:@"video_preferred_fps_preference"]); + linphone_core_set_download_bandwidth(lc, [self integerForKey:@"download_bandwidth_preference"]); + linphone_core_set_upload_bandwidth(lc, [self integerForKey:@"download_bandwidth_preference"]); } - - // Audio & Video Port + // call section { - NSString *audio_port_preference = [self stringForKey:@"audio_port_preference"]; - int minPort, maxPort; - [LinphoneCoreSettingsStore parsePortRange:audio_port_preference minPort:&minPort maxPort:&maxPort]; - linphone_core_set_audio_port_range(lc, minPort, maxPort); + linphone_core_set_use_rfc2833_for_dtmf(lc, [self boolForKey:@"rfc_dtmf_preference"]); + linphone_core_set_use_info_for_dtmf(lc, [self boolForKey:@"sipinfo_dtmf_preference"]); + linphone_core_set_inc_timeout(lc, [self integerForKey:@"incoming_call_timeout_preference"]); + linphone_core_set_in_call_timeout(lc, [self integerForKey:@"in_call_timeout_preference"]); + [lm lpConfigSetString:[self stringForKey:@"voice_mail_uri_preference"] forKey:@"voice_mail_uri"]; + [lm lpConfigSetBool:[self boolForKey:@"repeat_call_notification_preference"] + forKey:@"repeat_call_notification"]; + NSString *ringtone = [LinphoneManager bundleFile:[self objectForKey:@"call_ringtone_preference"]]; + linphone_core_set_ring(lc, ringtone.UTF8String); } + + // network section { - NSString *video_port_preference = [self stringForKey:@"video_port_preference"]; - int minPort, maxPort; - [LinphoneCoreSettingsStore parsePortRange:video_port_preference minPort:&minPort maxPort:&maxPort]; - linphone_core_set_video_port_range(lc, minPort, maxPort); - } + BOOL edgeOpt = [self boolForKey:@"edge_opt_preference"]; + [lm lpConfigSetInt:edgeOpt forKey:@"edge_opt_preference"]; - int upload_bandwidth = [self integerForKey:@"upload_bandwidth_preference"]; - linphone_core_set_upload_bandwidth(lc, upload_bandwidth); - - int download_bandwidth = [self integerForKey:@"download_bandwidth_preference"]; - linphone_core_set_download_bandwidth(lc, download_bandwidth); - - float playback_gain = [self floatForKey:@"playback_gain_preference"]; - linphone_core_set_playback_gain_db(lc, playback_gain); - - float mic_gain = [self floatForKey:@"microphone_gain_preference"]; - linphone_core_set_mic_gain_db(lc, mic_gain); - - UIDevice* device = [UIDevice currentDevice]; - bool backgroundSupported = false; - if ([device respondsToSelector:@selector(isMultitaskingSupported)]) - backgroundSupported = [device isMultitaskingSupported]; - BOOL isbackgroundModeEnabled; - if (backgroundSupported) { - isbackgroundModeEnabled = [self boolForKey:@"backgroundmode_preference"]; - } else { - isbackgroundModeEnabled = false; - } - - lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "backgroundmode_preference", isbackgroundModeEnabled); - lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "start_at_boot_preference", [self boolForKey:@"start_at_boot_preference"]); - lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "autoanswer_notif_preference", [self boolForKey:@"autoanswer_notif_preference"]); - lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "advanced_account_preference", [self boolForKey:@"advanced_account_preference"]); - - BOOL firstloginview = [self boolForKey:@"enable_first_login_view_preference"]; - lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "enable_first_login_view_preference", firstloginview); - - BOOL edgeOpt = [self boolForKey:@"edge_opt_preference"]; - lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "edge_opt_preference", edgeOpt); - - BOOL debugmode = [self boolForKey:@"debugenable_preference"]; - lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "debugenable_preference", debugmode); - [[LinphoneManager instance] setLogsEnabled:debugmode]; - - BOOL animations = [self boolForKey:@"animations_preference"]; - lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "animations_preference", animations); - - BOOL wifiOnly = [self boolForKey:@"wifi_only_preference"]; - lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "wifi_only_preference", wifiOnly); - if([self valueChangedForKey:@"wifi_only_preference"]) { - [[LinphoneManager instance] setupNetworkReachabilityCallback]; - } - - NSString* sharing_server = [self stringForKey:@"sharing_server_preference"]; - [[LinphoneManager instance] lpConfigSetString:sharing_server forKey:@"sharing_server_preference"]; - - - //Tunnel - if (linphone_core_tunnel_available()){ - NSString* lTunnelPrefMode = [self stringForKey:@"tunnel_mode_preference"]; - NSString* lTunnelPrefAddress = [self stringForKey:@"tunnel_address_preference"]; - int lTunnelPrefPort = [self integerForKey:@"tunnel_port_preference"]; - LinphoneTunnel *tunnel = linphone_core_get_tunnel([LinphoneManager getLc]); - TunnelMode mode = tunnel_off; - int lTunnelPort = 443; - if (lTunnelPrefPort) { - lTunnelPort = lTunnelPrefPort; + BOOL wifiOnly = [self boolForKey:@"wifi_only_preference"]; + [lm lpConfigSetInt:wifiOnly forKey:@"wifi_only_preference"]; + if ([self valueChangedForKey:@"wifi_only_preference"]) { + [[LinphoneManager instance] setupNetworkReachabilityCallback]; } - linphone_tunnel_clean_servers(tunnel); - if (lTunnelPrefAddress && [lTunnelPrefAddress length]) { - LinphoneTunnelConfig *ltc = linphone_tunnel_config_new(); - linphone_tunnel_config_set_host(ltc, [lTunnelPrefAddress UTF8String]); - linphone_tunnel_config_set_port(ltc, lTunnelPort); - linphone_tunnel_add_server(tunnel, ltc); - - if ([lTunnelPrefMode isEqualToString:@"off"]) { - mode = tunnel_off; - } else if ([lTunnelPrefMode isEqualToString:@"on"]) { - mode = tunnel_on; - } else if ([lTunnelPrefMode isEqualToString:@"wwan"]) { - mode = tunnel_wwan; - } else if ([lTunnelPrefMode isEqualToString:@"auto"]) { - mode = tunnel_auto; + NSString *stun_server = [self stringForKey:@"stun_preference"]; + if ([stun_server length] > 0) { + linphone_core_set_stun_server(lc, [stun_server UTF8String]); + BOOL ice_preference = [self boolForKey:@"ice_preference"]; + if (ice_preference) { + linphone_core_set_firewall_policy(lc, LinphonePolicyUseIce); } else { - [LinphoneLogger logc:LinphoneLoggerError format:"Unexpected tunnel mode [%s]",[lTunnelPrefMode cStringUsingEncoding:[NSString defaultCStringEncoding]]]; + linphone_core_set_firewall_policy(lc, LinphonePolicyUseStun); } + } else { + linphone_core_set_stun_server(lc, NULL); + linphone_core_set_firewall_policy(lc, LinphonePolicyNoFirewall); } - lp_config_set_string(linphone_core_get_config(lc), LINPHONERC_APPLICATION_KEY, "tunnel_mode_preference", [lTunnelPrefMode UTF8String]); - [[LinphoneManager instance] setTunnelMode:mode]; + { + NSString *audio_port_preference = [self stringForKey:@"audio_port_preference"]; + int minPort, maxPort; + [LinphoneCoreSettingsStore parsePortRange:audio_port_preference minPort:&minPort maxPort:&maxPort]; + linphone_core_set_audio_port_range(lc, minPort, maxPort); + } + { + NSString *video_port_preference = [self stringForKey:@"video_port_preference"]; + int minPort, maxPort; + [LinphoneCoreSettingsStore parsePortRange:video_port_preference minPort:&minPort maxPort:&maxPort]; + linphone_core_set_video_port_range(lc, minPort, maxPort); + } + + NSString *menc = [self stringForKey:@"media_encryption_preference"]; + if (menc && [menc compare:@"SRTP"] == NSOrderedSame) + linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionSRTP); + else if (menc && [menc compare:@"ZRTP"] == NSOrderedSame) + linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionZRTP); + else if (menc && [menc compare:@"DTLS"] == NSOrderedSame) + linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionDTLS); + else + linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionNone); + + linphone_core_enable_adaptive_rate_control(lc, [self boolForKey:@"adaptive_rate_control_preference"]); + } + + // tunnel section + { + if (linphone_core_tunnel_available()) { + NSString *lTunnelPrefMode = [self stringForKey:@"tunnel_mode_preference"]; + NSString *lTunnelPrefAddress = [self stringForKey:@"tunnel_address_preference"]; + int lTunnelPrefPort = [self integerForKey:@"tunnel_port_preference"]; + LinphoneTunnel *tunnel = linphone_core_get_tunnel([LinphoneManager getLc]); + TunnelMode mode = tunnel_off; + int lTunnelPort = 443; + if (lTunnelPrefPort) { + lTunnelPort = lTunnelPrefPort; + } + + linphone_tunnel_clean_servers(tunnel); + if (lTunnelPrefAddress && [lTunnelPrefAddress length]) { + LinphoneTunnelConfig *ltc = linphone_tunnel_config_new(); + linphone_tunnel_config_set_host(ltc, [lTunnelPrefAddress UTF8String]); + linphone_tunnel_config_set_port(ltc, lTunnelPort); + linphone_tunnel_add_server(tunnel, ltc); + + if ([lTunnelPrefMode isEqualToString:@"off"]) { + mode = tunnel_off; + } else if ([lTunnelPrefMode isEqualToString:@"on"]) { + mode = tunnel_on; + } else if ([lTunnelPrefMode isEqualToString:@"wwan"]) { + mode = tunnel_wwan; + } else if ([lTunnelPrefMode isEqualToString:@"auto"]) { + mode = tunnel_auto; + } else { + LOGE(@"Unexpected tunnel mode [%s]", [lTunnelPrefMode UTF8String]); + } + } + + [lm lpConfigSetString:lTunnelPrefMode forKey:@"tunnel_mode_preference"]; + [[LinphoneManager instance] setTunnelMode:mode]; + } + } + + // advanced section + { + BOOL debugmode = [self boolForKey:@"debugenable_preference"]; + [lm lpConfigSetInt:debugmode forKey:@"debugenable_preference"]; + [[LinphoneManager instance] setLogsEnabled:debugmode]; + + BOOL animations = [self boolForKey:@"animations_preference"]; + [lm lpConfigSetInt:animations forKey:@"animations_preference"]; + + UIDevice *device = [UIDevice currentDevice]; + bool backgroundSupported = + [device respondsToSelector:@selector(isMultitaskingSupported)] && [device isMultitaskingSupported]; + BOOL isbackgroundModeEnabled = backgroundSupported && [self boolForKey:@"backgroundmode_preference"]; + [lm lpConfigSetInt:isbackgroundModeEnabled forKey:@"backgroundmode_preference"]; + + [lm lpConfigSetInt:[self integerForKey:@"start_at_boot_preference"] forKey:@"start_at_boot_preference"]; + [lm lpConfigSetInt:[self integerForKey:@"autoanswer_notif_preference"] forKey:@"autoanswer_notif_preference"]; + [lm lpConfigSetInt:[self integerForKey:@"show_msg_in_notif"] forKey:@"show_msg_in_notif"]; + + BOOL firstloginview = [self boolForKey:@"enable_first_login_view_preference"]; + [lm lpConfigSetInt:firstloginview forKey:@"enable_first_login_view_preference"]; + + NSString *displayname = [self stringForKey:@"primary_displayname_preference"]; + NSString *username = [self stringForKey:@"primary_username_preference"]; + LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(lc); + if (parsed != NULL) { + linphone_address_set_display_name(parsed, [displayname UTF8String]); + linphone_address_set_username(parsed, [username UTF8String]); + char *contact = linphone_address_as_string(parsed); + linphone_core_set_primary_contact(lc, contact); + ms_free(contact); + linphone_address_destroy(parsed); + } + + [lm lpConfigSetInt:[self integerForKey:@"account_mandatory_advanced_preference"] + forKey:@"account_mandatory_advanced_preference"]; + + linphone_core_set_file_transfer_server(lc, + [[self stringForKey:@"file_transfer_server_url_preference"] UTF8String]); } - [changedDict release]; changedDict = [[NSMutableDictionary alloc] init]; // Post event @@ -749,4 +852,26 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); return YES; } +- (void)removeAccount { + LinphoneCore *lc = [LinphoneManager getLc]; + LinphoneProxyConfig *config = ms_list_nth_data(linphone_core_get_proxy_config_list(lc), + [self integerForKey:@"current_proxy_config_preference"]); + + BOOL isDefault = (linphone_core_get_default_proxy_config(lc) == config); + + const LinphoneAuthInfo *ai = linphone_proxy_config_find_auth_info(config); + linphone_core_remove_proxy_config(lc, config); + if (ai) { + linphone_core_remove_auth_info(lc, ai); + } + [self setInteger:-1 forKey:@"current_proxy_config_preference"]; + + if (isDefault) { + // if we removed the default proxy config, set another one instead + if (linphone_core_get_proxy_config_list(lc) != NULL) { + linphone_core_set_default_proxy_index(lc, 0); + } + } + [self transformLinphoneCoreToKeys]; +} @end diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index daa3c4779..ba7a45232 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -30,16 +30,16 @@ #import "IASKSettingsStore.h" #import "IASKAppSettingsViewController.h" #import "FastAddressBook.h" -#import "Utils.h" +#import "InAppProductsManager.h" #include "linphone/linphonecore.h" #include "linphone/linphone_tunnel.h" -extern const char *const LINPHONERC_APPLICATION_KEY; +extern NSString *const LINPHONERC_APPLICATION_KEY; extern NSString *const kLinphoneCoreUpdate; extern NSString *const kLinphoneDisplayStatusUpdate; -extern NSString *const kLinphoneTextReceived; +extern NSString *const kLinphoneMessageReceived; extern NSString *const kLinphoneTextComposeEvent; extern NSString *const kLinphoneCallUpdate; extern NSString *const kLinphoneRegistrationUpdate; @@ -51,6 +51,9 @@ extern NSString *const kLinphoneBluetoothAvailabilityUpdate; extern NSString *const kLinphoneConfiguringStateUpdate; extern NSString *const kLinphoneGlobalStateUpdate; extern NSString *const kLinphoneNotifyReceived; +extern NSString *const kLinphoneCallEncryptionChanged; +extern NSString *const kLinphoneFileTransferSendUpdate; +extern NSString *const kLinphoneFileTransferRecvUpdate; typedef enum _NetworkType { network_none = 0, @@ -104,7 +107,7 @@ typedef struct _LinphoneManagerSounds { @interface LinphoneManager : NSObject { @protected SCNetworkReachabilityRef proxyReachability; - + @private NSTimer* mIterateTimer; NSMutableArray* pushCallIDs; @@ -121,7 +124,6 @@ typedef struct _LinphoneManagerSounds { + (void)instanceRelease; #endif + (LinphoneCore*) getLc; -+ (BOOL)isLcReady; + (BOOL)runningOnIpad; + (BOOL)isNotIphone3G; + (NSString *)getPreferenceForCodec: (const char*) name withRate: (int) rate; @@ -132,8 +134,8 @@ typedef struct _LinphoneManagerSounds { - (void)playMessageSound; - (void)resetLinphoneCore; -- (void)startLibLinphone; -- (void)destroyLibLinphone; +- (void)startLinphoneCore; +- (void)destroyLinphoneCore; - (BOOL)resignActive; - (void)becomeActive; - (BOOL)enterBackgroundMode; @@ -159,7 +161,7 @@ typedef struct _LinphoneManagerSounds { + (NSString*)documentFile:(NSString*)file; + (NSString*)cacheDirectory; -- (void)acceptCall:(LinphoneCall *)call; +- (void)acceptCall:(LinphoneCall *)call evenWithVideo:(BOOL)video; - (void)call:(NSString *)address displayName:(NSString*)displayName transfer:(BOOL)transfer; @@ -167,29 +169,41 @@ typedef struct _LinphoneManagerSounds { +(void)setValueInMessageAppData:(id)value forKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg; - (void)lpConfigSetString:(NSString*)value forKey:(NSString*)key; -- (NSString*)lpConfigStringForKey:(NSString*)key; -- (NSString*)lpConfigStringForKey:(NSString*)key withDefault:(NSString*)value; -- (void)lpConfigSetString:(NSString*)value forKey:(NSString*)key forSection:(NSString*)section; -- (NSString*)lpConfigStringForKey:(NSString*)key forSection:(NSString*)section; -- (void)lpConfigSetInt:(NSInteger)value forKey:(NSString*)key; -- (NSInteger)lpConfigIntForKey:(NSString*)key; -- (void)lpConfigSetInt:(NSInteger)value forKey:(NSString*)key forSection:(NSString*)section; -- (NSInteger)lpConfigIntForKey:(NSString*)key forSection:(NSString*)section; +- (void)lpConfigSetString:(NSString *)value forKey:(NSString *)key inSection:(NSString *)section; +- (NSString *)lpConfigStringForKey:(NSString *)key; +- (NSString *)lpConfigStringForKey:(NSString *)key inSection:(NSString *)section; +- (NSString *)lpConfigStringForKey:(NSString *)key withDefault:(NSString *)value; +- (NSString *)lpConfigStringForKey:(NSString *)key inSection:(NSString *)section withDefault:(NSString *)value; + +- (void)lpConfigSetInt:(int)value forKey:(NSString *)key; +- (void)lpConfigSetInt:(int)value forKey:(NSString *)key inSection:(NSString *)section; +- (int)lpConfigIntForKey:(NSString *)key; +- (int)lpConfigIntForKey:(NSString *)key inSection:(NSString *)section; +- (int)lpConfigIntForKey:(NSString *)key withDefault:(int)value; +- (int)lpConfigIntForKey:(NSString *)key inSection:(NSString *)section withDefault:(int)value; + - (void)lpConfigSetBool:(BOOL)value forKey:(NSString*)key; -- (BOOL)lpConfigBoolForKey:(NSString*)key; -- (void)lpConfigSetBool:(BOOL)value forKey:(NSString*)key forSection:(NSString*)section; -- (BOOL)lpConfigBoolForKey:(NSString*)key forSection:(NSString*)section; +- (void)lpConfigSetBool:(BOOL)value forKey:(NSString *)key inSection:(NSString *)section; +- (BOOL)lpConfigBoolForKey:(NSString *)key; +- (BOOL)lpConfigBoolForKey:(NSString *)key inSection:(NSString *)section; +- (BOOL)lpConfigBoolForKey:(NSString *)key withDefault:(BOOL)value; +- (BOOL)lpConfigBoolForKey:(NSString *)key inSection:(NSString *)section withDefault:(BOOL)value; + - (void)silentPushFailed:(NSTimer*)timer; +- (void)removeAllAccounts; + ++ (BOOL)isMyself:(const LinphoneAddress *)addr; + @property (readonly) BOOL isTesting; -@property (readonly) FastAddressBook* fastAddressBook; +@property(readonly, strong) FastAddressBook *fastAddressBook; @property Connectivity connectivity; @property (readonly) NetworkType network; @property (readonly) const char* frontCamId; @property (readonly) const char* backCamId; -@property (retain, nonatomic) NSString* SSID; +@property(strong, nonatomic) NSString *SSID; @property (readonly) sqlite3* database; -@property (nonatomic, retain) NSData *pushNotificationToken; +@property(nonatomic, strong) NSData *pushNotificationToken; @property (readonly) LinphoneManagerSounds sounds; @property (readonly) NSMutableArray *logs; @property (nonatomic, assign) BOOL speakerEnabled; @@ -202,6 +216,7 @@ typedef struct _LinphoneManagerSounds { @property (copy) void (^silentPushCompletion)(UIBackgroundFetchResult); @property (readonly) BOOL wasRemoteProvisioned; @property (readonly) LpConfig *configDb; +@property(readonly) InAppProductsManager *iapManager; +@property(strong, nonatomic) NSMutableArray *fileTransferDelegates; @end - diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index 2f5606027..c7dc898e4 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -32,6 +32,7 @@ #import "LinphoneManager.h" #import "LinphoneCoreSettingsStore.h" +#import "Utils/FileTransferDelegate.h" #include "linphone/linphonecore_utils.h" #include "linphone/lpconfig.h" @@ -40,23 +41,25 @@ #import "LinphoneIOSVersion.h" #import +#import "Utils.h" +#import "Utils/DTFoundation/DTAlertView.h" +#import "PhoneMainView.h" #define LINPHONE_LOGS_MAX_ENTRY 5000 -static void audioRouteChangeListenerCallback ( - void *inUserData, // 1 - AudioSessionPropertyID inPropertyID, // 2 - UInt32 inPropertyValueSize, // 3 - const void *inPropertyValue // 4 - ); -static LinphoneCore* theLinphoneCore = nil; -static LinphoneManager* theLinphoneManager = nil; +static void audioRouteChangeListenerCallback(void *inUserData, // 1 + AudioSessionPropertyID inPropertyID, // 2 + UInt32 inPropertyValueSize, // 3 + const void *inPropertyValue // 4 + ); +static LinphoneCore *theLinphoneCore = nil; +static LinphoneManager *theLinphoneManager = nil; -const char *const LINPHONERC_APPLICATION_KEY = "app"; +NSString *const LINPHONERC_APPLICATION_KEY = @"app"; NSString *const kLinphoneCoreUpdate = @"LinphoneCoreUpdate"; NSString *const kLinphoneDisplayStatusUpdate = @"LinphoneDisplayStatusUpdate"; -NSString *const kLinphoneTextReceived = @"LinphoneTextReceived"; +NSString *const kLinphoneMessageReceived = @"LinphoneMessageReceived"; NSString *const kLinphoneTextComposeEvent = @"LinphoneTextComposeStarted"; NSString *const kLinphoneCallUpdate = @"LinphoneCallUpdate"; NSString *const kLinphoneRegistrationUpdate = @"LinphoneRegistrationUpdate"; @@ -68,9 +71,11 @@ NSString *const kLinphoneBluetoothAvailabilityUpdate = @"LinphoneBluetoothAvaila NSString *const kLinphoneConfiguringStateUpdate = @"LinphoneConfiguringStateUpdate"; NSString *const kLinphoneGlobalStateUpdate = @"LinphoneGlobalStateUpdate"; NSString *const kLinphoneNotifyReceived = @"LinphoneNotifyReceived"; +NSString *const kLinphoneCallEncryptionChanged = @"LinphoneCallEncryptionChanged"; +NSString *const kLinphoneFileTransferSendUpdate = @"LinphoneFileTransferSendUpdate"; +NSString *const kLinphoneFileTransferRecvUpdate = @"LinphoneFileTransferRecvUpdate"; - -const int kLinphoneAudioVbrCodecDefaultBitrate=36; /*you can override this from linphonerc or linphonerc-factory*/ +const int kLinphoneAudioVbrCodecDefaultBitrate = 36; /*you can override this from linphonerc or linphonerc-factory*/ extern void libmsilbc_init(void); extern void libmsamr_init(void); @@ -78,34 +83,31 @@ extern void libmsx264_init(void); extern void libmsopenh264_init(void); extern void libmssilk_init(void); extern void libmsbcg729_init(void); +extern void libmswebrtc_init(void); -#define FRONT_CAM_NAME "AV Capture: com.apple.avfoundation.avcapturedevice.built-in_video:1" /*"AV Capture: Front Camera"*/ -#define BACK_CAM_NAME "AV Capture: com.apple.avfoundation.avcapturedevice.built-in_video:0" /*"AV Capture: Back Camera"*/ +#define FRONT_CAM_NAME \ + "AV Capture: com.apple.avfoundation.avcapturedevice.built-in_video:1" /*"AV Capture: Front Camera"*/ +#define BACK_CAM_NAME \ + "AV Capture: com.apple.avfoundation.avcapturedevice.built-in_video:0" /*"AV Capture: Back Camera"*/ - -NSString *const kLinphoneOldChatDBFilename = @"chat_database.sqlite"; +NSString *const kLinphoneOldChatDBFilename = @"chat_database.sqlite"; NSString *const kLinphoneInternalChatDBFilename = @"linphone_chats.db"; @implementation LinphoneCallAppData - (id)init { if ((self = [super init])) { - self->batteryWarningShown = FALSE; - self->notification = nil; - self->videoRequested = FALSE; - self->userInfos = [[NSMutableDictionary alloc] init]; + batteryWarningShown = FALSE; + notification = nil; + videoRequested = FALSE; + userInfos = [[NSMutableDictionary alloc] init]; } return self; } -- (void)dealloc { - [self->userInfos release]; - [super dealloc]; -} @end - @interface LinphoneManager () -@property (retain, nonatomic) AVAudioPlayer* messagePlayer; +@property(strong, nonatomic) AVAudioPlayer *messagePlayer; @end @implementation LinphoneManager @@ -128,137 +130,125 @@ NSString *const kLinphoneInternalChatDBFilename = @"linphone_chats.db"; @synthesize wasRemoteProvisioned; @synthesize configDb; -struct codec_name_pref_table{ +struct codec_name_pref_table { const char *name; int rate; - NSString *prefname; + const char *prefname; }; -struct codec_name_pref_table codec_pref_table[]={ - { "speex", 8000, @"speex_8k_preference" }, - { "speex", 16000, @"speex_16k_preference" }, - { "silk", 24000, @"silk_24k_preference" }, - { "silk", 16000, @"silk_16k_preference" }, - { "amr", 8000, @"amr_preference" }, - { "gsm", 8000, @"gsm_preference" }, - { "ilbc", 8000, @"ilbc_preference"}, - { "pcmu", 8000, @"pcmu_preference"}, - { "pcma", 8000, @"pcma_preference"}, - { "g722", 8000, @"g722_preference"}, - { "g729", 8000, @"g729_preference"}, - { "mp4v-es", 90000, @"mp4v-es_preference"}, - { "h264", 90000, @"h264_preference"}, - { "vp8", 90000, @"vp8_preference"}, - { "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 } -}; +struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_preference"}, + {"speex", 16000, "speex_16k_preference"}, + {"silk", 24000, "silk_24k_preference"}, + {"silk", 16000, "silk_16k_preference"}, + {"amr", 8000, "amr_preference"}, + {"gsm", 8000, "gsm_preference"}, + {"ilbc", 8000, "ilbc_preference"}, + {"isac", 16000, "isac_preference"}, + {"pcmu", 8000, "pcmu_preference"}, + {"pcma", 8000, "pcma_preference"}, + {"g722", 8000, "g722_preference"}, + {"g729", 8000, "g729_preference"}, + {"mp4v-es", 90000, "mp4v-es_preference"}, + {"h264", 90000, "h264_preference"}, + {"vp8", 90000, "vp8_preference"}, + {"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}}; -+ (NSString *)getPreferenceForCodec: (const char*) name withRate: (int) rate{ ++ (NSString *)getPreferenceForCodec:(const char *)name withRate:(int)rate { int i; - for(i=0;codec_pref_table[i].name!=NULL;++i){ - if (strcasecmp(codec_pref_table[i].name,name)==0 && codec_pref_table[i].rate==rate) - return codec_pref_table[i].prefname; + for (i = 0; codec_pref_table[i].name != NULL; ++i) { + if (strcasecmp(codec_pref_table[i].name, name) == 0 && codec_pref_table[i].rate == rate) + return [NSString stringWithUTF8String:codec_pref_table[i].prefname]; } return Nil; } + (NSSet *)unsupportedCodecs { NSMutableSet *set = [NSMutableSet set]; - for(int i=0;codec_pref_table[i].name!=NULL;++i) { - PayloadType* available = linphone_core_find_payload_type(theLinphoneCore, - 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"] - && ![codec_pref_table[i].prefname isEqualToString:@"mp4v-es_preference"] - ) - { - [set addObject:codec_pref_table[i].prefname]; + for (int i = 0; codec_pref_table[i].name != NULL; ++i) { + PayloadType *available = linphone_core_find_payload_type( + theLinphoneCore, 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 + && strcmp(codec_pref_table[i].prefname, "h264_preference") != 0 && + strcmp(codec_pref_table[i].prefname, "mp4v-es_preference") != 0) { + [set addObject:[NSString stringWithUTF8String:codec_pref_table[i].prefname]]; } } return set; } -+ (BOOL)isCodecSupported: (const char *)codecName { ++ (BOOL)isCodecSupported:(const char *)codecName { return (codecName != NULL) && - (NULL != linphone_core_find_payload_type(theLinphoneCore, codecName, - LINPHONE_FIND_PAYLOAD_IGNORE_RATE, - LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS)); + (NULL != linphone_core_find_payload_type(theLinphoneCore, codecName, LINPHONE_FIND_PAYLOAD_IGNORE_RATE, + LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS)); } + (BOOL)runningOnIpad { -#ifdef UI_USER_INTERFACE_IDIOM - return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad); -#else - return NO; -#endif + return ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad); } + (BOOL)isRunningTests { - NSDictionary *environment = [[NSProcessInfo processInfo] environment]; - NSString *injectBundle = environment[@"XCInjectBundle"]; - return [[injectBundle pathExtension] isEqualToString:@"xctest"]; + NSDictionary *environment = [[NSProcessInfo processInfo] environment]; + NSString *injectBundle = environment[@"XCInjectBundle"]; + return [[injectBundle pathExtension] isEqualToString:@"xctest"]; } -+ (BOOL)isNotIphone3G -{ - static BOOL done=FALSE; ++ (BOOL)isNotIphone3G { + static BOOL done = FALSE; static BOOL result; - if (!done){ + if (!done) { size_t size; sysctlbyname("hw.machine", NULL, &size, NULL, 0); char *machine = malloc(size); sysctlbyname("hw.machine", machine, &size, NULL, 0); - NSString *platform = [[NSString alloc ] initWithUTF8String:machine]; + NSString *platform = [[NSString alloc] initWithUTF8String:machine]; free(machine); result = ![platform isEqualToString:@"iPhone1,2"]; - [platform release]; - done=TRUE; + done = TRUE; } return result; } + (NSString *)getUserAgent { - return [NSString stringWithFormat:@"LinphoneIphone/%@ (Linphone/%s; Apple %@/%@)", - [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)kCFBundleVersionKey], - linphone_core_get_version(), - [UIDevice currentDevice].systemName, - [UIDevice currentDevice].systemVersion]; + return + [NSString stringWithFormat:@"LinphoneIphone/%@ (Linphone/%s; Apple %@/%@)", + [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey], + linphone_core_get_version(), [UIDevice currentDevice].systemName, + [UIDevice currentDevice].systemVersion]; } -+ (LinphoneManager*)instance { - if(theLinphoneManager == nil) { - theLinphoneManager = [LinphoneManager alloc]; - [theLinphoneManager init]; ++ (LinphoneManager *)instance { + @synchronized(self) { + if (theLinphoneManager == nil) { + theLinphoneManager = [[LinphoneManager alloc] init]; + } } return theLinphoneManager; } #ifdef DEBUG + (void)instanceRelease { - if(theLinphoneManager != nil) { - [theLinphoneManager release]; + if (theLinphoneManager != nil) { theLinphoneManager = nil; } } #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; + 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 @@ -266,33 +256,35 @@ struct codec_name_pref_table codec_pref_table[]={ - (id)init { if ((self = [super init])) { AudioSessionInitialize(NULL, NULL, NULL, NULL); - OSStatus lStatus = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self); + OSStatus lStatus = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, + audioRouteChangeListenerCallback, (__bridge void *)(self)); if (lStatus) { - [LinphoneLogger logc:LinphoneLoggerError format:"cannot register route change handler [%ld]",lStatus]; + LOGE(@"cannot register route change handler [%ld]", lStatus); } + NSString *path = [[NSBundle mainBundle] pathForResource:@"msg" ofType:@"wav"]; + self.messagePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path] error:nil]; - NSString *path = [[NSBundle mainBundle] pathForResource:@"msg" ofType:@"wav"]; - self.messagePlayer = [[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path] error:nil] autorelease]; + sounds.vibrate = kSystemSoundID_Vibrate; - sounds.vibrate = kSystemSoundID_Vibrate; - - logs = [[NSMutableArray alloc] init]; + logs = [[NSMutableArray alloc] init]; database = NULL; speakerEnabled = FALSE; bluetoothEnabled = FALSE; tunnelMode = FALSE; - [self copyDefaultSettings]; - pushCallIDs = [[NSMutableArray alloc] init ]; + + _fileTransferDelegates = [[NSMutableArray alloc] init]; + + pushCallIDs = [[NSMutableArray alloc] init]; photoLibrary = [[ALAssetsLibrary alloc] init]; - self->_isTesting = [LinphoneManager isRunningTests]; + _isTesting = [LinphoneManager isRunningTests]; - NSString* factoryConfig = [LinphoneManager bundleFile:[LinphoneManager runningOnIpad]?@"linphonerc-factory~ipad":@"linphonerc-factory"]; - NSString *confiFileName = [LinphoneManager documentFile:@".linphonerc"]; - configDb=lp_config_new_with_factory([confiFileName cStringUsingEncoding:[NSString defaultCStringEncoding]] , [factoryConfig cStringUsingEncoding:[NSString defaultCStringEncoding]]); + [self renameDefaultSettings]; + [self copyDefaultSettings]; + [self overrideDefaultSettings]; - //set default values for first boot - if (lp_config_get_string(configDb,LINPHONERC_APPLICATION_KEY,"debugenable_preference",NULL)==NULL){ + // set default values for first boot + if ([self lpConfigStringForKey:@"debugenable_preference"] == nil) { #ifdef DEBUG [self lpConfigSetBool:TRUE forKey:@"debugenable_preference"]; #else @@ -306,122 +298,114 @@ struct codec_name_pref_table codec_pref_table[]={ } - (void)dealloc { - [fastAddressBook release]; - [logs release]; - OSStatus lStatus = AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self); + OSStatus lStatus = AudioSessionRemovePropertyListenerWithUserData( + kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, (__bridge void *)(self)); if (lStatus) { - [LinphoneLogger logc:LinphoneLoggerError format:"cannot un register route change handler [%ld]", lStatus]; + LOGE(@"cannot un register route change handler [%ld]", lStatus); } [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:kLinphoneGlobalStateUpdate]; [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:kLinphoneConfiguringStateUpdate]; - - - [photoLibrary release]; - [pushCallIDs release]; - [super dealloc]; } -- (void)silentPushFailed:(NSTimer*)timer -{ - if( silentPushCompletion ){ - [LinphoneLogger log:LinphoneLoggerLog format:@"silentPush failed, silentPushCompletion block: %p", silentPushCompletion ]; +- (void)silentPushFailed:(NSTimer *)timer { + if (silentPushCompletion) { + LOGI(@"silentPush failed, silentPushCompletion block: %p", silentPushCompletion); silentPushCompletion(UIBackgroundFetchResultNoData); silentPushCompletion = nil; } } -#pragma mark - Database Functions +#pragma mark - Migration -static int check_should_migrate_images(void* data ,int argc,char** argv,char** cnames){ - *((BOOL*)data) = TRUE; +static int check_should_migrate_images(void *data, int argc, char **argv, char **cnames) { + *((BOOL *)data) = TRUE; return 0; } -- (BOOL)migrateChatDBIfNeeded:(LinphoneCore*)lc { - sqlite3* newDb; +- (BOOL)migrateChatDBIfNeeded:(LinphoneCore *)lc { + sqlite3 *newDb; char *errMsg; - NSError* error; + NSError *error; NSString *oldDbPath = [LinphoneManager documentFile:kLinphoneOldChatDBFilename]; NSString *newDbPath = [LinphoneManager documentFile:kLinphoneInternalChatDBFilename]; - BOOL shouldMigrate = [[NSFileManager defaultManager] fileExistsAtPath:oldDbPath]; + BOOL shouldMigrate = [[NSFileManager defaultManager] fileExistsAtPath:oldDbPath]; BOOL shouldMigrateImages = FALSE; - LinphoneProxyConfig* default_proxy; - const char* identity = NULL; + const char *identity = NULL; BOOL migrated = FALSE; - char* attach_stmt = NULL; + char *attach_stmt = NULL; + LinphoneProxyConfig *default_proxy = linphone_core_get_default_proxy_config(lc); - linphone_core_get_default_proxy(lc, &default_proxy); - - - if( sqlite3_open([newDbPath UTF8String], &newDb) != SQLITE_OK) { - [LinphoneLogger log:LinphoneLoggerError format:@"Can't open \"%@\" sqlite3 database.", newDbPath]; + if (sqlite3_open([newDbPath UTF8String], &newDb) != SQLITE_OK) { + LOGE(@"Can't open \"%@\" sqlite3 database.", newDbPath); return FALSE; } - const char* check_appdata = "SELECT url,message FROM history WHERE url LIKE 'assets-library%' OR message LIKE 'assets-library%' LIMIT 1;"; + const char *check_appdata = + "SELECT url,message FROM history WHERE url LIKE 'assets-library%' OR message LIKE 'assets-library%' LIMIT 1;"; // will set "needToMigrateImages to TRUE if a result comes by sqlite3_exec(newDb, check_appdata, check_should_migrate_images, &shouldMigrateImages, NULL); - if( !shouldMigrate && !shouldMigrateImages ) { + if (!shouldMigrate && !shouldMigrateImages) { sqlite3_close(newDb); return FALSE; } + LOGI(@"Starting migration procedure"); - [LinphoneLogger logc:LinphoneLoggerLog format:"Starting migration procedure"]; - - if( shouldMigrate ){ + if (shouldMigrate) { // attach old database to the new one: attach_stmt = sqlite3_mprintf("ATTACH DATABASE %Q AS oldchats", [oldDbPath UTF8String]); - if( sqlite3_exec(newDb, attach_stmt, NULL, NULL, &errMsg) != SQLITE_OK ){ - [LinphoneLogger logc:LinphoneLoggerError format:"Can't attach old chat table, error[%s] ", errMsg]; + if (sqlite3_exec(newDb, attach_stmt, NULL, NULL, &errMsg) != SQLITE_OK) { + LOGE(@"Can't attach old chat table, error[%s] ", errMsg); sqlite3_free(errMsg); goto exit_dbmigration; } + // migrate old chats to the new db. The iOS stores timestamp in UTC already, so we can directly put it in the + // 'utc' field and set 'time' to -1 + const char *migration_statement = + "INSERT INTO history (localContact,remoteContact,direction,message,utc,read,status,time) " + "SELECT localContact,remoteContact,direction,message,time,read,state,'-1' FROM oldchats.chat"; - // migrate old chats to the new db. The iOS stores timestamp in UTC already, so we can directly put it in the 'utc' field and set 'time' to -1 - const char* migration_statement = "INSERT INTO history (localContact,remoteContact,direction,message,utc,read,status,time) " - "SELECT localContact,remoteContact,direction,message,time,read,state,'-1' FROM oldchats.chat"; - - if( sqlite3_exec(newDb, migration_statement, NULL, NULL, &errMsg) != SQLITE_OK ){ - [LinphoneLogger logc:LinphoneLoggerError format:"DB migration failed, error[%s] ", errMsg]; + if (sqlite3_exec(newDb, migration_statement, NULL, NULL, &errMsg) != SQLITE_OK) { + LOGE(@"DB migration failed, error[%s] ", errMsg); sqlite3_free(errMsg); goto exit_dbmigration; } // invert direction of old messages, because iOS was storing the direction flag incorrectly - const char* invert_direction = "UPDATE history SET direction = NOT direction"; - if( sqlite3_exec(newDb, invert_direction, NULL, NULL, &errMsg) != SQLITE_OK){ - [LinphoneLogger log: LinphoneLoggerError format:@"Inverting direction failed, error[%s]", errMsg]; + const char *invert_direction = "UPDATE history SET direction = NOT direction"; + if (sqlite3_exec(newDb, invert_direction, NULL, NULL, &errMsg) != SQLITE_OK) { + LOGE(@"Inverting direction failed, error[%s]", errMsg); sqlite3_free(errMsg); goto exit_dbmigration; } // replace empty from: or to: by the current identity. - if( default_proxy ){ + if (default_proxy) { identity = linphone_proxy_config_get_identity(default_proxy); } - if( !identity ){ + if (!identity) { identity = "sip:unknown@sip.linphone.org"; } - char* from_conversion = sqlite3_mprintf("UPDATE history SET localContact = %Q WHERE localContact = ''", identity); - if( sqlite3_exec(newDb, from_conversion, NULL, NULL, &errMsg) != SQLITE_OK ){ - [LinphoneLogger logc:LinphoneLoggerError format:"FROM conversion failed, error[%s] ", errMsg]; + char *from_conversion = + sqlite3_mprintf("UPDATE history SET localContact = %Q WHERE localContact = ''", identity); + if (sqlite3_exec(newDb, from_conversion, NULL, NULL, &errMsg) != SQLITE_OK) { + LOGE(@"FROM conversion failed, error[%s] ", errMsg); sqlite3_free(errMsg); } sqlite3_free(from_conversion); - char* to_conversion = sqlite3_mprintf("UPDATE history SET remoteContact = %Q WHERE remoteContact = ''", identity); - if( sqlite3_exec(newDb, to_conversion, NULL, NULL, &errMsg) != SQLITE_OK ){ - [LinphoneLogger logc:LinphoneLoggerError format:"DB migration failed, error[%s] ", errMsg]; + char *to_conversion = + sqlite3_mprintf("UPDATE history SET remoteContact = %Q WHERE remoteContact = ''", identity); + if (sqlite3_exec(newDb, to_conversion, NULL, NULL, &errMsg) != SQLITE_OK) { + LOGE(@"DB migration failed, error[%s] ", errMsg); sqlite3_free(errMsg); } sqlite3_free(to_conversion); - } // local image paths were stored in the 'message' field historically. They were @@ -429,16 +413,18 @@ static int check_should_migrate_images(void* data ,int argc,char** argv,char** c // encoded field. These are the migration steps to migrate them. // move already stored images from the messages to the appdata JSON field - const char* assetslib_migration = "UPDATE history SET appdata='{\"localimage\":\"'||message||'\"}' , message='' WHERE message LIKE 'assets-library%'"; - if( sqlite3_exec(newDb, assetslib_migration, NULL, NULL, &errMsg) != SQLITE_OK ){ - [LinphoneLogger logc:LinphoneLoggerError format:"Assets-history migration for MESSAGE failed, error[%s] ", errMsg]; + const char *assetslib_migration = "UPDATE history SET appdata='{\"localimage\":\"'||message||'\"}' , message='' " + "WHERE message LIKE 'assets-library%'"; + if (sqlite3_exec(newDb, assetslib_migration, NULL, NULL, &errMsg) != SQLITE_OK) { + LOGE(@"Assets-history migration for MESSAGE failed, error[%s] ", errMsg); sqlite3_free(errMsg); } // move already stored images from the url to the appdata JSON field - const char* assetslib_migration_fromurl = "UPDATE history SET appdata='{\"localimage\":\"'||url||'\"}' , url='' WHERE url LIKE 'assets-library%'"; - if( sqlite3_exec(newDb, assetslib_migration_fromurl, NULL, NULL, &errMsg) != SQLITE_OK ){ - [LinphoneLogger logc:LinphoneLoggerError format:"Assets-history migration for URL failed, error[%s] ", errMsg]; + const char *assetslib_migration_fromurl = + "UPDATE history SET appdata='{\"localimage\":\"'||url||'\"}' , url='' WHERE url LIKE 'assets-library%'"; + if (sqlite3_exec(newDb, assetslib_migration_fromurl, NULL, NULL, &errMsg) != SQLITE_OK) { + LOGE(@"Assets-history migration for URL failed, error[%s] ", errMsg); sqlite3_free(errMsg); } @@ -447,273 +433,272 @@ static int check_should_migrate_images(void* data ,int argc,char** argv,char** c exit_dbmigration: - if( attach_stmt ) sqlite3_free(attach_stmt); + if (attach_stmt) + sqlite3_free(attach_stmt); sqlite3_close(newDb); // in any case, we should remove the old chat db - if( shouldMigrate && ![[NSFileManager defaultManager] removeItemAtPath:oldDbPath error:&error] ){ - [LinphoneLogger logc:LinphoneLoggerError format:"Could not remove old chat DB: %@", error]; + if (shouldMigrate && ![[NSFileManager defaultManager] removeItemAtPath:oldDbPath error:&error]) { + LOGE(@"Could not remove old chat DB: %@", error); } - [LinphoneLogger log:LinphoneLoggerLog format:@"Message storage migration finished: success = %@", migrated ? @"TRUE":@"FALSE"]; + LOGI(@"Message storage migration finished: success = %@", migrated ? @"TRUE" : @"FALSE"); return migrated; } - (void)migrateFromUserPrefs { - static const char* migration_flag = "userpref_migration_done"; + static NSString *migration_flag = @"userpref_migration_done"; - if( configDb == nil ) return; + if (configDb == nil) + return; - if( lp_config_get_int(configDb, LINPHONERC_APPLICATION_KEY, migration_flag, 0) ){ - Linphone_log(@"UserPrefs migration already performed, skip"); + if ([self lpConfigIntForKey:migration_flag withDefault:0]) { + LOGI(@"UserPrefs migration already performed, skip"); return; } - NSDictionary* defaults = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; - NSArray* defaults_keys = [defaults allKeys]; - NSDictionary* values = @{@"backgroundmode_preference" :@YES, - @"debugenable_preference" :@NO, - @"start_at_boot_preference" :@YES}; - BOOL shouldSync = FALSE; + NSDictionary *defaults = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; + NSArray *defaults_keys = [defaults allKeys]; + NSDictionary *values = + @{ @"backgroundmode_preference" : @YES, + @"debugenable_preference" : @NO, + @"start_at_boot_preference" : @YES }; + BOOL shouldSync = FALSE; - Linphone_log(@"%lu user prefs", (unsigned long)[defaults_keys count]); + LOGI(@"%lu user prefs", (unsigned long)[defaults_keys count]); - for( NSString* userpref in values ){ - if( [defaults_keys containsObject:userpref] ){ - Linphone_log(@"Migrating %@ from user preferences: %d", userpref, [[defaults objectForKey:userpref] boolValue]); - lp_config_set_int(configDb, LINPHONERC_APPLICATION_KEY, [userpref UTF8String], [[defaults objectForKey:userpref] boolValue]); + for (NSString *userpref in values) { + if ([defaults_keys containsObject:userpref]) { + LOGI(@"Migrating %@ from user preferences: %d", userpref, [[defaults objectForKey:userpref] boolValue]); + [self lpConfigSetBool:[[defaults objectForKey:userpref] boolValue] forKey:userpref]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:userpref]; shouldSync = TRUE; - } else if ( lp_config_get_string(configDb, LINPHONERC_APPLICATION_KEY, [userpref UTF8String], NULL) == NULL ){ + } else if ([self lpConfigStringForKey:userpref] == nil) { // no default value found in our linphonerc, we need to add them - lp_config_set_int(configDb, LINPHONERC_APPLICATION_KEY, [userpref UTF8String], [[values objectForKey:userpref] boolValue]); + [self lpConfigSetBool:[[values objectForKey:userpref] boolValue] forKey:userpref]; } } - if( shouldSync ){ - Linphone_log(@"Synchronizing..."); + if (shouldSync) { + LOGI(@"Synchronizing..."); [[NSUserDefaults standardUserDefaults] synchronize]; } // don't get back here in the future - lp_config_set_int(configDb, LINPHONERC_APPLICATION_KEY, migration_flag, 1); + [self lpConfigSetBool:YES forKey:migration_flag]; } +- (void)migrationLinphoneSettings { + // we need to proceed to the migration *after* the chat database was opened, so that we know it is in consistent + // state + NSString *chatDBFileName = [LinphoneManager documentFile:kLinphoneInternalChatDBFilename]; + if ([self migrateChatDBIfNeeded:theLinphoneCore]) { + // if a migration was performed, we should reinitialize the chat database + linphone_core_set_chat_database_path(theLinphoneCore, [chatDBFileName UTF8String]); + } + /* AVPF migration */ + if ([self lpConfigBoolForKey:@"avpf_migration_done"] == FALSE) { + const MSList *proxies = linphone_core_get_proxy_config_list(theLinphoneCore); + while (proxies) { + LinphoneProxyConfig *proxy = (LinphoneProxyConfig *)proxies->data; + const char *addr = linphone_proxy_config_get_addr(proxy); + // we want to enable AVPF for the proxies + if (addr && strstr(addr, "sip.linphone.org") != 0) { + LOGI(@"Migrating proxy config to use AVPF"); + linphone_proxy_config_enable_avpf(proxy, TRUE); + } + proxies = proxies->next; + } + [self lpConfigSetBool:TRUE forKey:@"avpf_migration_done"]; + } + /* Quality Reporting migration */ + if ([self lpConfigBoolForKey:@"quality_report_migration_done"] == FALSE) { + const MSList *proxies = linphone_core_get_proxy_config_list(theLinphoneCore); + while (proxies) { + LinphoneProxyConfig *proxy = (LinphoneProxyConfig *)proxies->data; + const char *addr = linphone_proxy_config_get_addr(proxy); + // we want to enable quality reporting for the proxies that are on linphone.org + if (addr && strstr(addr, "sip.linphone.org") != 0) { + LOGI(@"Migrating proxy config to send quality report"); + linphone_proxy_config_set_quality_reporting_collector( + proxy, "sip:voip-metrics@sip.linphone.org;transport=tls"); + linphone_proxy_config_set_quality_reporting_interval(proxy, 180); + linphone_proxy_config_enable_quality_reporting(proxy, TRUE); + } + proxies = proxies->next; + } + [self lpConfigSetBool:TRUE forKey:@"quality_report_migration_done"]; + } + /* File transfer migration */ + if ([self lpConfigBoolForKey:@"file_transfer_migration_done"] == FALSE) { + const char *newURL = "https://www.linphone.org:444/lft.php"; + LOGI(@"Migrating sharing server url from %s to %s", + linphone_core_get_file_transfer_server([LinphoneManager getLc]), newURL); + linphone_core_set_file_transfer_server([LinphoneManager getLc], newURL); + [self lpConfigSetBool:TRUE forKey:@"file_transfer_migration_done"]; + } +} #pragma mark - Linphone Core Functions -+ (LinphoneCore*)getLc { - if (theLinphoneCore==nil) { - @throw([NSException exceptionWithName:@"LinphoneCoreException" reason:@"Linphone core not initialized yet" userInfo:nil]); ++ (LinphoneCore *)getLc { + if (theLinphoneCore == nil) { + @throw([NSException exceptionWithName:@"LinphoneCoreException" + reason:@"Linphone core not initialized yet" + userInfo:nil]); } return theLinphoneCore; } -+ (BOOL)isLcReady { - return theLinphoneCore != nil; -} - #pragma mark Debug functions struct _entry_data { - const LpConfig* conf; - const char* section; + const LpConfig *conf; + const char *section; }; -static void dump_entry(const char* entry, void*data) { - struct _entry_data *d = (struct _entry_data*)data; - const char* value = lp_config_get_string(d->conf, d->section, entry, ""); - [LinphoneLogger log:LinphoneLoggerLog format:@"%s=%s", entry, value]; +static void dump_entry(const char *entry, void *data) { + struct _entry_data *d = (struct _entry_data *)data; + const char *value = lp_config_get_string(d->conf, d->section, entry, ""); + LOGI(@"%s=%s", entry, value); } -static void dump_section(const char* section, void* data){ - [LinphoneLogger log:LinphoneLoggerLog format:@"[%s]", section ]; - struct _entry_data d = {(const LpConfig*)data, section}; - lp_config_for_each_entry((const LpConfig*)data, section, dump_entry, &d); +static void dump_section(const char *section, void *data) { + LOGI(@"[%s]", section); + struct _entry_data d = {(const LpConfig *)data, section}; + lp_config_for_each_entry((const LpConfig *)data, section, dump_entry, &d); } -+ (void)dumpLCConfig { - if (theLinphoneCore ){ - LpConfig *conf=[LinphoneManager instance].configDb; ++ (void)dumpLcConfig { + if (theLinphoneCore) { + LpConfig *conf = [LinphoneManager instance].configDb; lp_config_for_each_section(conf, dump_section, conf); } } - -#pragma mark - Logs Functions - -//generic log handler for debug version -void linphone_iphone_log_handler(int lev, const char *fmt, va_list args){ - NSString* format = [[NSString alloc] initWithUTF8String:fmt]; - NSLogv(format, args); -// NSString* formatedString = [[NSString alloc] initWithFormat:format arguments:args]; -// -// dispatch_async(dispatch_get_main_queue(), ^{ -// if([[LinphoneManager instance].logs count] >= LINPHONE_LOGS_MAX_ENTRY) { -// [[LinphoneManager instance].logs removeObjectAtIndex:0]; -// } -// [[LinphoneManager instance].logs addObject:formatedString]; -// -// // Post event -// NSDictionary *dict = [NSDictionary dictionaryWithObject:formatedString forKey:@"log"]; -// [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneLogsUpdate object:[LinphoneManager instance] userInfo:dict]; -// }); -// -// [formatedString release]; - [format release]; +#pragma mark - Logs Functions handlers +static void linphone_iphone_log_user_info(struct _LinphoneCore *lc, const char *message) { + linphone_iphone_log_handler(ORTP_MESSAGE, message, NULL); } - -//Error/warning log handler -static void linphone_iphone_log(struct _LinphoneCore * lc, const char * message) { - NSString* log = [NSString stringWithCString:message encoding:[NSString defaultCStringEncoding]]; - NSLog(log, NULL); - -// dispatch_async(dispatch_get_main_queue(), ^{ -// if([[LinphoneManager instance].logs count] >= LINPHONE_LOGS_MAX_ENTRY) { -// [[LinphoneManager instance].logs removeObjectAtIndex:0]; -// } -// [[LinphoneManager instance].logs addObject:log]; -// -// // Post event -// NSDictionary *dict = [NSDictionary dictionaryWithObject:log forKey:@"log"]; -// [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneLogsUpdate object:[LinphoneManager instance] userInfo:dict]; -// }); +static void linphone_iphone_log_user_warning(struct _LinphoneCore *lc, const char *message) { + linphone_iphone_log_handler(ORTP_WARNING, message, NULL); } - #pragma mark - Display Status Functions -- (void)displayStatus:(NSString*) message { +- (void)displayStatus:(NSString *)message { // Post event - [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneDisplayStatusUpdate - object:self - userInfo:@{@"message":message}]; + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneDisplayStatusUpdate + object:self + userInfo:@{ + @"message" : message + }]; } - -static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char * message) { - NSString* status = [[NSString alloc] initWithCString:message encoding:[NSString defaultCStringEncoding]]; - [(LinphoneManager*)linphone_core_get_user_data(lc) displayStatus:status]; - [status release]; +static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char *message) { + NSString *status = [[NSString alloc] initWithCString:message encoding:[NSString defaultCStringEncoding]]; + [(__bridge LinphoneManager *)linphone_core_get_user_data(lc) displayStatus:status]; } - #pragma mark - Call State Functions -- (void)localNotifContinue:(NSTimer*) timer { - UILocalNotification* notif = [timer userInfo]; - if (notif){ - [LinphoneLogger log:LinphoneLoggerLog format:@"cancelling/presenting local notif"]; +- (void)localNotifContinue:(NSTimer *)timer { + UILocalNotification *notif = [timer userInfo]; + if (notif) { + LOGI(@"cancelling/presenting local notif"); [[UIApplication sharedApplication] cancelLocalNotification:notif]; [[UIApplication sharedApplication] presentLocalNotificationNow:notif]; } } -- (void)onCall:(LinphoneCall*)call StateChanged:(LinphoneCallState)state withMessage:(const char *)message { +- (void)onCall:(LinphoneCall *)call StateChanged:(LinphoneCallState)state withMessage:(const char *)message { // Handling wrapper - LinphoneCallAppData* data=(LinphoneCallAppData*)linphone_call_get_user_pointer(call); + LinphoneCallAppData *data = (__bridge LinphoneCallAppData *)linphone_call_get_user_data(call); if (!data) { data = [[LinphoneCallAppData alloc] init]; - linphone_call_set_user_pointer(call, data); + linphone_call_set_user_data(call, (void *)CFBridgingRetain(data)); } if (silentPushCompletion) { // we were woken up by a silent push. Call the completion handler with NEWDATA // so that the push is notified to the user - [LinphoneLogger log:LinphoneLoggerLog format:@"onCall - handler %p", silentPushCompletion]; + LOGI(@"onCall - handler %p", silentPushCompletion); silentPushCompletion(UIBackgroundFetchResultNewData); silentPushCompletion = nil; } const LinphoneAddress *addr = linphone_call_get_remote_address(call); - NSString* address = nil; - if(addr != NULL) { - BOOL useLinphoneAddress = true; - // contact name - char* lAddress = linphone_address_as_string_uri_only(addr); - if(lAddress) { - NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:lAddress]]; - ABRecordRef contact = [fastAddressBook getContact:normalizedSipAddress]; - if(contact) { - address = [FastAddressBook getContactDisplayName:contact]; - useLinphoneAddress = false; - } - ms_free(lAddress); - } - if(useLinphoneAddress) { - const char* lDisplayName = linphone_address_get_display_name(addr); - const char* lUserName = linphone_address_get_username(addr); - if (lDisplayName) - address = [NSString stringWithUTF8String:lDisplayName]; - else if(lUserName) - address = [NSString stringWithUTF8String:lUserName]; - } - } - if(address == nil) { - address = NSLocalizedString(@"Unknown", nil); - } + NSString *address = [FastAddressBook displayNameForAddress:addr]; if (state == LinphoneCallIncomingReceived) { /*first step is to re-enable ctcall center*/ - CTCallCenter* lCTCallCenter = [[CTCallCenter alloc] init]; + CTCallCenter *lCTCallCenter = [[CTCallCenter alloc] init]; /*should we reject this call ?*/ - if ([lCTCallCenter currentCalls]!=nil) { - char *tmp=linphone_call_get_remote_address_as_string(call); + if ([lCTCallCenter currentCalls] != nil) { + char *tmp = linphone_call_get_remote_address_as_string(call); if (tmp) { - [LinphoneLogger logc:LinphoneLoggerLog format:"Mobile call ongoing... rejecting call from [%s]",tmp]; + LOGI(@"Mobile call ongoing... rejecting call from [%s]", tmp); ms_free(tmp); } - linphone_core_decline_call(theLinphoneCore, call,LinphoneReasonBusy); - [lCTCallCenter release]; + linphone_core_decline_call(theLinphoneCore, call, LinphoneReasonBusy); return; } - [lCTCallCenter release]; - if( [UIApplication sharedApplication].applicationState == UIApplicationStateBackground) { + if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) { - LinphoneCallLog* callLog=linphone_call_get_call_log(call); - NSString* callId=[NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)]; + LinphoneCallLog *callLog = linphone_call_get_call_log(call); + NSString *callId = [NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)]; - if (![[LinphoneManager instance] popPushCallID:callId]){ + if (![[LinphoneManager instance] popPushCallID:callId]) { // case where a remote notification is not already received // Create a new local notification data->notification = [[UILocalNotification alloc] init]; if (data->notification) { - // 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]; - } + // iOS8 doesn't need the timer trick for the local notification. + if ([[UIDevice currentDevice].systemVersion floatValue] >= 8 && + [self lpConfigBoolForKey:@"repeat_call_notification"] == NO) { + NSString *ring = + ([LinphoneManager bundleFile:[self lpConfigStringForKey:@"local_ring" inSection:@"sound"]] + ?: [LinphoneManager bundleFile:@"notes_of_the_optimistic.caf"]) + .lastPathComponent; + NSString *soundName = [NSString stringWithFormat:@"sounds/%@", ring]; + data->notification.soundName = soundName; + data->notification.category = @"incoming_call"; + } else { + data->notification.soundName = @"sounds/shortring.caf"; + data->timer = [NSTimer scheduledTimerWithTimeInterval:4.0 + target:self + selector:@selector(localNotifContinue:) + userInfo:data->notification + repeats:TRUE]; + } data->notification.repeatInterval = 0; - data->notification.alertBody =[NSString stringWithFormat:NSLocalizedString(@"IC_MSG",nil), address]; + data->notification.alertBody = + [NSString stringWithFormat:NSLocalizedString(@"IC_MSG", nil), address]; data->notification.alertAction = NSLocalizedString(@"Answer", nil); - data->notification.userInfo = @{@"callId": callId, @"timer":[NSNumber numberWithInt:1] }; + data->notification.userInfo = @{ @"callId" : callId, @"timer" : [NSNumber numberWithInt:1] }; data->notification.applicationIconBadgeNumber = 1; [[UIApplication sharedApplication] presentLocalNotificationNow:data->notification]; - if (!incallBgTask){ - incallBgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^{ - [LinphoneLogger log:LinphoneLoggerWarning format:@"Call cannot ring any more, too late"]; - [[UIApplication sharedApplication] endBackgroundTask:incallBgTask]; - incallBgTask=0; + if (!incallBgTask) { + incallBgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ + LOGW(@"Call cannot ring any more, too late"); + [[UIApplication sharedApplication] endBackgroundTask:incallBgTask]; + incallBgTask = 0; }]; - if( data->timer ){ - [[NSRunLoop currentRunLoop] addTimer:data->timer forMode:NSRunLoopCommonModes]; - } + if (data->timer) { + [[NSRunLoop currentRunLoop] addTimer:data->timer forMode:NSRunLoopCommonModes]; + } } - } } } @@ -726,7 +711,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char // Disable speaker when no more call if ((state == LinphoneCallEnd || state == LinphoneCallError)) { speaker_already_enabled = FALSE; - if(linphone_core_get_calls_nb(theLinphoneCore) == 0) { + if (linphone_core_get_calls_nb(theLinphoneCore) == 0) { [self setSpeakerEnabled:FALSE]; [self removeCTCallCenterCb]; bluetoothAvailable = FALSE; @@ -735,47 +720,45 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char linphone_core_start_dtmf_stream(theLinphoneCore); } if (incallBgTask) { - [[UIApplication sharedApplication] endBackgroundTask:incallBgTask]; - incallBgTask=0; + [[UIApplication sharedApplication] endBackgroundTask:incallBgTask]; + incallBgTask = 0; } - if(data != nil && data->notification != nil) { + if (data != nil && data->notification != nil) { LinphoneCallLog *log = linphone_call_get_call_log(call); // cancel local notif if needed - if( data->timer ){ + if (data->timer) { [data->timer invalidate]; data->timer = nil; } [[UIApplication sharedApplication] cancelLocalNotification:data->notification]; - [data->notification release]; data->notification = nil; - if(log == NULL || linphone_call_log_get_status(log) == LinphoneCallMissed) { + if (log == NULL || linphone_call_log_get_status(log) == LinphoneCallMissed) { UILocalNotification *notification = [[UILocalNotification alloc] init]; notification.repeatInterval = 0; - notification.alertBody = [NSString stringWithFormat:NSLocalizedString(@"You missed a call from %@", nil), address]; + notification.alertBody = + [NSString stringWithFormat:NSLocalizedString(@"You missed a call from %@", nil), address]; notification.alertAction = NSLocalizedString(@"Show", nil); - notification.userInfo = [NSDictionary dictionaryWithObject:[NSString stringWithUTF8String:linphone_call_log_get_call_id(log)] forKey:@"callLog"]; + notification.userInfo = [NSDictionary + dictionaryWithObject:[NSString stringWithUTF8String:linphone_call_log_get_call_id(log)] + forKey:@"callLog"]; [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; - [notification release]; } - } } - if(state == LinphoneCallReleased) { - if(data != NULL) { - [data release]; - linphone_call_set_user_pointer(call, NULL); + if (state == LinphoneCallReleased) { + if (data != NULL) { + linphone_call_set_user_data(call, NULL); + CFBridgingRelease((__bridge CFTypeRef)(data)); } } // Enable speaker when video - if(state == LinphoneCallIncomingReceived || - state == LinphoneCallOutgoingInit || - state == LinphoneCallConnected || - state == LinphoneCallStreamsRunning) { + if (state == LinphoneCallIncomingReceived || state == LinphoneCallOutgoingInit || state == LinphoneCallConnected || + state == LinphoneCallStreamsRunning) { if (linphone_call_params_video_enabled(linphone_call_get_current_params(call)) && !speaker_already_enabled) { [self setSpeakerEnabled:TRUE]; speaker_already_enabled = TRUE; @@ -787,384 +770,464 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char [self setupGSMInteraction]; } // Post event - NSDictionary* dict = @{@"call": [NSValue valueWithPointer:call], - @"state": [NSNumber numberWithInt:state], - @"message":[NSString stringWithUTF8String:message]}; + NSDictionary *dict = @{ + @"call" : [NSValue valueWithPointer:call], + @"state" : [NSNumber numberWithInt:state], + @"message" : [NSString stringWithUTF8String:message] + }; + LOGI(@"Call %p changed to state %s: %s", call, linphone_call_state_to_string(state), message); [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCallUpdate object:self userInfo:dict]; } -static void linphone_iphone_call_state(LinphoneCore *lc, LinphoneCall* call, LinphoneCallState state,const char* message) { - [(LinphoneManager*)linphone_core_get_user_data(lc) onCall:call StateChanged: state withMessage: message]; +static void linphone_iphone_call_state(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState state, + const char *message) { + [(__bridge LinphoneManager *)linphone_core_get_user_data(lc) onCall:call StateChanged:state withMessage:message]; } - #pragma mark - Transfert State Functions -static void linphone_iphone_transfer_state_changed(LinphoneCore* lc, LinphoneCall* call, LinphoneCallState state) { +static void linphone_iphone_transfer_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState state) { } #pragma mark - Global state change static void linphone_iphone_global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message) { - [(LinphoneManager*)linphone_core_get_user_data(lc) onGlobalStateChanged:gstate withMessage:message]; + [(__bridge LinphoneManager *)linphone_core_get_user_data(lc) onGlobalStateChanged:gstate withMessage:message]; } --(void)onGlobalStateChanged:(LinphoneGlobalState)state withMessage:(const char*)message { - [LinphoneLogger log:LinphoneLoggerLog format:@"onGlobalStateChanged: %d (message: %s)", state, message]; +- (void)onGlobalStateChanged:(LinphoneGlobalState)state withMessage:(const char *)message { + LOGI(@"onGlobalStateChanged: %d (message: %s)", state, message); - NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt:state], @"state", - [NSString stringWithUTF8String:message?message:""], @"message", - nil]; + NSDictionary *dict = [NSDictionary + dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:state], @"state", + [NSString stringWithUTF8String:message ? message : ""], @"message", nil]; // dispatch the notification asynchronously - dispatch_async(dispatch_get_main_queue(), ^(void){ - [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneGlobalStateUpdate object:self userInfo:dict]; + dispatch_async(dispatch_get_main_queue(), ^(void) { + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneGlobalStateUpdate object:self userInfo:dict]; }); } - --(void)globalStateChangedNotificationHandler:(NSNotification*)notif { - if( (LinphoneGlobalState)[[[notif userInfo] valueForKey:@"state"] integerValue] == LinphoneGlobalOn){ +- (void)globalStateChangedNotificationHandler:(NSNotification *)notif { + if ((LinphoneGlobalState)[[[notif userInfo] valueForKey:@"state"] integerValue] == LinphoneGlobalOn) { [self finishCoreConfiguration]; } } - #pragma mark - Configuring status changed -static void linphone_iphone_configuring_status_changed(LinphoneCore *lc, LinphoneConfiguringState status, const char *message) { - [(LinphoneManager*)linphone_core_get_user_data(lc) onConfiguringStatusChanged:status withMessage:message]; +static void linphone_iphone_configuring_status_changed(LinphoneCore *lc, LinphoneConfiguringState status, + const char *message) { + [(__bridge LinphoneManager *)linphone_core_get_user_data(lc) onConfiguringStatusChanged:status withMessage:message]; } --(void)onConfiguringStatusChanged:(LinphoneConfiguringState)status withMessage:(const char*)message { - [LinphoneLogger log:LinphoneLoggerLog format:@"onConfiguringStatusChanged: %d (message: %s)", status, message]; +- (void)onConfiguringStatusChanged:(LinphoneConfiguringState)status withMessage:(const char *)message { + LOGI(@"onConfiguringStatusChanged: %s %@", linphone_configuring_state_to_string(status), + message ? [NSString stringWithFormat:@"(message: %s)", message] : @""); - NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt:status], @"state", - [NSString stringWithUTF8String:message?message:""], @"message", - nil]; + NSDictionary *dict = [NSDictionary + dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:status], @"state", + [NSString stringWithUTF8String:message ? message : ""], @"message", nil]; // dispatch the notification asynchronously - dispatch_async(dispatch_get_main_queue(), ^(void){ - [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneConfiguringStateUpdate object:self userInfo:dict]; + dispatch_async(dispatch_get_main_queue(), ^(void) { + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneConfiguringStateUpdate + object:self + userInfo:dict]; }); } - --(void)configuringStateChangedNotificationHandler:(NSNotification*)notif { - if( (LinphoneConfiguringState)[[[notif userInfo] valueForKey:@"state"] integerValue] == LinphoneConfiguringSuccessful){ +- (void)configuringStateChangedNotificationHandler:(NSNotification *)notif { + if ((LinphoneConfiguringState)[[[notif userInfo] valueForKey:@"state"] integerValue] == + LinphoneConfiguringSuccessful) { wasRemoteProvisioned = TRUE; } else { wasRemoteProvisioned = FALSE; } } - #pragma mark - Registration State Functions -- (void)onRegister:(LinphoneCore *)lc cfg:(LinphoneProxyConfig*) cfg state:(LinphoneRegistrationState) state message:(const char*) message { - [LinphoneLogger logc:LinphoneLoggerLog format:"NEW REGISTRATION STATE: '%s' (message: '%s')", linphone_registration_state_to_string(state), message]; +- (void)onRegister:(LinphoneCore *)lc + cfg:(LinphoneProxyConfig *)cfg + state:(LinphoneRegistrationState)state + message:(const char *)message { + LOGI(@"New registration state: %s (message: %s)", linphone_registration_state_to_string(state), message); // Post event - NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt:state], @"state", - [NSValue valueWithPointer:cfg], @"cfg", - [NSString stringWithUTF8String:message], @"message", - nil]; + NSDictionary *dict = [NSDictionary + dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:state], @"state", [NSValue valueWithPointer:cfg], @"cfg", + [NSString stringWithUTF8String:message], @"message", nil]; [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneRegistrationUpdate object:self userInfo:dict]; } -static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyConfig* cfg, LinphoneRegistrationState state,const char* message) { - [(LinphoneManager*)linphone_core_get_user_data(lc) onRegister:lc cfg:cfg state:state message:message]; +static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyConfig *cfg, + LinphoneRegistrationState state, const char *message) { + [(__bridge LinphoneManager *)linphone_core_get_user_data(lc) onRegister:lc cfg:cfg state:state message:message]; } +#pragma mark - Auth info Function + +static void linphone_iphone_popup_password_request(LinphoneCore *lc, const char *realmC, const char *usernameC, + const char *domainC) { + // let the wizard handle its own errors + if ([PhoneMainView.instance currentView] != AssistantView.compositeViewDescription) { + static DTAlertView *alertView = nil; + + // avoid having multiple popups + if ([alertView isVisible]) { + [alertView dismissWithClickedButtonIndex:0 animated:NO]; + } + + // dont pop up if we are in background, in any case we will refresh registers when entering + // the application again + if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) { + return; + } + + NSString *realm = [NSString stringWithUTF8String:realmC]; + NSString *username = [NSString stringWithUTF8String:usernameC]; + NSString *domain = [NSString stringWithUTF8String:domainC]; + alertView = [[DTAlertView alloc] + initWithTitle:NSLocalizedString(@"Authentication needed.", nil) + message:[NSString + stringWithFormat:NSLocalizedString(@"Registration failed because authentication is " + @"missing or invalid for %@@%@.\nYou can " + @"provide password again, or check your " + @"account configuration in the settings.", + nil), + username, realm] + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Cancel", nil) + otherButtonTitles:nil]; + + alertView.alertViewStyle = UIAlertViewStyleSecureTextInput; + [alertView addButtonWithTitle:NSLocalizedString(@"Confirm password", nil) + block:^{ + NSString *password = [alertView textFieldAtIndex:0].text; + LinphoneAuthInfo *info = + linphone_auth_info_new(username.UTF8String, NULL, password.UTF8String, NULL, + realm.UTF8String, domain.UTF8String); + linphone_core_add_auth_info([LinphoneManager getLc], info); + [LinphoneManager.instance refreshRegisters]; + }]; + [alertView addButtonWithTitle:NSLocalizedString(@"Go to settings", nil) + block:^{ + SettingsView *view = VIEW(SettingsView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; + }]; + [alertView show]; + } +} #pragma mark - Text Received Functions -- (void)onMessageReceived:(LinphoneCore *)lc room:(LinphoneChatRoom *)room message:(LinphoneChatMessage*)msg { - +- (void)onMessageReceived:(LinphoneCore *)lc room:(LinphoneChatRoom *)room message:(LinphoneChatMessage *)msg { if (silentPushCompletion) { - // we were woken up by a silent push. Call the completion handler with NEWDATA // so that the push is notified to the user - [LinphoneLogger log:LinphoneLoggerLog format:@"onMessageReceived - handler %p", silentPushCompletion]; + LOGI(@"onMessageReceived - handler %p", silentPushCompletion); silentPushCompletion(UIBackgroundFetchResultNewData); silentPushCompletion = nil; } - const LinphoneAddress* remoteAddress = linphone_chat_message_get_from_address(msg); - char* c_address = linphone_address_as_string_uri_only(remoteAddress); - NSString* address = [NSString stringWithUTF8String:c_address]; - NSString* remote_uri = [NSString stringWithUTF8String:c_address]; - const char* call_id = linphone_chat_message_get_custom_header(msg, "Call-ID"); - NSString* callID = [NSString stringWithUTF8String:call_id]; + NSString *callID = [NSString stringWithUTF8String:linphone_chat_message_get_custom_header(msg, "Call-ID")]; + const LinphoneAddress *remoteAddress = linphone_chat_message_get_from_address(msg); + NSString *from = [FastAddressBook displayNameForAddress:remoteAddress]; + char *c_address = linphone_address_as_string_uri_only(remoteAddress); + NSString *remote_uri = [NSString stringWithUTF8String:c_address]; + const char *chat = linphone_chat_message_get_text(msg); + if (chat == NULL) + chat = ""; ms_free(c_address); if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) { - - ABRecordRef contact = [fastAddressBook getContact:address]; - if(contact) { - address = [FastAddressBook getContactDisplayName:contact]; - } else { - if ([[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"] == true) { - LinphoneAddress *linphoneAddress = linphone_address_new([address cStringUsingEncoding:[NSString defaultCStringEncoding]]); - address = [NSString stringWithUTF8String:linphone_address_get_username(linphoneAddress)]; - linphone_address_destroy(linphoneAddress); - } - } - if(address == nil) { - address = NSLocalizedString(@"Unknown", nil); - } - // Create a new notification - UILocalNotification* notif = [[[UILocalNotification alloc] init] autorelease]; + UILocalNotification *notif = [[UILocalNotification alloc] init]; if (notif) { notif.repeatInterval = 0; - if( [[UIDevice currentDevice].systemVersion floatValue] >= 8){ - notif.category = @"incoming_msg"; - } - notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_MSG",nil), address]; - notif.alertAction = NSLocalizedString(@"Show", nil); - notif.soundName = @"msg.caf"; - notif.userInfo = @{@"from":address, @"from_addr":remote_uri, @"call-id":callID}; + if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) { + notif.category = @"incoming_msg"; + } + if ([[LinphoneManager instance] lpConfigBoolForKey:@"show_msg_in_notif" withDefault:YES]) { + notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_FULLMSG", nil), from, @(chat)]; + } else { + notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_MSG", nil), from]; + } + notif.alertAction = NSLocalizedString(@"Show", nil); + notif.soundName = @"sounds/msg.caf"; + notif.userInfo = @{ @"from" : from, @"from_addr" : remote_uri, @"call-id" : callID }; [[UIApplication sharedApplication] presentLocalNotificationNow:notif]; } } // Post event - NSDictionary* dict = @{@"room" :[NSValue valueWithPointer:room], - @"from_address":[NSValue valueWithPointer:linphone_chat_message_get_from_address(msg)], - @"message" :[NSValue valueWithPointer:msg], - @"call-id" : callID}; + NSDictionary *dict = @{ + @"room" : [NSValue valueWithPointer:room], + @"from_address" : [NSValue valueWithPointer:linphone_chat_message_get_from_address(msg)], + @"message" : [NSValue valueWithPointer:msg], + @"call-id" : callID + }; - [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self userInfo:dict]; + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneMessageReceived object:self userInfo:dict]; } static void linphone_iphone_message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message) { - [(LinphoneManager*)linphone_core_get_user_data(lc) onMessageReceived:lc room:room message:message]; + [(__bridge LinphoneManager *)linphone_core_get_user_data(lc) onMessageReceived:lc room:room message:message]; } -- (void)onNotifyReceived:(LinphoneCore *)lc event:(LinphoneEvent *)lev notifyEvent:(const char *)notified_event content:(const LinphoneContent *)body { +- (void)onNotifyReceived:(LinphoneCore *)lc + event:(LinphoneEvent *)lev + notifyEvent:(const char *)notified_event + content:(const LinphoneContent *)body { // Post event - NSMutableDictionary* dict = [NSMutableDictionary dictionary]; + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; [dict setObject:[NSValue valueWithPointer:lev] forKey:@"event"]; [dict setObject:[NSString stringWithUTF8String:notified_event] forKey:@"notified_event"]; if (body != NULL) { [dict setObject:[NSValue valueWithPointer:body] forKey:@"content"]; } [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneNotifyReceived object:self userInfo:dict]; - } -static void linphone_iphone_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, const LinphoneContent *body) { - [(LinphoneManager*)linphone_core_get_user_data(lc) onNotifyReceived:lc event:lev notifyEvent:notified_event content:body]; +static void linphone_iphone_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, + const LinphoneContent *body) { + [(__bridge LinphoneManager *)linphone_core_get_user_data(lc) onNotifyReceived:lc + event:lev + notifyEvent:notified_event + content:body]; +} + +static void linphone_iphone_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t on, + const char *authentication_token) { + [(__bridge LinphoneManager *)linphone_core_get_user_data(lc) onCallEncryptionChanged:lc + call:call + on:on + token:authentication_token]; +} + +- (void)onCallEncryptionChanged:(LinphoneCore *)lc + call:(LinphoneCall *)call + on:(BOOL)on + token:(const char *)authentication_token { + // Post event + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + [dict setObject:[NSValue valueWithPointer:call] forKey:@"call"]; + [dict setObject:[NSNumber numberWithBool:on] forKey:@"on"]; + [dict setObject:[NSString stringWithUTF8String:authentication_token] forKey:@"token"]; + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCallEncryptionChanged + object:self + userInfo:dict]; } #pragma mark - Message composition start -- (void)onMessageComposeReceived:(LinphoneCore*)core forRoom:(LinphoneChatRoom*)room { +- (void)onMessageComposeReceived:(LinphoneCore *)core forRoom:(LinphoneChatRoom *)room { [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextComposeEvent object:self - userInfo:@{@"room":[NSValue valueWithPointer:room]}]; + userInfo:@{ + @"room" : [NSValue valueWithPointer:room] + }]; } -static void linphone_iphone_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room){ - [(LinphoneManager*)linphone_core_get_user_data(lc) onMessageComposeReceived:lc forRoom:room]; +static void linphone_iphone_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) { + [(__bridge LinphoneManager *)linphone_core_get_user_data(lc) onMessageComposeReceived:lc forRoom:room]; } - - #pragma mark - Network Functions -- (SCNetworkReachabilityRef) getProxyReachability { +- (SCNetworkReachabilityRef)getProxyReachability { return proxyReachability; } + (void)kickOffNetworkConnection { - static BOOL in_progress = FALSE; - if( in_progress ){ - Linphone_warn(@"Connection kickoff already in progress"); - return; - } - in_progress = TRUE; + static BOOL in_progress = FALSE; + if (in_progress) { + LOGW(@"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); - BOOL res = CFWriteStreamOpen (writeStream); - const char* buff="hello"; - time_t start = time(NULL); - time_t loop_time; + 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); + BOOL res = CFWriteStreamOpen(writeStream); + const char *buff = "hello"; + 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; - } + if (res == FALSE) { + LOGI(@"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++; - } + // 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; + if (status == kCFStreamStatusOpen) { + CFWriteStreamWrite(writeStream, (const UInt8 *)buff, strlen(buff)); + } else if (!timeout_reached) { + CFErrorRef error = CFWriteStreamCopyError(writeStream); + LOGD(@"CFStreamError: %@", error); + CFRelease(error); + } else if (timeout_reached) { + LOGI(@"CFStream timeout reached"); + } + CFWriteStreamClose(writeStream); + CFRelease(writeStream); + in_progress = FALSE; }); } -+ (NSString*)getCurrentWifiSSID { ++ (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")]; + CFDictionaryRef dict = CNCopyCurrentNetworkInfo((CFStringRef) @"en0"); + if (dict) { + LOGI(@"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."]; +static void showNetworkFlags(SCNetworkReachabilityFlags flags) { + NSMutableString *log = [[NSMutableString alloc] initWithString:@"Network connection flags: "]; + if (flags == 0) + [log appendString:@"no flags."]; if (flags & kSCNetworkReachabilityFlagsTransientConnection) - [LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsTransientConnection"]; + [log appendString:@"kSCNetworkReachabilityFlagsTransientConnection, "]; if (flags & kSCNetworkReachabilityFlagsReachable) - [LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsReachable"]; + [log appendString:@"kSCNetworkReachabilityFlagsReachable, "]; if (flags & kSCNetworkReachabilityFlagsConnectionRequired) - [LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsConnectionRequired"]; + [log appendString:@"kSCNetworkReachabilityFlagsConnectionRequired, "]; if (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) - [LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsConnectionOnTraffic"]; + [log appendString:@"kSCNetworkReachabilityFlagsConnectionOnTraffic, "]; if (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) - [LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsConnectionOnDemand"]; + [log appendString:@"kSCNetworkReachabilityFlagsConnectionOnDemand, "]; if (flags & kSCNetworkReachabilityFlagsIsLocalAddress) - [LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsIsLocalAddress"]; + [log appendString:@"kSCNetworkReachabilityFlagsIsLocalAddress, "]; if (flags & kSCNetworkReachabilityFlagsIsDirect) - [LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsIsDirect"]; + [log appendString:@"kSCNetworkReachabilityFlagsIsDirect, "]; if (flags & kSCNetworkReachabilityFlagsIsWWAN) - [LinphoneLogger logc:LinphoneLoggerLog format:"kSCNetworkReachabilityFlagsIsWWAN"]; + [log appendString:@"kSCNetworkReachabilityFlagsIsWWAN, "]; + LOGI(@"%@", log); } -static void networkReachabilityNotification(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { +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; + if ([newSSID compare:mgr.SSID] == NSOrderedSame) + return; mgr.SSID = newSSID; if (SCNetworkReachabilityGetFlags([mgr getProxyReachability], &flags)) { - networkReachabilityCallBack([mgr getProxyReachability],flags,nil); + networkReachabilityCallBack([mgr getProxyReachability], flags, nil); } } -void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* nilCtx){ +void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *nilCtx) { showNetworkFlags(flags); - LinphoneManager* lLinphoneMgr = [LinphoneManager instance]; - SCNetworkReachabilityFlags networkDownFlags=kSCNetworkReachabilityFlagsConnectionRequired |kSCNetworkReachabilityFlagsConnectionOnTraffic | kSCNetworkReachabilityFlagsConnectionOnDemand; + LinphoneManager *lm = [LinphoneManager instance]; + SCNetworkReachabilityFlags networkDownFlags = kSCNetworkReachabilityFlagsConnectionRequired | + kSCNetworkReachabilityFlagsConnectionOnTraffic | + kSCNetworkReachabilityFlagsConnectionOnDemand; if (theLinphoneCore != nil) { - LinphoneProxyConfig* proxy; - linphone_core_get_default_proxy(theLinphoneCore, &proxy); + LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(theLinphoneCore); - struct NetworkReachabilityContext* ctx = nilCtx ? ((struct NetworkReachabilityContext*)nilCtx) : 0; + struct NetworkReachabilityContext *ctx = nilCtx ? ((struct NetworkReachabilityContext *)nilCtx) : 0; if ((flags == 0) || (flags & networkDownFlags)) { linphone_core_set_network_reachable(theLinphoneCore, false); - lLinphoneMgr.connectivity = none; + lm.connectivity = none; [LinphoneManager kickOffNetworkConnection]; } else { LinphoneTunnel *tunnel = linphone_core_get_tunnel([LinphoneManager getLc]); - Connectivity newConnectivity; - BOOL isWifiOnly = lp_config_get_int(lLinphoneMgr.configDb, LINPHONERC_APPLICATION_KEY, "wifi_only_preference",FALSE); + Connectivity newConnectivity; + BOOL isWifiOnly = [lm lpConfigBoolForKey:@"wifi_only_preference" withDefault:FALSE]; if (!ctx || ctx->testWWan) - newConnectivity = flags & kSCNetworkReachabilityFlagsIsWWAN ? wwan:wifi; + newConnectivity = flags & kSCNetworkReachabilityFlagsIsWWAN ? wwan : wifi; else newConnectivity = wifi; - if (newConnectivity == wwan - && proxy - && isWifiOnly - && (lLinphoneMgr.connectivity == newConnectivity || lLinphoneMgr.connectivity == none)) { + if (newConnectivity == wwan && proxy && isWifiOnly && + (lm.connectivity == newConnectivity || lm.connectivity == none)) { linphone_proxy_config_expires(proxy, 0); - } else if (proxy){ - NSInteger defaultExpire = [[LinphoneManager instance] lpConfigIntForKey:@"default_expires"]; - if (defaultExpire>=0) + } else if (proxy) { + NSInteger defaultExpire = [lm lpConfigIntForKey:@"default_expires"]; + if (defaultExpire >= 0) linphone_proxy_config_expires(proxy, (int)defaultExpire); - //else keep default value from linphonecore + // else keep default value from linphonecore } - if (lLinphoneMgr.connectivity != newConnectivity) { - if (tunnel) linphone_tunnel_reconnect(tunnel); + if (lm.connectivity != newConnectivity) { + if (tunnel) + linphone_tunnel_reconnect(tunnel); // connectivity has changed - linphone_core_set_network_reachable(theLinphoneCore,false); + linphone_core_set_network_reachable(theLinphoneCore, false); if (newConnectivity == wwan && proxy && isWifiOnly) { linphone_proxy_config_expires(proxy, 0); } - linphone_core_set_network_reachable(theLinphoneCore,true); + linphone_core_set_network_reachable(theLinphoneCore, true); linphone_core_iterate(theLinphoneCore); - [LinphoneLogger logc:LinphoneLoggerLog format:"Network connectivity changed to type [%s]",(newConnectivity==wifi?"wifi":"wwan")]; + LOGI(@"Network connectivity changed to type [%s]", (newConnectivity == wifi ? "wifi" : "wwan")); } - lLinphoneMgr.connectivity=newConnectivity; - switch (lLinphoneMgr.tunnelMode) { + lm.connectivity = newConnectivity; + switch (lm.tunnelMode) { case tunnel_wwan: - linphone_tunnel_enable(tunnel,lLinphoneMgr.connectivity == wwan); + linphone_tunnel_enable(tunnel, lm.connectivity == wwan); break; case tunnel_auto: linphone_tunnel_auto_detect(tunnel); break; default: - //nothing to do + // nothing to do break; } } if (ctx && ctx->networkStateChanged) { - (*ctx->networkStateChanged)(lLinphoneMgr.connectivity); + (*ctx->networkStateChanged)(lm.connectivity); } } } - (void)setupNetworkReachabilityCallback { - SCNetworkReachabilityContext *ctx=NULL; - //any internet cnx + SCNetworkReachabilityContext *ctx = NULL; + // any internet cnx struct sockaddr_in zeroAddress; bzero(&zeroAddress, sizeof(zeroAddress)); zeroAddress.sin_len = sizeof(zeroAddress); zeroAddress.sin_family = AF_INET; if (proxyReachability) { - [LinphoneLogger logc:LinphoneLoggerLog format:"Cancelling old network reachability"]; + LOGI(@"Cancelling old network reachability"); SCNetworkReachabilityUnscheduleFromRunLoop(proxyReachability, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); CFRelease(proxyReachability); proxyReachability = nil; @@ -1173,95 +1236,87 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach // 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); + _SSID = [LinphoneManager getCurrentWifiSSID]; + CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), (__bridge const void *)(self), + CFSTR("com.apple.system.config.network_change"), NULL); + CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), (__bridge const void *)(self), + networkReachabilityNotification, CFSTR("com.apple.system.config.network_change"), + NULL, CFNotificationSuspensionBehaviorDeliverImmediately); - proxyReachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress); + proxyReachability = + SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)&zeroAddress); - if (!SCNetworkReachabilitySetCallback(proxyReachability, (SCNetworkReachabilityCallBack)networkReachabilityCallBack, ctx)){ - [LinphoneLogger logc:LinphoneLoggerError format:"Cannot register reachability cb: %s", SCErrorString(SCError())]; + if (!SCNetworkReachabilitySetCallback(proxyReachability, (SCNetworkReachabilityCallBack)networkReachabilityCallBack, + ctx)) { + LOGE(@"Cannot register reachability cb: %s", SCErrorString(SCError())); return; } - if(!SCNetworkReachabilityScheduleWithRunLoop(proxyReachability, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)){ - [LinphoneLogger logc:LinphoneLoggerError format:"Cannot register schedule reachability cb: %s", SCErrorString(SCError())]; + if (!SCNetworkReachabilityScheduleWithRunLoop(proxyReachability, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) { + LOGE(@"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 + + // 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)) { - networkReachabilityCallBack(proxyReachability,flags,nil); + networkReachabilityCallBack(proxyReachability, flags, nil); } } - (NetworkType)network { - if( [[[UIDevice currentDevice] systemVersion] floatValue] < 7 ){ + if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7) { UIApplication *app = [UIApplication sharedApplication]; - NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews]; + NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews]; NSNumber *dataNetworkItemView = nil; for (id subview in subviews) { - if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) { + if ([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) { dataNetworkItemView = subview; break; } } - NSNumber *number = (NSNumber*)[dataNetworkItemView valueForKey:@"dataNetworkType"]; + NSNumber *number = (NSNumber *)[dataNetworkItemView valueForKey:@"dataNetworkType"]; return [number intValue]; } else { - CTTelephonyNetworkInfo* info = [[CTTelephonyNetworkInfo alloc] init]; - NSString* currentRadio = info.currentRadioAccessTechnology; - if( [currentRadio isEqualToString:CTRadioAccessTechnologyEdge]){ + CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init]; + NSString *currentRadio = info.currentRadioAccessTechnology; + if ([currentRadio isEqualToString:CTRadioAccessTechnologyEdge]) { return network_2g; - } else if ([currentRadio isEqualToString:CTRadioAccessTechnologyLTE]){ + } else if ([currentRadio isEqualToString:CTRadioAccessTechnologyLTE]) { return network_4g; } return network_3g; } } - -#pragma mark - +#pragma mark - VTable static LinphoneCoreVTable linphonec_vtable = { - .show =NULL, - .call_state_changed =(LinphoneCoreCallStateChangedCb)linphone_iphone_call_state, + .call_state_changed = (LinphoneCoreCallStateChangedCb)linphone_iphone_call_state, .registration_state_changed = linphone_iphone_registration_state, - .notify_presence_received=NULL, + .notify_presence_received = NULL, .new_subscription_requested = NULL, - .auth_info_requested = NULL, - .display_status = linphone_iphone_display_status, - .display_message=linphone_iphone_log, - .display_warning=linphone_iphone_log, - .display_url=NULL, - .text_received=NULL, - .message_received=linphone_iphone_message_received, - .dtmf_received=NULL, - .transfer_state_changed=linphone_iphone_transfer_state_changed, + .auth_info_requested = linphone_iphone_popup_password_request, + .message_received = linphone_iphone_message_received, + .dtmf_received = NULL, + .transfer_state_changed = linphone_iphone_transfer_state_changed, .is_composing_received = linphone_iphone_is_composing_received, .configuring_status = linphone_iphone_configuring_status_changed, .global_state_changed = linphone_iphone_global_state_changed, - .notify_received = linphone_iphone_notify_received + .notify_received = linphone_iphone_notify_received, + .call_encryption_changed = linphone_iphone_call_encryption_changed, }; -//scheduling loop +#pragma mark - + +// scheduling loop - (void)iterate { linphone_core_iterate(theLinphoneCore); } -- (void)audioSessionInterrupted:(NSNotification *)notification -{ +- (void)audioSessionInterrupted:(NSNotification *)notification { int interruptionType = [notification.userInfo[AVAudioSessionInterruptionTypeKey] intValue]; if (interruptionType == AVAudioSessionInterruptionTypeBegan) { [self beginInterruption]; @@ -1273,124 +1328,79 @@ static LinphoneCoreVTable linphonec_vtable = { /** Should be called once per linphone_core_new() */ - (void)finishCoreConfiguration { - //get default config from bundle + // get default config from bundle NSString *zrtpSecretsFileName = [LinphoneManager documentFile:@"zrtp_secrets"]; - NSString *chatDBFileName = [LinphoneManager documentFile:kLinphoneInternalChatDBFilename]; - const char* lRootCa = [[LinphoneManager bundleFile:@"rootca.pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; + NSString *chatDBFileName = [LinphoneManager documentFile:kLinphoneInternalChatDBFilename]; + const char *lRootCa = [[LinphoneManager bundleFile:@"rootca.pem"] UTF8String]; - linphone_core_set_user_agent(theLinphoneCore, [[[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"] stringByAppendingString:@"Iphone"] UTF8String], LINPHONE_IOS_VERSION); + NSString *device = [NSString + stringWithFormat:@"%@_%@_iOS%@", [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleDisplayName"], + [LinphoneUtils deviceName], UIDevice.currentDevice.systemVersion]; + linphone_core_set_user_agent(theLinphoneCore, device.UTF8String, LINPHONE_IOS_VERSION); - [_contactSipField release]; - _contactSipField = [[self lpConfigStringForKey:@"contact_im_type_value" withDefault:@"SIP"] retain]; + _contactSipField = [self lpConfigStringForKey:@"contact_im_type_value" withDefault:@"SIP"]; - - fastAddressBook = [[FastAddressBook alloc] init]; + if (fastAddressBook == nil) { + fastAddressBook = [[FastAddressBook alloc] init]; + } linphone_core_set_root_ca(theLinphoneCore, lRootCa); - // Set audio assets - const char* lRing = [[LinphoneManager bundleFile:@"ring.wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; - linphone_core_set_ring(theLinphoneCore, lRing); - const char* lRingBack = [[LinphoneManager bundleFile:@"ringback.wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; - linphone_core_set_ringback(theLinphoneCore, lRingBack); - const char* lPlay = [[LinphoneManager bundleFile:@"hold.wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; - linphone_core_set_play_file(theLinphoneCore, lPlay); - linphone_core_set_zrtp_secrets_file(theLinphoneCore, [zrtpSecretsFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]); - linphone_core_set_chat_database_path(theLinphoneCore, [chatDBFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]); + linphone_core_set_zrtp_secrets_file(theLinphoneCore, [zrtpSecretsFileName UTF8String]); + linphone_core_set_chat_database_path(theLinphoneCore, [chatDBFileName UTF8String]); + linphone_core_set_call_logs_database_path(theLinphoneCore, [chatDBFileName UTF8String]); - // we need to proceed to the migration *after* the chat database was opened, so that we know it is in consistent state - BOOL migrated = [self migrateChatDBIfNeeded:theLinphoneCore]; - if( migrated ){ - // if a migration was performed, we should reinitialize the chat database - linphone_core_set_chat_database_path(theLinphoneCore, [chatDBFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]); - } - - /* AVPF migration */ - if( [self lpConfigBoolForKey:@"avpf_migration_done" forSection:@"app"] == FALSE ){ - const MSList* proxies = linphone_core_get_proxy_config_list(theLinphoneCore); - while(proxies){ - LinphoneProxyConfig* proxy = (LinphoneProxyConfig*)proxies->data; - const char* addr = linphone_proxy_config_get_addr(proxy); - // we want to enable AVPF for the proxies - if( addr && strstr(addr, "sip.linphone.org") != 0 ){ - Linphone_log(@"Migrating proxy config to use AVPF"); - linphone_proxy_config_enable_avpf(proxy, TRUE); - } - proxies = proxies->next; - } - [self lpConfigSetBool:TRUE forKey:@"avpf_migration_done"]; - } - /* Quality Reporting migration */ - if( [self lpConfigBoolForKey:@"quality_report_migration_done" forSection:@"app"] == FALSE ){ - const MSList* proxies = linphone_core_get_proxy_config_list(theLinphoneCore); - while(proxies){ - LinphoneProxyConfig* proxy = (LinphoneProxyConfig*)proxies->data; - const char* addr = linphone_proxy_config_get_addr(proxy); - // we want to enable quality reporting for the proxies that are on linphone.org - if( addr && strstr(addr, "sip.linphone.org") != 0 ){ - Linphone_log(@"Migrating proxy config to send quality report"); - linphone_proxy_config_set_quality_reporting_collector(proxy, "sip:voip-metrics@sip.linphone.org"); - linphone_proxy_config_set_quality_reporting_interval(proxy, 180); - linphone_proxy_config_enable_quality_reporting(proxy, TRUE); - } - proxies = proxies->next; - } - [self lpConfigSetBool:TRUE forKey:@"quality_report_migration_done"]; - } + [self migrationLinphoneSettings]; [self setupNetworkReachabilityCallback]; - NSString* path = [LinphoneManager bundleFile:@"nowebcamCIF.jpg"]; + NSString *path = [LinphoneManager bundleFile:@"nowebcamCIF.jpg"]; if (path) { - const char* imagePath = [path cStringUsingEncoding:[NSString defaultCStringEncoding]]; - [LinphoneLogger logc:LinphoneLoggerLog format:"Using '%s' as source image for no webcam", imagePath]; + const char *imagePath = [path UTF8String]; + LOGI(@"Using '%s' as source image for no webcam", imagePath); linphone_core_set_static_picture(theLinphoneCore, imagePath); } /*DETECT cameras*/ - frontCamId= backCamId=nil; - char** camlist = (char**)linphone_core_get_video_devices(theLinphoneCore); - for (char* cam = *camlist;*camlist!=NULL;cam=*++camlist) { - if (strcmp(FRONT_CAM_NAME, cam)==0) { + frontCamId = backCamId = nil; + char **camlist = (char **)linphone_core_get_video_devices(theLinphoneCore); + for (char *cam = *camlist; *camlist != NULL; cam = *++camlist) { + if (strcmp(FRONT_CAM_NAME, cam) == 0) { frontCamId = cam; - //great set default cam to front + // great set default cam to front linphone_core_set_video_device(theLinphoneCore, cam); } - if (strcmp(BACK_CAM_NAME, cam)==0) { + if (strcmp(BACK_CAM_NAME, cam) == 0) { backCamId = cam; } - } - if (![LinphoneManager isNotIphone3G]){ - PayloadType *pt=linphone_core_find_payload_type(theLinphoneCore,"SILK",24000,-1); + if (![LinphoneManager isNotIphone3G]) { + PayloadType *pt = linphone_core_find_payload_type(theLinphoneCore, "SILK", 24000, -1); if (pt) { - linphone_core_enable_payload_type(theLinphoneCore,pt,FALSE); - [LinphoneLogger logc:LinphoneLoggerWarning format:"SILK/24000 and video disabled on old iPhone 3G"]; + linphone_core_enable_payload_type(theLinphoneCore, pt, FALSE); + LOGW(@"SILK/24000 and video disabled on old iPhone 3G"); } - linphone_core_enable_video(theLinphoneCore, FALSE, FALSE); + linphone_core_enable_video_display(theLinphoneCore, FALSE); + linphone_core_enable_video_capture(theLinphoneCore, FALSE); } - [LinphoneLogger logc:LinphoneLoggerWarning format:"Linphone [%s] started on [%s]", linphone_core_get_version(), [[UIDevice currentDevice].model cStringUsingEncoding:[NSString defaultCStringEncoding]]]; - + LOGI(@"Linphone [%s] started on [%s]", linphone_core_get_version(), [[UIDevice currentDevice].model UTF8String]); // Post event - NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore] - forKey:@"core"]; + NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore] forKey:@"core"]; [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCoreUpdate object:[LinphoneManager instance] userInfo:dict]; - } - static BOOL libStarted = FALSE; -- (void)startLibLinphone { +- (void)startLinphoneCore { - if ( libStarted ) { - [LinphoneLogger logc:LinphoneLoggerError format:"Liblinphone is already initialized!"]; + if (libStarted) { + LOGE(@"Liblinphone is already initialized!"); return; } @@ -1399,179 +1409,195 @@ static BOOL libStarted = FALSE; connectivity = none; signal(SIGPIPE, SIG_IGN); - // create linphone core [self createLinphoneCore]; + + _iapManager = [[InAppProductsManager alloc] init]; + linphone_core_migrate_to_multi_transport(theLinphoneCore); // init audio session (just getting the instance will init) AVAudioSession *audioSession = [AVAudioSession sharedInstance]; - BOOL bAudioInputAvailable= audioSession.inputAvailable; - NSError* err; + BOOL bAudioInputAvailable = audioSession.inputAvailable; + NSError *err; - if( ![audioSession setActive:NO error: &err] && err ){ - NSLog(@"audioSession setActive failed: %@", [err description]); + if (![audioSession setActive:NO error:&err] && err) { + LOGE(@"audioSession setActive failed: %@", [err description]); } - if(!bAudioInputAvailable){ - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"No microphone",nil) - message:NSLocalizedString(@"You need to plug a microphone to your device to use this application.",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Ok",nil) - otherButtonTitles:nil ,nil]; + if (!bAudioInputAvailable) { + UIAlertView *error = [[UIAlertView alloc] + initWithTitle:NSLocalizedString(@"No microphone", nil) + message:NSLocalizedString( + @"You need to plug a microphone to your device to use this application.", nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Ok", nil) + otherButtonTitles:nil, nil]; [error show]; - [error release]; } - if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) { - //go directly to bg mode + if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) { + // go directly to bg mode [self enterBackgroundMode]; } - } - (void)createLinphoneCore { if (theLinphoneCore != nil) { - [LinphoneLogger logc:LinphoneLoggerLog format:"linphonecore is already created"]; + LOGI(@"linphonecore is already created"); return; } - [LinphoneLogger logc:LinphoneLoggerLog format:"Create linphonecore"]; - - connectivity=none; - - ms_init(); // Need to initialize mediastreamer2 before loading the plugins - - libmsilbc_init(); -#if defined (HAVE_SILK) - libmssilk_init(); -#endif -#ifdef HAVE_AMR - libmsamr_init(); //load amr plugin if present from the liblinphone sdk -#endif -#ifdef HAVE_X264 - libmsx264_init(); //load x264 plugin if present from the liblinphone sdk -#endif -#ifdef HAVE_OPENH264 - libmsopenh264_init(); //load openh264 plugin if present from the liblinphone sdk -#endif - -#if HAVE_G729 - libmsbcg729_init(); // load g729 plugin -#endif - linphone_core_set_log_collection_path([[LinphoneManager cacheDirectory] UTF8String]); [self setLogsEnabled:[self lpConfigBoolForKey:@"debugenable_preference"]]; + connectivity = none; + ms_init(); // Need to initialize mediastreamer2 before loading the plugins + // Load plugins if available in the linphone SDK - otherwise these calls will do nothing + libmsilbc_init(); + libmssilk_init(); + libmsamr_init(); + libmsx264_init(); + libmsopenh264_init(); + libmsbcg729_init(); + libmswebrtc_init(); - theLinphoneCore = linphone_core_new_with_config (&linphonec_vtable - ,configDb - ,self /* user_data */); - - + // Set audio assets + NSString *ring = ([LinphoneManager bundleFile:[self lpConfigStringForKey:@"local_ring" inSection:@"sound"]] + ?: [LinphoneManager bundleFile:@"notes_of_the_optimistic.caf"]) + .lastPathComponent; + NSString *ringback = ([LinphoneManager bundleFile:[self lpConfigStringForKey:@"ringback_tone" inSection:@"sound"]] + ?: [LinphoneManager bundleFile:@"ringback.wav"]) + .lastPathComponent; + NSString *hold = ([LinphoneManager bundleFile:[self lpConfigStringForKey:@"hold_music" inSection:@"sound"]] + ?: [LinphoneManager bundleFile:@"hold.caf"]) + .lastPathComponent; + [self lpConfigSetString:[LinphoneManager bundleFile:ring] forKey:@"local_ring" inSection:@"sound"]; + [self lpConfigSetString:[LinphoneManager bundleFile:ringback] forKey:@"ringback_tone" inSection:@"sound"]; + [self lpConfigSetString:[LinphoneManager bundleFile:hold] forKey:@"hold_music" inSection:@"sound"]; + theLinphoneCore = linphone_core_new_with_config(&linphonec_vtable, configDb, (__bridge void *)(self)); + LOGI(@"Create linphonecore %p", theLinphoneCore); /* 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]]; + const char *lRootCa = [[LinphoneManager bundleFile:@"rootca.pem"] UTF8String]; linphone_core_set_root_ca(theLinphoneCore, lRootCa); - linphone_core_set_user_certificates_path(theLinphoneCore,[[LinphoneManager cacheDirectory] UTF8String]); - - /* The core will call the linphone_iphone_configuring_status_changed callback when the remote provisioning is loaded (or skipped). + linphone_core_set_user_certificates_path(theLinphoneCore, [[LinphoneManager cacheDirectory] UTF8String]); + + /* The core will call the linphone_iphone_configuring_status_changed callback when the remote provisioning is loaded + (or skipped). Wait for this to finish the code configuration */ - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioSessionInterrupted:) name:AVAudioSessionInterruptionNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(globalStateChangedNotificationHandler:) name:kLinphoneGlobalStateUpdate object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(configuringStateChangedNotificationHandler:) name:kLinphoneConfiguringStateUpdate object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(audioSessionInterrupted:) + name:AVAudioSessionInterruptionNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(globalStateChangedNotificationHandler:) + name:kLinphoneGlobalStateUpdate + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(configuringStateChangedNotificationHandler:) + name:kLinphoneConfiguringStateUpdate + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(inappReady:) name:kIAPReady object:nil]; - /*call iterate once immediately in order to initiate background connections with sip server or remote provisioning grab, if any */ + /*call iterate once immediately in order to initiate background connections with sip server or remote provisioning + * grab, if any */ linphone_core_iterate(theLinphoneCore); // start scheduler - mIterateTimer = [NSTimer scheduledTimerWithTimeInterval:0.02 - target:self - selector:@selector(iterate) - userInfo:nil - repeats:YES]; + mIterateTimer = + [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(iterate) userInfo:nil repeats:YES]; } -- (void)destroyLibLinphone { +- (void)destroyLinphoneCore { [mIterateTimer invalidate]; - //just in case + // just in case [self removeCTCallCenterCb]; [[NSNotificationCenter defaultCenter] removeObserver:self]; - if (theLinphoneCore != nil) { //just in case application terminate before linphone core initialization - [LinphoneLogger logc:LinphoneLoggerLog format:"Destroy linphonecore"]; + if (theLinphoneCore != nil) { // just in case application terminate before linphone core initialization + + for (FileTransferDelegate *ftd in _fileTransferDelegates) { + [ftd stopAndDestroy]; + } + [_fileTransferDelegates removeAllObjects]; + linphone_core_destroy(theLinphoneCore); + LOGI(@"Destroy linphonecore %p", theLinphoneCore); theLinphoneCore = nil; ms_exit(); // Uninitialize mediastreamer2 // Post event - NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore] forKey:@"core"]; - [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCoreUpdate object:[LinphoneManager instance] userInfo:dict]; + NSDictionary *dict = + [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore] forKey:@"core"]; + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCoreUpdate + object:[LinphoneManager instance] + userInfo:dict]; SCNetworkReachabilityUnscheduleFromRunLoop(proxyReachability, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); if (proxyReachability) CFRelease(proxyReachability); - proxyReachability=nil; - + proxyReachability = nil; } - libStarted = FALSE; + libStarted = FALSE; } -- (void) resetLinphoneCore { - [self destroyLibLinphone]; +- (void)resetLinphoneCore { + [self destroyLinphoneCore]; [self createLinphoneCore]; // reset network state to trigger a new network connectivity assessment linphone_core_set_network_reachable(theLinphoneCore, FALSE); } -static int comp_call_id(const LinphoneCall* call , const char *callid) { +static int comp_call_id(const LinphoneCall *call, const char *callid) { if (linphone_call_log_get_call_id(linphone_call_get_call_log(call)) == nil) { - ms_error ("no callid for call [%p]", call); + ms_error("no callid for call [%p]", call); return 1; } return strcmp(linphone_call_log_get_call_id(linphone_call_get_call_log(call)), callid); } -- (void)cancelLocalNotifTimerForCallId:(NSString*)callid { - //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)cancelLocalNotifTimerForCallId:(NSString *)callid { + // 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 = + (__bridge LinphoneCallAppData *)(linphone_call_get_user_data((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 - 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)acceptCallForCallId:(NSString *)callid { + // 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 evenWithVideo:YES]; + return; + }; } -- (void)addPushCallId:(NSString*) 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])) { - Linphone_warn(@"Call id [%@] already handled",callid); - return; - }; - if ([pushCallIDs count] > 10 /*max number of pending notif*/) - [pushCallIDs removeObjectAtIndex:0]; +- (void)addPushCallId:(NSString *)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])) { + LOGW(@"Call id [%@] already handled", callid); + return; + }; + if ([pushCallIDs count] > 10 /*max number of pending notif*/) + [pushCallIDs removeObjectAtIndex:0]; - [pushCallIDs addObject:callid]; + [pushCallIDs addObject:callid]; } -- (BOOL)popPushCallID:(NSString*) callId { - for (NSString* pendingNotif in pushCallIDs) { - if ([pendingNotif compare:callId] == NSOrderedSame) { +- (BOOL)popPushCallID:(NSString *)callId { + for (NSString *pendingNotif in pushCallIDs) { + if ([pendingNotif compare:callId] == NSOrderedSame) { [pushCallIDs removeObject:pendingNotif]; return TRUE; } @@ -1586,93 +1612,88 @@ static int comp_call_id(const LinphoneCall* call , const char *callid) { } - (void)playMessageSound { - BOOL success = [self.messagePlayer play]; - if( !success ){ - Linphone_err(@"Could not play the message sound"); - } - AudioServicesPlaySystemSound([LinphoneManager instance].sounds.vibrate); + BOOL success = [self.messagePlayer play]; + if (!success) { + LOGE(@"Could not play the message sound"); + } + AudioServicesPlaySystemSound([LinphoneManager instance].sounds.vibrate); } -static int comp_call_state_paused (const LinphoneCall* call, const void* param) { +static int comp_call_state_paused(const LinphoneCall *call, const void *param) { return linphone_call_get_state(call) != LinphoneCallPaused; } -- (void) startCallPausedLongRunningTask { - pausedCallBgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^{ - [LinphoneLogger log:LinphoneLoggerWarning format:@"Call cannot be paused any more, too late"]; - [[UIApplication sharedApplication] endBackgroundTask:pausedCallBgTask]; +- (void)startCallPausedLongRunningTask { + pausedCallBgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ + LOGW(@"Call cannot be paused any more, too late"); + [[UIApplication sharedApplication] endBackgroundTask:pausedCallBgTask]; }]; - [LinphoneLogger log:LinphoneLoggerLog format:@"Long running task started, remaining [%g s] because at least one call is paused" - ,[[UIApplication sharedApplication] backgroundTimeRemaining]]; + LOGI(@"Long running task started, remaining [%g s] because at least one call is paused", + [[UIApplication sharedApplication] backgroundTimeRemaining]); } - (BOOL)enterBackgroundMode { - LinphoneProxyConfig* proxyCfg; - linphone_core_get_default_proxy(theLinphoneCore, &proxyCfg); - BOOL shouldEnterBgMode=FALSE; + LinphoneProxyConfig *proxyCfg = linphone_core_get_default_proxy_config(theLinphoneCore); + BOOL shouldEnterBgMode = FALSE; - //handle proxy config if any + // handle proxy config if any if (proxyCfg) { if ([[LinphoneManager instance] lpConfigBoolForKey:@"backgroundmode_preference"] || [[LinphoneManager instance] lpConfigBoolForKey:@"pushnotification_preference"]) { - //For registration register + // For registration register [self refreshRegisters]; } if ([[LinphoneManager instance] lpConfigBoolForKey:@"backgroundmode_preference"]) { - //register keepalive - if ([[UIApplication sharedApplication] setKeepAliveTimeout:600/*(NSTimeInterval)linphone_proxy_config_get_expires(proxyCfg)*/ - handler:^{ - [LinphoneLogger logc:LinphoneLoggerWarning format:"keepalive handler"]; - if (mLastKeepAliveDate) - [mLastKeepAliveDate release]; - mLastKeepAliveDate=[NSDate date]; - [mLastKeepAliveDate retain]; - if (theLinphoneCore == nil) { - [LinphoneLogger logc:LinphoneLoggerWarning format:"It seems that Linphone BG mode was deactivated, just skipping"]; - return; - } - //kick up network cnx, just in case - [self refreshRegisters]; - linphone_core_iterate(theLinphoneCore); - } - ]) { + // register keepalive + if ([[UIApplication sharedApplication] + setKeepAliveTimeout:600 /*(NSTimeInterval)linphone_proxy_config_get_expires(proxyCfg)*/ + handler:^{ + LOGW(@"keepalive handler"); + mLastKeepAliveDate = [NSDate date]; + if (theLinphoneCore == nil) { + LOGW(@"It seems that Linphone BG mode was deactivated, just skipping"); + return; + } + // kick up network cnx, just in case + [self refreshRegisters]; + linphone_core_iterate(theLinphoneCore); + }]) { - - [LinphoneLogger logc:LinphoneLoggerLog format:"keepalive handler succesfully registered"]; + LOGI(@"keepalive handler succesfully registered"); } else { - [LinphoneLogger logc:LinphoneLoggerLog format:"keepalive handler cannot be registered"]; + LOGI(@"keepalive handler cannot be registered"); } - shouldEnterBgMode=TRUE; + shouldEnterBgMode = TRUE; } } - LinphoneCall* currentCall = linphone_core_get_current_call(theLinphoneCore); - const MSList* callList = linphone_core_get_calls(theLinphoneCore); - if (!currentCall //no active call - && callList // at least one call in a non active state - && ms_list_find_custom((MSList*)callList, (MSCompareFunc) comp_call_state_paused, NULL)) { + LinphoneCall *currentCall = linphone_core_get_current_call(theLinphoneCore); + const MSList *callList = linphone_core_get_calls(theLinphoneCore); + if (!currentCall // no active call + && callList // at least one call in a non active state + && ms_list_find_custom((MSList *)callList, (MSCompareFunc)comp_call_state_paused, NULL)) { [self startCallPausedLongRunningTask]; } - if (callList){ + if (callList) { /*if at least one call exist, enter normal bg mode */ - shouldEnterBgMode=TRUE; + shouldEnterBgMode = TRUE; } /*stop the video preview*/ - if (theLinphoneCore){ + if (theLinphoneCore) { linphone_core_enable_video_preview(theLinphoneCore, FALSE); linphone_core_iterate(theLinphoneCore); } linphone_core_stop_dtmf_stream(theLinphoneCore); - [LinphoneLogger logc:LinphoneLoggerLog format:"Entering [%s] bg mode",shouldEnterBgMode?"normal":"lite"]; + LOGI(@"Entering [%s] bg mode", shouldEnterBgMode ? "normal" : "lite"); - if (!shouldEnterBgMode ) { - if([[LinphoneManager instance] lpConfigBoolForKey:@"pushnotification_preference"]) { - [LinphoneLogger logc:LinphoneLoggerLog format:"Keeping lc core to handle push"]; + if (!shouldEnterBgMode) { + if ([[LinphoneManager instance] lpConfigBoolForKey:@"pushnotification_preference"]) { + LOGI(@"Keeping lc core to handle push"); /*destroy voip socket if any and reset connectivity mode*/ - connectivity=none; + connectivity = none; linphone_core_set_network_reachable(theLinphoneCore, FALSE); return YES; } @@ -1685,60 +1706,92 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param) - (void)becomeActive { [self refreshRegisters]; if (pausedCallBgTask) { - [[UIApplication sharedApplication] endBackgroundTask:pausedCallBgTask]; - pausedCallBgTask=0; + [[UIApplication sharedApplication] endBackgroundTask:pausedCallBgTask]; + pausedCallBgTask = 0; } if (incallBgTask) { - [[UIApplication sharedApplication] endBackgroundTask:incallBgTask]; - incallBgTask=0; + [[UIApplication sharedApplication] endBackgroundTask:incallBgTask]; + incallBgTask = 0; } /*IOS specific*/ linphone_core_start_dtmf_stream(theLinphoneCore); /*start the video preview in case we are in the main view*/ - if ([LinphoneManager runningOnIpad] && linphone_core_video_enabled(theLinphoneCore) && [self lpConfigBoolForKey:@"preview_preference"]){ + if (IPAD && linphone_core_video_display_enabled(theLinphoneCore) && + [self lpConfigBoolForKey:@"preview_preference"]) { linphone_core_enable_video_preview(theLinphoneCore, TRUE); } /*check last keepalive handler date*/ - if (mLastKeepAliveDate!=Nil){ - NSDate *current=[NSDate date]; - if ([current timeIntervalSinceDate:mLastKeepAliveDate]>700){ - NSString *datestr=[mLastKeepAliveDate description]; - [LinphoneLogger logc:LinphoneLoggerWarning format:"keepalive handler was called for the last time at %@",datestr]; + if (mLastKeepAliveDate != Nil) { + NSDate *current = [NSDate date]; + if ([current timeIntervalSinceDate:mLastKeepAliveDate] > 700) { + NSString *datestr = [mLastKeepAliveDate description]; + LOGW(@"keepalive handler was called for the last time at %@", datestr); } } - } - (void)beginInterruption { - LinphoneCall* c = linphone_core_get_current_call(theLinphoneCore); - [LinphoneLogger logc:LinphoneLoggerLog format:"Sound interruption detected!"]; + LinphoneCall *c = linphone_core_get_current_call(theLinphoneCore); + LOGI(@"Sound interruption detected!"); if (c && linphone_call_get_state(c) == LinphoneCallStreamsRunning) { linphone_core_pause_call(theLinphoneCore, c); } } - (void)endInterruption { - [LinphoneLogger logc:LinphoneLoggerLog format:"Sound interruption ended!"]; + LOGI(@"Sound interruption ended!"); } -- (void)refreshRegisters{ - if (connectivity==none){ - //don't trust ios when he says there is no network. Create a new reachability context, the previous one might be mis-functionning. +- (void)refreshRegisters { + if (connectivity == none) { + // don't trust ios when he says there is no network. Create a new reachability context, the previous one might + // be mis-functionning. [self setupNetworkReachabilityCallback]; } - linphone_core_refresh_registers(theLinphoneCore);//just to make sure REGISTRATION is up to date + linphone_core_refresh_registers(theLinphoneCore); // just to make sure REGISTRATION is up to date } +- (void)renameDefaultSettings { + // rename .linphonerc to linphonerc to ease debugging: when downloading + // containers from MacOSX, Finder do not display hidden files leading + // to useless painful operations to display the .linphonerc file + NSString *src = [LinphoneManager documentFile:@".linphonerc"]; + NSString *dst = [LinphoneManager documentFile:@"linphonerc"]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *fileError = nil; + if ([fileManager fileExistsAtPath:src]) { + if ([fileManager fileExistsAtPath:dst]) { + [fileManager removeItemAtPath:src error:&fileError]; + LOGW(@"%@ already exists, simply removing %@ %@", dst, src, + fileError ? fileError.localizedDescription : @"successfully"); + } else { + [fileManager moveItemAtPath:src toPath:dst error:&fileError]; + LOGI(@"%@ moving to %@ %@", dst, src, fileError ? fileError.localizedDescription : @"successfully"); + } + } +} - (void)copyDefaultSettings { - NSString *src = [LinphoneManager bundleFile:[LinphoneManager runningOnIpad]?@"linphonerc~ipad":@"linphonerc"]; - NSString *dst = [LinphoneManager documentFile:@".linphonerc"]; + NSString *src = [LinphoneManager bundleFile:@"linphonerc"]; + NSString *srcIpad = [LinphoneManager bundleFile:@"linphonerc~ipad"]; + if (IPAD && [[NSFileManager defaultManager] fileExistsAtPath:srcIpad]) { + src = srcIpad; + } + NSString *dst = [LinphoneManager documentFile:@"linphonerc"]; [LinphoneManager copyFile:src destination:dst override:FALSE]; } - +- (void)overrideDefaultSettings { + NSString *factory = [LinphoneManager bundleFile:@"linphonerc-factory"]; + NSString *factoryIpad = [LinphoneManager bundleFile:@"linphonerc-factory~ipad"]; + if (IPAD && [[NSFileManager defaultManager] fileExistsAtPath:factoryIpad]) { + factory = factoryIpad; + } + NSString *confiFileName = [LinphoneManager documentFile:@"linphonerc"]; + configDb = lp_config_new_with_factory([confiFileName UTF8String], [factory UTF8String]); +} #pragma mark - Audio route Functions - (bool)allowSpeaker { @@ -1747,50 +1800,48 @@ static int comp_call_state_paused (const LinphoneCall* call, const void* param) UInt32 lNewRouteSize = sizeof(lNewRoute); OSStatus lStatus = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &lNewRouteSize, &lNewRoute); if (!lStatus && lNewRouteSize > 0) { - NSString *route = (NSString *) lNewRoute; - notallow = [route isEqualToString: @"Headset"] || - [route isEqualToString: @"Headphone"] || - [route isEqualToString: @"HeadphonesAndMicrophone"] || - [route isEqualToString: @"HeadsetInOut"] || - [route isEqualToString: @"Lineout"] || - [LinphoneManager runningOnIpad]; + NSString *route = (__bridge NSString *)lNewRoute; + notallow = [route isEqualToString:@"Headset"] || [route isEqualToString:@"Headphone"] || + [route isEqualToString:@"HeadphonesAndMicrophone"] || [route isEqualToString:@"HeadsetInOut"] || + [route isEqualToString:@"Lineout"] || IPAD; CFRelease(lNewRoute); } return !notallow; } -static void audioRouteChangeListenerCallback ( - void *inUserData, // 1 - AudioSessionPropertyID inPropertyID, // 2 - UInt32 inPropertyValueSize, // 3 - const void *inPropertyValue // 4 - ) { - if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return; // 5 - LinphoneManager* lm = (LinphoneManager*)inUserData; +static void audioRouteChangeListenerCallback(void *inUserData, // 1 + AudioSessionPropertyID inPropertyID, // 2 + UInt32 inPropertyValueSize, // 3 + const void *inPropertyValue // 4 + ) { + if (inPropertyID != kAudioSessionProperty_AudioRouteChange) + return; // 5 + LinphoneManager *lm = (__bridge LinphoneManager *)inUserData; bool speakerEnabled = false; CFStringRef lNewRoute = CFSTR("Unknown"); UInt32 lNewRouteSize = sizeof(lNewRoute); OSStatus lStatus = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &lNewRouteSize, &lNewRoute); if (!lStatus && lNewRouteSize > 0) { - NSString *route = (NSString *) lNewRoute; - [LinphoneLogger logc:LinphoneLoggerLog format:"Current audio route is [%s]", [route cStringUsingEncoding:[NSString defaultCStringEncoding]]]; + NSString *route = (__bridge NSString *)lNewRoute; + LOGI(@"Current audio route is [%s]", [route UTF8String]); - speakerEnabled = [route isEqualToString: @"Speaker"] || - [route isEqualToString: @"SpeakerAndMicrophone"]; - if (![LinphoneManager runningOnIpad] && [route isEqualToString:@"HeadsetBT"] && !speakerEnabled) { + speakerEnabled = [route isEqualToString:@"Speaker"] || [route isEqualToString:@"SpeakerAndMicrophone"]; + if (!IPAD && [route isEqualToString:@"HeadsetBT"] && !speakerEnabled) { lm.bluetoothEnabled = TRUE; lm.bluetoothAvailable = TRUE; - NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:lm.bluetoothAvailable], @"available", nil]; - [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneBluetoothAvailabilityUpdate object:lm userInfo:dict]; + NSDictionary *dict = [NSDictionary + dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:lm.bluetoothAvailable], @"available", nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneBluetoothAvailabilityUpdate + object:lm + userInfo:dict]; } else { lm.bluetoothEnabled = FALSE; } CFRelease(lNewRoute); } - if(speakerEnabled != lm.speakerEnabled) { // Reforce value + if (speakerEnabled != lm.speakerEnabled) { // Reforce value lm.speakerEnabled = lm.speakerEnabled; } } @@ -1798,22 +1849,21 @@ static void audioRouteChangeListenerCallback ( - (void)setSpeakerEnabled:(BOOL)enable { speakerEnabled = enable; - if(enable && [self allowSpeaker]) { + if (enable && [self allowSpeaker]) { UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; - AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute - , sizeof (audioRouteOverride) - , &audioRouteOverride); + AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), + &audioRouteOverride); bluetoothEnabled = FALSE; } else { UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None; - AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute - , sizeof (audioRouteOverride) - , &audioRouteOverride); + AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), + &audioRouteOverride); } if (bluetoothAvailable) { UInt32 bluetoothInputOverride = bluetoothEnabled; - AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput, sizeof(bluetoothInputOverride), &bluetoothInputOverride); + AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput, + sizeof(bluetoothInputOverride), &bluetoothInputOverride); } } @@ -1831,157 +1881,154 @@ static void audioRouteChangeListenerCallback ( #pragma mark - Call Functions -- (void)acceptCall:(LinphoneCall *)call { - LinphoneCallParams* lcallParams = linphone_core_create_call_params(theLinphoneCore,call); - if([self lpConfigBoolForKey:@"edge_opt_preference"]) { +- (void)acceptCall:(LinphoneCall *)call evenWithVideo:(BOOL)video { + LinphoneCallParams *lcallParams = linphone_core_create_call_params(theLinphoneCore, call); + if (!lcallParams) { + LOGW(@"Could not create call parameters for %p, call has probably already ended.", call); + return; + } + + if ([self lpConfigBoolForKey:@"edge_opt_preference"]) { bool low_bandwidth = self.network == network_2g; - if(low_bandwidth) { - [LinphoneLogger log:LinphoneLoggerLog format:@"Low bandwidth mode"]; + if (low_bandwidth) { + LOGI(@"Low bandwidth mode"); } linphone_call_params_enable_low_bandwidth(lcallParams, low_bandwidth); } + linphone_call_params_enable_video(lcallParams, video); - linphone_core_accept_call_with_params(theLinphoneCore,call, lcallParams); + linphone_core_accept_call_with_params(theLinphoneCore, call, lcallParams); } -- (void)call:(NSString *)address displayName:(NSString*)displayName transfer:(BOOL)transfer { +- (void)call:(NSString *)address displayName:(NSString *)displayName transfer:(BOOL)transfer { + // First verify that network is available, abort otherwise. if (!linphone_core_is_network_reachable(theLinphoneCore)) { - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Network Error",nil) - message:NSLocalizedString(@"There is no network connection available, enable WIFI or WWAN prior to place a call",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; + UIAlertView *error = [[UIAlertView alloc] + initWithTitle:NSLocalizedString(@"Network Error", nil) + message: + NSLocalizedString( + @"There is no network connection available, enable WIFI or WWAN prior to place a call", + nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Cancel", nil) + otherButtonTitles:nil]; [error show]; - [error release]; return; } - CTCallCenter* callCenter = [[CTCallCenter alloc] init]; - if ([callCenter currentCalls]!=nil) { - [LinphoneLogger logc:LinphoneLoggerError format:"GSM call in progress, cancelling outgoing SIP call request"]; - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Cannot make call",nil) - message:NSLocalizedString(@"Please terminate GSM call",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; + // Then check that no GSM calls are in progress, abort otherwise. + CTCallCenter *callCenter = [[CTCallCenter alloc] init]; + if ([callCenter currentCalls] != nil) { + LOGE(@"GSM call in progress, cancelling outgoing SIP call request"); + UIAlertView *error = + [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Cannot make call", nil) + message:NSLocalizedString(@"Please terminate GSM call first.", nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Cancel", nil) + otherButtonTitles:nil]; [error show]; - [error release]; - [callCenter release]; return; } - [callCenter release]; - - LinphoneProxyConfig* proxyCfg; - //get default proxy - linphone_core_get_default_proxy(theLinphoneCore,&proxyCfg); - LinphoneCallParams* lcallParams = linphone_core_create_default_call_parameters(theLinphoneCore); - if([self lpConfigBoolForKey:@"edge_opt_preference"]) { - bool low_bandwidth = self.network == network_2g; - if(low_bandwidth) { - [LinphoneLogger log:LinphoneLoggerLog format:@"Low bandwidth mode"]; - } - linphone_call_params_enable_low_bandwidth(lcallParams, low_bandwidth); - } - LinphoneCall* call=NULL; - - BOOL addressIsASCII = [address canBeConvertedToEncoding:[NSString defaultCStringEncoding]]; - - if ([address length] == 0) return; //just return - 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]; - - } - LinphoneAddress* linphoneAddress = linphone_core_interpret_url(theLinphoneCore, [address cStringUsingEncoding:[NSString defaultCStringEncoding]]); - - if (linphoneAddress) { - - if(displayName!=nil) { - linphone_address_set_display_name(linphoneAddress,[displayName cStringUsingEncoding:[NSString defaultCStringEncoding]]); - } - if ([[LinphoneManager instance] lpConfigBoolForKey:@"override_domain_with_default_one"]) - linphone_address_set_domain(linphoneAddress, [[[LinphoneManager instance] lpConfigStringForKey:@"domain" forSection:@"wizard"] cStringUsingEncoding:[NSString defaultCStringEncoding]]); - if(transfer) { - linphone_core_transfer_call(theLinphoneCore, linphone_core_get_current_call(theLinphoneCore), [address cStringUsingEncoding:[NSString defaultCStringEncoding]]); - } else { - call=linphone_core_invite_address_with_params(theLinphoneCore, linphoneAddress, lcallParams); - } - linphone_address_destroy(linphoneAddress); + LinphoneAddress *addr = NULL; + // Continue by checking that the provided address is a valid SIP address, abort otherwise. + if ([address length] == 0) { + // no address provided... nothing to do + } else if ((addr = linphone_core_interpret_url([LinphoneManager getLc], address.UTF8String)) == NULL) { + UIAlertView *error = [[UIAlertView alloc] + initWithTitle:NSLocalizedString(@"Invalid SIP address", nil) + message:NSLocalizedString(@"Either configure a SIP proxy server from settings prior to place a " + @"call or use a valid SIP address (I.E sip:john@example.net)", + nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Cancel", nil) + otherButtonTitles:nil]; + [error show]; } else { + // Finally we can make the call + LinphoneCallParams *lcallParams = linphone_core_create_call_params(theLinphoneCore, NULL); + if ([self lpConfigBoolForKey:@"edge_opt_preference"] && (self.network == network_2g)) { + LOGI(@"Enabling low bandwidth mode"); + linphone_call_params_enable_low_bandwidth(lcallParams, YES); + } - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid SIP address",nil) - message:NSLocalizedString(@"Either configure a SIP proxy server from settings prior to place a call or use a valid SIP address (I.E sip:john@example.net)",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; + if (displayName != nil) { + linphone_address_set_display_name(addr, displayName.UTF8String); + } + if ([[LinphoneManager instance] lpConfigBoolForKey:@"override_domain_with_default_one"]) { + linphone_address_set_domain( + addr, [[[LinphoneManager instance] lpConfigStringForKey:@"domain" inSection:@"assistant"] UTF8String]); + } - } - - - if (call) { - // 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); + if (transfer) { + char *caddr = linphone_address_as_string(addr); + linphone_core_transfer_call(theLinphoneCore, linphone_core_get_current_call(theLinphoneCore), caddr); + ms_free(caddr); + } else { + LinphoneCall *call = linphone_core_invite_address_with_params(theLinphoneCore, addr, lcallParams); + if (call) { + // 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 = (__bridge LinphoneCallAppData *)linphone_call_get_user_data(call); + if (data == nil) { + LOGE(@"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*/ + } else { + data->videoRequested = linphone_call_params_video_enabled(lcallParams); + } + } + } + linphone_address_destroy(addr); + linphone_call_params_destroy(lcallParams); } - linphone_call_params_destroy(lcallParams); } - #pragma mark - Property Functions - (void)setPushNotificationToken:(NSData *)apushNotificationToken { - if(apushNotificationToken == pushNotificationToken) { + if (apushNotificationToken == pushNotificationToken) { return; } - if(pushNotificationToken != nil) { - [pushNotificationToken release]; + if (pushNotificationToken != nil) { pushNotificationToken = nil; } - 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); - } + if (apushNotificationToken != nil) { + pushNotificationToken = apushNotificationToken; + } + LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(theLinphoneCore); + if (cfg) { + linphone_proxy_config_edit(cfg); + [self configurePushTokenForProxyConfig:cfg]; + linphone_proxy_config_done(cfg); + } } -- (void)configurePushTokenForProxyConfig:(LinphoneProxyConfig*)proxyCfg{ - NSData *tokenData = pushNotificationToken; - if(tokenData != nil && [self lpConfigBoolForKey:@"pushnotification_preference"]) { +- (void)configurePushTokenForProxyConfig:(LinphoneProxyConfig *)proxyCfg { + NSData *tokenData = pushNotificationToken; + if (tokenData != nil && [self lpConfigBoolForKey:@"pushnotification_preference"]) { const unsigned char *tokenBuffer = [tokenData bytes]; - NSMutableString *tokenString = [NSMutableString stringWithCapacity:[tokenData length]*2]; - for(int i = 0; i < [tokenData length]; ++i) { + NSMutableString *tokenString = [NSMutableString stringWithCapacity:[tokenData length] * 2]; + for (int i = 0; i < [tokenData length]; ++i) { [tokenString appendFormat:@"%02X", (unsigned int)tokenBuffer[i]]; } - // NSLocalizedString(@"IC_MSG", nil); // Fake for genstrings - // NSLocalizedString(@"IM_MSG", nil); // Fake for genstrings -#ifdef DEBUG +// NSLocalizedString(@"IC_MSG", nil); // Fake for genstrings +// NSLocalizedString(@"IM_MSG", nil); // Fake for genstrings +// NSLocalizedString(@"IM_FULLMSG", nil); // Fake for genstrings +#ifdef USE_APN_DEV #define APPMODE_SUFFIX @"dev" #else #define APPMODE_SUFFIX @"prod" #endif - NSString *params = [NSString stringWithFormat:@"app-id=%@.%@;pn-type=apple;pn-tok=%@;pn-msg-str=IM_MSG;pn-call-str=IC_MSG;pn-call-snd=ring.caf;pn-msg-snd=msg.caf", [[NSBundle mainBundle] bundleIdentifier],APPMODE_SUFFIX,tokenString]; + NSString *soundName = @"shortring.caf"; + NSString *params = [NSString + stringWithFormat:@"app-id=%@.%@;pn-type=apple;pn-tok=%@;pn-msg-str=IM_MSG;pn-call-str=IC_MSG;pn-" + @"call-snd=%@;pn-msg-snd=sounds/msg.caf", + [[NSBundle mainBundle] bundleIdentifier], APPMODE_SUFFIX, tokenString, soundName]; - linphone_proxy_config_set_contact_uri_parameters(proxyCfg, [params UTF8String]); - linphone_proxy_config_set_contact_parameters(proxyCfg, NULL); + 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); @@ -1989,240 +2036,261 @@ static void audioRouteChangeListenerCallback ( } } - - #pragma mark - Misc Functions -+ (NSString*)bundleFile:(NSString*)file { ++ (NSString *)bundleFile:(NSString *)file { return [[NSBundle mainBundle] pathForResource:[file stringByDeletingPathExtension] ofType:[file pathExtension]]; } -+ (NSString*)documentFile:(NSString*)file { ++ (NSString *)documentFile:(NSString *)file { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsPath = [paths objectAtIndex:0]; return [documentsPath stringByAppendingPathComponent:file]; } -+ (NSString*)cacheDirectory { ++ (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]; + if (![[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&isDir] && isDir == NO) { + [[NSFileManager defaultManager] createDirectoryAtPath:cachePath + withIntermediateDirectories:NO + attributes:nil + error:&error]; } - return cachePath; + 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; - } + int count = 0; + const MSList *rooms = linphone_core_get_chat_rooms([LinphoneManager getLc]); + const 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; + return count; } -+ (BOOL)copyFile:(NSString*)src destination:(NSString*)dst override:(BOOL)override { ++ (BOOL)copyFile:(NSString *)src destination:(NSString *)dst override:(BOOL)override { NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error = nil; + if ([fileManager fileExistsAtPath:src] == NO) { + LOGE(@"Can't find \"%@\": %@", src, [error localizedDescription]); + return FALSE; + } if ([fileManager fileExistsAtPath:dst] == YES) { - if(override) { + if (override) { [fileManager removeItemAtPath:dst error:&error]; - if(error != nil) { - [LinphoneLogger log:LinphoneLoggerError format:@"Can't remove \"%@\": %@", dst, [error localizedDescription]]; + if (error != nil) { + LOGE(@"Can't remove \"%@\": %@", dst, [error localizedDescription]); return FALSE; } } else { - [LinphoneLogger log:LinphoneLoggerWarning format:@"\"%@\" already exists", dst]; + LOGW(@"\"%@\" already exists", dst); return FALSE; } } - if ([fileManager fileExistsAtPath:src] == NO) { - [LinphoneLogger log:LinphoneLoggerError format:@"Can't find \"%@\": %@", src, [error localizedDescription]]; - return FALSE; - } [fileManager copyItemAtPath:src toPath:dst error:&error]; - if(error != nil) { - [LinphoneLogger log:LinphoneLoggerError format:@"Can't copy \"%@\" to \"%@\": %@", src, dst, [error localizedDescription]]; + if (error != nil) { + LOGE(@"Can't copy \"%@\" to \"%@\": %@", src, dst, [error localizedDescription]); return FALSE; } return TRUE; } -- (void)configureVbrCodecs{ +- (void)configureVbrCodecs { PayloadType *pt; - int bitrate=lp_config_get_int(configDb,"audio","codec_bitrate_limit",kLinphoneAudioVbrCodecDefaultBitrate);/*default value is in linphonerc or linphonerc-factory*/ - 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) { - NSLog(@"Enabling debug logs"); - 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 { - NSLog(@"Disabling debug logs"); - linphone_core_enable_log_collection(enabled); - linphone_core_disable_logs(); + int bitrate = lp_config_get_int( + configDb, "audio", "codec_bitrate_limit", + kLinphoneAudioVbrCodecDefaultBitrate); /*default value is in linphonerc or linphonerc-factory*/ + 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; } } -+(id)getMessageAppDataForKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg { +- (void)setLogsEnabled:(BOOL)enabled { + if ([LinphoneManager isRunningTests]) { + NSLog(@"Running tests, forcing logs to MESSAGE level"); + linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler); + linphone_core_set_log_level(ORTP_MESSAGE); + } else { + if (enabled) { + NSLog(@"Enabling debug logs"); + linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler); + linphone_core_set_log_level(ORTP_DEBUG); + linphone_core_enable_log_collection(enabled); + } else { + NSLog(@"Disabling debug logs"); + linphone_core_enable_log_collection(enabled); + linphone_core_disable_logs(); + } + } +} - if(msg == nil ) return nil; ++ (id)getMessageAppDataForKey:(NSString *)key inMessage:(LinphoneChatMessage *)msg { + + if (msg == nil) + return nil; id value = nil; - const char* appData = linphone_chat_message_get_appdata(msg); - if( appData) { - NSDictionary* appDataDict = [NSJSONSerialization JSONObjectWithData:[NSData dataWithBytes:appData length:strlen(appData)] options:0 error:nil]; + const char *appData = linphone_chat_message_get_appdata(msg); + if (appData) { + NSDictionary *appDataDict = + [NSJSONSerialization JSONObjectWithData:[NSData dataWithBytes:appData length:strlen(appData)] + options:0 + error:nil]; value = [appDataDict objectForKey:key]; } return value; } -+(void)setValueInMessageAppData:(id)value forKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg { ++ (void)setValueInMessageAppData:(id)value forKey:(NSString *)key inMessage:(LinphoneChatMessage *)msg { - NSMutableDictionary* appDataDict = [NSMutableDictionary dictionary]; - const char* appData = linphone_chat_message_get_appdata(msg); - if( appData) { - appDataDict = [NSJSONSerialization JSONObjectWithData:[NSData dataWithBytes:appData length:strlen(appData)] options:NSJSONReadingMutableContainers error:nil]; + NSMutableDictionary *appDataDict = [NSMutableDictionary dictionary]; + const char *appData = linphone_chat_message_get_appdata(msg); + if (appData) { + appDataDict = [NSJSONSerialization JSONObjectWithData:[NSData dataWithBytes:appData length:strlen(appData)] + options:NSJSONReadingMutableContainers + error:nil]; } [appDataDict setValue:value forKey:key]; - NSData* data = [NSJSONSerialization dataWithJSONObject:appDataDict options:0 error:nil]; - NSString* appdataJSON = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + 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]); - [appdataJSON release]; } #pragma mark - LPConfig Functions -- (void)lpConfigSetString:(NSString*)value forKey:(NSString*)key { - [self lpConfigSetString:value forKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]]; +- (void)lpConfigSetString:(NSString *)value forKey:(NSString *)key { + [self lpConfigSetString:value forKey:key inSection:LINPHONERC_APPLICATION_KEY]; +} +- (void)lpConfigSetString:(NSString *)value forKey:(NSString *)key inSection:(NSString *)section { + if (!key) + return; + lp_config_set_string(configDb, [section UTF8String], [key UTF8String], value ? [value UTF8String] : NULL); +} +- (NSString *)lpConfigStringForKey:(NSString *)key { + return [self lpConfigStringForKey:key withDefault:nil]; +} +- (NSString *)lpConfigStringForKey:(NSString *)key withDefault:(NSString *)defaultValue { + return [self lpConfigStringForKey:key inSection:LINPHONERC_APPLICATION_KEY withDefault:defaultValue]; +} +- (NSString *)lpConfigStringForKey:(NSString *)key inSection:(NSString *)section { + return [self lpConfigStringForKey:key inSection:section withDefault:nil]; +} +- (NSString *)lpConfigStringForKey:(NSString *)key inSection:(NSString *)section withDefault:(NSString *)defaultValue { + if (!key) + return defaultValue; + const char *value = lp_config_get_string(configDb, [section UTF8String], [key UTF8String], NULL); + return value ? [NSString stringWithUTF8String:value] : defaultValue; } -- (void)lpConfigSetString:(NSString*)value forKey:(NSString*)key forSection:(NSString *)section { - if (!key) return; - lp_config_set_string(configDb, [section UTF8String], [key UTF8String], value?[value UTF8String]:NULL); +- (void)lpConfigSetInt:(int)value forKey:(NSString *)key { + [self lpConfigSetInt:value forKey:key inSection:LINPHONERC_APPLICATION_KEY]; +} +- (void)lpConfigSetInt:(int)value forKey:(NSString *)key inSection:(NSString *)section { + if (!key) + return; + lp_config_set_int(configDb, [section UTF8String], [key UTF8String], (int)value); +} +- (int)lpConfigIntForKey:(NSString *)key { + return [self lpConfigIntForKey:key withDefault:-1]; +} +- (int)lpConfigIntForKey:(NSString *)key withDefault:(int)defaultValue { + return [self lpConfigIntForKey:key inSection:LINPHONERC_APPLICATION_KEY withDefault:defaultValue]; +} +- (int)lpConfigIntForKey:(NSString *)key inSection:(NSString *)section { + return [self lpConfigIntForKey:key inSection:section withDefault:-1]; +} +- (int)lpConfigIntForKey:(NSString *)key inSection:(NSString *)section withDefault:(int)defaultValue { + if (!key) + return defaultValue; + return lp_config_get_int(configDb, [section UTF8String], [key UTF8String], (int)defaultValue); } -- (NSString*)lpConfigStringForKey:(NSString*)key { - return [self lpConfigStringForKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]]; +- (void)lpConfigSetBool:(BOOL)value forKey:(NSString *)key { + [self lpConfigSetBool:value forKey:key inSection:LINPHONERC_APPLICATION_KEY]; } -- (NSString*)lpConfigStringForKey:(NSString*)key withDefault:(NSString*)defaultValue { - NSString* value = [self lpConfigStringForKey:key]; - return value?value:defaultValue; +- (void)lpConfigSetBool:(BOOL)value forKey:(NSString *)key inSection:(NSString *)section { + [self lpConfigSetInt:(int)(value == TRUE) forKey:key inSection:section]; } - -- (NSString*)lpConfigStringForKey:(NSString*)key forSection:(NSString *)section { - if (!key) return nil; - const char* value = lp_config_get_string(configDb, [section UTF8String], [key UTF8String], NULL); - if (value) - return [NSString stringWithUTF8String:value]; - else - return nil; +- (BOOL)lpConfigBoolForKey:(NSString *)key { + return [self lpConfigBoolForKey:key withDefault:FALSE]; } - -- (void)lpConfigSetInt:(NSInteger)value forKey:(NSString*)key { - [self lpConfigSetInt:value forKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]]; +- (BOOL)lpConfigBoolForKey:(NSString *)key withDefault:(BOOL)defaultValue { + return [self lpConfigBoolForKey:key inSection:LINPHONERC_APPLICATION_KEY withDefault:defaultValue]; } - -- (void)lpConfigSetInt:(NSInteger)value forKey:(NSString*)key forSection:(NSString *)section { - if (!key) return; - lp_config_set_int(configDb, [section UTF8String], [key UTF8String], (int)value ); +- (BOOL)lpConfigBoolForKey:(NSString *)key inSection:(NSString *)section { + return [self lpConfigBoolForKey:key inSection:section withDefault:FALSE]; } - -- (NSInteger)lpConfigIntForKey:(NSString*)key { - return [self lpConfigIntForKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]]; -} - -- (NSInteger)lpConfigIntForKey:(NSString*)key forSection:(NSString *)section { - if (!key) return -1; - return lp_config_get_int(configDb, [section UTF8String], [key UTF8String], -1); -} - -- (void)lpConfigSetBool:(BOOL)value forKey:(NSString*)key { - [self lpConfigSetBool:value forKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]]; -} - -- (void)lpConfigSetBool:(BOOL)value forKey:(NSString*)key forSection:(NSString *)section { - return [self lpConfigSetInt:(NSInteger)(value == TRUE) forKey:key forSection:section]; -} - -- (BOOL)lpConfigBoolForKey:(NSString*)key { - return [self lpConfigBoolForKey:key forSection:[NSString stringWithUTF8String:LINPHONERC_APPLICATION_KEY]]; -} - -- (BOOL)lpConfigBoolForKey:(NSString*)key forSection:(NSString *)section { - return [self lpConfigIntForKey:key forSection:section] == 1; +- (BOOL)lpConfigBoolForKey:(NSString *)key inSection:(NSString *)section withDefault:(BOOL)defaultValue { + if (!key) + return defaultValue; + int val = [self lpConfigIntForKey:key inSection:section withDefault:-1]; + return (val != -1) ? (val == 1) : defaultValue; } #pragma mark - GSM management --(void) removeCTCallCenterCb { +- (void)removeCTCallCenterCb { if (mCallCenter != nil) { - [LinphoneLogger log:LinphoneLoggerLog format:@"Removing CT call center listener [%p]",mCallCenter]; - mCallCenter.callEventHandler=NULL; - [mCallCenter release]; + LOGI(@"Removing CT call center listener [%p]", mCallCenter); + mCallCenter.callEventHandler = NULL; } - mCallCenter=nil; + mCallCenter = nil; } - (void)setupGSMInteraction { [self removeCTCallCenterCb]; mCallCenter = [[CTCallCenter alloc] init]; - [LinphoneLogger log:LinphoneLoggerLog format:@"Adding CT call center listener [%p]",mCallCenter]; - mCallCenter.callEventHandler = ^(CTCall* call) { - // post on main thread - [self performSelectorOnMainThread:@selector(handleGSMCallInteration:) - withObject:mCallCenter - waitUntilDone:YES]; + LOGI(@"Adding CT call center listener [%p]", mCallCenter); + __block __weak LinphoneManager *weakSelf = self; + __block __weak CTCallCenter *weakCCenter = mCallCenter; + mCallCenter.callEventHandler = ^(CTCall *call) { + // post on main thread + [weakSelf performSelectorOnMainThread:@selector(handleGSMCallInteration:) + withObject:weakCCenter + waitUntilDone:YES]; }; - } -- (void)handleGSMCallInteration: (id) cCenter { - CTCallCenter* ct = (CTCallCenter*) cCenter; +- (void)handleGSMCallInteration:(id)cCenter { + CTCallCenter *ct = (CTCallCenter *)cCenter; /* pause current call, if any */ - LinphoneCall* call = linphone_core_get_current_call(theLinphoneCore); - if ([ct currentCalls]!=nil) { + LinphoneCall *call = linphone_core_get_current_call(theLinphoneCore); + if ([ct currentCalls] != nil) { if (call) { - [LinphoneLogger log:LinphoneLoggerLog format:@"Pausing SIP call because GSM call"]; + LOGI(@"Pausing SIP call because GSM call"); linphone_core_pause_call(theLinphoneCore, call); [self startCallPausedLongRunningTask]; } else if (linphone_core_is_in_conference(theLinphoneCore)) { - [LinphoneLogger log:LinphoneLoggerLog format:@"Leaving conference call because GSM call"]; + LOGI(@"Leaving conference call because GSM call"); linphone_core_leave_conference(theLinphoneCore); [self startCallPausedLongRunningTask]; } - } //else nop, keep call in paused state + } // else nop, keep call in paused state } --(NSString*) contactFilter { - NSString* filter=@"*"; - if ( [self lpConfigBoolForKey:@"contact_filter_on_default_domain"]) { - LinphoneProxyConfig* proxy_cfg; - linphone_core_get_default_proxy(theLinphoneCore, &proxy_cfg); +- (NSString *)contactFilter { + NSString *filter = @"*"; + if ([self lpConfigBoolForKey:@"contact_filter_on_default_domain"]) { + LinphoneProxyConfig *proxy_cfg = linphone_core_get_default_proxy_config(theLinphoneCore); if (proxy_cfg && linphone_proxy_config_get_addr(proxy_cfg)) { return [NSString stringWithCString:linphone_proxy_config_get_domain(proxy_cfg) encoding:[NSString defaultCStringEncoding]]; @@ -2253,9 +2321,35 @@ static void audioRouteChangeListenerCallback ( case tunnel_auto: linphone_tunnel_auto_detect(tunnel); break; - } } +#pragma mark - InApp Purchase events + +- (void)inappReady:(NSNotification *)notif { + // Query our in-app server to retrieve InApp purchases + [_iapManager retrievePurchases]; +} + +#pragma mark - + +- (void)removeAllAccounts { + linphone_core_clear_proxy_config([LinphoneManager getLc]); + linphone_core_clear_all_auth_info([LinphoneManager getLc]); +} + ++ (BOOL)isMyself:(const LinphoneAddress *)addr { + if (!addr) + return NO; + + const MSList *it = linphone_core_get_proxy_config_list([LinphoneManager getLc]); + while (it) { + if (linphone_address_weak_equal(addr, linphone_proxy_config_get_identity_address(it->data))) { + return YES; + } + it = it->next; + } + return NO; +} @end diff --git a/Classes/LinphoneUI/Base.lproj/StatusBarView.strings b/Classes/LinphoneUI/Base.lproj/StatusBarView.strings new file mode 100644 index 000000000..3ca9a0d25 Binary files /dev/null and b/Classes/LinphoneUI/Base.lproj/StatusBarView.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/StatusBarView.xib b/Classes/LinphoneUI/Base.lproj/StatusBarView.xib new file mode 100644 index 000000000..d0caf7bd6 --- /dev/null +++ b/Classes/LinphoneUI/Base.lproj/StatusBarView.xib @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/Base.lproj/TabBarView.strings b/Classes/LinphoneUI/Base.lproj/TabBarView.strings new file mode 100644 index 000000000..cf4ea9723 Binary files /dev/null and b/Classes/LinphoneUI/Base.lproj/TabBarView.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/TabBarView.xib b/Classes/LinphoneUI/Base.lproj/TabBarView.xib new file mode 100644 index 000000000..2f2d909a2 --- /dev/null +++ b/Classes/LinphoneUI/Base.lproj/TabBarView.xib @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/Base.lproj/UICallBar.strings b/Classes/LinphoneUI/Base.lproj/UICallBar.strings deleted file mode 100644 index 726f09e44..000000000 Binary files a/Classes/LinphoneUI/Base.lproj/UICallBar.strings and /dev/null differ diff --git a/Classes/LinphoneUI/Base.lproj/UICallBar.xib b/Classes/LinphoneUI/Base.lproj/UICallBar.xib deleted file mode 100644 index f76753d37..000000000 --- a/Classes/LinphoneUI/Base.lproj/UICallBar.xib +++ /dev/null @@ -1,1043 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/LinphoneUI/Base.lproj/UICallBar~ipad.strings b/Classes/LinphoneUI/Base.lproj/UICallBar~ipad.strings deleted file mode 100644 index b4e261950..000000000 Binary files a/Classes/LinphoneUI/Base.lproj/UICallBar~ipad.strings and /dev/null differ diff --git a/Classes/LinphoneUI/Base.lproj/UICallBar~ipad.xib b/Classes/LinphoneUI/Base.lproj/UICallBar~ipad.xib deleted file mode 100644 index ceb7256d2..000000000 --- a/Classes/LinphoneUI/Base.lproj/UICallBar~ipad.xib +++ /dev/null @@ -1,813 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/LinphoneUI/Base.lproj/UICallCell.strings b/Classes/LinphoneUI/Base.lproj/UICallCell.strings index 9d9551217..cc5ae2ee6 100644 Binary files a/Classes/LinphoneUI/Base.lproj/UICallCell.strings and b/Classes/LinphoneUI/Base.lproj/UICallCell.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UICallCell.xib b/Classes/LinphoneUI/Base.lproj/UICallCell.xib deleted file mode 100644 index c46edde08..000000000 --- a/Classes/LinphoneUI/Base.lproj/UICallCell.xib +++ /dev/null @@ -1,457 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/LinphoneUI/Base.lproj/UICallConferenceCell.strings b/Classes/LinphoneUI/Base.lproj/UICallConferenceCell.strings new file mode 100644 index 000000000..e24779e2c Binary files /dev/null and b/Classes/LinphoneUI/Base.lproj/UICallConferenceCell.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UICallConferenceCell.xib b/Classes/LinphoneUI/Base.lproj/UICallConferenceCell.xib new file mode 100644 index 000000000..0b81fa266 --- /dev/null +++ b/Classes/LinphoneUI/Base.lproj/UICallConferenceCell.xib @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/Base.lproj/UICallPausedCell.strings b/Classes/LinphoneUI/Base.lproj/UICallPausedCell.strings new file mode 100644 index 000000000..db95ec94e Binary files /dev/null and b/Classes/LinphoneUI/Base.lproj/UICallPausedCell.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UICallPausedCell.xib b/Classes/LinphoneUI/Base.lproj/UICallPausedCell.xib new file mode 100644 index 000000000..423378a9e --- /dev/null +++ b/Classes/LinphoneUI/Base.lproj/UICallPausedCell.xib @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.strings new file mode 100644 index 000000000..50aac70af Binary files /dev/null and b/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.xib b/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.xib new file mode 100644 index 000000000..bc35ae1e4 --- /dev/null +++ b/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.xib @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/Base.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/Base.lproj/UIChatBubbleTextCell.strings new file mode 100644 index 000000000..caf8f1e21 Binary files /dev/null and b/Classes/LinphoneUI/Base.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UIChatBubbleTextCell.xib b/Classes/LinphoneUI/Base.lproj/UIChatBubbleTextCell.xib new file mode 100644 index 000000000..b564ae75b --- /dev/null +++ b/Classes/LinphoneUI/Base.lproj/UIChatBubbleTextCell.xib @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/Base.lproj/UIChatCell.strings b/Classes/LinphoneUI/Base.lproj/UIChatCell.strings index c16425967..20c2bc60b 100644 Binary files a/Classes/LinphoneUI/Base.lproj/UIChatCell.strings and b/Classes/LinphoneUI/Base.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UIChatCell.xib b/Classes/LinphoneUI/Base.lproj/UIChatCell.xib index 600a66d1c..4f89590d7 100644 --- a/Classes/LinphoneUI/Base.lproj/UIChatCell.xib +++ b/Classes/LinphoneUI/Base.lproj/UIChatCell.xib @@ -1,8 +1,8 @@ - + - + @@ -10,84 +10,74 @@ - - - + + + - - + + - - + + - - + - - - - + + - - - - - diff --git a/Classes/LinphoneUI/Base.lproj/UIChatCreateCell.strings b/Classes/LinphoneUI/Base.lproj/UIChatCreateCell.strings new file mode 100644 index 000000000..ac8173e78 Binary files /dev/null and b/Classes/LinphoneUI/Base.lproj/UIChatCreateCell.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UIChatCreateCell.xib b/Classes/LinphoneUI/Base.lproj/UIChatCreateCell.xib new file mode 100644 index 000000000..5ec042951 --- /dev/null +++ b/Classes/LinphoneUI/Base.lproj/UIChatCreateCell.xib @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/Base.lproj/UIChatRoomCell.strings b/Classes/LinphoneUI/Base.lproj/UIChatRoomCell.strings index 91f270f45..aa7f96da1 100644 Binary files a/Classes/LinphoneUI/Base.lproj/UIChatRoomCell.strings and b/Classes/LinphoneUI/Base.lproj/UIChatRoomCell.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UIChatRoomCell.xib b/Classes/LinphoneUI/Base.lproj/UIChatRoomCell.xib deleted file mode 100644 index e4a9593a5..000000000 --- a/Classes/LinphoneUI/Base.lproj/UIChatRoomCell.xib +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Classes/LinphoneUI/Base.lproj/UICompositeView.xib b/Classes/LinphoneUI/Base.lproj/UICompositeView.xib new file mode 100644 index 000000000..1668cddf2 --- /dev/null +++ b/Classes/LinphoneUI/Base.lproj/UICompositeView.xib @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/Base.lproj/UICompositeViewController.xib b/Classes/LinphoneUI/Base.lproj/UICompositeViewController.xib deleted file mode 100644 index c400fdb98..000000000 --- a/Classes/LinphoneUI/Base.lproj/UICompositeViewController.xib +++ /dev/null @@ -1,367 +0,0 @@ - - - - 1296 - 11E53 - 2549 - 1138.47 - 569.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1498 - - - IBProxyObject - IBUIView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 301 - - - - 314 - {{0, 23}, {320, 397}} - - - - _NS:9 - - 3 - MCAwAA - - NO - 1 - IBCocoaTouchFramework - - - - 290 - {320, 23} - - - - _NS:9 - - NO - 2 - IBCocoaTouchFramework - - - - 266 - {{0, 420}, {320, 60}} - - - _NS:9 - - NO - 3 - IBCocoaTouchFramework - - - {320, 480} - - - - - IBCocoaTouchFramework - - - - 301 - - - - 314 - {{0, 23}, {480, 237}} - - - - _NS:9 - - NO - 1 - IBCocoaTouchFramework - - - - 290 - {480, 23} - - - - _NS:9 - - NO - 2 - IBCocoaTouchFramework - - - - 266 - {{0, 260}, {480, 60}} - - - _NS:9 - - NO - 3 - IBCocoaTouchFramework - - - {480, 320} - - - - - - 3 - 3 - - IBCocoaTouchFramework - - - - - - - view - - - - 3 - - - - contentView - - - - 17 - - - - stateBarView - - - - 18 - - - - tabBarView - - - - 19 - - - - portraitView - - - - 24 - - - - landscapeView - - - - 25 - - - - - - 0 - - - - - - 1 - - - - - - - - Portrait View - - - -1 - - - File's Owner - - - -2 - - - - - 15 - - - content - - - 14 - - - stateBar - - - 16 - - - tabBar - - - 20 - - - - - - - - Landscape View - - - 22 - - - stateBar - - - 23 - - - - content - - - 21 - - - tabBar - - - - - UICompositeViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UITransparentView - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UITransparentView - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UITransparentView - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UITransparentView - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 25 - - - - - TPMultiLayoutViewController - UIViewController - - UIView - UIView - - - - landscapeView - UIView - - - portraitView - UIView - - - - IBProjectSource - ./Classes/TPMultiLayoutViewController.h - - - - UICompositeViewController - TPMultiLayoutViewController - - UIView - UIView - UIView - - - - contentView - UIView - - - stateBarView - UIView - - - tabBarView - UIView - - - - IBProjectSource - ./Classes/UICompositeViewController.h - - - - UITransparentView - UIView - - IBProjectSource - ./Classes/UITransparentView.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - YES - 3 - 1498 - - diff --git a/Classes/LinphoneUI/Base.lproj/UICompositeView~ipad.xib b/Classes/LinphoneUI/Base.lproj/UICompositeView~ipad.xib new file mode 100644 index 000000000..d4b20b633 --- /dev/null +++ b/Classes/LinphoneUI/Base.lproj/UICompositeView~ipad.xib @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/Base.lproj/UIConferenceHeader.strings b/Classes/LinphoneUI/Base.lproj/UIConferenceHeader.strings deleted file mode 100644 index 7371f5243..000000000 Binary files a/Classes/LinphoneUI/Base.lproj/UIConferenceHeader.strings and /dev/null differ diff --git a/Classes/LinphoneUI/Base.lproj/UIConferenceHeader.xib b/Classes/LinphoneUI/Base.lproj/UIConferenceHeader.xib deleted file mode 100644 index 8c6e1f63e..000000000 --- a/Classes/LinphoneUI/Base.lproj/UIConferenceHeader.xib +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Classes/LinphoneUI/Base.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/Base.lproj/UIConfirmationDialog.strings new file mode 100644 index 000000000..230ecb71d Binary files /dev/null and b/Classes/LinphoneUI/Base.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UIConfirmationDialog.xib b/Classes/LinphoneUI/Base.lproj/UIConfirmationDialog.xib new file mode 100644 index 000000000..7cd0c8bb0 --- /dev/null +++ b/Classes/LinphoneUI/Base.lproj/UIConfirmationDialog.xib @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/Base.lproj/UIContactCell.strings b/Classes/LinphoneUI/Base.lproj/UIContactCell.strings index b3ed706ee..aca210d0b 100644 Binary files a/Classes/LinphoneUI/Base.lproj/UIContactCell.strings and b/Classes/LinphoneUI/Base.lproj/UIContactCell.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UIContactCell.xib b/Classes/LinphoneUI/Base.lproj/UIContactCell.xib index 5fdff6747..5754ba770 100644 --- a/Classes/LinphoneUI/Base.lproj/UIContactCell.xib +++ b/Classes/LinphoneUI/Base.lproj/UIContactCell.xib @@ -1,260 +1,46 @@ - - - - 1296 - 11E53 - 2549 - 1138.47 - 569.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1498 - - - IBProxyObject - IBUIImageView - IBUILabel - IBUIView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 300 - {{6, 6}, {32, 32}} - - - - _NS:9 - NO - IBCocoaTouchFramework - - - - 274 - {{46, 0}, {55, 44}} - - - - _NS:328 - - 3 - MCAwAA - - NO - YES - 7 - 2 - NO - - Firstname - - IBCocoaTouchFramework - John - - 1 - 10 - - 1 - 25 - - - Helvetica - 25 - 16 - - - - - 274 - {{111, 0}, {200, 44}} - - - - _NS:328 - - NO - YES - 7 - 2 - NO - - Lastname - - IBCocoaTouchFramework - Doe - - 1 - 10 - - 2 - 25 - - - Helvetica-Bold - 25 - 16 - - - - {320, 44} - - - - _NS:9 - - IBCocoaTouchFramework - - - - - - - firstNameLabel - - - - 17 - - - - lastNameLabel - - - - 18 - - - - avatarImage - - - - 24 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 16 - - - - - - - - - - 6 - - - firstName - - - 10 - - - lastName - - - 23 - - - avatarImage - - - - - UIContactCell - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 24 - - - - - UIContactCell - UITableViewCell - - UIImageView - UILabel - UILabel - - - - avatarImage - UIImageView - - - firstNameLabel - UILabel - - - lastNameLabel - UILabel - - - - IBProjectSource - ./Classes/UIContactCell.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - YES - 3 - 1498 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/Base.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/Base.lproj/UIContactDetailsCell.strings new file mode 100644 index 000000000..1c3e5ecc2 Binary files /dev/null and b/Classes/LinphoneUI/Base.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UIContactDetailsCell.xib b/Classes/LinphoneUI/Base.lproj/UIContactDetailsCell.xib new file mode 100644 index 000000000..faa721798 --- /dev/null +++ b/Classes/LinphoneUI/Base.lproj/UIContactDetailsCell.xib @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/Base.lproj/UIContactDetailsFooter.strings b/Classes/LinphoneUI/Base.lproj/UIContactDetailsFooter.strings deleted file mode 100644 index 85d6b67a3..000000000 Binary files a/Classes/LinphoneUI/Base.lproj/UIContactDetailsFooter.strings and /dev/null differ diff --git a/Classes/LinphoneUI/Base.lproj/UIContactDetailsFooter.xib b/Classes/LinphoneUI/Base.lproj/UIContactDetailsFooter.xib deleted file mode 100644 index e070c8c2d..000000000 --- a/Classes/LinphoneUI/Base.lproj/UIContactDetailsFooter.xib +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Classes/LinphoneUI/Base.lproj/UIContactDetailsHeader.strings b/Classes/LinphoneUI/Base.lproj/UIContactDetailsHeader.strings deleted file mode 100644 index 55ec8b262..000000000 Binary files a/Classes/LinphoneUI/Base.lproj/UIContactDetailsHeader.strings and /dev/null differ diff --git a/Classes/LinphoneUI/Base.lproj/UIContactDetailsHeader.xib b/Classes/LinphoneUI/Base.lproj/UIContactDetailsHeader.xib deleted file mode 100644 index f4934c521..000000000 --- a/Classes/LinphoneUI/Base.lproj/UIContactDetailsHeader.xib +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Classes/LinphoneUI/Base.lproj/UIHistoryCell.strings b/Classes/LinphoneUI/Base.lproj/UIHistoryCell.strings index 4bdf055cb..731db2b00 100644 Binary files a/Classes/LinphoneUI/Base.lproj/UIHistoryCell.strings and b/Classes/LinphoneUI/Base.lproj/UIHistoryCell.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UIHistoryCell.xib b/Classes/LinphoneUI/Base.lproj/UIHistoryCell.xib index 980b82a44..14810c2b7 100644 --- a/Classes/LinphoneUI/Base.lproj/UIHistoryCell.xib +++ b/Classes/LinphoneUI/Base.lproj/UIHistoryCell.xib @@ -1,79 +1,66 @@ - + - + - - - - + + + + - - + + - - - - - - + + + + - + + - - - - + + + + - - - - - diff --git a/Classes/LinphoneUI/Base.lproj/UIMainBar.strings b/Classes/LinphoneUI/Base.lproj/UIMainBar.strings index c472a605a..7dcd85f93 100644 Binary files a/Classes/LinphoneUI/Base.lproj/UIMainBar.strings and b/Classes/LinphoneUI/Base.lproj/UIMainBar.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UIMainBar.xib b/Classes/LinphoneUI/Base.lproj/UIMainBar.xib deleted file mode 100644 index fc8405d9b..000000000 --- a/Classes/LinphoneUI/Base.lproj/UIMainBar.xib +++ /dev/null @@ -1,278 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/LinphoneUI/Base.lproj/UIMainBar~ipad.strings b/Classes/LinphoneUI/Base.lproj/UIMainBar~ipad.strings index a12201c8a..670e50eb1 100644 Binary files a/Classes/LinphoneUI/Base.lproj/UIMainBar~ipad.strings and b/Classes/LinphoneUI/Base.lproj/UIMainBar~ipad.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UIMainBar~ipad.xib b/Classes/LinphoneUI/Base.lproj/UIMainBar~ipad.xib deleted file mode 100644 index 2e6fdeb96..000000000 --- a/Classes/LinphoneUI/Base.lproj/UIMainBar~ipad.xib +++ /dev/null @@ -1,340 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/LinphoneUI/Base.lproj/UIStateBar.strings b/Classes/LinphoneUI/Base.lproj/UIStateBar.strings index cce74a594..4056cdda2 100644 Binary files a/Classes/LinphoneUI/Base.lproj/UIStateBar.strings and b/Classes/LinphoneUI/Base.lproj/UIStateBar.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UIStateBar.xib b/Classes/LinphoneUI/Base.lproj/UIStateBar.xib deleted file mode 100644 index 59d49c22d..000000000 --- a/Classes/LinphoneUI/Base.lproj/UIStateBar.xib +++ /dev/null @@ -1,149 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/LinphoneUI/UIStateBar.h b/Classes/LinphoneUI/StatusBarView.h similarity index 54% rename from Classes/LinphoneUI/UIStateBar.h rename to Classes/LinphoneUI/StatusBarView.h index 735cb9bd7..afd5e4ed0 100644 --- a/Classes/LinphoneUI/UIStateBar.h +++ b/Classes/LinphoneUI/StatusBarView.h @@ -1,4 +1,4 @@ -/* UIStateBar.h +/* StatusBarViewController.h * * Copyright (C) 2012 Belledonne Comunications, Grenoble, France * @@ -19,20 +19,23 @@ #import #import "TPMultiLayoutViewController.h" -#import "DTActionSheet.h" +#import "UIConfirmationDialog.h" +#import "LinphoneManager.h" -@interface UIStateBar : TPMultiLayoutViewController { - DTActionSheet *securitySheet; +@interface StatusBarView : TPMultiLayoutViewController { + UIConfirmationDialog *securityDialog; } -@property (nonatomic, retain) IBOutlet UIImageView* registrationStateImage; -@property (nonatomic, retain) IBOutlet UILabel* registrationStateLabel; -@property (nonatomic, retain) IBOutlet UIImageView* callQualityImage; -@property (nonatomic, retain) IBOutlet UIImageView* callSecurityImage; -@property (nonatomic, retain) IBOutlet UIButton* callSecurityButton; -@property (retain, nonatomic) IBOutlet UILabel *voicemailCount; - -- (IBAction)doSecurityClick:(id)sender; +@property(weak, nonatomic) IBOutlet UIButton *registrationState; +@property(nonatomic, strong) IBOutlet UIButton *callSecurityButton; +@property(weak, nonatomic) IBOutlet UIButton *voicemailButton; +@property(weak, nonatomic) IBOutlet UIButton *callQualityButton; +@property(weak, nonatomic) IBOutlet UIView *incallView; +@property(weak, nonatomic) IBOutlet UIView *outcallView; +- (IBAction)onSecurityClick:(id)sender; +- (IBAction)onSideMenuClick:(id)sender; +- (IBAction)onRegistrationStateClick:(id)sender; ++ (UIImage *)imageForState:(LinphoneRegistrationState)state; @end diff --git a/Classes/LinphoneUI/StatusBarView.m b/Classes/LinphoneUI/StatusBarView.m new file mode 100644 index 000000000..1e0b19cdc --- /dev/null +++ b/Classes/LinphoneUI/StatusBarView.m @@ -0,0 +1,355 @@ +/* StatusBarViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "StatusBarView.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" + +@implementation StatusBarView { + + NSTimer *callQualityTimer; + NSTimer *callSecurityTimer; + int messagesUnreadCount; +} + +#pragma mark - Lifecycle Functions + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [callQualityTimer invalidate]; +} + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + // Set observer + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(registrationUpdate:) + name:kLinphoneRegistrationUpdate + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(globalStateUpdate:) + name:kLinphoneGlobalStateUpdate + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(notifyReceived:) + name:kLinphoneNotifyReceived + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(callUpdate:) + name:kLinphoneCallUpdate + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(onCallEncryptionChanged:) + name:kLinphoneCallEncryptionChanged + object:nil]; + + // Update to default state + LinphoneProxyConfig *config = linphone_core_get_default_proxy_config([LinphoneManager getLc]); + messagesUnreadCount = + lp_config_get_int(linphone_core_get_config([LinphoneManager getLc]), "app", "voice_mail_messages_count", 0); + + [self proxyConfigUpdate:config]; + [self updateUI:linphone_core_get_calls_nb([LinphoneManager getLc])]; + [self updateVoicemail]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + // Remove observer + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneRegistrationUpdate object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneGlobalStateUpdate object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneNotifyReceived object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneCallUpdate object:nil]; + + if (callQualityTimer != nil) { + [callQualityTimer invalidate]; + callQualityTimer = nil; + } + if (callSecurityTimer != nil) { + [callSecurityTimer invalidate]; + callSecurityTimer = nil; + } + + if (securityDialog != nil) { + [securityDialog dismiss]; + securityDialog = nil; + } +} + +#pragma mark - Event Functions + +- (void)registrationUpdate:(NSNotification *)notif { + LinphoneProxyConfig *config = linphone_core_get_default_proxy_config([LinphoneManager getLc]); + [self proxyConfigUpdate:config]; +} + +- (void)globalStateUpdate:(NSNotification *)notif { + [self registrationUpdate:notif]; +} + +- (void)onCallEncryptionChanged:(NSNotification *)notif { + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); + + if (call && (linphone_call_params_get_media_encryption(linphone_call_get_current_params(call)) == + LinphoneMediaEncryptionZRTP) && + (!linphone_call_get_authentication_token_verified(call))) { + [self onSecurityClick:nil]; + } +} + +- (void)notifyReceived:(NSNotification *)notif { + const LinphoneContent *content = [[notif.userInfo objectForKey:@"content"] pointerValue]; + + if ((content == NULL) || (strcmp("application", linphone_content_get_type(content)) != 0) || + (strcmp("simple-message-summary", linphone_content_get_subtype(content)) != 0) || + (linphone_content_get_buffer(content) == NULL)) { + return; + } + const char *body = linphone_content_get_buffer(content); + if ((body = strstr(body, "voice-message: ")) == NULL) { + LOGW(@"Received new NOTIFY from voice mail but could not find 'voice-message' in BODY. Ignoring it."); + return; + } + + sscanf(body, "voice-message: %d", &messagesUnreadCount); + + LOGI(@"Received new NOTIFY from voice mail: there is/are now %d message(s) unread", messagesUnreadCount); + + // save in lpconfig for future + lp_config_set_int(linphone_core_get_config([LinphoneManager getLc]), "app", "voice_mail_messages_count", + messagesUnreadCount); + + [self updateVoicemail]; +} + +- (void)updateVoicemail { + _voicemailButton.hidden = (messagesUnreadCount <= 0); + _voicemailButton.titleLabel.text = @(messagesUnreadCount).stringValue; +} + +- (void)callUpdate:(NSNotification *)notif { + // show voice mail only when there is no call + [self updateUI:linphone_core_get_calls([LinphoneManager getLc]) != NULL]; + [self updateVoicemail]; +} + +#pragma mark - + ++ (UIImage *)imageForState:(LinphoneRegistrationState)state { + switch (state) { + case LinphoneRegistrationFailed: + return [UIImage imageNamed:@"led_error.png"]; + case LinphoneRegistrationCleared: + case LinphoneRegistrationNone: + return [UIImage imageNamed:@"led_disconnected.png"]; + case LinphoneRegistrationProgress: + return [UIImage imageNamed:@"led_inprogress.png"]; + case LinphoneRegistrationOk: + return [UIImage imageNamed:@"led_connected.png"]; + } +} +- (void)proxyConfigUpdate:(LinphoneProxyConfig *)config { + LinphoneRegistrationState state = LinphoneRegistrationNone; + NSString *message = nil; + LinphoneCore *lc = [LinphoneManager getLc]; + LinphoneGlobalState gstate = linphone_core_get_global_state(lc); + + if (gstate == LinphoneGlobalConfiguring) { + message = NSLocalizedString(@"Fetching remote configuration", nil); + } else if (config == NULL) { + state = LinphoneRegistrationNone; + if (linphone_core_get_proxy_config_list(lc) != NULL) { + if (linphone_core_is_network_reachable([LinphoneManager getLc])) { + message = NSLocalizedString(@"No default account", nil); + } else { + message = NSLocalizedString(@"Network down", nil); + } + } else { + message = NSLocalizedString(@"No account configured", nil); + } + + } else { + state = linphone_proxy_config_get_state(config); + + switch (state) { + case LinphoneRegistrationOk: + message = NSLocalizedString(@"Registered", nil); + break; + case LinphoneRegistrationNone: + case LinphoneRegistrationCleared: + message = NSLocalizedString(@"Not registered", nil); + break; + case LinphoneRegistrationFailed: + message = NSLocalizedString(@"Registration failed", nil); + break; + case LinphoneRegistrationProgress: + message = NSLocalizedString(@"Registration in progress", nil); + break; + default: + break; + } + } + [_registrationState setTitle:message forState:UIControlStateNormal]; + _registrationState.accessibilityValue = message; + [_registrationState setImage:[self.class imageForState:state] forState:UIControlStateNormal]; +} + +#pragma mark - + +- (void)updateUI:(BOOL)inCall { + // nothing changed + if (_outcallView.hidden == inCall) + return; + + _outcallView.hidden = inCall; + _incallView.hidden = !inCall; + + if (callQualityTimer) { + [callQualityTimer invalidate]; + callQualityTimer = nil; + } + if (callSecurityTimer) { + [callSecurityTimer invalidate]; + callSecurityTimer = nil; + } + if (securityDialog) { + [securityDialog dismiss]; + } + + // if we are in call, we have to update quality and security icons every sec + if (inCall) { + callQualityTimer = [NSTimer scheduledTimerWithTimeInterval:1 + target:self + selector:@selector(callQualityUpdate) + userInfo:nil + repeats:YES]; + callSecurityTimer = [NSTimer scheduledTimerWithTimeInterval:1 + target:self + selector:@selector(callSecurityUpdate) + userInfo:nil + repeats:YES]; + } +} + +- (void)callSecurityUpdate { + BOOL pending = false; + BOOL security = true; + + const MSList *list = linphone_core_get_calls([LinphoneManager getLc]); + if (list == NULL) { + if (securityDialog) { + [securityDialog dismiss]; + } + } else { + _callSecurityButton.hidden = NO; + while (list != NULL) { + LinphoneCall *call = (LinphoneCall *)list->data; + LinphoneMediaEncryption enc = + linphone_call_params_get_media_encryption(linphone_call_get_current_params(call)); + if (enc == LinphoneMediaEncryptionNone) + security = false; + else if (enc == LinphoneMediaEncryptionZRTP) { + if (!linphone_call_get_authentication_token_verified(call)) { + pending = true; + } + } + list = list->next; + } + NSString *imageName = + (security ? (pending ? @"security_pending.png" : @"security_ok.png") : @"security_ko.png"); + [_callSecurityButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal]; + } +} + +- (void)callQualityUpdate { + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); + if (call != NULL) { + int quality = MIN(4, floor(linphone_call_get_average_quality(call))); + NSString *accessibilityValue = [NSString stringWithFormat:NSLocalizedString(@"Call quality: %d", nil), quality]; + if (![accessibilityValue isEqualToString:_callQualityButton.accessibilityValue]) { + _callQualityButton.accessibilityValue = accessibilityValue; + _callQualityButton.hidden = NO; //(quality == -1.f); + UIImage *image = + (quality == -1.f) + ? [UIImage imageNamed:@"call_quality_indicator_0.png"] // nil + : [UIImage imageNamed:[NSString stringWithFormat:@"call_quality_indicator_%d.png", quality]]; + [_callQualityButton setImage:image forState:UIControlStateNormal]; + } + } +} + +#pragma mark - Action Functions + +- (IBAction)onSecurityClick:(id)sender { + if (linphone_core_get_calls_nb([LinphoneManager getLc])) { + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); + if (call != NULL) { + LinphoneMediaEncryption enc = + linphone_call_params_get_media_encryption(linphone_call_get_current_params(call)); + if (enc == LinphoneMediaEncryptionZRTP) { + NSString *message = + [NSString stringWithFormat:NSLocalizedString(@"Confirm the following SAS with peer:\n%s", nil), + linphone_call_get_authentication_token(call)]; + if (securityDialog == nil) { + __block __strong StatusBarView *weakSelf = self; + securityDialog = [UIConfirmationDialog ShowWithMessage:message + cancelMessage:NSLocalizedString(@"DENY", nil) + confirmMessage:NSLocalizedString(@"ACCEPT", nil) + onCancelClick:^() { + if (linphone_core_get_current_call([LinphoneManager getLc]) == call) { + linphone_call_set_authentication_token_verified(call, NO); + } + weakSelf->securityDialog = nil; + } + onConfirmationClick:^() { + if (linphone_core_get_current_call([LinphoneManager getLc]) == call) { + linphone_call_set_authentication_token_verified(call, YES); + } + weakSelf->securityDialog = nil; + }]; + } + } + } + } +} + +- (IBAction)onSideMenuClick:(id)sender { + UICompositeView *cvc = PhoneMainView.instance.mainViewController; + [cvc hideSideMenu:(cvc.sideMenuView.frame.origin.x == 0)]; +} + +- (IBAction)onRegistrationStateClick:(id)sender { + LinphoneCore *lc = [LinphoneManager getLc]; + if (linphone_core_get_default_proxy_config(lc)) { + linphone_core_refresh_registers(lc); + } else if (linphone_core_get_proxy_config_list(lc)) { + [PhoneMainView.instance changeCurrentView:SettingsView.compositeViewDescription]; + } else { + [PhoneMainView.instance changeCurrentView:AssistantView.compositeViewDescription]; + } +} + +@end diff --git a/Classes/LinphoneUI/TabBarView.h b/Classes/LinphoneUI/TabBarView.h new file mode 100644 index 000000000..d132c3433 --- /dev/null +++ b/Classes/LinphoneUI/TabBarView.h @@ -0,0 +1,44 @@ +/* TabBarViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import +#import "TPMultiLayoutViewController.h" +#import "UIBouncingView.h" + +@interface TabBarView : TPMultiLayoutViewController { +} + +@property(nonatomic, strong) IBOutlet UIButton *historyButton; +@property(nonatomic, strong) IBOutlet UIButton *contactsButton; +@property(nonatomic, strong) IBOutlet UIButton *dialerButton; +@property(nonatomic, strong) IBOutlet UIButton *chatButton; +@property(nonatomic, strong) IBOutlet UIBouncingView *historyNotificationView; +@property(nonatomic, strong) IBOutlet UIBouncingView *chatNotificationView; +@property(nonatomic, strong) IBOutlet UILabel *chatNotificationLabel; +@property(nonatomic, strong) IBOutlet UILabel *historyNotificationLabel; +@property(weak, nonatomic) IBOutlet UIImageView *selectedButtonImage; + +- (void)update:(BOOL)appear; + +- (IBAction)onHistoryClick:(id)event; +- (IBAction)onContactsClick:(id)event; +- (IBAction)onDialerClick:(id)event; +- (IBAction)onChatClick:(id)event; + +@end diff --git a/Classes/LinphoneUI/TabBarView.m b/Classes/LinphoneUI/TabBarView.m new file mode 100644 index 000000000..9899e059c --- /dev/null +++ b/Classes/LinphoneUI/TabBarView.m @@ -0,0 +1,168 @@ +/* TabBarViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "TabBarView.h" +#import "PhoneMainView.h" + +@implementation TabBarView + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(changeViewEvent:) + name:kLinphoneMainViewChange + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(callUpdate:) + name:kLinphoneCallUpdate + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(messageReceived:) + name:kLinphoneMessageReceived + object:nil]; + [self update:FALSE]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { + [self update:FALSE]; +} + +#pragma mark - Event Functions + +- (void)callUpdate:(NSNotification *)notif { + // LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue]; + // LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue]; + [self updateMissedCall:linphone_core_get_missed_calls_count([LinphoneManager getLc]) appear:TRUE]; +} + +- (void)changeViewEvent:(NSNotification *)notif { + UICompositeViewDescription *view = [notif.userInfo objectForKey:@"view"]; + if (view != nil) { + [self updateSelectedButton:view]; + } +} + +- (void)messageReceived:(NSNotification *)notif { + [self updateUnreadMessage:TRUE]; +} + +#pragma mark - UI Update + +- (void)update:(BOOL)appear { + [self updateSelectedButton:[PhoneMainView.instance currentView]]; + [self updateMissedCall:linphone_core_get_missed_calls_count([LinphoneManager getLc]) appear:appear]; + [self updateUnreadMessage:appear]; +} + +- (void)updateUnreadMessage:(BOOL)appear { + int unreadMessage = [LinphoneManager unreadMessageCount]; + if (unreadMessage > 0) { + _chatNotificationLabel.text = [NSString stringWithFormat:@"%i", unreadMessage]; + [_chatNotificationView startAnimating:appear]; + } else { + [_chatNotificationView stopAnimating:appear]; + } +} + +- (void)updateMissedCall:(int)missedCall appear:(BOOL)appear { + if (missedCall > 0) { + _historyNotificationLabel.text = [NSString stringWithFormat:@"%i", missedCall]; + [_historyNotificationView startAnimating:appear]; + } else { + [_historyNotificationView stopAnimating:appear]; + } +} + +- (void)updateSelectedButton:(UICompositeViewDescription *)view { + _historyButton.selected = [view equal:HistoryListView.compositeViewDescription] || + [view equal:HistoryDetailsView.compositeViewDescription]; + _contactsButton.selected = [view equal:ContactsListView.compositeViewDescription] || + [view equal:ContactDetailsView.compositeViewDescription]; + _dialerButton.selected = [view equal:DialerView.compositeViewDescription]; + _chatButton.selected = [view equal:ChatsListView.compositeViewDescription] || + [view equal:ChatConversationCreateView.compositeViewDescription] || + [view equal:ChatConversationView.compositeViewDescription]; + CGRect selectedNewFrame = _selectedButtonImage.frame; + if ([self viewIsCurrentlyPortrait]) { + selectedNewFrame.origin.x = + (_historyButton.selected + ? _historyButton.frame.origin.x + : (_contactsButton.selected + ? _contactsButton.frame.origin.x + : (_dialerButton.selected + ? _dialerButton.frame.origin.x + : (_chatButton.selected + ? _chatButton.frame.origin.x + : -selectedNewFrame.size.width /*hide it if none is selected*/)))); + } else { + selectedNewFrame.origin.y = + (_historyButton.selected + ? _historyButton.frame.origin.y + : (_contactsButton.selected + ? _contactsButton.frame.origin.y + : (_dialerButton.selected + ? _dialerButton.frame.origin.y + : (_chatButton.selected + ? _chatButton.frame.origin.y + : -selectedNewFrame.size.height /*hide it if none is selected*/)))); + } + + CGFloat delay = [[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"] ? 0.3 : 0; + [UIView animateWithDuration:delay + animations:^{ + _selectedButtonImage.frame = selectedNewFrame; + + }]; +} + +#pragma mark - Action Functions + +- (IBAction)onHistoryClick:(id)event { + [PhoneMainView.instance changeCurrentView:HistoryListView.compositeViewDescription]; +} + +- (IBAction)onContactsClick:(id)event { + [ContactSelection setAddAddress:nil]; + [ContactSelection setSipFilter:nil]; + [ContactSelection enableEmailFilter:FALSE]; + [ContactSelection setNameOrEmailFilter:nil]; + [PhoneMainView.instance changeCurrentView:ContactsListView.compositeViewDescription]; +} + +- (IBAction)onDialerClick:(id)event { + [PhoneMainView.instance changeCurrentView:DialerView.compositeViewDescription]; +} + +- (IBAction)onSettingsClick:(id)event { + [PhoneMainView.instance changeCurrentView:SettingsView.compositeViewDescription]; +} + +- (IBAction)onChatClick:(id)event { + [PhoneMainView.instance changeCurrentView:ChatsListView.compositeViewDescription]; +} + +@end diff --git a/Classes/LinphoneUI/UIAddressTextField.h b/Classes/LinphoneUI/UIAddressTextField.h index b08c462a3..d0c179654 100644 --- a/Classes/LinphoneUI/UIAddressTextField.h +++ b/Classes/LinphoneUI/UIAddressTextField.h @@ -4,21 +4,21 @@ * * 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 + * 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 -@interface UIAddressTextField : UITextField +@interface UIAddressTextField : UITextField @end diff --git a/Classes/LinphoneUI/UIAddressTextField.m b/Classes/LinphoneUI/UIAddressTextField.m index 52028bb63..70c777e83 100644 --- a/Classes/LinphoneUI/UIAddressTextField.m +++ b/Classes/LinphoneUI/UIAddressTextField.m @@ -4,35 +4,35 @@ * * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ + */ #import "UIAddressTextField.h" @implementation UIAddressTextField - (void)setText:(NSString *)text { - [super setText:text]; - [self sendActionsForControlEvents:UIControlEventEditingChanged]; + [super setText:text]; + [self sendActionsForControlEvents:UIControlEventEditingChanged]; } --(BOOL)canPerformAction:(SEL)action withSender:(id)sender{ - // disable "define" option, since it messes with the keyboard - if ([[NSStringFromSelector(action) lowercaseString] rangeOfString:@"define"].location != NSNotFound) { - return NO; - } else { - return [super canPerformAction:action withSender:sender]; - } +- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { + // disable "define" option, since it messes with the keyboard + if ([[NSStringFromSelector(action) lowercaseString] rangeOfString:@"define"].location != NSNotFound) { + return NO; + } else { + return [super canPerformAction:action withSender:sender]; + } } @end diff --git a/Classes/LinphoneUI/UIAssistantTextField.h b/Classes/LinphoneUI/UIAssistantTextField.h new file mode 100644 index 000000000..d6b1a7e9f --- /dev/null +++ b/Classes/LinphoneUI/UIAssistantTextField.h @@ -0,0 +1,25 @@ +// +// UIAssistantTextField.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 30/09/15. +// +// + +#import + +typedef BOOL (^UIDisplayError)(NSString *inputEntry); + +@interface UIAssistantTextField : UITextField + +@property(nonatomic, strong) IBOutlet UILabel *errorLabel; +@property(nonatomic, readonly) UIDisplayError showErrorPredicate; +@property(nonatomic, strong) NSString *lastText; +// we should show error only when user finished editted the field at least once +@property(atomic) BOOL canShowError; + +- (void)showError:(NSString *)msg when:(UIDisplayError)pred; +- (void)showError:(NSString *)msg; +- (BOOL)isInvalid; + +@end diff --git a/Classes/LinphoneUI/UIAssistantTextField.m b/Classes/LinphoneUI/UIAssistantTextField.m new file mode 100644 index 000000000..6e392b0ee --- /dev/null +++ b/Classes/LinphoneUI/UIAssistantTextField.m @@ -0,0 +1,61 @@ +// +// UIAssistantTextField.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 30/09/15. +// +// + +#import "UIAssistantTextField.h" +#import "Utils.h" + +@implementation UIAssistantTextField + +INIT_WITH_COMMON { + self.delegate = self; + return self; +} + +- (void)showError:(NSString *)msg { + _errorLabel.text = msg; + _lastText = self.text; + + _errorLabel.hidden = NO; + self.layer.borderWidth = .8; + self.layer.cornerRadius = 4.f; + self.autoresizingMask = YES; + self.layer.borderColor = _errorLabel.hidden ? [[UIColor clearColor] CGColor] : [[UIColor redColor] CGColor]; +} + +- (void)showError:(NSString *)msg when:(UIDisplayError)apred { + _showErrorPredicate = apred; + [self showError:msg]; + [self checkDisplayError]; +} + +- (void)checkDisplayError { + _errorLabel.hidden = !(_canShowError && [self isInvalid]); + self.layer.borderColor = _errorLabel.hidden ? [[UIColor clearColor] CGColor] : [[UIColor redColor] CGColor]; +} + +- (BOOL)isInvalid { + return _showErrorPredicate && _showErrorPredicate(_lastText); +} + +#pragma mark - UITextFieldDelegate Functions + +- (BOOL)textField:(UITextField *)textField + shouldChangeCharactersInRange:(NSRange)range + replacementString:(NSString *)string { + _lastText = [textField.text stringByReplacingCharactersInRange:range withString:string]; + [self checkDisplayError]; + return YES; +} + +- (void)textFieldDidEndEditing:(UITextField *)textField { + _lastText = textField.text; + _canShowError = YES; + [self checkDisplayError]; +} + +@end diff --git a/Classes/LinphoneUI/UIBackToCallButton.h b/Classes/LinphoneUI/UIBackToCallButton.h new file mode 100644 index 000000000..31f3b6c5e --- /dev/null +++ b/Classes/LinphoneUI/UIBackToCallButton.h @@ -0,0 +1,17 @@ +// +// UIBackToCallButton.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 26/10/15. +// +// + +#import "UIIconButton.h" + +@interface UIBackToCallButton : UIIconButton + +- (IBAction)onBackToCallClick:(id)sender; +- (void)update; + +@property(assign, nonatomic) IBOutlet UITableView *tableView; +@end diff --git a/Classes/LinphoneUI/UIBackToCallButton.m b/Classes/LinphoneUI/UIBackToCallButton.m new file mode 100644 index 000000000..377e1ea57 --- /dev/null +++ b/Classes/LinphoneUI/UIBackToCallButton.m @@ -0,0 +1,42 @@ +// +// UIBackToCallButton.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 26/10/15. +// +// + +#import "UIBackToCallButton.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" + +@implementation UIBackToCallButton + +- (instancetype)init { + if (self = [super init]) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(callUpdateEvent:) + name:kLinphoneCallUpdate + object:nil]; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)callUpdateEvent:(NSNotification *)notif { + [self update]; +} + +- (void)update { + self.hidden = (_tableView.isEditing || linphone_core_get_current_call([LinphoneManager getLc]) == NULL); +} + +- (IBAction)onBackToCallClick:(id)sender { + CallView *view = VIEW(CallView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; +} + +@end diff --git a/Classes/LinphoneUI/UIBluetoothButton.m b/Classes/LinphoneUI/UIBluetoothButton.m index 6c3ee43f3..002d02624 100644 --- a/Classes/LinphoneUI/UIBluetoothButton.m +++ b/Classes/LinphoneUI/UIBluetoothButton.m @@ -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 "UIBluetoothButton.h" #import @@ -24,50 +24,38 @@ #include "linphone/linphonecore.h" @implementation UIBluetoothButton -#define check_auresult(au,method) \ -if (au!=0) [LinphoneLogger logc:LinphoneLoggerError format:"UIBluetoothButton error for %s: ret=%ld",method,au] +#define check_auresult(au, method) \ + if (au != 0) \ + LOGE(@"UIBluetoothButton error for %s: ret=%ld", method, au) - (void)onOn { - //redirect audio to bluetooth + // redirect audio to bluetooth UInt32 size = sizeof(CFStringRef); - CFStringRef route=CFSTR("HeadsetBT"); + CFStringRef route = CFSTR("HeadsetBT"); OSStatus result = AudioSessionSetProperty(kAudioSessionProperty_AudioRoute, size, &route); - check_auresult(result,"set kAudioSessionProperty_AudioRoute HeadsetBT"); - - int allowBluetoothInput = 1; - result = AudioSessionSetProperty ( - kAudioSessionProperty_OverrideCategoryEnableBluetoothInput, - sizeof (allowBluetoothInput), - &allowBluetoothInput - ); - check_auresult(result,"set kAudioSessionProperty_OverrideCategoryEnableBluetoothInput 1"); + check_auresult(result, "set kAudioSessionProperty_AudioRoute HeadsetBT"); + int allowBluetoothInput = 1; + result = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput, + sizeof(allowBluetoothInput), &allowBluetoothInput); + check_auresult(result, "set kAudioSessionProperty_OverrideCategoryEnableBluetoothInput 1"); } - (void)onOff { - //redirect audio to bluetooth + // redirect audio to bluetooth int allowBluetoothInput = 0; - OSStatus result = AudioSessionSetProperty ( - kAudioSessionProperty_OverrideCategoryEnableBluetoothInput, - sizeof (allowBluetoothInput), - &allowBluetoothInput - ); - check_auresult(result,"set kAudioSessionProperty_OverrideCategoryEnableBluetoothInput 0"); + OSStatus result = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput, + sizeof(allowBluetoothInput), &allowBluetoothInput); + check_auresult(result, "set kAudioSessionProperty_OverrideCategoryEnableBluetoothInput 0"); UInt32 size = sizeof(CFStringRef); - CFStringRef route=CFSTR("ReceiverAndMicrophone"); + CFStringRef route = CFSTR("ReceiverAndMicrophone"); result = AudioSessionSetProperty(kAudioSessionProperty_AudioRoute, size, &route); - check_auresult(result,"set kAudioSessionProperty_AudioRoute ReceiverAndMicrophone"); - - + check_auresult(result, "set kAudioSessionProperty_AudioRoute ReceiverAndMicrophone"); } - (bool)onUpdate { return false; } -- (void)dealloc { - [super dealloc]; -} - @end diff --git a/Classes/LinphoneUI/UIBouncingView.h b/Classes/LinphoneUI/UIBouncingView.h new file mode 100644 index 000000000..34d77f963 --- /dev/null +++ b/Classes/LinphoneUI/UIBouncingView.h @@ -0,0 +1,16 @@ +// +// UIBouncingView.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 11/12/15. +// +// + +#import + +@interface UIBouncingView : UIView + +- (void)startAnimating:(BOOL)animated; +- (void)stopAnimating:(BOOL)animated; + +@end diff --git a/Classes/LinphoneUI/UIBouncingView.m b/Classes/LinphoneUI/UIBouncingView.m new file mode 100644 index 000000000..99d285266 --- /dev/null +++ b/Classes/LinphoneUI/UIBouncingView.m @@ -0,0 +1,144 @@ +// +// UIBouncingView.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 11/12/15. +// +// + +#import "UIBouncingView.h" + +#import "CAAnimation+Blocks.h" +#import "Utils.h" + +static NSString *const kBounceAnimation = @"bounce"; +static NSString *const kAppearAnimation = @"appear"; +static NSString *const kDisappearAnimation = @"disappear"; + +@implementation UIBouncingView + +INIT_WITH_COMMON { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(settingsUpdate:) + name:kLinphoneSettingsUpdate + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationWillEnterForeground:) + name:UIApplicationWillEnterForegroundNotification + object:nil]; + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)settingsUpdate:(NSNotification *)notif { + if ([[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"] == false) { + [self stopAnimating:NO]; + } else { + if (![self isHidden]) { + self.hidden = YES; + [self startAnimating:YES]; + } + } +} + +- (void)applicationWillEnterForeground:(NSNotification *)notif { + // Force the animations + if (self.isHidden) { + self.hidden = NO; + [self stopAnimating:NO]; + } else { + self.hidden = YES; + [self startAnimating:NO]; + } +} + +#pragma mark - Animation + +- (void)appearAnimation:(NSString *)animationID target:(UIView *)target completion:(void (^)(BOOL finished))completion { + CABasicAnimation *appear = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; + appear.duration = 0.4; + appear.fromValue = [NSNumber numberWithDouble:0.0f]; + appear.toValue = [NSNumber numberWithDouble:1.0f]; + appear.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; + appear.fillMode = kCAFillModeForwards; + appear.removedOnCompletion = NO; + [appear setCompletion:completion]; + [target.layer addAnimation:appear forKey:animationID]; +} + +- (void)disappearAnimation:(NSString *)animationID + target:(UIView *)target + completion:(void (^)(BOOL finished))completion { + CABasicAnimation *disappear = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; + disappear.duration = 0.4; + disappear.fromValue = [NSNumber numberWithDouble:1.0f]; + disappear.toValue = [NSNumber numberWithDouble:0.0f]; + disappear.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; + disappear.fillMode = kCAFillModeForwards; + disappear.removedOnCompletion = NO; + [disappear setCompletion:completion]; + [target.layer addAnimation:disappear forKey:animationID]; +} + +- (void)startBounceAnimation:(NSString *)animationID target:(UIView *)target { + CABasicAnimation *bounce = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"]; + bounce.duration = 0.3; + bounce.fromValue = [NSNumber numberWithDouble:0.0f]; + bounce.toValue = [NSNumber numberWithDouble:8.0f]; + bounce.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; + bounce.autoreverses = TRUE; + bounce.repeatCount = HUGE_VALF; + [target.layer addAnimation:bounce forKey:animationID]; +} + +- (void)stopBounceAnimation:(NSString *)animationID target:(UIView *)target { + [target.layer removeAnimationForKey:animationID]; +} + +- (void)startAnimating:(BOOL)animated { + animated = NO; + if (!self.hidden) { + return; + } + + [self setHidden:FALSE]; + if ([[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"] == true) { + if (animated) { + [self appearAnimation:kAppearAnimation + target:self + completion:^(BOOL finished) { + [self startBounceAnimation:kBounceAnimation target:self]; + if (finished) { + [self.layer removeAnimationForKey:kAppearAnimation]; + } + }]; + } else { + [self startBounceAnimation:kBounceAnimation target:self]; + } + } +} + +- (void)stopAnimating:(BOOL)animated { + animated = NO; + if (self.hidden) { + return; + } + + [self stopBounceAnimation:kBounceAnimation target:self]; + if (animated) { + [self disappearAnimation:kDisappearAnimation + target:self + completion:^(BOOL finished) { + [self setHidden:TRUE]; + if (finished) { + [self.layer removeAnimationForKey:kDisappearAnimation]; + } + }]; + } else { + [self setHidden:TRUE]; + } +} +@end diff --git a/Classes/LinphoneUI/UIButtonShrinkable.h b/Classes/LinphoneUI/UIButtonShrinkable.h deleted file mode 100644 index 370a40b57..000000000 --- a/Classes/LinphoneUI/UIButtonShrinkable.h +++ /dev/null @@ -1,24 +0,0 @@ -/* 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 - -@interface UIButtonShrinkable : UIButton - -@end diff --git a/Classes/LinphoneUI/UIButtonShrinkable.m b/Classes/LinphoneUI/UIButtonShrinkable.m deleted file mode 100644 index 40c63f18a..000000000 --- a/Classes/LinphoneUI/UIButtonShrinkable.m +++ /dev/null @@ -1,34 +0,0 @@ -/* 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 diff --git a/Classes/LinphoneUI/UICallBar.h b/Classes/LinphoneUI/UICallBar.h deleted file mode 100644 index 832a5906c..000000000 --- a/Classes/LinphoneUI/UICallBar.h +++ /dev/null @@ -1,78 +0,0 @@ -/* UICallBar.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UIMicroButton.h" -#import "UIPauseButton.h" -#import "UISpeakerButton.h" -#import "UIVideoButton.h" -#import "UIHangUpButton.h" -#import "UIDigitButton.h" -#import "TPMultiLayoutViewController.h" - -@interface UICallBar: TPMultiLayoutViewController { -} - -@property (nonatomic, retain) IBOutlet UIPauseButton* pauseButton; -@property (nonatomic, retain) IBOutlet UIButton* conferenceButton; -@property (nonatomic, retain) IBOutlet UIVideoButton* videoButton; -@property (nonatomic, retain) IBOutlet UIMicroButton* microButton; -@property (nonatomic, retain) IBOutlet UISpeakerButton* speakerButton; -@property (nonatomic, retain) IBOutlet UIToggleButton* routesButton; -@property (nonatomic, retain) IBOutlet UIToggleButton* optionsButton; -@property (nonatomic, retain) IBOutlet UIHangUpButton* hangupButton; -@property (nonatomic, retain) IBOutlet UIView* padView; -@property (nonatomic, retain) IBOutlet UIView* routesView; -@property (nonatomic, retain) IBOutlet UIView* optionsView; -@property (nonatomic, retain) IBOutlet UIButton* routesReceiverButton; -@property (nonatomic, retain) IBOutlet UIButton* routesSpeakerButton; -@property (nonatomic, retain) IBOutlet UIButton* routesBluetoothButton; -@property (nonatomic, retain) IBOutlet UIButton* optionsAddButton; -@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; -@property (nonatomic, retain) IBOutlet UIDigitButton* fourButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* fiveButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* sixButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* sevenButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* eightButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* nineButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* starButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* zeroButton; -@property (nonatomic, retain) IBOutlet UIDigitButton* sharpButton; - -- (IBAction)onRoutesClick:(id)sender; -- (IBAction)onRoutesBluetoothClick:(id)sender; -- (IBAction)onRoutesReceiverClick:(id)sender; -- (IBAction)onRoutesSpeakerClick:(id)sender; -- (IBAction)onOptionsClick:(id)sender; -- (IBAction)onOptionsTransferClick:(id)sender; -- (IBAction)onOptionsAddClick:(id)sender; -- (IBAction)onConferenceClick:(id)sender; -- (IBAction)onPadClick:(id)sender; - -@end diff --git a/Classes/LinphoneUI/UICallBar.m b/Classes/LinphoneUI/UICallBar.m deleted file mode 100644 index 8847b39cf..000000000 --- a/Classes/LinphoneUI/UICallBar.m +++ /dev/null @@ -1,601 +0,0 @@ -/* UICallBar.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UICallBar.h" -#import "LinphoneManager.h" -#import "PhoneMainView.h" -#import "Utils.h" -#import "CAAnimation+Blocks.h" - -#include "linphone/linphonecore.h" - -@implementation UICallBar - -@synthesize pauseButton; -@synthesize conferenceButton; -@synthesize videoButton; -@synthesize microButton; -@synthesize speakerButton; -@synthesize routesButton; -@synthesize optionsButton; -@synthesize hangupButton; -@synthesize routesBluetoothButton; -@synthesize routesReceiverButton; -@synthesize routesSpeakerButton; -@synthesize optionsAddButton; -@synthesize optionsTransferButton; -@synthesize dialerButton; - -@synthesize padView; -@synthesize routesView; -@synthesize optionsView; - -@synthesize oneButton; -@synthesize twoButton; -@synthesize threeButton; -@synthesize fourButton; -@synthesize fiveButton; -@synthesize sixButton; -@synthesize sevenButton; -@synthesize eightButton; -@synthesize nineButton; -@synthesize starButton; -@synthesize zeroButton; -@synthesize sharpButton; - - -#pragma mark - Lifecycle Functions - -- (id)init { - return [super initWithNibName:@"UICallBar" bundle:[NSBundle mainBundle]]; -} - -- (void)dealloc { - [pauseButton release]; - [conferenceButton release]; - [videoButton release]; - [microButton release]; - [speakerButton release]; - [routesButton release]; - [optionsButton release]; - [routesBluetoothButton release]; - [routesReceiverButton release]; - [routesSpeakerButton release]; - [optionsAddButton release]; - [optionsTransferButton release]; - [dialerButton release]; - - [oneButton release]; - [twoButton release]; - [threeButton release]; - [fourButton release]; - [fiveButton release]; - [sixButton release]; - [sevenButton release]; - [eightButton release]; - [nineButton release]; - [starButton release]; - [zeroButton release]; - [sharpButton release]; - - [padView release]; - [routesView release]; - [optionsView release]; - - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [super dealloc]; -} - - -#pragma mark - ViewController Functions - -- (void)viewDidLoad { - [pauseButton setType:UIPauseButtonType_CurrentCall call:nil]; - - [zeroButton setDigit:'0']; - [zeroButton setDtmf:true]; - [oneButton setDigit:'1']; - [oneButton setDtmf:true]; - [twoButton setDigit:'2']; - [twoButton setDtmf:true]; - [threeButton setDigit:'3']; - [threeButton setDtmf:true]; - [fourButton setDigit:'4']; - [fourButton setDtmf:true]; - [fiveButton setDigit:'5']; - [fiveButton setDtmf:true]; - [sixButton setDigit:'6']; - [sixButton setDtmf:true]; - [sevenButton setDigit:'7']; - [sevenButton setDtmf:true]; - [eightButton setDigit:'8']; - [eightButton setDtmf:true]; - [nineButton setDigit:'9']; - [nineButton setDtmf:true]; - [starButton setDigit:'*']; - [starButton setDtmf:true]; - [sharpButton setDigit:'#']; - [sharpButton setDtmf:true]; - - { - UIButton *videoButtonLandscape = (UIButton*)[landscapeView viewWithTag:[videoButton tag]]; - // Set selected+disabled background: IB lack ! - [videoButton setBackgroundImage:[UIImage imageNamed:@"video_on_disabled.png"] - forState:(UIControlStateDisabled | UIControlStateSelected)]; - [videoButtonLandscape setBackgroundImage:[UIImage imageNamed:@"video_on_disabled_landscape.png"] - forState:(UIControlStateDisabled | UIControlStateSelected)]; - - // Set selected+over background: IB lack ! - [videoButton setBackgroundImage:[UIImage imageNamed:@"video_on_over.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - [videoButtonLandscape setBackgroundImage:[UIImage imageNamed:@"video_on_over_landscape.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStates:videoButton]; - [LinphoneUtils buttonFixStates:videoButtonLandscape]; - } - - { - 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 ! - [speakerButton setBackgroundImage:[UIImage imageNamed:@"speaker_on_disabled.png"] - forState:(UIControlStateDisabled | UIControlStateSelected)]; - [speakerButtonLandscape setBackgroundImage:[UIImage imageNamed:@"speaker_on_disabled_landscape.png"] - forState:(UIControlStateDisabled | UIControlStateSelected)]; - - // Set selected+over background: IB lack ! - [speakerButton setBackgroundImage:[UIImage imageNamed:@"speaker_on_over.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - [speakerButtonLandscape setBackgroundImage:[UIImage imageNamed:@"sspeaker_on_over_landscape.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStates:speakerButton]; - [LinphoneUtils buttonFixStates:speakerButtonLandscape]; - } - - if (![LinphoneManager runningOnIpad]) { - UIButton *routesButtonLandscape = (UIButton*) [landscapeView viewWithTag:[routesButton tag]]; - // Set selected+over background: IB lack ! - [routesButton setBackgroundImage:[UIImage imageNamed:@"routes_over.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - [routesButtonLandscape setBackgroundImage:[UIImage imageNamed:@"routes_over_landscape.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStates:routesButton]; - [LinphoneUtils buttonFixStates:routesButtonLandscape]; - } - - { - UIButton *microButtonLandscape = (UIButton*) [landscapeView viewWithTag:[microButton tag]]; - // Set selected+disabled background: IB lack ! - [microButton setBackgroundImage:[UIImage imageNamed:@"micro_on_disabled.png"] - forState:(UIControlStateDisabled | UIControlStateSelected)]; - [microButtonLandscape setBackgroundImage:[UIImage imageNamed:@"micro_on_disabled_landscape.png"] - forState:(UIControlStateDisabled | UIControlStateSelected)]; - - // Set selected+over background: IB lack ! - [microButton setBackgroundImage:[UIImage imageNamed:@"micro_on_over.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - [microButtonLandscape setBackgroundImage:[UIImage imageNamed:@"micro_on_over_landscape.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStates:microButton]; - [LinphoneUtils buttonFixStates:microButtonLandscape]; - } - - { - UIButton *optionsButtonLandscape = (UIButton*) [landscapeView viewWithTag:[optionsButton tag]]; - // Set selected+over background: IB lack ! - [optionsButton setBackgroundImage:[UIImage imageNamed:@"options_over.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - [optionsButtonLandscape setBackgroundImage:[UIImage imageNamed:@"options_over_landscape.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStates:optionsButton]; - [LinphoneUtils buttonFixStates:optionsButtonLandscape]; - } - - { - UIButton *pauseButtonLandscape = (UIButton*) [landscapeView viewWithTag:[pauseButton tag]]; - // Set selected+over background: IB lack ! - [pauseButton setBackgroundImage:[UIImage imageNamed:@"pause_on_over.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - [pauseButtonLandscape setBackgroundImage:[UIImage imageNamed:@"pause_on_over_landscape.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStates:pauseButton]; - [LinphoneUtils buttonFixStates:pauseButtonLandscape]; - } - - { - UIButton *dialerButtonLandscape = (UIButton*) [landscapeView viewWithTag:[dialerButton tag]] ; - // Set selected+over background: IB lack ! - [dialerButton setBackgroundImage:[UIImage imageNamed:@"dialer_alt_back_over.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - [dialerButtonLandscape setBackgroundImage:[UIImage imageNamed:@"dialer_alt_back_over_landscape.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStates:dialerButton]; - [LinphoneUtils buttonFixStates:dialerButtonLandscape]; - } - - [super viewDidLoad]; -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(callUpdateEvent:) - name:kLinphoneCallUpdate - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(bluetoothAvailabilityUpdateEvent:) - name:kLinphoneBluetoothAvailabilityUpdate - object:nil]; - // Update on show - LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); - LinphoneCallState state = (call != NULL)?linphone_call_get_state(call): 0; - [self callUpdate:call state:state]; - [self hideRoutes:FALSE]; - [self hideOptions:FALSE]; - [self hidePad:FALSE]; - [self showSpeaker]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneCallUpdate - object:nil]; - if (linphone_core_get_calls_nb([LinphoneManager getLc]) == 0) { - //reseting speaker button because no more call - speakerButton.selected=FALSE; - } -} - -#pragma mark - Event Functions - -- (void)callUpdateEvent:(NSNotification*)notif { - LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue]; - LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue]; - [self callUpdate:call state:state]; -} - -- (void)bluetoothAvailabilityUpdateEvent:(NSNotification*)notif { - bool available = [[notif.userInfo objectForKey:@"available"] intValue]; - [self bluetoothAvailabilityUpdate:available]; -} - - -#pragma mark - - -- (void)callUpdate:(LinphoneCall*)call state:(LinphoneCallState)state { - LinphoneCore* lc = [LinphoneManager getLc]; - - [speakerButton update]; - [microButton update]; - [pauseButton update]; - [videoButton update]; - [hangupButton update]; - - - // Show Pause/Conference button following call count - if(linphone_core_get_calls_nb(lc) > 1) { - if(![pauseButton isHidden]) { - [pauseButton setHidden:true]; - [conferenceButton setHidden:false]; - } - bool enabled = true; - const MSList *list = linphone_core_get_calls(lc); - while(list != NULL) { - LinphoneCall *call = (LinphoneCall*) list->data; - LinphoneCallState state = linphone_call_get_state(call); - if(state == LinphoneCallIncomingReceived || - state == LinphoneCallOutgoingInit || - state == LinphoneCallOutgoingProgress || - state == LinphoneCallOutgoingRinging || - state == LinphoneCallOutgoingEarlyMedia || - state == LinphoneCallConnected) { - enabled = false; - } - list = list->next; - } - [conferenceButton setEnabled:enabled]; - } else { - if([pauseButton isHidden]) { - [pauseButton setHidden:false]; - [conferenceButton setHidden:true]; - } - } - - // Disable transfert in conference - if(linphone_core_get_current_call(lc) == NULL) { - [optionsTransferButton setEnabled:FALSE]; - } else { - [optionsTransferButton setEnabled:TRUE]; - } - - switch(state) { - case LinphoneCallEnd: - case LinphoneCallError: - case LinphoneCallIncoming: - case LinphoneCallOutgoing: - [self hidePad:TRUE]; - [self hideOptions:TRUE]; - [self hideRoutes:TRUE]; - default: - break; - } -} - -- (void)bluetoothAvailabilityUpdate:(bool)available { - if (available) { - [self hideSpeaker]; - } else { - [self showSpeaker]; - } -} - - -#pragma mark - - -- (void)showAnimation:(NSString*)animationID target:(UIView*)target completion:(void (^)(BOOL finished))completion { - CGRect frame = [target frame]; - int original_y = frame.origin.y; - frame.origin.y = [[self view] frame].size.height; - [target setFrame:frame]; - [target setHidden:FALSE]; - [UIView animateWithDuration:0.5 - delay:0.0 - options:UIViewAnimationOptionCurveEaseOut - animations:^{ - CGRect frame = [target frame]; - frame.origin.y = original_y; - [target setFrame:frame]; - } - completion:^(BOOL finished){ - CGRect frame = [target frame]; - frame.origin.y = original_y; - [target setFrame:frame]; - completion(finished); - }]; -} - -- (void)hideAnimation:(NSString*)animationID target:(UIView*)target completion:(void (^)(BOOL finished))completion { - CGRect frame = [target frame]; - int original_y = frame.origin.y; - [UIView animateWithDuration:0.5 - delay:0.0 - options:UIViewAnimationOptionCurveEaseIn - animations:^{ - CGRect frame = [target frame]; - frame.origin.y = [[self view] frame].size.height; - [target setFrame:frame]; - } - completion:^(BOOL finished){ - CGRect frame = [target frame]; - frame.origin.y = original_y; - [target setHidden:TRUE]; - [target setFrame:frame]; - completion(finished); - }]; -} - -- (void)showPad:(BOOL)animated { - [dialerButton setOn]; - if([padView isHidden]) { - if(animated) { - [self showAnimation:@"show" target:padView completion:^(BOOL finished){}]; - } else { - [padView setHidden:FALSE]; - } - } -} - -- (void)hidePad:(BOOL)animated { - [dialerButton setOff]; - if(![padView isHidden]) { - if(animated) { - [self hideAnimation:@"hide" target:padView completion:^(BOOL finished){}]; - } else { - [padView setHidden:TRUE]; - } - } -} - -- (void)showRoutes:(BOOL)animated { - if (![LinphoneManager runningOnIpad]) { - [routesButton setOn]; - [routesBluetoothButton setSelected:[[LinphoneManager instance] bluetoothEnabled]]; - [routesSpeakerButton setSelected:[[LinphoneManager instance] speakerEnabled]]; - [routesReceiverButton setSelected:!([[LinphoneManager instance] bluetoothEnabled] || [[LinphoneManager instance] speakerEnabled])]; - if([routesView isHidden]) { - if(animated) { - [self showAnimation:@"show" target:routesView completion:^(BOOL finished){}]; - } else { - [routesView setHidden:FALSE]; - } - } - } -} - -- (void)hideRoutes:(BOOL)animated { - if (![LinphoneManager runningOnIpad]) { - [routesButton setOff]; - if(![routesView isHidden]) { - if(animated) { - [self hideAnimation:@"hide" target:routesView completion:^(BOOL finished){}]; - } else { - [routesView setHidden:TRUE]; - } - } - } -} - -- (void)showOptions:(BOOL)animated { - [optionsButton setOn]; - if([optionsView isHidden]) { - if(animated) { - [self showAnimation:@"show" target:optionsView completion:^(BOOL finished){}]; - } else { - [optionsView setHidden:FALSE]; - } - } -} - -- (void)hideOptions:(BOOL)animated { - [optionsButton setOff]; - if(![optionsView isHidden]) { - if(animated) { - [self hideAnimation:@"hide" target:optionsView completion:^(BOOL finished){}]; - } else { - [optionsView setHidden:TRUE]; - } - } -} - -- (void)showSpeaker { - if (![LinphoneManager runningOnIpad]) { - [speakerButton setHidden:FALSE]; - [routesButton setHidden:TRUE]; - } -} - -- (void)hideSpeaker { - if (![LinphoneManager runningOnIpad]) { - [speakerButton setHidden:TRUE]; - [routesButton setHidden:FALSE]; - } -} - - -#pragma mark - Action Functions - -- (IBAction)onPadClick:(id)sender { - if([padView isHidden]) { - [self showPad:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; - } else { - [self hidePad:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; - } -} - -- (IBAction)onRoutesBluetoothClick:(id)sender { - [self hideRoutes:TRUE]; - [[LinphoneManager instance] setBluetoothEnabled:TRUE]; -} - -- (IBAction)onRoutesReceiverClick:(id)sender { - [self hideRoutes:TRUE]; - [[LinphoneManager instance] setSpeakerEnabled:FALSE]; - [[LinphoneManager instance] setBluetoothEnabled:FALSE]; -} - -- (IBAction)onRoutesSpeakerClick:(id)sender { - [self hideRoutes:TRUE]; - [[LinphoneManager instance] setSpeakerEnabled:TRUE]; -} - -- (IBAction)onRoutesClick:(id)sender { - if([routesView isHidden]) { - [self showRoutes:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; - } else { - [self hideRoutes:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; - } -} - -- (IBAction)onOptionsTransferClick:(id)sender { - [self hideOptions:TRUE]; - // Go to dialer view - DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController); - if(controller != nil) { - [controller setAddress:@""]; - [controller setTransferMode:TRUE]; - } -} - -- (IBAction)onOptionsAddClick:(id)sender { - [self hideOptions:TRUE]; - // Go to dialer view - DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController); - if(controller != nil) { - [controller setAddress:@""]; - [controller setTransferMode:FALSE]; - } -} - -- (IBAction)onOptionsClick:(id)sender { - if([optionsView isHidden]) { - [self showOptions:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; - } else { - [self hideOptions:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; - } -} - -- (IBAction)onConferenceClick:(id)sender { - linphone_core_add_all_to_conference([LinphoneManager getLc]); -} - - -#pragma mark - TPMultiLayoutViewController Functions - -- (NSDictionary*)attributesForView:(UIView*)view { - NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; - - [attributes setObject:[NSValue valueWithCGRect:view.frame] forKey:@"frame"]; - [attributes setObject:[NSValue valueWithCGRect:view.bounds] forKey:@"bounds"]; - if([view isKindOfClass:[UIButton class]]) { - UIButton *button = (UIButton *)view; - [LinphoneUtils buttonMultiViewAddAttributes:attributes button:button]; - } 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"]; - - return attributes; -} - -- (void)applyAttributes:(NSDictionary*)attributes toView:(UIView*)view { - view.frame = [[attributes objectForKey:@"frame"] CGRectValue]; - view.bounds = [[attributes objectForKey:@"bounds"] CGRectValue]; - if([view isKindOfClass:[UIButton class]]) { - UIButton *button = (UIButton *)view; - [LinphoneUtils buttonMultiViewApplyAttributes:attributes button:button]; - } else if (view.tag ==self.leftPadding.tag || view.tag == self.rightPadding.tag){ - - [(UIImageView*)view setImage:[attributes objectForKey:@"image"]]; - } - view.autoresizingMask = [[attributes objectForKey:@"autoresizingMask"] integerValue]; -} - -@end diff --git a/Classes/LinphoneUI/UICallButton.h b/Classes/LinphoneUI/UICallButton.h index d8b317a1d..7261c8ee5 100644 --- a/Classes/LinphoneUI/UICallButton.h +++ b/Classes/LinphoneUI/UICallButton.h @@ -19,10 +19,13 @@ #import +#import "UIIconButton.h" -@interface UICallButton : UIButton { +@interface UICallButton : UIIconButton { } -@property (nonatomic, retain) IBOutlet UITextField* addressField; +@property(nonatomic, strong) IBOutlet UITextField *addressField; + +- (void)updateVideoPolicy; @end diff --git a/Classes/LinphoneUI/UICallButton.m b/Classes/LinphoneUI/UICallButton.m index 000e67f00..184b5c20c 100644 --- a/Classes/LinphoneUI/UICallButton.m +++ b/Classes/LinphoneUI/UICallButton.m @@ -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 "UICallButton.h" #import "LinphoneManager.h" @@ -26,90 +26,83 @@ @synthesize addressField; - #pragma mark - Lifecycle Functions - (void)initUICallButton { - [self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside]; + [self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside]; } - (id)init { - self = [super init]; - if (self) { + self = [super init]; + if (self) { [self initUICallButton]; - } - return self; + } + return self; } - (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { + self = [super initWithFrame:frame]; + if (self) { [self initUICallButton]; - } - return self; + } + return self; } - (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { + self = [super initWithCoder:decoder]; + if (self) { [self initUICallButton]; } - return self; -} - -- (void)dealloc { - [addressField release]; - - [super dealloc]; + return self; } - #pragma mark - -- (void)touchUp:(id) sender { - NSString *address = [addressField text]; - NSString *displayName = nil; +- (void)touchUp:(id)sender { + NSString *address = addressField.text; + if (address.length == 0) { + LinphoneCore *lc = [LinphoneManager getLc]; + LinphoneCallLog *log = linphone_core_get_last_outgoing_call_log(lc); + if (log) { + LinphoneAddress *to = linphone_call_log_get_to(log); + const char *domain = linphone_address_get_domain(to); + char *bis_address = NULL; + LinphoneProxyConfig *def_proxy = linphone_core_get_default_proxy_config(lc); - if( [address length] == 0){ - const MSList* logs = linphone_core_get_call_logs([LinphoneManager getLc]); - while( logs ){ - LinphoneCallLog* log = logs->data; - if( linphone_call_log_get_dir(log) == LinphoneCallOutgoing ){ - LinphoneProxyConfig* def_proxy = NULL; - LinphoneAddress* to = linphone_call_log_get_to(log); - const char* domain = linphone_address_get_domain(to); - char* bis_address = NULL; + // if the 'to' address is on the default proxy, only present the username + if (def_proxy) { + const char *def_domain = linphone_proxy_config_get_domain(def_proxy); + if (def_domain && domain && !strcmp(domain, def_domain)) { + bis_address = ms_strdup(linphone_address_get_username(to)); + } + } + if (bis_address == NULL) { + bis_address = linphone_address_as_string_uri_only(to); + } + [addressField setText:[NSString stringWithUTF8String:bis_address]]; + ms_free(bis_address); + // return after filling the address, let the user confirm the call by pressing again + return; + } + } - linphone_core_get_default_proxy([LinphoneManager getLc], &def_proxy); - - // if the 'to' address is on the default proxy, only present the username - if( def_proxy ){ - const char* def_domain = linphone_proxy_config_get_domain(def_proxy); - if( def_domain && domain && !strcmp(domain, def_domain) ){ - bis_address = ms_strdup(linphone_address_get_username(to)); - } - } - - if( bis_address == NULL ) { - bis_address = linphone_address_as_string_uri_only(to); - } - - [addressField setText:[NSString stringWithUTF8String:bis_address]]; - ms_free(bis_address); - // return after filling the address, let the user confirm the call by pressing again - return; - } - logs = ms_list_next(logs); - } - } - - if( [address length] > 0){ - ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:address]; - if(contact) { - displayName = [FastAddressBook getContactDisplayName:contact]; - } - [[LinphoneManager instance] call:address displayName:displayName transfer:FALSE]; - } + if ([address length] > 0) { + LinphoneAddress *addr = linphone_address_new(address.UTF8String); + NSString *displayName = addr ? [FastAddressBook displayNameForAddress:addr] : nil; + if (addr) + linphone_address_destroy(addr); + [LinphoneManager.instance call:address displayName:displayName transfer:FALSE]; + } } +- (void)updateVideoPolicy { + LinphoneCore *lc = [LinphoneManager getLc]; + if (linphone_core_video_capture_enabled(lc) && linphone_core_get_video_policy(lc)->automatically_initiate) { + [self setImage:[UIImage imageNamed:@"call_video_start_default.png"] forState:UIControlStateNormal]; + [self setImage:[UIImage imageNamed:@"call_video_start_disabled.png"] forState:UIControlStateDisabled]; + } else { + [self setImage:[UIImage imageNamed:@"call_audio_start_default.png"] forState:UIControlStateNormal]; + [self setImage:[UIImage imageNamed:@"call_audio_start_disabled.png"] forState:UIControlStateDisabled]; + } +} @end diff --git a/Classes/LinphoneUI/UICallCell.h b/Classes/LinphoneUI/UICallCell.h deleted file mode 100644 index f79714ce1..000000000 --- a/Classes/LinphoneUI/UICallCell.h +++ /dev/null @@ -1,113 +0,0 @@ -/* UICallCell.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#include "linphone/linphonecore.h" -#include "UIPauseButton.h" -#import "UITransparentTVCell.h" - -typedef enum _UICallCellOtherView { - UICallCellOtherView_Avatar = 0, - UICallCellOtherView_AudioStats, - UICallCellOtherView_VideoStats, - UICallCellOtherView_MAX -} UICallCellOtherView; - -@interface UICallCellData : NSObject { - @public - bool minimize; - UICallCellOtherView view; - LinphoneCall *call; -} - -- (id)init:(LinphoneCall*) call minimized:(BOOL)minimized; - -@property (nonatomic, retain) UIImage *image; -@property (nonatomic, retain) NSString *address; - -@end - -@interface UICallCell : UITransparentTVCell { -} - -@property (nonatomic, retain) UICallCellData *data; - -@property (nonatomic, retain) IBOutlet UIImageView* headerBackgroundImage; -@property (nonatomic, retain) IBOutlet UIImageView* headerBackgroundHighlightImage; - -@property (nonatomic, retain) IBOutlet UILabel* addressLabel; -@property (nonatomic, retain) IBOutlet UILabel* stateLabel; -@property (nonatomic, retain) IBOutlet UIImageView* stateImage; -@property (nonatomic, retain) IBOutlet UIImageView* avatarImage; -@property (nonatomic, retain) IBOutlet UIButton *removeButton; -@property (nonatomic, retain) IBOutlet UIPauseButton *pauseButton; - -@property (nonatomic, retain) IBOutlet UIView* headerView; -@property (nonatomic, retain) IBOutlet UIView* avatarView; - -@property (nonatomic, retain) IBOutlet UIView* audioStatsView; - -@property (nonatomic, retain) IBOutlet UILabel* audioCodecLabel; -@property (nonatomic, retain) IBOutlet UILabel* audioCodecHeaderLabel; -@property (nonatomic, retain) IBOutlet UILabel* audioUploadBandwidthLabel; -@property (nonatomic, retain) IBOutlet UILabel* audioUploadBandwidthHeaderLabel; -@property (nonatomic, retain) IBOutlet UILabel* audioDownloadBandwidthLabel; -@property (nonatomic, retain) IBOutlet UILabel* audioDownloadBandwidthHeaderLabel; -@property (nonatomic, retain) IBOutlet UILabel* audioIceConnectivityLabel; -@property (nonatomic, retain) IBOutlet UILabel* audioIceConnectivityHeaderLabel; - -@property (nonatomic, retain) IBOutlet UIView* videoStatsView; - -@property (nonatomic, retain) IBOutlet UILabel* videoCodecLabel; -@property (nonatomic, retain) IBOutlet UILabel* videoCodecHeaderLabel; - -@property (retain, nonatomic) IBOutlet UILabel *videoSentSizeHeaderLabel; -@property (retain, nonatomic) IBOutlet UILabel *videoSentSizeLabel; -@property (retain, nonatomic) IBOutlet UILabel *videoRecvSizeHeaderLabel; -@property (retain, nonatomic) IBOutlet UILabel *videoRecvSizeLabel; - -@property (nonatomic, retain) IBOutlet UILabel* videoUploadBandwidthLabel; -@property (nonatomic, retain) IBOutlet UILabel* videoUploadBandwidthHeaderLabel; -@property (nonatomic, retain) IBOutlet UILabel* videoDownloadBandwidthLabel; -@property (nonatomic, retain) IBOutlet UILabel* videoDownloadBandwidthHeaderLabel; -@property (nonatomic, retain) IBOutlet UILabel* videoIceConnectivityLabel; -@property (nonatomic, retain) IBOutlet UILabel* videoIceConnectivityHeaderLabel; - -@property (nonatomic, retain) IBOutlet UIView* otherView; - -@property (nonatomic, retain) IBOutlet UISwipeGestureRecognizer *detailsLeftSwipeGestureRecognizer; -@property (nonatomic, retain) IBOutlet UISwipeGestureRecognizer *detailsRightSwipeGestureRecognizer; - -@property (assign) BOOL firstCell; -@property (assign) BOOL conferenceCell; -@property (nonatomic, assign) BOOL currentCall; - -- (void)update; - -- (id)initWithIdentifier:(NSString*)identifier; - -- (IBAction)doHeaderClick:(id)sender; -- (IBAction)doRemoveClick:(id)sender; -- (IBAction)doDetailsSwipe:(UISwipeGestureRecognizer *)sender; - -+ (int)getMaximizedHeight; -+ (int)getMinimizedHeight; - -@end diff --git a/Classes/LinphoneUI/UICallCell.m b/Classes/LinphoneUI/UICallCell.m deleted file mode 100644 index 894cf1a27..000000000 --- a/Classes/LinphoneUI/UICallCell.m +++ /dev/null @@ -1,584 +0,0 @@ -/* UICallCell.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UICallCell.h" -#import "UILinphone.h" -#import "LinphoneManager.h" -#import "FastAddressBook.h" - -@implementation UICallCellData - -@synthesize address; -@synthesize image; - -- (id)init:(LinphoneCall*)acall minimized:(BOOL)minimized{ - self = [super init]; - if(self != nil) { - self->minimize = minimized; - self->view = UICallCellOtherView_Avatar; - self->call = acall; - image = [[UIImage imageNamed:@"avatar_unknown.png"] retain]; - address = [NSLocalizedString(@"Unknown",nil) retain]; - [self update]; - } - return self; -} - -- (void)update { - if(call == NULL) { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update call cell: null call or data"]; - return; - } - const LinphoneAddress* addr = linphone_call_get_remote_address(call); - - if(addr != NULL) { - BOOL useLinphoneAddress = true; - // contact name - char* lAddress = linphone_address_as_string_uri_only(addr); - if(lAddress) { - NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:lAddress]]; - ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress]; - if(contact) { - useLinphoneAddress = false; - self.address = [FastAddressBook getContactDisplayName:contact]; - UIImage *tmpImage = [FastAddressBook getContactImage:contact thumbnail:false]; - if(tmpImage != nil) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) { - UIImage *tmpImage2 = [UIImage decodedImageWithImage:tmpImage]; - dispatch_async(dispatch_get_main_queue(), ^{ - [self setImage: tmpImage2]; - }); - }); - } - } - ms_free(lAddress); - } - if(useLinphoneAddress) { - const char* lDisplayName = linphone_address_get_display_name(addr); - const char* lUserName = linphone_address_get_username(addr); - if (lDisplayName) - self.address = [NSString stringWithUTF8String:lDisplayName]; - else if(lUserName) - self.address = [NSString stringWithUTF8String:lUserName]; - } - } -} - -- (void)dealloc { - [address release]; - [image release]; - - [super dealloc]; -} - -@end - -@implementation UICallCell - -@synthesize data; - -@synthesize headerBackgroundImage; -@synthesize headerBackgroundHighlightImage; - -@synthesize addressLabel; -@synthesize stateLabel; -@synthesize stateImage; -@synthesize avatarImage; -@synthesize pauseButton; -@synthesize removeButton; - -@synthesize headerView; -@synthesize avatarView; - -@synthesize audioStatsView; - -@synthesize audioCodecLabel; -@synthesize audioCodecHeaderLabel; -@synthesize audioUploadBandwidthLabel; -@synthesize audioUploadBandwidthHeaderLabel; -@synthesize audioDownloadBandwidthLabel; -@synthesize audioDownloadBandwidthHeaderLabel; -@synthesize audioIceConnectivityLabel; -@synthesize audioIceConnectivityHeaderLabel; - -@synthesize videoStatsView; - -@synthesize videoCodecLabel, videoCodecHeaderLabel; -@synthesize videoUploadBandwidthLabel, videoUploadBandwidthHeaderLabel; -@synthesize videoDownloadBandwidthLabel, videoDownloadBandwidthHeaderLabel; -@synthesize videoIceConnectivityLabel, videoIceConnectivityHeaderLabel; - -@synthesize videoRecvSizeHeaderLabel, videoRecvSizeLabel; -@synthesize videoSentSizeHeaderLabel, videoSentSizeLabel; - -@synthesize otherView; - -@synthesize firstCell; -@synthesize conferenceCell; -@synthesize currentCall; -@synthesize detailsLeftSwipeGestureRecognizer; -@synthesize detailsRightSwipeGestureRecognizer; - - -#pragma mark - Lifecycle Functions - -- (id)initWithIdentifier:(NSString*)identifier { - if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) { - NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"UICallCell" - owner:self - options:nil]; - - if ([arrayOfViews count] >= 1) { - //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"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - self->currentCall = FALSE; - - self->detailsRightSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(doDetailsSwipe:)]; - [detailsRightSwipeGestureRecognizer setDirection:UISwipeGestureRecognizerDirectionLeft]; - [otherView addGestureRecognizer:detailsRightSwipeGestureRecognizer]; - - self->detailsRightSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(doDetailsSwipe:)]; - [detailsRightSwipeGestureRecognizer setDirection:UISwipeGestureRecognizerDirectionRight]; - [otherView addGestureRecognizer:detailsRightSwipeGestureRecognizer]; - - [self->avatarView setHidden:TRUE]; - [self->audioStatsView setHidden:TRUE]; - [self->videoStatsView setHidden:TRUE]; - - [UICallCell adaptSize:audioCodecHeaderLabel field:audioCodecLabel]; - [UICallCell adaptSize:audioDownloadBandwidthHeaderLabel field:audioDownloadBandwidthLabel]; - [UICallCell adaptSize:audioUploadBandwidthHeaderLabel field:audioUploadBandwidthLabel]; - [UICallCell adaptSize:audioIceConnectivityHeaderLabel field:audioIceConnectivityLabel]; - - [UICallCell adaptSize:videoCodecHeaderLabel field:videoCodecLabel]; - [UICallCell adaptSize:videoDownloadBandwidthHeaderLabel field:videoDownloadBandwidthLabel]; - [UICallCell adaptSize:videoUploadBandwidthHeaderLabel field:videoUploadBandwidthLabel]; - [UICallCell adaptSize:videoIceConnectivityHeaderLabel field:videoIceConnectivityLabel]; - - 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 - object:nil]; - } - return self; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIApplicationWillEnterForegroundNotification - object:nil]; - - - [headerBackgroundImage release]; - [headerBackgroundHighlightImage release]; - - [addressLabel release]; - [stateLabel release]; - [stateImage release]; - [avatarImage release]; - [pauseButton release]; - [removeButton release]; - - [headerView release]; - [avatarView release]; - - [audioStatsView release]; - - [audioCodecLabel release]; - [audioCodecHeaderLabel release]; - [audioUploadBandwidthLabel release]; - [audioUploadBandwidthHeaderLabel release]; - [audioDownloadBandwidthLabel release]; - [audioDownloadBandwidthHeaderLabel release]; - [audioIceConnectivityLabel release]; - [audioIceConnectivityHeaderLabel release]; - - [videoStatsView release]; - - [videoCodecLabel release]; - [videoCodecHeaderLabel release]; - [videoUploadBandwidthLabel release]; - [videoUploadBandwidthHeaderLabel release]; - [videoDownloadBandwidthLabel release]; - [videoDownloadBandwidthHeaderLabel release]; - [videoIceConnectivityLabel release]; - [videoIceConnectivityHeaderLabel release]; - - [otherView release]; - - [data release]; - - [detailsLeftSwipeGestureRecognizer release]; - [detailsRightSwipeGestureRecognizer release]; - - [videoSentSizeHeaderLabel release]; - [videoSentSizeLabel release]; - [videoRecvSizeHeaderLabel release]; - [videoRecvSizeLabel release]; - [super dealloc]; -} - - -#pragma mark - Properties Functions - -- (void)setData:(UICallCellData *)adata { - if(adata == data) { - return; - } - if(data != nil) { - [data release]; - data = nil; - } - if(adata != nil) { - data = [adata retain]; - } -} - -- (void)setCurrentCall:(BOOL) val { - currentCall = val; - if (currentCall && ![self isBlinkAnimationRunning:@"blink" target:headerBackgroundHighlightImage]) { - [self startBlinkAnimation:@"blink" target:headerBackgroundHighlightImage]; - } - if (!currentCall) { - [self stopBlinkAnimation:@"blink" target:headerBackgroundHighlightImage]; - } -} - - -#pragma mark - Static Functions - -+ (int)getMaximizedHeight { - return [LinphoneManager runningOnIpad] ? 600 : 300; -} - -+ (int)getMinimizedHeight { - return [LinphoneManager runningOnIpad] ? 126 : 63; -} - -+ (void)adaptSize:(UILabel*)label field:(UIView*)field { - // - // Adapt size - // - CGRect labelFrame = [label frame]; - CGRect fieldFrame = [field frame]; - - fieldFrame.origin.x -= labelFrame.size.width; - - // Compute firstName size - CGSize contraints; - contraints.height = [label frame].size.height; - contraints.width = ([field frame].size.width + [field frame].origin.x) - [label frame].origin.x; - CGSize firstNameSize = [[label text] sizeWithFont:[label font] constrainedToSize: contraints]; - labelFrame.size.width = firstNameSize.width; - - // Compute lastName size & position - fieldFrame.origin.x += labelFrame.size.width; - fieldFrame.size.width = (contraints.width + [label frame].origin.x) - fieldFrame.origin.x; - - [label setFrame: labelFrame]; - [field setFrame: fieldFrame]; -} - - -+ (NSString*)iceToString:(LinphoneIceState)state { - switch (state) { - case LinphoneIceStateNotActivated: - return NSLocalizedString(@"Not activated", @"ICE has not been activated for this call"); - break; - case LinphoneIceStateFailed: - return NSLocalizedString(@"Failed", @"ICE processing has failed"); - break; - case LinphoneIceStateInProgress: - return NSLocalizedString(@"In progress", @"ICE process is in progress"); - break; - case LinphoneIceStateHostConnection: - return NSLocalizedString(@"Direct connection", @"ICE has established a direct connection to the remote host"); - break; - case LinphoneIceStateReflexiveConnection: - return NSLocalizedString(@"NAT(s) connection", @"ICE has established a connection to the remote host through one or several NATs"); - break; - case LinphoneIceStateRelayConnection: - return NSLocalizedString(@"Relay connection", @"ICE has established a connection through a relay"); - break; - } -} - - -#pragma mark - Event Functions - -- (void)applicationWillEnterForeground:(NSNotification*)notif { - if (currentCall) { - [self startBlinkAnimation:@"blink" target:headerBackgroundHighlightImage]; - } -} - - -#pragma mark - Animation Functions - -- (void)startBlinkAnimation:(NSString *)animationID target:(UIView *)target { - if( [[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]){ - CABasicAnimation *blink = [CABasicAnimation animationWithKeyPath:@"opacity"]; - blink.duration = 1.0; - blink.fromValue = [NSNumber numberWithDouble:0.0f]; - blink.toValue = [NSNumber numberWithDouble:1.0f]; - blink.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; - blink.autoreverses = TRUE; - blink.repeatCount = HUGE_VALF; - [target.layer addAnimation:blink forKey:animationID]; - } else { - [target setAlpha:1.0f]; - } -} - -- (BOOL)isBlinkAnimationRunning:(NSString *)animationID target:(UIView *)target { - return [target.layer animationForKey:animationID] != nil; -} - -- (void)stopBlinkAnimation:(NSString *)animationID target:(UIView *)target { - if( [self isBlinkAnimationRunning:animationID target:target] ){ - [target.layer removeAnimationForKey:animationID]; - } - [target setAlpha:0.0f]; -} - - -#pragma mark - - -- (void)update { - if(data == nil || data->call == NULL) { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update call cell: null call or data"]; - return; - } - LinphoneCall *call = data->call; - - [pauseButton setType:UIPauseButtonType_Call call:call]; - - [addressLabel setText:data.address]; - [avatarImage setImage:data.image]; - - LinphoneCallState state = linphone_call_get_state(call); - if(!conferenceCell) { - if(state == LinphoneCallOutgoingRinging) { - [stateImage setImage:[UIImage imageNamed:@"call_state_ringing_default.png"]]; - [stateImage setHidden:false]; - [pauseButton setHidden:true]; - } else if(state == LinphoneCallOutgoingInit || state == LinphoneCallOutgoingProgress){ - [stateImage setImage:[UIImage imageNamed:@"call_state_outgoing_default.png"]]; - [stateImage setHidden:false]; - [pauseButton setHidden:true]; - } else { - [stateImage setHidden:true]; - [pauseButton setHidden:false]; - [pauseButton update]; - } - [removeButton setHidden:true]; - if(firstCell) { - [headerBackgroundImage setImage:[UIImage imageNamed:@"cell_call_first.png"]]; - [headerBackgroundHighlightImage setImage:[UIImage imageNamed:@"cell_call_first_highlight.png"]]; - } else { - [headerBackgroundImage setImage:[UIImage imageNamed:@"cell_call.png"]]; - [headerBackgroundHighlightImage setImage:[UIImage imageNamed:@"cell_call_highlight.png"]]; - } - } else { - [stateImage setHidden:true]; - [pauseButton setHidden:true]; - [removeButton setHidden:false]; - [headerBackgroundImage setImage:[UIImage imageNamed:@"cell_conference.png"]]; - } - - int duration = linphone_call_get_duration(call); - [stateLabel setText:[NSString stringWithFormat:@"%02i:%02i", (duration/60), (duration%60), nil]]; - - if(!data->minimize) { - CGRect frame = [self frame]; - 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; - [self setFrame:frame]; - [otherView setHidden:true]; - } - - [self updateStats]; - - [self updateDetailsView]; -} - -- (void)updateStats { - if(data == nil || data->call == NULL) { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update call cell: null call or data"]; - return; - } - LinphoneCall *call = data->call; - - const LinphoneCallParams *params = linphone_call_get_current_params(call); - { - const PayloadType* payload = linphone_call_params_get_used_audio_codec(params); - if(payload != NULL) { - [audioCodecLabel setText:[NSString stringWithFormat:@"%s/%i/%i", payload->mime_type, payload->clock_rate, payload->channels]]; - } else { - [audioCodecLabel setText:NSLocalizedString(@"No codec", nil)]; - } - const LinphoneCallStats *stats = linphone_call_get_audio_stats(call); - if(stats != NULL) { - [audioUploadBandwidthLabel setText:[NSString stringWithFormat:@"%1.1f kbits/s", stats->upload_bandwidth]]; - [audioDownloadBandwidthLabel setText:[NSString stringWithFormat:@"%1.1f kbits/s", stats->download_bandwidth]]; - [audioIceConnectivityLabel setText:[UICallCell iceToString:stats->ice_state]]; - } else { - [audioUploadBandwidthLabel setText:@""]; - [audioDownloadBandwidthLabel setText:@""]; - [audioIceConnectivityLabel setText:@""]; - } - } - - { - const PayloadType* payload = linphone_call_params_get_used_video_codec(params); - if(payload != NULL) { - [videoCodecLabel setText:[NSString stringWithFormat:@"%s/%i", payload->mime_type, payload->clock_rate]]; - } else { - [videoCodecLabel setText:NSLocalizedString(@"No codec", nil)]; - } - - const LinphoneCallStats *stats = linphone_call_get_video_stats(call); - - MSVideoSize sentSize = linphone_call_params_get_sent_video_size(params); - MSVideoSize recvSize = linphone_call_params_get_received_video_size(params); - - if(stats != NULL) { - [videoUploadBandwidthLabel setText:[NSString stringWithFormat:@"%1.1f kbits/s", stats->upload_bandwidth]]; - [videoDownloadBandwidthLabel setText:[NSString stringWithFormat:@"%1.1f kbits/s", stats->download_bandwidth]]; - [videoIceConnectivityLabel setText:[UICallCell iceToString:stats->ice_state]]; - [videoSentSizeLabel setText:[NSString stringWithFormat:@"%dx%d",sentSize.width, sentSize.height]]; - [videoRecvSizeLabel setText:[NSString stringWithFormat:@"%dx%d",recvSize.width, recvSize.height]]; - } else { - [videoUploadBandwidthLabel setText:@""]; - [videoDownloadBandwidthLabel setText:@""]; - [videoIceConnectivityLabel setText:@""]; - [videoSentSizeLabel setText:@"0x0"]; - [videoRecvSizeLabel setText:@"0x0"]; - - } - } -} - - -- (void)updateDetailsView { - if(data == nil || data->call == NULL) { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update call cell: null call or data"]; - return; - } - if(data->view == UICallCellOtherView_Avatar && avatarView.isHidden) { - [self->avatarView setHidden:FALSE]; - [self->audioStatsView setHidden:TRUE]; - [self->videoStatsView setHidden:TRUE]; - } else if(data->view == UICallCellOtherView_AudioStats && audioStatsView.isHidden) { - [self->avatarView setHidden:TRUE]; - [self->audioStatsView setHidden:FALSE]; - [self->videoStatsView setHidden:TRUE]; - } else if(data->view == UICallCellOtherView_VideoStats && videoStatsView.isHidden) { - [self->avatarView setHidden:TRUE]; - [self->audioStatsView setHidden:TRUE]; - [self->videoStatsView setHidden:FALSE]; - } -} - -- (void)selfUpdate { - UITableView *parentTable = (UITableView *)self.superview; - - while( parentTable != nil && ![parentTable isKindOfClass:[UITableView class]] ) parentTable = (UITableView *)[parentTable superview]; - - if(parentTable != nil) { - NSIndexPath *index= [parentTable indexPathForCell:self]; - if(index != nil) { - [parentTable reloadRowsAtIndexPaths:@[index] withRowAnimation:false]; - } - } -} - - -#pragma mark - Action Functions - -- (IBAction)doHeaderClick:(id)sender { - if(data) { - data->minimize = !data->minimize; - [self selfUpdate]; - } -} - -- (IBAction)doRemoveClick:(id)sender { - if(data != nil && data->call != NULL) { - linphone_core_remove_from_conference([LinphoneManager getLc], data->call); - } -} - -- (IBAction)doDetailsSwipe:(UISwipeGestureRecognizer *)sender { - CATransition* trans = nil; - if(data != nil) { - if (sender.direction == UISwipeGestureRecognizerDirectionLeft) { - if(data->view == UICallCellOtherView_MAX - 1) { - data->view = 0; - } else { - ++data->view; - } - trans = [CATransition animation]; - [trans setType:kCATransitionPush]; - [trans setDuration:0.35]; - [trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; - [trans setSubtype:kCATransitionFromRight]; - } else if (sender.direction == UISwipeGestureRecognizerDirectionRight) { - if(data->view == 0) { - data->view = UICallCellOtherView_MAX - 1; - } else { - --data->view; - } - trans = [CATransition animation]; - [trans setType:kCATransitionPush]; - [trans setDuration:0.35]; - [trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; - [trans setSubtype:kCATransitionFromLeft]; - } - if(trans) { - [otherView.layer removeAnimationForKey:@"transition"]; - [otherView.layer addAnimation:trans forKey:@"transition"]; - [self updateDetailsView]; - } - } -} - -@end diff --git a/Classes/LinphoneUI/UICallConferenceCell.h b/Classes/LinphoneUI/UICallConferenceCell.h new file mode 100644 index 000000000..ce00eed21 --- /dev/null +++ b/Classes/LinphoneUI/UICallConferenceCell.h @@ -0,0 +1,22 @@ +// +// UIPausedCallCell.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 11/09/15. +// +// + +#import "UIRoundedImageView.h" +#import "LinphoneManager.h" + +@interface UICallConferenceCell : UITableViewCell + +@property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage; +@property(weak, nonatomic) IBOutlet UILabel *nameLabel; +@property(weak, nonatomic) IBOutlet UILabel *durationLabel; +@property(nonatomic, setter=setCall:) LinphoneCall *call; + +- (id)initWithIdentifier:(NSString *)identifier; +- (IBAction)onKickClick:(id)sender; + +@end diff --git a/Classes/LinphoneUI/UICallConferenceCell.m b/Classes/LinphoneUI/UICallConferenceCell.m new file mode 100644 index 000000000..6470df9cf --- /dev/null +++ b/Classes/LinphoneUI/UICallConferenceCell.m @@ -0,0 +1,48 @@ +// +// UIPausedCallCell.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 11/09/15. +// +// + +#import "UICallConferenceCell.h" +#import "Utils.h" + +@implementation UICallConferenceCell + +- (id)initWithIdentifier:(NSString *)identifier { + self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; + if (self != nil) { + NSArray *arrayOfViews = + [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + if ([arrayOfViews count] >= 1) { + // 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]; + } + } + return self; +} + +- (void)setCall:(LinphoneCall *)call { + _call = call; + if (!call || !linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call))) { + LOGF(@"Invalid call: either NULL or not in conference."); + return; + } + + const LinphoneAddress *addr = linphone_call_get_remote_address(call); + [ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr]; + + [_avatarImage setImage:[FastAddressBook imageForAddress:addr thumbnail:YES] bordered:NO withRoundedRadius:YES]; + + _durationLabel.text = [LinphoneUtils durationToString:linphone_call_get_duration(call)]; +} + +- (IBAction)onKickClick:(id)sender { + linphone_core_remove_from_conference([LinphoneManager getLc], _call); +} +@end diff --git a/Classes/LinphoneUI/UICallPausedCell.h b/Classes/LinphoneUI/UICallPausedCell.h new file mode 100644 index 000000000..85bf8f09f --- /dev/null +++ b/Classes/LinphoneUI/UICallPausedCell.h @@ -0,0 +1,23 @@ +// +// UIPausedCallCell.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 11/09/15. +// +// + +#import "UIRoundedImageView.h" +#import "LinphoneManager.h" +#import "UIPauseButton.h" + +@interface UICallPausedCell : UITableViewCell + +@property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage; +@property(weak, nonatomic) IBOutlet UILabel *nameLabel; +@property(weak, nonatomic) IBOutlet UILabel *durationLabel; +@property(weak, nonatomic) IBOutlet UIPauseButton *pauseButton; + +- (id)initWithIdentifier:(NSString *)identifier; +- (void)setCall:(LinphoneCall *)call; + +@end diff --git a/Classes/LinphoneUI/UICallPausedCell.m b/Classes/LinphoneUI/UICallPausedCell.m new file mode 100644 index 000000000..9107bcd75 --- /dev/null +++ b/Classes/LinphoneUI/UICallPausedCell.m @@ -0,0 +1,49 @@ +// +// UIPausedCallCell.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 11/09/15. +// +// + +#import "UICallPausedCell.h" +#import "Utils.h" + +@implementation UICallPausedCell + +- (id)initWithIdentifier:(NSString *)identifier { + self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; + if (self != nil) { + NSArray *arrayOfViews = + [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + if ([arrayOfViews count] >= 1) { + // 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]; + } + } + return self; +} + +- (void)setCall:(LinphoneCall *)call { + // if no call is provided, we assume that this is a conference + if (!call) { + [_pauseButton setType:UIPauseButtonType_Conference call:call]; + _nameLabel.text = NSLocalizedString(@"Conference", nil); + [_avatarImage setImage:[UIImage imageNamed:@"options_start_conference_default.png"] + bordered:NO + withRoundedRadius:YES]; + _durationLabel.text = @""; + } else { + [_pauseButton setType:UIPauseButtonType_Call call:call]; + const LinphoneAddress *addr = linphone_call_get_remote_address(call); + [ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr]; + [_avatarImage setImage:[FastAddressBook imageForAddress:addr thumbnail:YES] bordered:NO withRoundedRadius:YES]; + _durationLabel.text = [LinphoneUtils durationToString:linphone_call_get_duration(call)]; + } + [_pauseButton update]; +} + +@end diff --git a/Classes/LinphoneUI/UICamSwitch.h b/Classes/LinphoneUI/UICamSwitch.h index bcde2513c..76b7eaf4f 100644 --- a/Classes/LinphoneUI/UICamSwitch.h +++ b/Classes/LinphoneUI/UICamSwitch.h @@ -19,10 +19,10 @@ #import +#import "UIIconButton.h" -@interface UICamSwitch : UIButton { -@private +@interface UICamSwitch : UIIconButton + +@property(nonatomic, weak) IBOutlet UIView *preview; -} -@property (nonatomic, retain) IBOutlet UIView* preview; @end diff --git a/Classes/LinphoneUI/UICamSwitch.m b/Classes/LinphoneUI/UICamSwitch.m index cc5bcab87..6716ff59b 100644 --- a/Classes/LinphoneUI/UICamSwitch.m +++ b/Classes/LinphoneUI/UICamSwitch.m @@ -4,88 +4,56 @@ * * 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 + * 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 "UICamSwitch.h" #include "LinphoneManager.h" +#import "Utils.h" @implementation UICamSwitch @synthesize preview; - #pragma mark - Lifecycle Functions -- (id)initUICamSwitch { +INIT_WITH_COMMON { [self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside]; return self; } -- (id)init { - self = [super init]; - if (self) { - [self initUICamSwitch]; - } - return self; -} +#pragma mark - -- (id)initWithFrame:(CGRect)frame { - - self = [super initWithFrame:frame]; - if (self) { - [self initUICamSwitch]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { - [self initUICamSwitch]; - } - return self; -} - - -- (void)dealloc { - [super dealloc]; - [preview release]; -} - - -#pragma mark - - --(void) touchUp:(id) sender { - 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; +- (void)touchUp:(id)sender { + 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; int i; - - for (i=0;cameras[i]!=NULL;++i){ - if (strcmp(cameras[i],"StaticImage: Static picture")==0) continue; - if (strcmp(cameras[i],currentCamId)!=0){ - newCamId=cameras[i]; + + for (i = 0; cameras[i] != NULL; ++i) { + if (strcmp(cameras[i], "StaticImage: Static picture") == 0) + continue; + if (strcmp(cameras[i], currentCamId) != 0) { + newCamId = cameras[i]; break; } } - if (newCamId){ - [LinphoneLogger logc:LinphoneLoggerLog format:"Switching from [%s] to [%s]", currentCamId, newCamId]; + if (newCamId) { + LOGI(@"Switching from [%s] to [%s]", currentCamId, newCamId); linphone_core_set_video_device([LinphoneManager getLc], newCamId); LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); - if(call != NULL) { - linphone_core_update_call([LinphoneManager getLc], call, NULL); - } - + if (call != NULL) { + linphone_core_update_call([LinphoneManager getLc], call, NULL); + } } } diff --git a/Classes/LinphoneUI/UIChatBubblePhotoCell.h b/Classes/LinphoneUI/UIChatBubblePhotoCell.h new file mode 100644 index 000000000..f196dbcd1 --- /dev/null +++ b/Classes/LinphoneUI/UIChatBubblePhotoCell.h @@ -0,0 +1,45 @@ +/* UIChatRoomCell.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import + +#import "UILoadingImageView.h" +#import "UITextViewNoDefine.h" +#import "FileTransferDelegate.h" +#import "ChatConversationTableView.h" +#import "UIChatBubbleTextCell.h" + +@interface UIChatBubblePhotoCell : UIChatBubbleTextCell + +@property(nonatomic, strong) IBOutlet UILoadingImageView *messageImageView; +@property(nonatomic, strong) IBOutlet UIButton *downloadButton; +@property(weak, nonatomic) IBOutlet UIProgressView *fileTransferProgress; +@property(weak, nonatomic) IBOutlet UIButton *cancelButton; +@property(weak, nonatomic) IBOutlet UIView *imageSubView; +@property(weak, nonatomic) IBOutlet UIView *totalView; +@property(strong, nonatomic) IBOutlet UITapGestureRecognizer *imageGestureRecognizer; + +- (void)setChatMessage:(LinphoneChatMessage *)message; +- (void)connectToFileDelegate:(FileTransferDelegate *)ftd; +- (IBAction)onDownloadClick:(id)event; +- (IBAction)onImageClick:(id)event; +- (IBAction)onCancelClick:(id)sender; +- (IBAction)onResendClick:(id)event; + +@end diff --git a/Classes/LinphoneUI/UIChatBubblePhotoCell.m b/Classes/LinphoneUI/UIChatBubblePhotoCell.m new file mode 100644 index 000000000..a1b3bd068 --- /dev/null +++ b/Classes/LinphoneUI/UIChatBubblePhotoCell.m @@ -0,0 +1,258 @@ +/* UIChatRoomCell.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "UIChatBubblePhotoCell.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" + +#import +#import + +@implementation UIChatBubblePhotoCell { + FileTransferDelegate *_ftd; +} + +#pragma mark - Lifecycle Functions + +- (id)initWithIdentifier:(NSString *)identifier { + if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) { + // TODO: remove text cell subview + NSArray *arrayOfViews = + [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + // resize cell to match .nib size. It is needed when resized the cell to + // correctly adapt its height too + UIView *sub = nil; + for (int i = 0; i < arrayOfViews.count; i++) { + if ([arrayOfViews[i] isKindOfClass:UIView.class]) { + sub = arrayOfViews[i]; + break; + } + } + [self setFrame:CGRectMake(0, 0, sub.frame.size.width, sub.frame.size.height)]; + [self addSubview:sub]; + } + return self; +} + +#pragma mark - + +- (void)setChatMessage:(LinphoneChatMessage *)amessage { + _imageGestureRecognizer.enabled = NO; + _messageImageView.image = nil; + _fileTransferProgress.progress = 0; + [self disconnectFromFileDelegate]; + + if (amessage) { + const LinphoneContent *c = linphone_chat_message_get_file_transfer_information(amessage); + if (c) { + const char *name = linphone_content_get_name(c); + for (FileTransferDelegate *aftd in [[LinphoneManager instance] fileTransferDelegates]) { + if (linphone_chat_message_get_file_transfer_information(aftd.message) && + (linphone_chat_message_is_outgoing(aftd.message) == linphone_chat_message_is_outgoing(amessage)) && + strcmp(name, linphone_content_get_name( + linphone_chat_message_get_file_transfer_information(aftd.message))) == 0) { + LOGI(@"Chat message [%p] with file transfer delegate [%p], connecting to it!", amessage, aftd); + [self connectToFileDelegate:aftd]; + break; + } + } + } + } + + [super setChatMessage:amessage]; +} + +- (void)update { + if (self.message == nil) { + LOGW(@"Cannot update message room cell: NULL message"); + return; + } + [super update]; + + const char *url = linphone_chat_message_get_external_body_url(self.message); + BOOL is_external = + (url && (strstr(url, "http") == url)) || linphone_chat_message_get_file_transfer_information(self.message); + NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:self.message]; + BOOL fullScreenImage = NO; + assert(is_external || localImage); + if (localImage) { + // image is being saved on device - just wait for it + if ([localImage isEqualToString:@"saving..."]) { + _cancelButton.hidden = _fileTransferProgress.hidden = _downloadButton.hidden = YES; + fullScreenImage = YES; + } else { + // we did not load the image yet, so start doing so + if (_messageImageView.image == nil) { + NSURL *imageUrl = [NSURL URLWithString:localImage]; + [_messageImageView startLoading]; + __block LinphoneChatMessage *achat = self.message; + [LinphoneManager.instance.photoLibrary assetForURL:imageUrl + resultBlock:^(ALAsset *asset) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), + ^(void) { + if (achat == self.message) { // Avoid glitch and scrolling + UIImage *image = [[UIImage alloc] initWithCGImage:[asset thumbnail]]; + dispatch_async(dispatch_get_main_queue(), ^{ + [_messageImageView setImage:image]; + [_messageImageView setFullImageUrl:asset]; + [_messageImageView stopLoading]; + _messageImageView.hidden = NO; + _imageGestureRecognizer.enabled = YES; + }); + } + }); + } + failureBlock:^(NSError *error) { + LOGE(@"Can't read image"); + }]; + } + // we are uploading the image + if (_ftd.message != nil) { + _cancelButton.hidden = NO; + _fileTransferProgress.hidden = NO; + _downloadButton.hidden = YES; + } else { + _cancelButton.hidden = _fileTransferProgress.hidden = _downloadButton.hidden = YES; + fullScreenImage = YES; + } + } + // we must download the image: either it has already started (show cancel button) or not yet (show download + // button) + } else { + _messageImageView.hidden = _cancelButton.hidden = (_ftd.message == nil); + _downloadButton.hidden = !_cancelButton.hidden; + _fileTransferProgress.hidden = NO; + } + + // resize image so that it take the full bubble space available + CGRect newFrame = _totalView.frame; + newFrame.origin.x = newFrame.origin.y = 0; + if (!fullScreenImage) { + newFrame.size.height -= _imageSubView.frame.size.height; + } + _messageImageView.frame = newFrame; +} + +- (IBAction)onDownloadClick:(id)event { + [_ftd cancel]; + _ftd = [[FileTransferDelegate alloc] init]; + [self connectToFileDelegate:_ftd]; + [_ftd download:self.message]; + _cancelButton.hidden = NO; + _downloadButton.hidden = YES; + + // we must tell the tableview to refresh the cell to reflect its internal state + ChatConversationView *view = VIEW(ChatConversationView); + [view.tableController updateChatEntry:self.message]; +} + +- (IBAction)onCancelClick:(id)sender { + FileTransferDelegate *tmp = _ftd; + [self disconnectFromFileDelegate]; + [tmp cancel]; + _fileTransferProgress.progress = 0; + [self update]; + // we must tell the tableview to refresh the cell to reflect its internal state + ChatConversationView *view = VIEW(ChatConversationView); + [view.tableController updateChatEntry:self.message]; +} + +- (void)onResendClick:(id)event { + if (_downloadButton.hidden == NO) { + // if download button is displayed, click on it + [self onDownloadClick:event]; + } else if (_cancelButton.hidden == NO) { + [self onCancelClick:event]; + } else { + [super onResendClick:event]; + } +} + +- (IBAction)onImageClick:(id)event { + LinphoneChatMessageState state = linphone_chat_message_get_state(self.message); + if (state == LinphoneChatMessageStateNotDelivered) { + [self onResendClick:event]; + } else { + if (![_messageImageView isLoading]) { + ImageView *view = VIEW(ImageView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE]; + CGImageRef fullScreenRef = [[_messageImageView.fullImageUrl defaultRepresentation] fullScreenImage]; + UIImage *fullScreen = [UIImage imageWithCGImage:fullScreenRef]; + [view setImage:fullScreen]; + } + } +} + +#pragma mark - LinphoneFileTransfer Notifications Handling + +- (void)connectToFileDelegate:(FileTransferDelegate *)aftd { + if (aftd.message && linphone_chat_message_get_state(aftd.message) == LinphoneChatMessageStateFileTransferError) { + LOGW(@"This file transfer failed unexpectedly, cleaning it"); + [aftd stopAndDestroy]; + return; + } + + _ftd = aftd; + _fileTransferProgress.progress = 0; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(onFileTransferSendUpdate:) + name:kLinphoneFileTransferSendUpdate + object:_ftd]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(onFileTransferRecvUpdate:) + name:kLinphoneFileTransferRecvUpdate + object:_ftd]; +} + +- (void)disconnectFromFileDelegate { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + _ftd = nil; +} + +- (void)onFileTransferSendUpdate:(NSNotification *)notif { + LinphoneChatMessageState state = [[[notif userInfo] objectForKey:@"state"] intValue]; + + if (state == LinphoneChatMessageStateInProgress) { + float progress = [[[notif userInfo] objectForKey:@"progress"] floatValue]; + // When uploading a file, the self.message file is first uploaded to the server, + // so we are in progress state. Then state goes to filetransfertdone. Then, + // the exact same self.message is sent to the other participant and we come + // back to in progress again. This second time is NOT an upload, so we must + // not update progress! + _fileTransferProgress.progress = MAX(_fileTransferProgress.progress, progress); + _fileTransferProgress.hidden = _cancelButton.hidden = (_fileTransferProgress.progress == 1.f); + } else { + ChatConversationView *view = VIEW(ChatConversationView); + [view.tableController updateChatEntry:self.message]; + } +} +- (void)onFileTransferRecvUpdate:(NSNotification *)notif { + LinphoneChatMessageState state = [[[notif userInfo] objectForKey:@"state"] intValue]; + if (state == LinphoneChatMessageStateInProgress) { + float progress = [[[notif userInfo] objectForKey:@"progress"] floatValue]; + _fileTransferProgress.progress = MAX(_fileTransferProgress.progress, progress); + _fileTransferProgress.hidden = _cancelButton.hidden = (_fileTransferProgress.progress == 1.f); + } else { + ChatConversationView *view = VIEW(ChatConversationView); + [view.tableController updateChatEntry:self.message]; + } +} + +@end diff --git a/Classes/LinphoneUI/UIChatBubbleTextCell.h b/Classes/LinphoneUI/UIChatBubbleTextCell.h new file mode 100644 index 000000000..5c300c628 --- /dev/null +++ b/Classes/LinphoneUI/UIChatBubbleTextCell.h @@ -0,0 +1,52 @@ +/* UIChatRoomCell.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import + +#import "UITextViewNoDefine.h" +#import "ChatConversationTableView.h" +#import "UIRoundedImageView.h" + +@interface UIChatBubbleTextCell : UITableViewCell + +@property(readonly, nonatomic) LinphoneChatMessage *message; +@property(nonatomic, weak) IBOutlet UIImageView *backgroundColorImage; +@property(nonatomic, weak) IBOutlet UIRoundedImageView *avatarImage; +@property(nonatomic, weak) IBOutlet UILabel *contactDateLabel; +@property(nonatomic, weak) IBOutlet UIImageView *statusErrorImage; +@property(weak, nonatomic) IBOutlet UIActivityIndicatorView *statusInProgressSpinner; +@property(nonatomic, weak) IBOutlet UITextViewNoDefine *messageText; +@property(weak, nonatomic) IBOutlet UIImageView *bottomBarColor; +@property(nonatomic, strong) id chatRoomDelegate; +@property(strong, nonatomic) IBOutlet UIView *bubbleView; +@property(strong, nonatomic) IBOutlet UITapGestureRecognizer *resendRecognizer; + ++ (CGSize)ViewSizeForMessage:(LinphoneChatMessage *)chat withWidth:(int)width; + +- (void)setChatMessage:(LinphoneChatMessage *)message; + +- (IBAction)onDeleteClick:(id)event; +- (IBAction)onResendClick:(id)event; +- (void)update; + ++ (CGSize)ViewHeightForMessage:(LinphoneChatMessage *)chat withWidth:(int)width; ++ (NSString *)TextMessageForChat:(LinphoneChatMessage *)message; ++ (CGSize)computeBoundingBox:(NSString *)text size:(CGSize)size font:(UIFont *)font; + +@end diff --git a/Classes/LinphoneUI/UIChatBubbleTextCell.m b/Classes/LinphoneUI/UIChatBubbleTextCell.m new file mode 100644 index 000000000..362c503d9 --- /dev/null +++ b/Classes/LinphoneUI/UIChatBubbleTextCell.m @@ -0,0 +1,312 @@ +/* UIChatRoomCell.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "UIChatBubbleTextCell.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" + +#import +#import + +@implementation UIChatBubbleTextCell + +#pragma mark - Lifecycle Functions + +- (id)initWithIdentifier:(NSString *)identifier { + if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) { + if ([identifier isEqualToString:NSStringFromClass(self.class)]) { + NSArray *arrayOfViews = + [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + // resize cell to match .nib size. It is needed when resized the cell to + // correctly adapt its height too + UIView *sub = ((UIView *)[arrayOfViews objectAtIndex:arrayOfViews.count - 1]); + [self setFrame:CGRectMake(0, 0, sub.frame.size.width, sub.frame.size.height)]; + [self addSubview:sub]; + } + } + return self; +} + +- (void)dealloc { + [self setChatMessage:NULL]; +} + +#pragma mark - + +- (void)setChatMessage:(LinphoneChatMessage *)amessage { + if (amessage == _message) { + return; + } + + if (_message) { + linphone_chat_message_unref(_message); + CFBridgingRelease(linphone_chat_message_get_user_data(_message)); + linphone_chat_message_set_user_data(_message, NULL); + linphone_chat_message_cbs_set_msg_state_changed(linphone_chat_message_get_callbacks(_message), NULL); + } + + _message = amessage; + if (amessage) { + linphone_chat_message_ref(_message); + linphone_chat_message_set_user_data(_message, (void *)CFBridgingRetain(self)); + linphone_chat_message_cbs_set_msg_state_changed(linphone_chat_message_get_callbacks(_message), message_status); + } +} + ++ (NSString *)TextMessageForChat:(LinphoneChatMessage *)message { + const char *text = linphone_chat_message_get_text(message) ?: ""; + return [NSString stringWithUTF8String:text] ?: [NSString stringWithCString:text encoding:NSASCIIStringEncoding] + ?: NSLocalizedString(@"(invalid string)", nil); +} + ++ (NSString *)ContactDateForChat:(LinphoneChatMessage *)message { + return [NSString + stringWithFormat:@"%@ - %@", [LinphoneUtils timeToString:linphone_chat_message_get_time(message) + withFormat:LinphoneDateChatBubble], + [FastAddressBook displayNameForAddress:linphone_chat_message_get_from_address(message)]]; +} + +- (NSString *)textMessage { + return [self.class TextMessageForChat:_message]; +} + +- (void)update { + if (_message == nil) { + LOGW(@"Cannot update message room cell: null message"); + return; + } + + _statusInProgressSpinner.accessibilityLabel = @"Delivery in progress"; + + if (_messageText) { + [_messageText setHidden:FALSE]; + /* 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:self.textMessage + attributes:@{ + NSFontAttributeName : _messageText.font, + NSForegroundColorAttributeName : [UIColor darkGrayColor] + }]; + _messageText.attributedText = attr_text; + } + + LinphoneChatMessageState state = linphone_chat_message_get_state(_message); + BOOL outgoing = linphone_chat_message_is_outgoing(_message); + + if (outgoing) { + _avatarImage.image = [LinphoneUtils selfAvatar]; + } else { + [_avatarImage setImage:[FastAddressBook imageForAddress:linphone_chat_message_get_peer_address(_message) + thumbnail:YES] + bordered:NO + withRoundedRadius:YES]; + } + _contactDateLabel.text = [self.class ContactDateForChat:_message]; + + _backgroundColorImage.image = _bottomBarColor.image = + [UIImage imageNamed:(outgoing ? @"color_A.png" : @"color_D.png")]; + _contactDateLabel.textColor = [UIColor colorWithPatternImage:_backgroundColorImage.image]; + + if (outgoing && state == LinphoneChatMessageStateInProgress) { + _statusErrorImage.hidden = YES; + [_statusInProgressSpinner startAnimating]; + } else if (outgoing && + (state == LinphoneChatMessageStateNotDelivered || state == LinphoneChatMessageStateFileTransferError)) { + _statusErrorImage.hidden = NO; + [_statusInProgressSpinner stopAnimating]; + + NSAttributedString *resend_text = + [[NSAttributedString alloc] initWithString:NSLocalizedString(@"Resend", @"Resend") + attributes:@{NSForegroundColorAttributeName : [UIColor redColor]}]; + [_contactDateLabel setAttributedText:resend_text]; + } else if (!outgoing && state == LinphoneChatMessageStateFileTransferError) { + _statusErrorImage.hidden = NO; + [_statusInProgressSpinner stopAnimating]; + } else { + _statusErrorImage.hidden = YES; + [_statusInProgressSpinner stopAnimating]; + } + + if (outgoing) { + [_messageText setAccessibilityLabel:@"Outgoing message"]; + } else { + [_messageText setAccessibilityLabel:@"Incoming message"]; + } +} + +- (void)setEditing:(BOOL)editing { + [self setEditing:editing animated:FALSE]; +} + +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + _messageText.userInteractionEnabled = !editing; + _resendRecognizer.enabled = !editing; +} + +#pragma mark - Action Functions + +- (IBAction)onDeleteClick:(id)event { + if (_message != NULL) { + UITableView *tableView = VIEW(ChatConversationView).tableController.tableView; + NSIndexPath *indexPath = [tableView indexPathForCell:self]; + [tableView.dataSource tableView:tableView + commitEditingStyle:UITableViewCellEditingStyleDelete + forRowAtIndexPath:indexPath]; + } +} + +- (IBAction)onResendClick:(id)event { + if (_message == nil || !linphone_chat_message_is_outgoing(_message)) + return; + + LinphoneChatMessageState state = linphone_chat_message_get_state(_message); + if (state == LinphoneChatMessageStateNotDelivered || state == LinphoneChatMessageStateFileTransferError) { + if (linphone_chat_message_get_file_transfer_information(_message) != NULL) { + NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:_message]; + NSURL *imageUrl = [NSURL URLWithString:localImage]; + + [self onDeleteClick:nil]; + + [[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]]; + [_chatRoomDelegate startImageUpload:image url:imageUrl]; + }); + } + failureBlock:^(NSError *error) { + LOGE(@"Can't read image"); + }]; + } else { + [self onDeleteClick:nil]; + + double delayInSeconds = 0.4; + dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); + dispatch_after(popTime, dispatch_get_main_queue(), ^(void) { + [_chatRoomDelegate resendChat:self.textMessage withExternalUrl:nil]; + }); + } + } +} +#pragma mark - State changed handling +static void message_status(LinphoneChatMessage *msg, LinphoneChatMessageState state) { + LOGI(@"State for message [%p] changed to %s", msg, linphone_chat_message_state_to_string(state)); + ChatConversationView *view = VIEW(ChatConversationView); + [view.tableController updateChatEntry:msg]; +} + +#pragma mark - Bubble size computing + ++ (CGSize)computeBoundingBox:(NSString *)text size:(CGSize)size font:(UIFont *)font { + if (!text || text.length == 0) + return CGSizeMake(0, 0); + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 + if ([[[UIDevice currentDevice] systemVersion] doubleValue] >= 7) { + return [text boundingRectWithSize:size + options:(NSStringDrawingUsesLineFragmentOrigin | + NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesFontLeading) + attributes:@{ + NSFontAttributeName : font + } + context:nil] + .size; + } +#endif + { return [text sizeWithFont:font constrainedToSize:size lineBreakMode:NSLineBreakByCharWrapping]; } +} + +static const CGFloat CELL_MIN_HEIGHT = 60.0f; +static const CGFloat CELL_MIN_WIDTH = 150.0f; +static const CGFloat CELL_MESSAGE_X_MARGIN = 78 + 10.0f; +static const CGFloat CELL_MESSAGE_Y_MARGIN = 44; +static const CGFloat CELL_IMAGE_HEIGHT = 100.0f; +static const CGFloat CELL_IMAGE_WIDTH = 100.0f; + ++ (CGSize)ViewHeightForMessage:(LinphoneChatMessage *)chat withWidth:(int)width { + NSString *messageText = [UIChatBubbleTextCell TextMessageForChat:chat]; + static UIFont *messageFont = nil; + if (!messageFont) { + UIChatBubbleTextCell *cell = + [[UIChatBubbleTextCell alloc] initWithIdentifier:NSStringFromClass(UIChatBubbleTextCell.class)]; + messageFont = cell.messageText.font; + } + // UITableView *tableView = VIEW(ChatConversationView).tableController.tableView; + // if (tableView.isEditing) + width -= 40; /*checkbox */ + CGSize size; + const char *url = linphone_chat_message_get_external_body_url(chat); + if (url == nil && linphone_chat_message_get_file_transfer_information(chat) == NULL) { + size = [self computeBoundingBox:messageText + size:CGSizeMake(width - CELL_MESSAGE_X_MARGIN - 4, CGFLOAT_MAX) + font:messageFont]; + } else { + NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:chat]; + size = (localImage != nil) ? CGSizeMake(CELL_IMAGE_WIDTH, CELL_IMAGE_HEIGHT) : CGSizeMake(50, 50); + } + size.width = MAX(size.width + CELL_MESSAGE_X_MARGIN, CELL_MIN_WIDTH); + size.height = MAX(size.height + CELL_MESSAGE_Y_MARGIN, CELL_MIN_HEIGHT); + return size; +} ++ (CGSize)ViewSizeForMessage:(LinphoneChatMessage *)chat withWidth:(int)width { + static UIFont *dateFont = nil; + static CGSize dateViewSize; + + if (!dateFont) { + UIChatBubbleTextCell *cell = + [[UIChatBubbleTextCell alloc] initWithIdentifier:NSStringFromClass(UIChatBubbleTextCell.class)]; + dateFont = cell.contactDateLabel.font; + dateViewSize = cell.contactDateLabel.frame.size; + dateViewSize.width = CGFLOAT_MAX; + } + + CGSize messageSize = [self ViewHeightForMessage:chat withWidth:width]; + CGSize dateSize = [self computeBoundingBox:[self ContactDateForChat:chat] size:dateViewSize font:dateFont]; + messageSize.width = MAX(MAX(messageSize.width, MIN(dateSize.width + CELL_MESSAGE_X_MARGIN, width)), CELL_MIN_WIDTH); + + return messageSize; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + if (_message != nil) { + UITableView *tableView = VIEW(ChatConversationView).tableController.tableView; + BOOL is_outgoing = linphone_chat_message_is_outgoing(_message); + CGRect bubbleFrame = _bubbleView.frame; + int available_width = self.frame.size.width; + int origin_x; + + bubbleFrame.size = [self.class ViewSizeForMessage:_message withWidth:available_width]; + + if (tableView.isEditing) { + origin_x = 0; + } else { + origin_x = (is_outgoing ? self.frame.size.width - bubbleFrame.size.width : 0); + } + + bubbleFrame.origin.x = origin_x; + _bubbleView.frame = bubbleFrame; + } +} + +@end diff --git a/Classes/LinphoneUI/UIChatCell.h b/Classes/LinphoneUI/UIChatCell.h index 10ae8d29c..38ab5f605 100644 --- a/Classes/LinphoneUI/UIChatCell.h +++ b/Classes/LinphoneUI/UIChatCell.h @@ -19,20 +19,22 @@ #import -#import "UITransparentTVCell.h" +#import "UIRoundedImageView.h" +#import "UIIconButton.h" +#import "UIBouncingView.h" #include "linphone/linphonecore.h" -@interface UIChatCell : UITransparentTVCell { - LinphoneChatRoom* chatRoom; +@interface UIChatCell : UITableViewCell { + LinphoneChatRoom *chatRoom; } -@property (nonatomic, retain) IBOutlet UIImageView *avatarImage; -@property (nonatomic, retain) IBOutlet UILabel* addressLabel; -@property (nonatomic, retain) IBOutlet UILabel* chatContentLabel; -@property (nonatomic, retain) IBOutlet UIButton * deleteButton; -@property (nonatomic, retain) IBOutlet UIView * unreadMessageView; -@property (nonatomic, retain) IBOutlet UILabel * unreadMessageLabel; +@property(nonatomic, strong) IBOutlet UIRoundedImageView *avatarImage; +@property(nonatomic, strong) IBOutlet UILabel *addressLabel; +@property(nonatomic, strong) IBOutlet UILabel *chatContentLabel; +@property(weak, nonatomic) IBOutlet UILabel *chatLatestTimeLabel; +@property(weak, nonatomic) IBOutlet UIBouncingView *unreadCountView; +@property(weak, nonatomic) IBOutlet UILabel *unreadCountLabel; - (id)initWithIdentifier:(NSString*)identifier; diff --git a/Classes/LinphoneUI/UIChatCell.m b/Classes/LinphoneUI/UIChatCell.m index 5fcf753ad..58b57d1a1 100644 --- a/Classes/LinphoneUI/UIChatCell.m +++ b/Classes/LinphoneUI/UIChatCell.m @@ -4,16 +4,16 @@ * * 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 + * 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. */ @@ -24,159 +24,116 @@ @implementation UIChatCell -@synthesize avatarImage; -@synthesize addressLabel; -@synthesize chatContentLabel; -@synthesize deleteButton; -@synthesize unreadMessageLabel; -@synthesize unreadMessageView; - - #pragma mark - Lifecycle Functions -- (id)initWithIdentifier:(NSString*)identifier { - if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) { - NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"UIChatCell" - owner:self - options:nil]; - - if ([arrayOfViews count] >= 1) { - - [self.contentView addSubview:[arrayOfViews objectAtIndex:0]]; - } - [chatContentLabel setAdjustsFontSizeToFitWidth:TRUE]; // Auto shrink: IB lack! - } - return self; +- (id)initWithIdentifier:(NSString *)identifier { + if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) { + NSArray *arrayOfViews = + [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + + // 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]; + } + return self; } -- (void)dealloc { - [addressLabel release]; - [chatContentLabel release]; - [avatarImage release]; - [deleteButton release]; - [unreadMessageLabel release]; - [unreadMessageView release]; - - [super dealloc]; -} - - #pragma mark - Property Funcitons - (void)setChatRoom:(LinphoneChatRoom *)achat { - self->chatRoom = achat; - [self update]; + chatRoom = achat; + [self update]; } - -#pragma mark - +#pragma mark - - (NSString *)accessibilityValue { - return [NSString stringWithFormat:@"%@ - %@ (%ld)", addressLabel.text, chatContentLabel.text, (long)[unreadMessageLabel.text integerValue]]; + if (_chatContentLabel.text) { + return [NSString stringWithFormat:@"%@, %@ (%li)", _addressLabel.text, _chatContentLabel.text, + (long)[_unreadCountLabel.text integerValue]]; + } else { + return [NSString stringWithFormat:@"%@ (%li)", _addressLabel.text, (long)[_unreadCountLabel.text integerValue]]; + } } - - (void)update { - NSString *displayName = nil; - UIImage *image = nil; - if(chatRoom == nil) { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat cell: null chat"]; - return; - } - const LinphoneAddress* linphoneAddress = linphone_chat_room_get_peer_address(chatRoom); - - if (linphoneAddress == NULL) + if (chatRoom == nil) { + LOGW(@"Cannot update chat cell: null chat"); return; - char *tmp = linphone_address_as_string_uri_only(linphoneAddress); - NSString *normalizedSipAddress = [NSString stringWithUTF8String:tmp]; - ms_free(tmp); - - ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress]; - if(contact != nil) { - displayName = [FastAddressBook getContactDisplayName:contact]; - image = [FastAddressBook getContactImage:contact thumbnail:true]; - } - - // Display name - if(displayName == nil) { - const char* username = linphone_address_get_username(linphoneAddress); - char* address = linphone_address_as_string(linphoneAddress); - displayName = [NSString stringWithUTF8String:username?:address]; - ms_free(address); - } - [addressLabel setText:displayName]; + } + const LinphoneAddress *addr = linphone_chat_room_get_peer_address(chatRoom); + [ContactDisplay setDisplayNameLabel:_addressLabel forAddress:addr]; + [_avatarImage setImage:[FastAddressBook imageForAddress:addr thumbnail:YES] bordered:NO withRoundedRadius:YES]; - // Avatar - if(image == nil) { - image = [UIImage imageNamed:@"avatar_unknown_small.png"]; - } - [avatarImage setImage:image]; + LinphoneChatMessage *last_message = linphone_chat_room_get_user_data(chatRoom); + if (last_message) { + const char *text = linphone_chat_message_get_text(last_message); + const char *url = linphone_chat_message_get_external_body_url(last_message); + const LinphoneContent *last_content = linphone_chat_message_get_file_transfer_information(last_message); + // Last message was a file transfer (image) so display a picture... + if (url || last_content) { + _chatContentLabel.text = @"🗻"; + // otherwise show beginning of the text message + } else if (text) { + NSString *message = [NSString stringWithUTF8String:text]; + // shorten long messages + if ([message length] > 50) + message = [[message substringToIndex:50] stringByAppendingString:@"[...]"]; - LinphoneChatMessage* last_message = linphone_chat_room_get_user_data(chatRoom); + _chatContentLabel.text = message; + } - if( last_message ){ + _chatLatestTimeLabel.text = + [LinphoneUtils timeToString:linphone_chat_message_get_time(last_message) withFormat:LinphoneDateChatList]; + _chatLatestTimeLabel.hidden = NO; + } else { + _chatContentLabel.text = nil; + _chatLatestTimeLabel.text = NSLocalizedString(@"Now", nil); + } - const char* text = linphone_chat_message_get_text(last_message); - const char* url = linphone_chat_message_get_external_body_url(last_message); - // Message - if(url) { - [chatContentLabel setText:@""]; - } else if (text) { - NSString *message = [NSString stringWithUTF8String:text]; - // shorten long messages - if([message length] > 50) - message = [[message substringToIndex:50] stringByAppendingString:@"[...]"]; - - [chatContentLabel setText:message]; - } - - int count = linphone_chat_room_get_unread_messages_count(chatRoom); - if(count > 0) { - [unreadMessageView setHidden:FALSE]; - [unreadMessageLabel setText:[NSString stringWithFormat:@"%i", count]]; - } else { - [unreadMessageView setHidden:TRUE]; - } - } else { - chatContentLabel.text = nil; - [unreadMessageView setHidden:TRUE]; - } + int count = linphone_chat_room_get_unread_messages_count(chatRoom); + _unreadCountLabel.text = [NSString stringWithFormat:@"%i", count]; + if (count > 0) { + [_unreadCountView startAnimating:YES]; + } else { + [_unreadCountView stopAnimating:YES]; + } + UIFont *addressFont = (count <= 0) ? [UIFont systemFontOfSize:25] : [UIFont boldSystemFontOfSize:25]; + _addressLabel.font = addressFont; } - (void)setEditing:(BOOL)editing { - [self setEditing:editing animated:FALSE]; + [self setEditing:editing animated:FALSE]; } - (void)setEditing:(BOOL)editing animated:(BOOL)animated { - if(animated) { - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:0.3]; - } - if(editing) { - [deleteButton setAlpha:1.0f]; - } else { - [deleteButton setAlpha:0.0f]; - } - if(animated) { - [UIView commitAnimations]; - } + if (animated) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.3]; + } + if (editing) { + [_unreadCountView stopAnimating:animated]; + } else if (linphone_chat_room_get_unread_messages_count(chatRoom) > 0) { + [_unreadCountView startAnimating:animated]; + } + if (animated) { + [UIView commitAnimations]; + } } - #pragma mark - Action Functions -- (IBAction)onDeleteClick: (id) event { - if(chatRoom != NULL) { - UIView *view = [self superview]; - // Find TableViewCell - while( view != nil && ![view isKindOfClass:[UITableView class]]) view = [view superview]; - if(view != nil) { - UITableView *tableView = (UITableView*) view; - NSIndexPath *indexPath = [tableView indexPathForCell:self]; - [[tableView dataSource] tableView:tableView commitEditingStyle:UITableViewCellEditingStyleDelete forRowAtIndexPath:indexPath]; - } - } +- (IBAction)onDeleteClick:(id)event { + if (chatRoom != NULL) { + UITableView *tableView = VIEW(ChatsListView).tableController.tableView; + NSIndexPath *indexPath = [tableView indexPathForCell:self]; + [[tableView dataSource] tableView:tableView + commitEditingStyle:UITableViewCellEditingStyleDelete + forRowAtIndexPath:indexPath]; + } } @end diff --git a/Classes/LinphoneUI/UIChatCreateCell.h b/Classes/LinphoneUI/UIChatCreateCell.h new file mode 100644 index 000000000..723245629 --- /dev/null +++ b/Classes/LinphoneUI/UIChatCreateCell.h @@ -0,0 +1,17 @@ +// +// UIChatCreateCellViewTableViewCell.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 12/10/15. +// +// + +#import + +@interface UIChatCreateCell : UITableViewCell +@property(weak, nonatomic) IBOutlet UILabel *displayNameLabel; +@property(weak, nonatomic) IBOutlet UILabel *addressLabel; + +- (id)initWithIdentifier:(NSString *)identifier; + +@end diff --git a/Classes/LinphoneUI/UIChatCreateCell.m b/Classes/LinphoneUI/UIChatCreateCell.m new file mode 100644 index 000000000..e7fdcf73a --- /dev/null +++ b/Classes/LinphoneUI/UIChatCreateCell.m @@ -0,0 +1,29 @@ +// +// UIChatCreateCellViewTableViewCell.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 12/10/15. +// +// + +#import "UIChatCreateCell.h" + +@implementation UIChatCreateCell + +- (id)initWithIdentifier:(NSString *)identifier { + self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; + if (self != nil) { + NSArray *arrayOfViews = + [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + if ([arrayOfViews count] >= 1) { + // 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]; + } + } + return self; +} + +@end diff --git a/Classes/LinphoneUI/UIChatRoomCell.h b/Classes/LinphoneUI/UIChatRoomCell.h deleted file mode 100644 index eb7c75d2b..000000000 --- a/Classes/LinphoneUI/UIChatRoomCell.h +++ /dev/null @@ -1,56 +0,0 @@ -/* UIChatRoomCell.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "ChatRoomTableViewController.h" -#import "UILoadingImageView.h" -#import "UITransparentTVCell.h" -#import "UITextViewNoDefine.h" -#include "linphone/linphonecore.h" - - -@interface UIChatRoomCell : UITransparentTVCell { - LinphoneChatMessage* chat; -} - -@property (nonatomic, retain) IBOutlet UIView *innerView; -@property (nonatomic, retain) IBOutlet UIView *bubbleView; -@property (nonatomic, retain) IBOutlet UIImageView* backgroundImage; -@property (nonatomic, retain) IBOutlet UITextViewNoDefine *messageText; -@property (nonatomic, retain) IBOutlet UILoadingImageView *messageImageView; -@property (nonatomic, retain) IBOutlet UIButton *deleteButton; -@property (nonatomic, retain) IBOutlet UILabel *dateLabel; -@property (nonatomic, retain) IBOutlet UIImageView* statusImage; -@property (nonatomic, retain) IBOutlet UIButton* downloadButton; -@property (nonatomic, retain) IBOutlet UITapGestureRecognizer* imageTapGestureRecognizer; -@property (nonatomic, retain) IBOutlet UITapGestureRecognizer* resendTapGestureRecognizer; - -- (id)initWithIdentifier:(NSString*)identifier; -+ (CGFloat)height:(LinphoneChatMessage*)chatMessage width:(int)width; - -@property (nonatomic, retain) id chatRoomDelegate; - -- (IBAction)onDeleteClick:(id)event; -- (IBAction)onDownloadClick:(id)event; -- (IBAction)onImageClick:(id)event; - -- (void)setChatMessage:(LinphoneChatMessage*)message; - -@end diff --git a/Classes/LinphoneUI/UIChatRoomCell.m b/Classes/LinphoneUI/UIChatRoomCell.m deleted file mode 100644 index 2ffa9a7e2..000000000 --- a/Classes/LinphoneUI/UIChatRoomCell.m +++ /dev/null @@ -1,381 +0,0 @@ -/* UIChatRoomCell.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UIChatRoomCell.h" -#import "UILinphone.h" -#import "Utils.h" -#import "LinphoneManager.h" -#import "PhoneMainView.h" - -#import -#import -#import -#include "linphone/linphonecore.h" - -@implementation UIChatRoomCell - -@synthesize innerView; -@synthesize bubbleView; -@synthesize backgroundImage; -@synthesize messageImageView; -@synthesize messageText; -@synthesize deleteButton; -@synthesize dateLabel; -@synthesize statusImage; -@synthesize downloadButton; -@synthesize chatRoomDelegate; -@synthesize imageTapGestureRecognizer; -@synthesize resendTapGestureRecognizer; - -static const CGFloat CELL_MIN_HEIGHT = 50.0f; -static const CGFloat CELL_MIN_WIDTH = 150.0f; -//static const CGFloat CELL_MAX_WIDTH = 320.0f; -static const CGFloat CELL_MESSAGE_X_MARGIN = 26.0f + 10.0f; -static const CGFloat CELL_MESSAGE_Y_MARGIN = 36.0f; -static const CGFloat CELL_FONT_SIZE = 17.0f; -static const CGFloat CELL_IMAGE_HEIGHT = 100.0f; -static const CGFloat CELL_IMAGE_WIDTH = 100.0f; -static UIFont *CELL_FONT = nil; - -#pragma mark - Lifecycle Functions - -- (id)initWithIdentifier:(NSString*)identifier { - if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) { - [[NSBundle mainBundle] loadNibNamed:@"UIChatRoomCell" - owner:self - options:nil]; - imageTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onImageClick:)]; - [messageImageView addGestureRecognizer:imageTapGestureRecognizer]; - - resendTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onResendClick:)]; - [dateLabel addGestureRecognizer:resendTapGestureRecognizer]; - - [self addSubview:innerView]; - [deleteButton setAlpha:0.0f]; - - // shift message box, otherwise it will collide with the bubble - CGRect messageCoords = [messageText frame]; - messageCoords.origin.x += 2; - messageCoords.origin.y += 2; - messageCoords.size.width -= 5; - [messageText setFrame:messageCoords]; - messageText.allowSelectAll = TRUE; - } - return self; -} - -- (void)dealloc { - [chatRoomDelegate release]; - [backgroundImage release]; - [innerView release]; - [bubbleView release]; - [messageText release]; - [messageImageView release]; - [deleteButton release]; - [dateLabel release]; - [statusImage release]; - [downloadButton release]; - [imageTapGestureRecognizer release]; - [resendTapGestureRecognizer release]; - - [super dealloc]; -} - -#pragma mark - - -- (void)setChatMessage:(LinphoneChatMessage *)message { - self->chat = message; - [self update]; - -} - -+ (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"]; - return; - } - const char* url = linphone_chat_message_get_external_body_url(chat); - const char* text = linphone_chat_message_get_text(chat); - BOOL is_external = url && (strstr(url, "http") == url); - NSString* localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:chat]; - - - if(is_external && !localImage ) { - [messageText setHidden:TRUE]; - [messageImageView setImage:nil]; - [messageImageView setHidden:TRUE]; - [downloadButton setHidden:FALSE]; - - } else if(localImage) { - - NSURL* imageUrl = [NSURL URLWithString:localImage]; - - [messageText setHidden:TRUE]; - [messageImageView setImage:nil]; - [messageImageView startLoading]; - __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) { - 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]; - [messageImageView stopLoading]; - [image release]; - }); - } - }); - } failureBlock:^(NSError *error) { - [LinphoneLogger log:LinphoneLoggerError format:@"Can't read image"]; - }]; - - [messageImageView setHidden:FALSE]; - [downloadButton setHidden:TRUE]; - } else { - // simple text message - [messageText setHidden:FALSE]; - 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:nstext - attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17.0], - NSForegroundColorAttributeName:[UIColor darkGrayColor]}]; - messageText.attributedText = attr_text; - [attr_text release]; - - } else { - messageText.text = @""; - } - - [messageImageView setImage:nil]; - [messageImageView setHidden:TRUE]; - - [downloadButton setHidden:TRUE]; - } - - // Date - NSDate* message_date = [NSDate dateWithTimeIntervalSince1970:linphone_chat_message_get_time(chat)]; - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setTimeStyle:NSDateFormatterMediumStyle]; - [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; - NSLocale *locale = [NSLocale currentLocale]; - [dateFormatter setLocale:locale]; - [dateLabel setText:[dateFormatter stringFromDate:message_date]]; - [dateFormatter release]; - - LinphoneChatMessageState state = linphone_chat_message_get_state(chat); - BOOL outgoing = linphone_chat_message_is_outgoing(chat); - - if( !outgoing ){ - statusImage.hidden = TRUE; // not useful for incoming chats.. - } else if (state== LinphoneChatMessageStateInProgress) { - [statusImage setImage:[UIImage imageNamed:@"chat_message_inprogress.png"]]; - [statusImage setAccessibilityValue:@"in progress"]; - statusImage.hidden = FALSE; - } else if (state == LinphoneChatMessageStateDelivered) { - [statusImage setImage:[UIImage imageNamed:@"chat_message_delivered.png"]]; - [statusImage setAccessibilityValue:@"delivered"]; - statusImage.hidden = FALSE; - } else { - [statusImage setImage:[UIImage imageNamed:@"chat_message_not_delivered.png"]]; - [statusImage setAccessibilityValue:@"not delivered"]; - statusImage.hidden = FALSE; - - NSAttributedString* resend_text = [[NSAttributedString alloc] - initWithString:NSLocalizedString(@"Resend", @"Resend") - attributes:@{NSForegroundColorAttributeName: [UIColor redColor]}]; - [dateLabel setAttributedText:resend_text]; - [resend_text release]; - } - - if( outgoing){ - [messageText setAccessibilityLabel:@"Outgoing message"]; - } else { - [messageText setAccessibilityLabel:@"Incoming message"]; - } - -} - -- (void)setEditing:(BOOL)editing { - [self setEditing:editing animated:FALSE]; -} - -- (void)setEditing:(BOOL)editing animated:(BOOL)animated { - if(animated) { - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:0.3]; - } - if(editing) { - [deleteButton setAlpha:1.0f]; - } else { - [deleteButton setAlpha:0.0f]; - } - if(animated) { - [UIView commitAnimations]; - } -} - -+ (CGSize)viewSize:(LinphoneChatMessage*)chat width:(int)width { - 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 ? [UIChatRoomCell decodeTextMessage:text] : @""; - if(url == nil) { - if(CELL_FONT == nil) { - CELL_FONT = [UIFont systemFontOfSize:CELL_FONT_SIZE]; - } - -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 - - if( [[[UIDevice currentDevice] systemVersion] doubleValue] >= 7){ - messageSize = [messageText - boundingRectWithSize:CGSizeMake(width - CELL_MESSAGE_X_MARGIN, CGFLOAT_MAX) - options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesFontLeading) - attributes:@{NSFontAttributeName: CELL_FONT} - context:nil].size; - } else -#endif - { - messageSize = [messageText sizeWithFont: CELL_FONT - constrainedToSize: CGSizeMake(width - CELL_MESSAGE_X_MARGIN, 10000.0f) - lineBreakMode: NSLineBreakByTruncatingTail]; - } - } else { - messageSize = CGSizeMake(CELL_IMAGE_WIDTH, CELL_IMAGE_HEIGHT); - } - messageSize.height += CELL_MESSAGE_Y_MARGIN; - if(messageSize.height < CELL_MIN_HEIGHT) - messageSize.height = CELL_MIN_HEIGHT; - messageSize.width += CELL_MESSAGE_X_MARGIN; - if(messageSize.width < CELL_MIN_WIDTH) - messageSize.width = CELL_MIN_WIDTH; - return messageSize; -} - -+ (CGFloat)height:(LinphoneChatMessage*)chatMessage width:(int)width { - return [UIChatRoomCell viewSize:chatMessage width:width].height; -} - - -#pragma mark - View Functions - -- (void)layoutSubviews { - [super layoutSubviews]; - if(chat != nil) { - // Resize inner - CGRect innerFrame; - BOOL is_outgoing = linphone_chat_message_is_outgoing(chat); - innerFrame.size = [UIChatRoomCell viewSize:chat width:[self frame].size.width]; - if(!is_outgoing) { // Inverted - innerFrame.origin.x = 0.0f; - innerFrame.origin.y = 0.0f; - } else { - innerFrame.origin.x = [self frame].size.width - innerFrame.size.width; - innerFrame.origin.y = 0.0f; - } - [innerView setFrame:innerFrame]; - - CGRect messageFrame = [bubbleView frame]; - messageFrame.origin.y = ([innerView frame].size.height - messageFrame.size.height)/2; - if(!is_outgoing) { // Inverted - UIImage* image = [UIImage imageNamed:@"chat_bubble_incoming"]; - image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(26, 32, 34, 56)]; - [backgroundImage setImage:image]; - messageFrame.origin.y += 5; - } else { - 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]; - } -} - - -#pragma mark - Action Functions - -- (IBAction)onDeleteClick:(id)event { - if(chat != NULL) { - UIView *view = [self superview]; - // Find TableViewCell - while(view != nil && ![view isKindOfClass:[UITableView class]]) view = [view superview]; - if(view != nil) { - UITableView *tableView = (UITableView*) view; - NSIndexPath *indexPath = [tableView indexPathForCell:self]; - [[tableView dataSource] tableView:tableView commitEditingStyle:UITableViewCellEditingStyleDelete forRowAtIndexPath:indexPath]; - } - } -} - -- (IBAction)onDownloadClick:(id)event { - NSURL* url = [NSURL URLWithString:[NSString stringWithUTF8String:linphone_chat_message_get_external_body_url(chat)]]; - [chatRoomDelegate chatRoomStartImageDownload:url userInfo:[NSValue valueWithPointer:chat]]; - -} - -- (IBAction)onImageClick:(id)event { - if(![messageImageView isLoading]) { - ImageViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ImageViewController compositeViewDescription] push:TRUE], ImageViewController); - if(controller != nil) { - CGImageRef fullScreenRef = [[messageImageView.fullImageUrl defaultRepresentation] fullScreenImage]; - UIImage* fullScreen = [UIImage imageWithCGImage:fullScreenRef]; - [controller setImage:fullScreen]; - } - } -} - -- (IBAction)onResendClick:(id)event { - if( chat == nil ) return; - - LinphoneChatMessageState state = linphone_chat_message_get_state(self->chat); - if (state == LinphoneChatMessageStateNotDelivered) { - const char* text = linphone_chat_message_get_text(self->chat); - const char* url = linphone_chat_message_get_external_body_url(self->chat); - NSString* message = text ? [NSString stringWithUTF8String:text] : nil; - NSString* exturl = url ? [NSString stringWithUTF8String:url] : nil; - - [self onDeleteClick:nil]; - - double delayInSeconds = 0.4; - dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); - dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ - [chatRoomDelegate resendChat:message withExternalUrl:exturl]; - }); - } -} - -@end diff --git a/Classes/LinphoneUI/UICheckBoxTableView.h b/Classes/LinphoneUI/UICheckBoxTableView.h new file mode 100644 index 000000000..d8d114375 --- /dev/null +++ b/Classes/LinphoneUI/UICheckBoxTableView.h @@ -0,0 +1,32 @@ +// +// UICheckBoxTVTableViewController.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 29/09/15. +// +// + +#pragma once + +#import + +@interface UICheckBoxTableView : UITableViewController + +@property(nonatomic, readonly) NSMutableArray *selectedItems; +@property(weak, nonatomic) IBOutlet UIButton *deleteButton; +@property(weak, nonatomic) IBOutlet UIButton *editButton; +@property(weak, nonatomic) IBOutlet UIButton *cancelButton; +@property(weak, nonatomic) IBOutlet UIButton *toggleSelectionButton; +@property(weak, nonatomic) IBOutlet UIView *emptyView; + +- (void)loadData; +- (void)accessoryForCell:(UITableViewCell *)cell atPath:(NSIndexPath *)indexPath; +- (void)removeSelectionUsing:(void (^)(NSIndexPath *indexPath))remover; + +- (IBAction)onSelectionToggle:(id)sender; +- (IBAction)onEditClick:(id)sender; +- (IBAction)onCancelClick:(id)sender; + +- (NSInteger)totalNumberOfItems; + +@end diff --git a/Classes/LinphoneUI/UICheckBoxTableView.m b/Classes/LinphoneUI/UICheckBoxTableView.m new file mode 100644 index 000000000..4a631f02b --- /dev/null +++ b/Classes/LinphoneUI/UICheckBoxTableView.m @@ -0,0 +1,160 @@ +/* HistoryTableViewController.m + * + * Copyright (C) 2009 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "UICheckBoxTableView.h" +#import "Utils.h" + +@implementation UICheckBoxTableView + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + _selectedItems = [[NSMutableArray alloc] init]; + return self; +} + +- (instancetype)init { + self = [super init]; + _selectedItems = [[NSMutableArray alloc] init]; + return self; +} + +#pragma mark - UITableViewDelegate Functions + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + _emptyView.hidden = _editButton.enabled = ([self totalNumberOfItems] != 0); +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; + [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:NO]; + if ([_selectedItems containsObject:indexPath]) { + [_selectedItems removeObject:indexPath]; + } else { + [_selectedItems addObject:indexPath]; + } + [self accessoryForCell:cell atPath:indexPath]; + [self selectToggleButton:(_selectedItems.count != [self totalNumberOfItems])]; +} + +- (void)selectToggleButton:(BOOL)select { + _toggleSelectionButton.selected = select; + if (select) { + _toggleSelectionButton.accessibilityLabel = NSLocalizedString(@"Select all", nil); + } else { + _toggleSelectionButton.accessibilityLabel = NSLocalizedString(@"Deselect all", nil); + } +} +#pragma mark - + +- (void)accessoryForCell:(UITableViewCell *)cell atPath:(NSIndexPath *)indexPath { + cell.selectionStyle = UITableViewCellSelectionStyleNone; + if ([self isEditing]) { + UIButton *checkBoxButton = [UIButton buttonWithType:UIButtonTypeCustom]; + UIImage *image = nil; + if ([_selectedItems containsObject:indexPath]) { + image = [UIImage imageNamed:@"checkbox_checked.png"]; + checkBoxButton.accessibilityValue = NSLocalizedString(@"Selected", nil); + } else { + image = [UIImage imageNamed:@"checkbox_unchecked.png"]; + checkBoxButton.accessibilityValue = NSLocalizedString(@"Deselected", nil); + } + [checkBoxButton setImage:image forState:UIControlStateNormal]; + [checkBoxButton setFrame:CGRectMake(0, 0, 19, 19)]; + [checkBoxButton setBackgroundColor:[UIColor clearColor]]; + checkBoxButton.accessibilityLabel = NSLocalizedString(@"Checkbox", nil); + checkBoxButton.userInteractionEnabled = NO; + cell.accessoryView = checkBoxButton; + } else { + cell.accessoryView = nil; + cell.accessoryType = UITableViewCellAccessoryNone; + } + _deleteButton.enabled = (_selectedItems.count != 0); + _editButton.enabled = YES; +} + +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + [super setEditing:editing animated:animated]; + + _editButton.hidden = editing; + _deleteButton.hidden = _cancelButton.hidden = _toggleSelectionButton.hidden = !editing; + [self selectToggleButton:YES]; + + // when switching editing mode, we must reload all cells to remove/add checkboxes + [self loadData]; +} + +- (void)loadData { + [_selectedItems removeAllObjects]; + [self.tableView reloadData]; + + _editButton.enabled = _emptyView.hidden = ([self totalNumberOfItems] > 0); +} + +- (void)removeSelectionUsing:(void (^)(NSIndexPath *indexPath))remover { + // we must iterate through selected items in reverse order + [_selectedItems sortUsingComparator:^(NSIndexPath *obj1, NSIndexPath *obj2) { + return [obj2 compare:obj1]; + }]; + NSArray *copy = [[NSArray alloc] initWithArray:_selectedItems]; + for (NSIndexPath *indexPath in copy) { + if (remover) { + remover(indexPath); + } else { + [self tableView:self.tableView + commitEditingStyle:UITableViewCellEditingStyleDelete + forRowAtIndexPath:indexPath]; + } + } + [_selectedItems removeAllObjects]; + [self setEditing:NO animated:YES]; +} + +- (void)onSelectionToggle:(id)sender { + [_selectedItems removeAllObjects]; + + [self selectToggleButton:!_toggleSelectionButton.selected]; // TODO: why do we need that? + for (int i = 0; i < [self numberOfSectionsInTableView:self.tableView]; i++) { + for (int j = 0; j < [self tableView:self.tableView numberOfRowsInSection:i]; j++) { + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:j inSection:i]; + UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; + if (!_toggleSelectionButton.selected) { + [_selectedItems addObject:indexPath]; + } + [self accessoryForCell:cell atPath:indexPath]; + } + } +} + +- (IBAction)onEditClick:(id)sender { + [self setEditing:YES animated:YES]; +} + +- (IBAction)onCancelClick:(id)sender { + [self setEditing:NO animated:YES]; +} + +- (NSInteger)totalNumberOfItems { + NSInteger total = 0; + for (int i = 0; i < [self numberOfSectionsInTableView:self.tableView]; i++) { + total += [self tableView:self.tableView numberOfRowsInSection:i]; + } + return total; +} +@end diff --git a/Classes/LinphoneUI/UICompositeView.h b/Classes/LinphoneUI/UICompositeView.h new file mode 100644 index 000000000..7af4bd45e --- /dev/null +++ b/Classes/LinphoneUI/UICompositeView.h @@ -0,0 +1,89 @@ +/* UICompositeView.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import +#import + +#import "LinphoneManager.h" +#import "TPMultiLayoutViewController.h" +#import "SideMenuTableView.h" + +@interface UICompositeViewDescription : NSObject { +} + +@property(strong) NSString *name; +@property(strong) NSString *statusBar; +@property(strong) NSString *tabBar; +@property(strong) NSString *sideMenu; +@property(strong) NSString *otherFragment; +@property(assign) BOOL statusBarEnabled; +@property(assign) BOOL tabBarEnabled; +@property(assign) BOOL sideMenuEnabled; +@property(assign) BOOL fullscreen; +@property(assign) BOOL isLeftFragment; +@property(assign) BOOL darkBackground; +@property(assign) BOOL landscapeMode; +@property(assign) BOOL portraitMode; + +- (id)copy; +- (BOOL)equal:(UICompositeViewDescription *)description; +- (id)init:(Class)name + statusBar:(Class)statusBar + tabBar:(Class)tabBar + sideMenu:(Class)sideMenu + fullscreen:(BOOL)fullscreen + isLeftFragment:(BOOL)isLeftFragment + fragmentWith:(Class)otherFragment; + +@end + +@protocol UICompositeViewDelegate + ++ (UICompositeViewDescription *)compositeViewDescription; +- (UICompositeViewDescription *)compositeViewDescription; + +@end + +@interface UICompositeView : TPMultiLayoutViewController { + @private + NSMutableDictionary *viewControllerCache; + UICompositeViewDescription *currentViewDescription; + UIInterfaceOrientation currentOrientation; +} + +@property(strong) CATransition *viewTransition; +@property(nonatomic, strong) IBOutlet UIView *statusBarView; +@property(nonatomic, strong) IBOutlet UIView *mainView; +@property(nonatomic, strong) IBOutlet UIView *detailsView; +@property(nonatomic, strong) IBOutlet UIView *tabBarView; +@property(strong, nonatomic) IBOutlet UIView *sideMenuView; + +- (void)changeView:(UICompositeViewDescription *)description; +- (void)setFullscreen:(BOOL)enabled; +- (void)hideStatusBar:(BOOL)hidden; +- (void)hideTabBar:(BOOL)hidden; +- (void)hideSideMenu:(BOOL)hidden; +- (BOOL)currentViewSupportsLandscape; +- (UIViewController *)getCachedController:(NSString *)name; +- (UIViewController *)getCurrentViewController; +- (UIInterfaceOrientation)currentOrientation; +- (void)clearCache:(NSArray *)exclude; +- (IBAction)onRightSwipe:(id)sender; + +@end diff --git a/Classes/LinphoneUI/UICompositeView.m b/Classes/LinphoneUI/UICompositeView.m new file mode 100644 index 000000000..470eff907 --- /dev/null +++ b/Classes/LinphoneUI/UICompositeView.m @@ -0,0 +1,705 @@ +/* UICompositeView.m +* +* Copyright (C) 2012 Belledonne Comunications, Grenoble, France +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Library General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "UICompositeView.h" + +#import "LinphoneAppDelegate.h" +#import "Utils.h" +#import "SideMenuView.h" + +@implementation UICompositeViewDescription + +- (id)copy { + UICompositeViewDescription *copy = [UICompositeViewDescription alloc]; + copy.name = self.name; + copy.statusBar = self.statusBar; + copy.tabBar = self.tabBar; + copy.sideMenu = self.sideMenu; + copy.statusBarEnabled = self.statusBarEnabled; + copy.tabBarEnabled = self.tabBarEnabled; + copy.sideMenuEnabled = self.sideMenuEnabled; + copy.fullscreen = self.fullscreen; + copy.landscapeMode = self.landscapeMode; + copy.portraitMode = self.portraitMode; + copy.isLeftFragment = self.isLeftFragment; + copy.otherFragment = self.otherFragment; + copy.darkBackground = self.darkBackground; + return copy; +} + +- (BOOL)equal:(UICompositeViewDescription *)description { + return [self.name compare:description.name] == NSOrderedSame; +} + +- (id)init:(Class)content + statusBar:(Class)statusBar + tabBar:(Class)tabBar + sideMenu:(Class)sideMenu + fullscreen:(BOOL)fullscreen + isLeftFragment:(BOOL)isLeftFragment + fragmentWith:(Class)otherFragment { + self.name = NSStringFromClass(content); + self.statusBar = NSStringFromClass(statusBar); + self.tabBar = NSStringFromClass(tabBar); + self.sideMenu = NSStringFromClass(sideMenu); + self.statusBarEnabled = YES; + self.tabBarEnabled = YES; + self.sideMenuEnabled = NO; + self.fullscreen = fullscreen; + self.landscapeMode = YES; + self.portraitMode = YES; + self.otherFragment = IPAD ? NSStringFromClass(otherFragment) : nil; + self.isLeftFragment = isLeftFragment || (self.otherFragment == nil); + self.darkBackground = true; + + return self; +} + +@end +@interface UICompositeView () + +@property(nonatomic, strong) UIViewController *statusBarViewController; +@property(nonatomic, strong) UIViewController *tabBarViewController; +@property(nonatomic, strong) UIViewController *mainViewController; +@property(nonatomic, strong) UIViewController *detailsViewController; +@property(nonatomic, strong) UIViewController *sideMenuViewController; + +@end + +@implementation UICompositeView + +#pragma mark - Lifecycle Functions + +- (void)initUICompositeView { + viewControllerCache = [[NSMutableDictionary alloc] init]; + currentOrientation = (UIInterfaceOrientation)UIDeviceOrientationUnknown; +} + +- (id)init { + self = [super init]; + if (self) { + [self initUICompositeView]; + } + return self; +} + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + [self initUICompositeView]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + [self initUICompositeView]; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +#pragma mark - ViewController Functions + +- (void)updateViewsFramesAccordingToLaunchOrientation { + CGRect frame = + [self.view frame]; // this view has the correct size at launch (1024/768 for iPad, 320*{568,480} for iPhone) + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + BOOL portrait = UIInterfaceOrientationIsPortrait(orientation); + CGRect oppositeFrame = frame; + oppositeFrame.size.height = frame.size.width; + 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].systemVersion floatValue] < 8) { + LOGI(@"landscape get opposite: %@", NSStringFromCGSize(oppositeFrame.size)); + [landscapeView setFrame:oppositeFrame]; + } else { + // if we start in landscape, the landscape view has to get the current size, + // whereas the portrait has to get the opposite + LOGI(@"landscape get frame: %@ and portrait gets opposite: %@", NSStringFromCGSize(frame.size), + NSStringFromCGSize(oppositeFrame.size)); + [landscapeView setFrame:frame]; + [portraitView setFrame:oppositeFrame]; + } +} + +- (void)viewDidLoad { + /* Force landscape view to match portrait view, because portrait view inherits + the device screen size at load */ + [self updateViewsFramesAccordingToLaunchOrientation]; + [super viewDidLoad]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [self.mainViewController viewWillAppear:animated]; + [self.detailsViewController viewWillAppear:animated]; + [self.tabBarViewController viewWillAppear:animated]; + [self.statusBarViewController viewWillAppear:animated]; + [self.sideMenuViewController viewWillAppear:animated]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(orientationDidChange:) + name:UIDeviceOrientationDidChangeNotification + object:nil]; + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [self.mainViewController viewDidAppear:animated]; + [self.detailsViewController viewDidAppear:animated]; + [self.tabBarViewController viewDidAppear:animated]; + [self.statusBarViewController viewDidAppear:animated]; + [self.sideMenuViewController viewDidAppear:animated]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [self.mainViewController viewWillDisappear:animated]; + [self.detailsViewController viewWillDisappear:animated]; + [self.tabBarViewController viewWillDisappear:animated]; + [self.statusBarViewController viewWillDisappear:animated]; + [self.sideMenuViewController viewWillDisappear:animated]; + + [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; + + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; +} + +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + [self.mainViewController viewDidDisappear:animated]; + [self.detailsViewController viewDidDisappear:animated]; + [self.tabBarViewController viewDidDisappear:animated]; + [self.statusBarViewController viewDidDisappear:animated]; + [self.sideMenuViewController viewDidDisappear:animated]; +} + +#pragma mark - Rotation messages + +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation + duration:(NSTimeInterval)duration { + currentOrientation = toInterfaceOrientation; + [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [self.mainViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [self.detailsViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [self.tabBarViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [self.statusBarViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [self.sideMenuViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; +} + +- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation + duration:(NSTimeInterval)duration { + [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation + duration:duration]; // Will invoke TPMultiLayout + [self.mainViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [self.detailsViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [self.tabBarViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [self.statusBarViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [self.sideMenuViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [self update:nil tabBar:nil statusBar:nil sideMenu:nil fullscreen:nil]; +} + +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { + [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; + [self.mainViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; + [self.detailsViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; + [self.tabBarViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; + [self.statusBarViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; + [self.sideMenuViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + if (interfaceOrientation == currentOrientation) + return YES; + return NO; +} + +#pragma mark - Event Functions + +- (void)orientationDidChange:(NSNotification *)notif { + // Update rotation + UIInterfaceOrientation correctOrientation = + [self getCorrectInterfaceOrientation:[[UIDevice currentDevice] orientation]]; + if (currentOrientation != correctOrientation) { + [UICompositeView setOrientation:correctOrientation animated:currentOrientation != UIDeviceOrientationUnknown]; + } +} + +#pragma mark - + +/* + Will simulate a device rotation + */ ++ (void)setOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated { + UIView *firstResponder = nil; + + UIViewController *controller = nil; + + controller = [[UIApplication sharedApplication] keyWindow].rootViewController; + CGRect frame = [[UIScreen mainScreen] bounds]; + UIInterfaceOrientation oldOrientation = controller.interfaceOrientation; + + NSTimeInterval animationDuration = animated ? 0.3f : 0.0; + + [controller willRotateToInterfaceOrientation:orientation duration:animationDuration]; + [controller willAnimateRotationToInterfaceOrientation:orientation duration:animationDuration]; + [controller didRotateFromInterfaceOrientation:oldOrientation]; + [UIView animateWithDuration:animationDuration + animations:^{ + [controller.view setFrame:frame]; + }]; + + if (firstResponder == nil) { + firstResponder = [UICompositeView findFirstResponder:controller.view]; + } + + [[UIApplication sharedApplication] setStatusBarOrientation:orientation animated:animated]; + if (firstResponder) { + [firstResponder resignFirstResponder]; + [firstResponder becomeFirstResponder]; + } +} + ++ (UIView *)findFirstResponder:(UIView *)view { + if (view.isFirstResponder) { + return view; + } + for (UIView *subView in view.subviews) { + UIView *ret = [UICompositeView findFirstResponder:subView]; + if (ret != nil) + return ret; + } + return nil; +} + +- (void)clearCache:(NSArray *)exclude { + for (NSString *key in [viewControllerCache allKeys]) { + bool remove = true; + + /*ImagePickerView can be used as popover and we do NOT want to free it*/; + if ([key isEqualToString:ImagePickerView.compositeViewDescription.name]) { + remove = false; + } else if (exclude != nil) { + for (UICompositeViewDescription *description in exclude) { + if ([key isEqualToString:description.name] || [key isEqualToString:description.statusBar] || + [key isEqualToString:description.tabBar] || [key isEqualToString:description.sideMenu]) { + remove = false; + break; + } + } + } + if (remove) { + LOGI(@"Free cached view: %@", key); + [viewControllerCache removeObjectForKey:key]; + } + } +} + +- (UIInterfaceOrientation)currentOrientation { + return currentOrientation; +} + +- (IBAction)onRightSwipe:(id)sender { + [self hideSideMenu:NO]; +} + ++ (void)addSubView:(UIViewController *)controller view:(UIView *)view { + if (controller != nil) { + [view addSubview:controller.view]; + } +} + ++ (void)removeSubView:(UIViewController *)controller { + if (controller != nil) { + [controller.view removeFromSuperview]; + } +} + +- (UIViewController *)getCachedController:(NSString *)name { + UIViewController *controller = nil; + if (name != nil) { + controller = [viewControllerCache objectForKey:name]; + if (controller == nil) { + controller = [[NSClassFromString(name) alloc] init]; + [viewControllerCache setValue:controller forKey:name]; + [controller view]; // Load the view + } + } + return controller; +} + +- (UIInterfaceOrientation)getCorrectInterfaceOrientation:(UIDeviceOrientation)deviceOrientation { + if (currentViewDescription != nil) { + // If unknown return status bar orientation + if (deviceOrientation == UIDeviceOrientationUnknown && currentOrientation == UIDeviceOrientationUnknown) { + return [UIApplication sharedApplication].statusBarOrientation; + } + + // Don't rotate in UIDeviceOrientationFaceUp UIDeviceOrientationFaceDown + if (!UIDeviceOrientationIsPortrait(deviceOrientation) && !UIDeviceOrientationIsLandscape(deviceOrientation)) { + if (currentOrientation == UIDeviceOrientationUnknown) { + return [UIApplication sharedApplication].statusBarOrientation; + } + deviceOrientation = (UIDeviceOrientation)currentOrientation; + } + if (UIDeviceOrientationIsPortrait(deviceOrientation)) { + if ([currentViewDescription portraitMode]) { + return (UIInterfaceOrientation)deviceOrientation; + } else { + return UIInterfaceOrientationLandscapeLeft; + } + } + if (UIDeviceOrientationIsLandscape(deviceOrientation)) { + if ([currentViewDescription landscapeMode]) { + return (UIInterfaceOrientation)deviceOrientation; + } else { + return UIInterfaceOrientationPortrait; + } + } + } + return UIInterfaceOrientationPortrait; +} + +#define IPHONE_STATUSBAR_HEIGHT 20 + +- (void)update:(UICompositeViewDescription *)description + tabBar:(NSNumber *)tabBar + statusBar:(NSNumber *)statusBar + sideMenu:(NSNumber *)sideMenu + fullscreen:(NSNumber *)fullscreen { + + UIViewController *oldMainViewController = self.mainViewController; + UIViewController *oldDetailsViewController = self.detailsViewController; + UIViewController *oldStatusBarViewController = self.statusBarViewController; + UIViewController *oldTabBarViewController = self.tabBarViewController; + UIViewController *oldSideMenuViewController = self.sideMenuViewController; + // Copy view description + UICompositeViewDescription *oldViewDescription = nil; + + if (description != nil) { + oldViewDescription = currentViewDescription; + currentViewDescription = [description copy]; + + UIViewController *newMainViewController = description.isLeftFragment + ? [self getCachedController:description.name] + : [self getCachedController:description.otherFragment]; + UIViewController *newDetailsViewController = !description.isLeftFragment + ? [self getCachedController:description.name] + : [self getCachedController:description.otherFragment]; + UIViewController *newStatusBarViewController = [self getCachedController:description.statusBar]; + UIViewController *newTabBarViewController = [self getCachedController:description.tabBar]; + UIViewController *newSideMenuViewController = [self getCachedController:description.sideMenu]; + + // Animate only with a previous screen + if (oldViewDescription != nil && self.viewTransition != nil) { + if (oldMainViewController != newMainViewController) { + [self.mainView.layer removeAnimationForKey:@"transition"]; + [self.mainView.layer addAnimation:self.viewTransition forKey:@"transition"]; + } else { + [self.mainView.layer removeAnimationForKey:@"transition"]; + } + if (oldDetailsViewController != newDetailsViewController) { + [self.detailsView.layer removeAnimationForKey:@"transition"]; + [self.detailsView.layer addAnimation:self.viewTransition forKey:@"transition"]; + } else { + [self.detailsView.layer removeAnimationForKey:@"transition"]; + } + + if (oldStatusBarViewController != newStatusBarViewController || + oldViewDescription.statusBarEnabled != currentViewDescription.statusBarEnabled) { + [self.statusBarView.layer removeAnimationForKey:@"transition"]; + [self.statusBarView.layer addAnimation:self.viewTransition forKey:@"transition"]; + } else { + [self.statusBarView.layer removeAnimationForKey:@"transition"]; + } + if (oldTabBarViewController != newTabBarViewController || + oldViewDescription.tabBarEnabled != currentViewDescription.tabBarEnabled) { + [self.tabBarView.layer removeAnimationForKey:@"transition"]; + [self.tabBarView.layer addAnimation:self.viewTransition forKey:@"transition"]; + } else { + [self.tabBarView.layer removeAnimationForKey:@"transition"]; + } + if (oldSideMenuViewController != newSideMenuViewController || + oldViewDescription.sideMenuEnabled != currentViewDescription.sideMenuEnabled) { + [self.sideMenuView.layer removeAnimationForKey:@"transition"]; + [self.sideMenuView.layer addAnimation:self.viewTransition forKey:@"transition"]; + } + } + + if (oldMainViewController != nil && oldMainViewController != newMainViewController) { + [UICompositeView removeSubView:oldMainViewController]; + } + if (oldDetailsViewController != nil && oldDetailsViewController != newDetailsViewController) { + [UICompositeView removeSubView:oldDetailsViewController]; + } + if (oldTabBarViewController != nil && oldTabBarViewController != newTabBarViewController) { + [UICompositeView removeSubView:oldTabBarViewController]; + } + if (oldStatusBarViewController != nil && oldStatusBarViewController != newStatusBarViewController) { + [UICompositeView removeSubView:oldStatusBarViewController]; + } + if (oldSideMenuViewController != nil && oldSideMenuViewController != newSideMenuViewController) { + [UICompositeView removeSubView:oldSideMenuViewController]; + } + + self.statusBarViewController = newStatusBarViewController; + self.mainViewController = newMainViewController; + self.detailsViewController = newDetailsViewController; + self.tabBarViewController = newTabBarViewController; + self.sideMenuViewController = newSideMenuViewController; + + // Update rotation + UIInterfaceOrientation correctOrientation = [self + getCorrectInterfaceOrientation:(UIDeviceOrientation)[UIApplication sharedApplication].statusBarOrientation]; + if (currentOrientation != correctOrientation) { + [UICompositeView setOrientation:correctOrientation + animated:currentOrientation != UIDeviceOrientationUnknown]; + if (UIInterfaceOrientationIsLandscape(correctOrientation)) { + [self.mainViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; + [self.detailsViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; + [self.tabBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; + [self.statusBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; + [self.sideMenuViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; + } + } else { + if (oldMainViewController != newMainViewController) { + UIInterfaceOrientation oldOrientation = self.mainViewController.interfaceOrientation; + [self.mainViewController willRotateToInterfaceOrientation:correctOrientation duration:0]; + [self.mainViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; + [self.mainViewController didRotateFromInterfaceOrientation:oldOrientation]; + } + if (oldDetailsViewController != newDetailsViewController) { + UIInterfaceOrientation oldOrientation = self.detailsViewController.interfaceOrientation; + [self.detailsViewController willRotateToInterfaceOrientation:correctOrientation duration:0]; + [self.detailsViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; + [self.detailsViewController didRotateFromInterfaceOrientation:oldOrientation]; + } + if (oldTabBarViewController != newTabBarViewController) { + UIInterfaceOrientation oldOrientation = self.tabBarViewController.interfaceOrientation; + [self.tabBarViewController willRotateToInterfaceOrientation:correctOrientation duration:0]; + [self.tabBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; + [self.tabBarViewController didRotateFromInterfaceOrientation:oldOrientation]; + } + if (oldSideMenuViewController != newSideMenuViewController) { + UIInterfaceOrientation oldOrientation = self.sideMenuViewController.interfaceOrientation; + [self.sideMenuViewController willRotateToInterfaceOrientation:correctOrientation duration:0]; + [self.sideMenuViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; + [self.sideMenuViewController didRotateFromInterfaceOrientation:oldOrientation]; + } + } + } + + if (currentViewDescription == nil) { + return; + } + + if (tabBar != nil) { + if (currentViewDescription.tabBarEnabled != [tabBar boolValue]) { + currentViewDescription.tabBarEnabled = [tabBar boolValue]; + } else { + tabBar = nil; // No change = No Update + } + } + + if (statusBar != nil) { + if (currentViewDescription.statusBarEnabled != [statusBar boolValue]) { + currentViewDescription.statusBarEnabled = [statusBar boolValue]; + } else { + statusBar = nil; // No change = No Update + } + } + + if (sideMenu != nil) { + if (currentViewDescription.sideMenuEnabled != [sideMenu boolValue]) { + currentViewDescription.sideMenuEnabled = [sideMenu boolValue]; + if (currentViewDescription.sideMenuEnabled) { + [_sideMenuViewController viewWillAppear:YES]; + } else { + [_sideMenuViewController viewWillDisappear:YES]; + } + } else { + sideMenu = nil; // No change = No Update + } + } + + if (fullscreen != nil) { + if (currentViewDescription.fullscreen != [fullscreen boolValue]) { + currentViewDescription.fullscreen = [fullscreen boolValue]; + [[UIApplication sharedApplication] setStatusBarHidden:currentViewDescription.fullscreen + withAnimation:UIStatusBarAnimationSlide]; + } else { + fullscreen = nil; // No change = No Update + } + } else { + [[UIApplication sharedApplication] setStatusBarHidden:currentViewDescription.fullscreen + withAnimation:UIStatusBarAnimationNone]; + } + + // Start animation + if (tabBar != nil || statusBar != nil || sideMenu != nil || fullscreen != nil) { + [UIView beginAnimations:@"resize" context:nil]; + [UIView setAnimationDuration:0.35]; + } + + // Compute frame for each elements + CGRect viewFrame = self.view.frame; + + // 1. status bar - fixed size on top + CGRect statusBarFrame = self.statusBarView.frame; + int origin = currentViewDescription.fullscreen ? 0 : IPHONE_STATUSBAR_HEIGHT; + if (self.statusBarViewController != nil && currentViewDescription.statusBarEnabled) { + statusBarFrame.origin.y = origin; + } else { + statusBarFrame.origin.y = origin - statusBarFrame.size.height; + } + + // 2. side menu - fixed size, always starting below status bar + CGRect sideMenuFrame = viewFrame; + sideMenuFrame.origin.y = origin + statusBarFrame.size.height; + sideMenuFrame.size.height -= sideMenuFrame.origin.y; + if (!currentViewDescription.sideMenuEnabled) { + // really hide; -width won't be enough since some animations may use this... + sideMenuFrame.origin.x = -3 * sideMenuFrame.size.width; + } + + // 3. tab bar - on portrait full width at bottom / on landscape on left, starting below status bar + // Resize TabBar + CGRect tabFrame = self.tabBarView.frame; + if (self.tabBarViewController != nil && currentViewDescription.tabBarEnabled) { + tabFrame.origin.x = 0; + if (UIInterfaceOrientationIsPortrait([self currentOrientation])) { + tabFrame.origin.y = viewFrame.size.height - tabFrame.size.height; + } else { + tabFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height; + tabFrame.size.height = viewFrame.size.height - tabFrame.origin.y; + } + } else { + tabFrame.origin.x = -tabFrame.size.width; + tabFrame.origin.y = viewFrame.size.height; + } + + // 4. main view and details view - space left width of 35%/65% each + CGRect mainFrame = viewFrame; + mainFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height; + mainFrame.size.height -= mainFrame.origin.y; + if (!currentViewDescription.fullscreen) { + if (UIInterfaceOrientationIsPortrait([self currentOrientation])) { + mainFrame.size.height -= viewFrame.size.height - tabFrame.origin.y; + } else { + mainFrame.origin.x = tabFrame.origin.x + tabFrame.size.width; + mainFrame.size.width -= mainFrame.origin.x; + } + } + CGRect detailsFrame = mainFrame; + if (self.detailsViewController != nil) { + detailsFrame = mainFrame; + mainFrame.size.width = ceil(mainFrame.size.width * .35); + detailsFrame.size.width -= mainFrame.size.width; + detailsFrame.origin.x += mainFrame.size.width; + } + + // Set frames + // 1. main view and details view + self.mainView.frame = mainFrame; + self.mainViewController.view.frame = self.mainView.bounds; + self.detailsView.frame = detailsFrame; + self.detailsViewController.view.frame = self.detailsView.bounds; + + // 2. tab bar + self.tabBarView.frame = tabFrame; + CGRect frame = self.tabBarViewController.view.frame; + frame.size = self.tabBarView.bounds.size; + self.tabBarViewController.view.frame = frame; + + // 3. status bar + self.statusBarView.frame = statusBarFrame; + frame = self.statusBarViewController.view.frame; + frame.size = self.statusBarView.bounds.size; + self.statusBarViewController.view.frame = frame; + + // 4. side menu + self.sideMenuView.frame = sideMenuFrame; + self.sideMenuViewController.view.frame = self.sideMenuView.bounds; + + // Commit animation + if (tabBar != nil || statusBar != nil || sideMenu != nil || fullscreen != nil) { + [UIView commitAnimations]; + } + + // Change view + if (description != nil) { + if (oldMainViewController == nil || oldMainViewController != self.tabBarViewController) { + [UICompositeView addSubView:self.mainViewController view:self.mainView]; + } + if (oldDetailsViewController == nil || oldDetailsViewController != self.detailsViewController) { + [UICompositeView addSubView:self.detailsViewController view:self.detailsView]; + } + if (oldTabBarViewController == nil || oldTabBarViewController != self.tabBarViewController) { + [UICompositeView addSubView:self.tabBarViewController view:self.tabBarView]; + } + if (oldStatusBarViewController == nil || oldStatusBarViewController != self.statusBarViewController) { + [UICompositeView addSubView:self.statusBarViewController view:self.statusBarView]; + } + if (oldSideMenuViewController == nil || oldSideMenuViewController != self.sideMenuViewController) { + [UICompositeView addSubView:self.sideMenuViewController view:self.sideMenuView]; + } + } + if (currentViewDescription.sideMenuEnabled) { + [_sideMenuViewController viewDidAppear:YES]; + } else { + [_sideMenuViewController viewDidDisappear:YES]; + } + // Dealloc old view description +} + +- (void)changeView:(UICompositeViewDescription *)description { + [self view]; // Force view load + [self update:description tabBar:nil statusBar:nil sideMenu:nil fullscreen:nil]; +} + +- (void)setFullscreen:(BOOL)enabled { + [self update:nil tabBar:nil statusBar:nil sideMenu:nil fullscreen:[NSNumber numberWithBool:enabled]]; +} + +- (void)hideTabBar:(BOOL)hidden { + [self update:nil tabBar:[NSNumber numberWithBool:!hidden] statusBar:nil sideMenu:nil fullscreen:nil]; +} + +- (void)hideStatusBar:(BOOL)hidden { + [self update:nil tabBar:nil statusBar:[NSNumber numberWithBool:!hidden] sideMenu:nil fullscreen:nil]; +} + +- (void)hideSideMenu:(BOOL)hidden { + [self update:nil tabBar:nil statusBar:nil sideMenu:[NSNumber numberWithBool:!hidden] fullscreen:nil]; +} +- (UIViewController *)getCurrentViewController { + return self.mainViewController; +} + +- (BOOL)currentViewSupportsLandscape { + return currentViewDescription ? currentViewDescription.landscapeMode : FALSE; +} + +@end diff --git a/Classes/LinphoneUI/UICompositeViewController.h b/Classes/LinphoneUI/UICompositeViewController.h deleted file mode 100644 index 3af7e6741..000000000 --- a/Classes/LinphoneUI/UICompositeViewController.h +++ /dev/null @@ -1,81 +0,0 @@ -/* UICompositeViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#import - -#import "LinphoneManager.h" -#import "TPMultiLayoutViewController.h" - -@interface UICompositeViewDescription: NSObject{ -} - -@property (retain) NSString *name; -@property (retain) NSString *content; -@property (retain) NSString *stateBar; -@property (assign) BOOL stateBarEnabled; -@property (retain) NSString *tabBar; -@property (assign) BOOL tabBarEnabled; -@property (assign) BOOL fullscreen; -@property (assign) BOOL landscapeMode; -@property (assign) BOOL portraitMode; -@property (assign) BOOL darkBackground; - -- (id)copy; -- (BOOL)equal:(UICompositeViewDescription*) description; -- (id)init:(NSString *)name content:(NSString *)content stateBar:(NSString*)stateBar - stateBarEnabled:(BOOL) stateBarEnabled - tabBar:(NSString*)tabBar - tabBarEnabled:(BOOL) tabBarEnabled - fullscreen:(BOOL) fullscreen - landscapeMode:(BOOL) landscapeMode - portraitMode:(BOOL) portraitMode; - -@end - -@protocol UICompositeViewDelegate - -+ (UICompositeViewDescription*) compositeViewDescription; - -@end - -@interface UICompositeViewController : TPMultiLayoutViewController { - @private - NSMutableDictionary *viewControllerCache; - UICompositeViewDescription *currentViewDescription; - UIInterfaceOrientation currentOrientation; -} - -@property (retain) CATransition *viewTransition; - -@property (nonatomic, retain) IBOutlet UIView* stateBarView; -@property (nonatomic, retain) IBOutlet UIView* contentView; -@property (nonatomic, retain) IBOutlet UIView* tabBarView; - -- (void)changeView:(UICompositeViewDescription *)description; -- (void)setFullScreen:(BOOL) enabled; -- (void)setStateBarHidden:(BOOL) hidden; -- (void)setToolBarHidden:(BOOL) hidden; -- (BOOL)currentViewSupportsLandscape; -- (UIViewController *)getCachedController:(NSString*)name; -- (UIViewController *)getCurrentViewController; -- (UIInterfaceOrientation)currentOrientation; -- (void)clearCache:(NSArray*)exclude; - -@end diff --git a/Classes/LinphoneUI/UICompositeViewController.m b/Classes/LinphoneUI/UICompositeViewController.m deleted file mode 100644 index f5e4126f5..000000000 --- a/Classes/LinphoneUI/UICompositeViewController.m +++ /dev/null @@ -1,635 +0,0 @@ -/* UICompositeViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UICompositeViewController.h" - -#import "LinphoneAppDelegate.h" - -@implementation UICompositeViewDescription - -@synthesize name; -@synthesize content; -@synthesize stateBar; -@synthesize stateBarEnabled; -@synthesize tabBar; -@synthesize tabBarEnabled; -@synthesize fullscreen; -@synthesize landscapeMode; -@synthesize portraitMode; - - -- (id)copy { - UICompositeViewDescription *copy = [UICompositeViewDescription alloc]; - copy.content = self.content; - copy.stateBar = self.stateBar; - copy.stateBarEnabled = self.stateBarEnabled; - copy.tabBar = self.tabBar; - copy.tabBarEnabled = self.tabBarEnabled; - copy.fullscreen = self.fullscreen; - copy.landscapeMode = self.landscapeMode; - copy.portraitMode = self.portraitMode; - copy.darkBackground = self.darkBackground; - return copy; -} - -- (BOOL)equal:(UICompositeViewDescription*) description { - return [self.name compare:description.name] == NSOrderedSame; -} - -- (id)init:(NSString *)aname content:(NSString *)acontent stateBar:(NSString*)astateBar - stateBarEnabled:(BOOL) astateBarEnabled - tabBar:(NSString*)atabBar - tabBarEnabled:(BOOL) atabBarEnabled - fullscreen:(BOOL) afullscreen - landscapeMode:(BOOL) alandscapeMode - portraitMode:(BOOL) aportraitMode{ - self.name = aname; - self.content = acontent; - self.stateBar = astateBar; - self.stateBarEnabled = astateBarEnabled; - self.tabBar = atabBar; - self.tabBarEnabled = atabBarEnabled; - self.fullscreen = afullscreen; - self.landscapeMode = alandscapeMode; - self.portraitMode = aportraitMode; - self.darkBackground = false; - - return self; -} - -- (void)dealloc { - [name release]; - [content release]; - [stateBar release]; - [tabBar release]; - [super dealloc]; -} - -@end -@interface UICompositeViewController () - -@property (nonatomic, retain) UIViewController *stateBarViewController; -@property (nonatomic, retain) UIViewController *tabBarViewController; -@property (nonatomic, retain) UIViewController *contentViewController; - -@end - -@implementation UICompositeViewController - -@synthesize stateBarView; -@synthesize contentView; -@synthesize tabBarView; -@synthesize tabBarViewController = _tabBarViewController; -@synthesize stateBarViewController = _stateBarViewController; -@synthesize contentViewController = _contentViewController; - -@synthesize viewTransition; - - -#pragma mark - Lifecycle Functions - -- (void)initUICompositeViewController { - viewControllerCache = [[NSMutableDictionary alloc] init]; - currentOrientation = (UIInterfaceOrientation)UIDeviceOrientationUnknown; -} - -- (id)init{ - self = [super init]; - if (self) { - [self initUICompositeViewController]; - } - return self; -} - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - [self initUICompositeViewController]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { - [self initUICompositeViewController]; - } - return self; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [self.stateBarViewController release]; - [self.tabBarViewController release]; - [self.contentViewController release]; - - [contentView release]; - [stateBarView release]; - [tabBarView release]; - [viewControllerCache release]; - [viewTransition release]; - [currentViewDescription release]; - - [super dealloc]; -} - - -#pragma mark - Property Functions - -- (UIViewController*)stateBarViewController { - return _stateBarViewController; -} - -- (UIViewController*)contentViewController { - return _contentViewController; -} - -- (UIViewController*)tabBarViewController { - return _tabBarViewController; -} - - -#pragma mark - ViewController Functions - -- (void)updateViewsFramesAccordingToLaunchOrientation { - CGRect frame = [self.view frame]; // this view has the correct size at launch (1024/768 for iPad, 320*{568,480} for iPhone) - UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; - BOOL portrait = UIInterfaceOrientationIsPortrait(orientation); - CGRect oppositeFrame = frame; - oppositeFrame.size.height = frame.size.width; - 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].systemVersion floatValue] < 8 ){ - Linphone_log(@"landscape get opposite: %@", NSStringFromCGSize(oppositeFrame.size)); - [landscapeView setFrame:oppositeFrame]; - } else { - // if we start in landscape, the landscape view has to get the current size, - // whereas the portrait has to get the opposite - Linphone_log(@"landscape get frame: %@ and portrait gets opposite: %@", NSStringFromCGSize(frame.size), NSStringFromCGSize(oppositeFrame.size)); - [landscapeView setFrame:frame]; - [portraitView setFrame:oppositeFrame]; - } -} - -- (void)viewDidLoad { - /* Force landscape view to match portrait view, because portrait view inherits - the device screen size at load */ - [self updateViewsFramesAccordingToLaunchOrientation]; - [super viewDidLoad]; -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - [self.contentViewController viewWillAppear:animated]; - [self.tabBarViewController viewWillAppear:animated]; - [self.stateBarViewController viewWillAppear:animated]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(orientationDidChange:) - name:UIDeviceOrientationDidChangeNotification - object:nil]; - [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; -} - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [self.contentViewController viewDidAppear:animated]; - [self.tabBarViewController viewDidAppear:animated]; - [self.stateBarViewController viewDidAppear:animated]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self.contentViewController viewWillDisappear:animated]; - [self.tabBarViewController viewWillDisappear:animated]; - [self.stateBarViewController viewWillDisappear:animated]; - - [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIDeviceOrientationDidChangeNotification - object:nil]; -} - -- (void)viewDidDisappear:(BOOL)animated { - [super viewDidDisappear:animated]; - [self.contentViewController viewDidDisappear:animated]; - [self.tabBarViewController viewDidDisappear:animated]; - [self.stateBarViewController viewDidDisappear:animated]; -} - -#pragma mark - Rotation messages - -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - currentOrientation = toInterfaceOrientation; - [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; - [self.contentViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; - [self.tabBarViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; - [self.stateBarViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; -} - -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; // Will invoke TPMultiLayout - [self.contentViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; - [self.tabBarViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; - [self.stateBarViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; - [self update:nil tabBar:nil stateBar:nil fullscreen:nil]; -} - -- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { - [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; - [self.contentViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; - [self.tabBarViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; - [self.stateBarViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - if(interfaceOrientation == currentOrientation) - return YES; - return NO; -} - - -#pragma mark - Event Functions - -- (void)orientationDidChange:(NSNotification*)notif { - // Update rotation - UIInterfaceOrientation correctOrientation = [self getCorrectInterfaceOrientation:[[UIDevice currentDevice] orientation]]; - if(currentOrientation != correctOrientation) { - [UICompositeViewController setOrientation:correctOrientation animated:currentOrientation != UIDeviceOrientationUnknown]; - } -} - - -#pragma mark - - -/* - Will simulate a device rotation - */ -+ (void)setOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated { - UIView *firstResponder = nil; - - UIViewController *controller = nil; - - controller = [[UIApplication sharedApplication] keyWindow].rootViewController; - CGRect frame = [[UIScreen mainScreen] bounds]; - UIInterfaceOrientation oldOrientation = controller.interfaceOrientation; - - NSTimeInterval animationDuration = animated? 0.3f : 0.0; - - [controller willRotateToInterfaceOrientation:orientation duration:animationDuration]; - [controller willAnimateRotationToInterfaceOrientation:orientation duration:animationDuration]; - [controller didRotateFromInterfaceOrientation:oldOrientation]; - [UIView animateWithDuration:animationDuration animations:^{ - [controller.view setFrame:frame]; - }]; - - if(firstResponder == nil) { - firstResponder = [UICompositeViewController findFirstResponder:controller.view]; - } - - [[UIApplication sharedApplication] setStatusBarOrientation:orientation animated:animated]; - if(firstResponder) { - [firstResponder resignFirstResponder]; - [firstResponder becomeFirstResponder]; - } -} - -+ (UIView*)findFirstResponder:(UIView*)view { - if (view.isFirstResponder) { - return view; - } - for (UIView *subView in view.subviews) { - UIView *ret = [UICompositeViewController findFirstResponder:subView]; - if (ret != nil) - return ret; - } - return nil; -} - -- (void)clearCache:(NSArray *)exclude { - for(NSString *key in [viewControllerCache allKeys]) { - bool remove = true; - if(exclude != nil) { - for (UICompositeViewDescription *description in exclude) { - if([key isEqualToString:description.content] || - [key isEqualToString:description.stateBar] || - [key isEqualToString:description.tabBar] - ) { - remove = false; - break; - } - } - } - if(remove) { - [LinphoneLogger log:LinphoneLoggerLog format:@"Free cached view: %@", key]; - [viewControllerCache removeObjectForKey:key]; - } - } -} - -- (UIInterfaceOrientation)currentOrientation { - return currentOrientation; -} - -+ (void)addSubView:(UIViewController*)controller view:(UIView*)view { - if(controller != nil) { - [view addSubview: controller.view]; - } -} - -+ (void)removeSubView:(UIViewController*)controller { - if(controller != nil) { - [controller.view removeFromSuperview]; - } -} - -- (UIViewController*)getCachedController:(NSString*)name { - UIViewController *controller = nil; - if(name != nil) { - controller = [viewControllerCache objectForKey:name]; - if(controller == nil) { - controller = [[[NSClassFromString(name) alloc] init] autorelease]; - [viewControllerCache setValue:controller forKey:name]; - [controller view]; // Load the view - } - } - return controller; -} - -- (UIInterfaceOrientation)getCorrectInterfaceOrientation:(UIDeviceOrientation)deviceOrientation { - if(currentViewDescription != nil) { - // If unknown return status bar orientation - if(deviceOrientation == UIDeviceOrientationUnknown && currentOrientation == UIDeviceOrientationUnknown) { - return [UIApplication sharedApplication].statusBarOrientation; - } - - // Don't rotate in UIDeviceOrientationFaceUp UIDeviceOrientationFaceDown - if(!UIDeviceOrientationIsPortrait(deviceOrientation) && !UIDeviceOrientationIsLandscape(deviceOrientation)) { - if(currentOrientation == UIDeviceOrientationUnknown) { - return [UIApplication sharedApplication].statusBarOrientation; - } - deviceOrientation = (UIDeviceOrientation)currentOrientation; - } - if (UIDeviceOrientationIsPortrait(deviceOrientation)) { - if ([currentViewDescription portraitMode]) { - return (UIInterfaceOrientation)deviceOrientation; - } else { - return UIInterfaceOrientationLandscapeLeft; - } - } - if (UIDeviceOrientationIsLandscape(deviceOrientation)) { - if ([currentViewDescription landscapeMode]) { - return (UIInterfaceOrientation)deviceOrientation; - } else { - return UIInterfaceOrientationPortrait; - } - } - } - return UIInterfaceOrientationPortrait; -} - -#define IPHONE_STATUSBAR_HEIGHT 20 - -- (void)update: (UICompositeViewDescription*) description tabBar:(NSNumber*)tabBar stateBar:(NSNumber*)stateBar fullscreen:(NSNumber*)fullscreen { - - UIViewController *oldContentViewController = self.contentViewController; - UIViewController *oldStateBarViewController = self.stateBarViewController; - UIViewController *oldTabBarViewController = self.tabBarViewController; - // Copy view description - UICompositeViewDescription *oldViewDescription = nil; - - if(description != nil) { - oldViewDescription = currentViewDescription; - currentViewDescription = [description copy]; - - // Animate only with a previous screen - if(oldViewDescription != nil && viewTransition != nil) { - [contentView.layer removeAnimationForKey:@"transition"]; - [contentView.layer addAnimation:viewTransition forKey:@"transition"]; - if(oldViewDescription.stateBar != currentViewDescription.stateBar || - oldViewDescription.stateBarEnabled != currentViewDescription.stateBarEnabled || - [stateBarView.layer animationForKey:@"transition"] != nil) { - [stateBarView.layer removeAnimationForKey:@"transition"]; - [stateBarView.layer addAnimation:viewTransition forKey:@"transition"]; - } - if(oldViewDescription.tabBar != currentViewDescription.tabBar || - oldViewDescription.tabBarEnabled != currentViewDescription.tabBarEnabled || - [tabBarView.layer animationForKey:@"transition"] != nil) { - [tabBarView.layer removeAnimationForKey:@"transition"]; - [tabBarView.layer addAnimation:viewTransition forKey:@"transition"]; - } - } - - UIViewController *newContentViewController = [self getCachedController:description.content]; - UIViewController *newStateBarViewController = [self getCachedController:description.stateBar]; - UIViewController *newTabBarViewController = [self getCachedController:description.tabBar]; - - [UICompositeViewController removeSubView: oldContentViewController]; - if(oldTabBarViewController != nil && oldTabBarViewController != newTabBarViewController) { - [UICompositeViewController removeSubView:oldTabBarViewController]; - } - if(oldStateBarViewController != nil && oldStateBarViewController != newStateBarViewController) { - [UICompositeViewController removeSubView:oldStateBarViewController]; - } - - self.stateBarViewController = newStateBarViewController; - self.contentViewController = newContentViewController; - self.tabBarViewController = newTabBarViewController; - - // Update rotation - UIInterfaceOrientation correctOrientation = [self getCorrectInterfaceOrientation:(UIDeviceOrientation)[UIApplication sharedApplication].statusBarOrientation]; - if(currentOrientation != correctOrientation) { - [UICompositeViewController setOrientation:correctOrientation animated:currentOrientation!=UIDeviceOrientationUnknown]; - if( UIInterfaceOrientationIsLandscape(correctOrientation) ){ - [self.contentViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; - [self.tabBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; - [self.stateBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; - } - } else { - if(oldContentViewController != newContentViewController) { - UIInterfaceOrientation oldOrientation = self.contentViewController.interfaceOrientation; - [self.contentViewController willRotateToInterfaceOrientation:correctOrientation duration:0]; - [self.contentViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; - [self.contentViewController didRotateFromInterfaceOrientation:oldOrientation]; - } - if(oldTabBarViewController != newTabBarViewController) { - UIInterfaceOrientation oldOrientation = self.tabBarViewController.interfaceOrientation; - [self.tabBarViewController willRotateToInterfaceOrientation:correctOrientation duration:0]; - [self.tabBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; - [self.tabBarViewController didRotateFromInterfaceOrientation:oldOrientation]; - } - if(oldStateBarViewController != newStateBarViewController) { - UIInterfaceOrientation oldOrientation = self.stateBarViewController.interfaceOrientation; - [self.stateBarViewController willRotateToInterfaceOrientation:correctOrientation duration:0]; - [self.stateBarViewController willAnimateRotationToInterfaceOrientation:correctOrientation duration:0]; - [self.stateBarViewController didRotateFromInterfaceOrientation:oldOrientation]; - } - } - } else { - oldViewDescription = (currentViewDescription != nil)? [currentViewDescription copy]: nil; - } - - if(currentViewDescription == nil) { - return; - } - - if(tabBar != nil) { - if(currentViewDescription.tabBarEnabled != [tabBar boolValue]) { - currentViewDescription.tabBarEnabled = [tabBar boolValue]; - } else { - tabBar = nil; // No change = No Update - } - } - - if(stateBar != nil) { - if(currentViewDescription.stateBarEnabled != [stateBar boolValue]) { - currentViewDescription.stateBarEnabled = [stateBar boolValue]; - } else { - stateBar = nil; // No change = No Update - } - } - - if(fullscreen != nil) { - if(currentViewDescription.fullscreen != [fullscreen boolValue]) { - currentViewDescription.fullscreen = [fullscreen boolValue]; - [[UIApplication sharedApplication] setStatusBarHidden:currentViewDescription.fullscreen withAnimation:UIStatusBarAnimationSlide]; - } else { - fullscreen = nil; // No change = No Update - } - } else { - [[UIApplication sharedApplication] setStatusBarHidden:currentViewDescription.fullscreen withAnimation:UIStatusBarAnimationNone]; - } - - // Start animation - if(tabBar != nil || stateBar != nil || fullscreen != nil) { - [UIView beginAnimations:@"resize" context:nil]; - [UIView setAnimationDuration:0.35]; - [UIView setAnimationBeginsFromCurrentState:TRUE]; - } - - CGRect contentFrame = contentView.frame; - CGRect viewFrame = [self.view frame]; - - // Resize StateBar - CGRect stateBarFrame = stateBarView.frame; - int origin = IPHONE_STATUSBAR_HEIGHT; - if(currentViewDescription.fullscreen) - origin = 0; - - if(self.stateBarViewController != nil && currentViewDescription.stateBarEnabled) { - contentFrame.origin.y = origin + stateBarFrame.size.height; - stateBarFrame.origin.y = origin; - } else { - contentFrame.origin.y = origin; - stateBarFrame.origin.y = origin - stateBarFrame.size.height; - } - - // Resize TabBar - CGRect tabFrame = tabBarView.frame; - if(self.tabBarViewController != nil && currentViewDescription.tabBarEnabled) { - tabFrame.origin.y = viewFrame.size.height; - tabFrame.origin.x = viewFrame.size.width; - tabFrame.size.height = self.tabBarViewController.view.frame.size.height; - //tabFrame.size.width = self.tabBarViewController.view.frame.size.width; - tabFrame.origin.y -= tabFrame.size.height; - tabFrame.origin.x -= tabFrame.size.width; - contentFrame.size.height = tabFrame.origin.y - contentFrame.origin.y; - - // for some views, we need the content to overlap, in which case - // we insert in the tab XIB a mask with tag -1 and with y = the amount of - // points that the content should overlap. - for (UIView *view in self.tabBarViewController.view.subviews) { - if(view.tag == -1) { - contentFrame.size.height += view.frame.origin.y; - break; - } - } - } else { - contentFrame.size.height = viewFrame.size.height - contentFrame.origin.y; - tabFrame.origin.y = viewFrame.size.height; - } - - if(currentViewDescription.fullscreen) { - contentFrame.origin.y = origin; - contentFrame.size.height = viewFrame.size.height - contentFrame.origin.y; - } - - // Set frames - [contentView setFrame: contentFrame]; - [self.contentViewController.view setFrame: [contentView bounds]]; - [tabBarView setFrame: tabFrame]; - CGRect frame = [self.tabBarViewController.view frame]; - frame.size.width = [tabBarView bounds].size.width; - [self.tabBarViewController.view setFrame:frame]; - [stateBarView setFrame: stateBarFrame]; - frame = [self.stateBarViewController.view frame]; - frame.size.width = [stateBarView bounds].size.width; - [self.stateBarViewController.view setFrame:frame]; - - // Commit animation - if(tabBar != nil || stateBar != nil || fullscreen != nil) { - [UIView commitAnimations]; - } - - // Change view - if(description != nil) { - [UICompositeViewController addSubView: self.contentViewController view:contentView]; - if(oldTabBarViewController == nil || oldTabBarViewController != self.tabBarViewController) { - [UICompositeViewController addSubView: self.tabBarViewController view:tabBarView]; - } - if(oldStateBarViewController == nil || oldStateBarViewController != self.stateBarViewController) { - [UICompositeViewController addSubView: self.stateBarViewController view:stateBarView]; - } - } - - // Dealloc old view description - if(oldViewDescription != nil) { - [oldViewDescription release]; - } -} - -- (void) changeView:(UICompositeViewDescription *)description { - [self view]; // Force view load - [self update:description tabBar:nil stateBar:nil fullscreen:nil]; -} - -- (void) setFullScreen:(BOOL) enabled { - [self update:nil tabBar:nil stateBar:nil fullscreen:[NSNumber numberWithBool:enabled]]; -} - -- (void) setToolBarHidden:(BOOL) hidden { - [self update:nil tabBar:[NSNumber numberWithBool:!hidden] stateBar:nil fullscreen:nil]; -} - -- (void) setStateBarHidden:(BOOL) hidden { - [self update:nil tabBar: nil stateBar:[NSNumber numberWithBool:!hidden] fullscreen:nil]; -} - -- (UIViewController *) getCurrentViewController { - return [[self.contentViewController retain] autorelease]; -} - -- (BOOL)currentViewSupportsLandscape { - return currentViewDescription ? currentViewDescription.landscapeMode : FALSE; -} - -@end diff --git a/Classes/LinphoneUI/UIConferenceHeader.h b/Classes/LinphoneUI/UIConferenceHeader.h deleted file mode 100644 index 5834c78ae..000000000 --- a/Classes/LinphoneUI/UIConferenceHeader.h +++ /dev/null @@ -1,33 +0,0 @@ -/* UIConferenceHeader.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UIPauseButton.h" - -@interface UIConferenceHeader : UIViewController { -} - -@property (nonatomic, retain) IBOutlet UIImageView* stateImage; -@property (nonatomic, retain) IBOutlet UIPauseButton *pauseButton; - -+ (int)getHeight; -- (void)update; - -@end diff --git a/Classes/LinphoneUI/UIConferenceHeader.m b/Classes/LinphoneUI/UIConferenceHeader.m deleted file mode 100644 index 78947b5fc..000000000 --- a/Classes/LinphoneUI/UIConferenceHeader.m +++ /dev/null @@ -1,69 +0,0 @@ -/* UIConferenceHeader.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UIConferenceHeader.h" - -#import "LinphoneManager.h" - -@implementation UIConferenceHeader - -@synthesize stateImage; -@synthesize pauseButton; - - -#pragma mark - Lifecycle Functions - -- (id)init { - return [super initWithNibName:@"UIConferenceHeader" bundle:[NSBundle mainBundle]]; -} - -- (void)dealloc { - [stateImage release]; - [pauseButton release]; - [super dealloc]; -} - - -#pragma mark - ViewController Functions - -- (void)viewDidLoad { - [super viewDidLoad]; - // Set selected+over background: IB lack ! - [pauseButton setImage:[UIImage imageNamed:@"call_state_pause_over.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - [pauseButton setType:UIPauseButtonType_Conference call:nil]; -} - - -#pragma mark - Static size Functions - -+ (int)getHeight { - return 50; -} - - -#pragma mark - - -- (void)update { - [self view]; // Force view load - [stateImage setHidden:true]; - [pauseButton update]; -} - -@end diff --git a/Classes/LinphoneUI/UIConfirmationDialog.h b/Classes/LinphoneUI/UIConfirmationDialog.h new file mode 100644 index 000000000..072bad3be --- /dev/null +++ b/Classes/LinphoneUI/UIConfirmationDialog.h @@ -0,0 +1,36 @@ +// +// UIConfirmationDialog.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 11/09/15. +// +// + +#include "UIRoundBorderedButton.h" + +typedef void (^UIConfirmationBlock)(void); + +@interface UIConfirmationDialog : UIViewController { + UIConfirmationBlock onCancelCb; + UIConfirmationBlock onConfirmCb; +} + ++ (UIConfirmationDialog *)ShowWithMessage:(NSString *)message + cancelMessage:(NSString *)cancel + confirmMessage:(NSString *)confirm + onCancelClick:(UIConfirmationBlock)onCancel + onConfirmationClick:(UIConfirmationBlock)onConfirm; ++ (UIConfirmationDialog *)ShowWithMessage:(NSString *)message + cancelMessage:(NSString *)cancel + confirmMessage:(NSString *)confirm + onCancelClick:(UIConfirmationBlock)onCancel + onConfirmationClick:(UIConfirmationBlock)onConfirm + inController:(UIViewController *)controller; + +@property(weak, nonatomic) IBOutlet UIRoundBorderedButton *cancelButton; +@property(weak, nonatomic) IBOutlet UIRoundBorderedButton *confirmationButton; +@property(weak, nonatomic) IBOutlet UILabel *titleLabel; +- (IBAction)onCancelClick:(id)sender; +- (IBAction)onConfirmationClick:(id)sender; +- (void)dismiss; +@end diff --git a/Classes/LinphoneUI/UIConfirmationDialog.m b/Classes/LinphoneUI/UIConfirmationDialog.m new file mode 100644 index 000000000..19211d558 --- /dev/null +++ b/Classes/LinphoneUI/UIConfirmationDialog.m @@ -0,0 +1,76 @@ +// +// UIConfirmationDialog.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 11/09/15. +// +// + +#import "UIConfirmationDialog.h" +#import "PhoneMainView.h" + +@implementation UIConfirmationDialog ++ (UIConfirmationDialog *)ShowWithMessage:(NSString *)message + cancelMessage:(NSString *)cancel + confirmMessage:(NSString *)confirm + onCancelClick:(UIConfirmationBlock)onCancel + onConfirmationClick:(UIConfirmationBlock)onConfirm + inController:(UIViewController *)controller { + UIConfirmationDialog *dialog = + [[UIConfirmationDialog alloc] initWithNibName:NSStringFromClass(self.class) bundle:NSBundle.mainBundle]; + + dialog.view.frame = PhoneMainView.instance.mainViewController.view.frame; + [controller.view addSubview:dialog.view]; + [controller addChildViewController:dialog]; + + dialog->onCancelCb = onCancel; + dialog->onConfirmCb = onConfirm; + + [dialog.titleLabel setText:message]; + if (cancel) { + [dialog.cancelButton setTitle:cancel forState:UIControlStateNormal]; + } + if (confirm) { + [dialog.confirmationButton setTitle:confirm forState:UIControlStateNormal]; + } + + dialog.confirmationButton.layer.borderColor = + [[UIColor colorWithPatternImage:[UIImage imageNamed:@"color_A.png"]] CGColor]; + dialog.cancelButton.layer.borderColor = + [[UIColor colorWithPatternImage:[UIImage imageNamed:@"color_F.png"]] CGColor]; + return dialog; +} + ++ (UIConfirmationDialog *)ShowWithMessage:(NSString *)message + cancelMessage:(NSString *)cancel + confirmMessage:(NSString *)confirm + onCancelClick:(UIConfirmationBlock)onCancel + onConfirmationClick:(UIConfirmationBlock)onConfirm { + return [self ShowWithMessage:message + cancelMessage:cancel + confirmMessage:confirm + onCancelClick:onCancel + onConfirmationClick:onConfirm + inController:PhoneMainView.instance.mainViewController]; +} + +- (IBAction)onCancelClick:(id)sender { + [self.view removeFromSuperview]; + [self removeFromParentViewController]; + if (onCancelCb) { + onCancelCb(); + } +} + +- (IBAction)onConfirmationClick:(id)sender { + [self.view removeFromSuperview]; + [self removeFromParentViewController]; + if (onConfirmCb) { + onConfirmCb(); + } +} + +- (void)dismiss { + [self onCancelClick:nil]; +} +@end diff --git a/Classes/LinphoneUI/UIContactCell.h b/Classes/LinphoneUI/UIContactCell.h index a5ecc54d7..0729a859b 100644 --- a/Classes/LinphoneUI/UIContactCell.h +++ b/Classes/LinphoneUI/UIContactCell.h @@ -19,14 +19,13 @@ #import #import -#import "UITransparentTVCell.h" +#import "UIRoundedImageView.h" -@interface UIContactCell : UITransparentTVCell { -} +@interface UIContactCell : UITableViewCell -@property (nonatomic, retain) IBOutlet UILabel* firstNameLabel; -@property (nonatomic, retain) IBOutlet UILabel* lastNameLabel; -@property (nonatomic, retain) IBOutlet UIImageView *avatarImage; +@property(nonatomic, strong) IBOutlet UILabel *nameLabel; +@property(nonatomic, strong) IBOutlet UIRoundedImageView *avatarImage; +@property(weak, nonatomic) IBOutlet UIImageView *linphoneImage; @property (nonatomic, assign) ABRecordRef contact; - (id)initWithIdentifier:(NSString*)identifier; diff --git a/Classes/LinphoneUI/UIContactCell.m b/Classes/LinphoneUI/UIContactCell.m index 5f3c595de..0fdd62a12 100644 --- a/Classes/LinphoneUI/UIContactCell.m +++ b/Classes/LinphoneUI/UIContactCell.m @@ -4,162 +4,84 @@ * * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ + */ #import "UIContactCell.h" #import "Utils.h" #import "FastAddressBook.h" +#import "UILabel+Boldify.h" @implementation UIContactCell -@synthesize firstNameLabel; -@synthesize lastNameLabel; -@synthesize avatarImage; -@synthesize contact; - - #pragma mark - Lifecycle Functions -- (id)initWithIdentifier:(NSString*)identifier { - if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) { - NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"UIContactCell" - owner:self - options:nil]; - - if ([arrayOfViews count] >= 1) { - [self.contentView addSubview:[arrayOfViews objectAtIndex:0] ]; - } - } - return self; -} +- (id)initWithIdentifier:(NSString *)identifier { + if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) { + NSArray *arrayOfViews = + [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; -- (void) dealloc { - [firstNameLabel release]; - [lastNameLabel release]; - [avatarImage release]; - - [super dealloc]; -} + // 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]; + // Sections are wider on iPad and overlap linphone image - let's move it a bit + if (IPAD) { + CGRect frame = _linphoneImage.frame; + frame.origin.x -= frame.size.width / 2; + _linphoneImage.frame = frame; + } + } + return self; +} #pragma mark - Property Functions - (void)setContact:(ABRecordRef)acontact { - contact = acontact; - [self update]; + _contact = acontact; + [ContactDisplay setDisplayNameLabel:_nameLabel forContact:_contact]; + _linphoneImage.hidden = !([FastAddressBook contactHasValidSipDomain:_contact]); } -#pragma mark - +#pragma mark - -- (void)touchUp:(id) sender { - [self setHighlighted:true animated:true]; +- (void)touchUp:(id)sender { + [self setHighlighted:true animated:true]; } -- (void)touchDown:(id) sender { - [self setHighlighted:false animated:true]; +- (void)touchDown:(id)sender { + [self setHighlighted:false animated:true]; } - (NSString *)accessibilityLabel { - return [NSString stringWithFormat:@"%@ %@", firstNameLabel.text, lastNameLabel.text]; + return _nameLabel.text; } -- (void)update { - if(contact == NULL) { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update contact cell: null contact"]; - return; - } - - CFStringRef lFirstName = ABRecordCopyValue(contact, kABPersonFirstNameProperty); - CFStringRef lLocalizedFirstName = (lFirstName != nil)?ABAddressBookCopyLocalizedLabel(lFirstName):nil; - CFStringRef lLastName = ABRecordCopyValue(contact, kABPersonLastNameProperty); - CFStringRef lLocalizedLastName = (lLastName != nil)?ABAddressBookCopyLocalizedLabel(lLastName):nil; - CFStringRef lOrganization = ABRecordCopyValue(contact, kABPersonOrganizationProperty); - CFStringRef lLocalizedOrganization = (lOrganization != nil)?ABAddressBookCopyLocalizedLabel(lOrganization):nil; - - if(lLocalizedFirstName != nil){ - [firstNameLabel setText: (NSString *)lLocalizedFirstName]; - } - else - [firstNameLabel setText: @""]; - - if(lLocalizedLastName != nil){ - [lastNameLabel setText: (NSString *)lLocalizedLastName]; - } - else - [lastNameLabel setText: @""]; - - if(lLocalizedFirstName == nil && lLocalizedLastName == nil) { - [firstNameLabel setText: (NSString *)lLocalizedOrganization]; - } - - if(lLocalizedOrganization != nil) - CFRelease(lLocalizedOrganization); - if(lOrganization != nil) - CFRelease(lOrganization); - if(lLocalizedLastName != nil) - CFRelease(lLocalizedLastName); - if(lLastName != nil) - CFRelease(lLastName); - if(lLocalizedFirstName != nil) - CFRelease(lLocalizedFirstName); - if(lFirstName != nil) - CFRelease(lFirstName); +- (void)setEditing:(BOOL)editing { + [self setEditing:editing animated:FALSE]; } -- (void)layoutSubviews { - [super layoutSubviews]; - // - // Adapt size - // - CGRect firstNameFrame = [firstNameLabel frame]; - CGRect lastNameFrame = [lastNameLabel frame]; - - // Compute firstName size - CGSize firstNameSize = [[firstNameLabel text] sizeWithFont:[firstNameLabel font]]; - CGSize lastNameSize = [[lastNameLabel text] sizeWithFont:[lastNameLabel font]]; - float sum = firstNameSize.width + 5 + lastNameSize.width; - float limit = self.bounds.size.width - 5 - firstNameFrame.origin.x; - if(sum >limit) { - firstNameSize.width *= limit/sum; - lastNameSize.width *= limit/sum; - } - - firstNameFrame.size.width = firstNameSize.width; - lastNameFrame.size.width = lastNameSize.width; - - // Compute lastName size & position - lastNameFrame.origin.x = firstNameFrame.origin.x + firstNameFrame.size.width; - if(firstNameFrame.size.width) - lastNameFrame.origin.x += 5; - - [firstNameLabel setFrame: firstNameFrame]; - [lastNameLabel setFrame: lastNameFrame]; -} - -- (void)setHighlighted:(BOOL)highlighted { - [self setHighlighted:highlighted animated:FALSE]; -} - -- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { - [super setHighlighted:highlighted animated:animated]; - if(highlighted) { - [lastNameLabel setTextColor:[UIColor whiteColor]]; - [firstNameLabel setTextColor:[UIColor whiteColor]]; - } else { - [lastNameLabel setTextColor:[UIColor blackColor]]; - [firstNameLabel setTextColor:[UIColor blackColor]]; - } +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + if (animated) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.3]; + } + _linphoneImage.alpha = editing ? 0 : 1; + if (animated) { + [UIView commitAnimations]; + } } @end diff --git a/Classes/LinphoneUI/UIContactDetailsCell.h b/Classes/LinphoneUI/UIContactDetailsCell.h new file mode 100644 index 000000000..e8192967e --- /dev/null +++ b/Classes/LinphoneUI/UIContactDetailsCell.h @@ -0,0 +1,41 @@ +/* UIEditableTableViewCell.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import + +#import "UIIconButton.h" + +@interface UIContactDetailsCell : UITableViewCell + +@property(weak, nonatomic) IBOutlet UIView *defaultView; +@property(weak, nonatomic) IBOutlet UILabel *addressLabel; +@property(weak, nonatomic) IBOutlet UITextField *editTextfield; +@property(weak, nonatomic) IBOutlet UIView *editView; +@property(weak, nonatomic) IBOutlet UIIconButton *deleteButton; +@property(weak, nonatomic) IBOutlet UIIconButton *callButton; +@property(weak, nonatomic) IBOutlet UIIconButton *chatButton; + +- (id)initWithIdentifier:(NSString *)identifier; +- (void)setAddress:(NSString *)address; +- (void)hideDeleteButton:(BOOL)hidden; + +- (IBAction)onCallClick:(id)sender; +- (IBAction)onChatClick:(id)sender; +- (IBAction)onDeleteClick:(id)sender; +@end diff --git a/Classes/LinphoneUI/UIContactDetailsCell.m b/Classes/LinphoneUI/UIContactDetailsCell.m new file mode 100644 index 000000000..2d301fdbd --- /dev/null +++ b/Classes/LinphoneUI/UIContactDetailsCell.m @@ -0,0 +1,111 @@ +/* UIEditableTableViewCell.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "UIContactDetailsCell.h" +#import "PhoneMainView.h" + +@implementation UIContactDetailsCell + +#pragma mark - Lifecycle Functions + +- (id)initWithIdentifier:(NSString *)identifier { + if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) { + NSArray *arrayOfViews = + [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + + // 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]; + } + return self; +} + +#pragma mark - UITableViewCell Functions + +- (void)setAddress:(NSString *)address { + _addressLabel.text = _editTextfield.text = address; + + LinphoneAddress *addr = linphone_core_interpret_url([LinphoneManager getLc], _addressLabel.text.UTF8String); + _chatButton.enabled = _callButton.enabled = (addr != NULL); + + _chatButton.accessibilityLabel = + [NSString stringWithFormat:NSLocalizedString(@"Chat with %@", nil), _addressLabel.text]; + _callButton.accessibilityLabel = [NSString stringWithFormat:NSLocalizedString(@"Call %@", nil), _addressLabel.text]; + if (addr) { + linphone_address_destroy(addr); + } +} + +- (void)hideDeleteButton:(BOOL)hidden { + CGRect newFrame = CGRectMake(8, 7, self.editView.frame.size.width - 16, self.editView.frame.size.height - 14); + if (!hidden) { + newFrame.size.width -= _deleteButton.frame.size.width; + } + _editTextfield.frame = newFrame; + _deleteButton.hidden = hidden; +} + +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + [super setEditing:editing animated:animated]; + + _defaultView.hidden = editing; + _editView.hidden = !editing; +} + +- (void)setEditing:(BOOL)editing { + [self setEditing:editing animated:FALSE]; +} + +- (IBAction)onCallClick:(id)event { + LinphoneAddress *addr = linphone_core_interpret_url([LinphoneManager getLc], _addressLabel.text.UTF8String); + if (addr == NULL) + return; + char *lAddress = linphone_address_as_string_uri_only(addr); + NSString *displayName = [FastAddressBook displayNameForAddress:addr]; + + DialerView *view = VIEW(DialerView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; + [view call:[NSString stringWithUTF8String:lAddress] displayName:displayName]; + ms_free(lAddress); + linphone_address_destroy(addr); +} + +- (IBAction)onChatClick:(id)event { + LinphoneAddress *addr = linphone_core_interpret_url([LinphoneManager getLc], _addressLabel.text.UTF8String); + if (addr == NULL) + return; + [PhoneMainView.instance changeCurrentView:ChatsListView.compositeViewDescription]; + ChatConversationView *view = VIEW(ChatConversationView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE]; + LinphoneChatRoom *room = linphone_core_get_chat_room([LinphoneManager getLc], addr); + [view setChatRoom:room]; + linphone_address_destroy(addr); +} + +- (IBAction)onDeleteClick:(id)sender { + UITableView *tableView = VIEW(ContactDetailsView).tableController.tableView; + NSIndexPath *indexPath = [tableView indexPathForCell:self]; + [tableView.dataSource tableView:tableView + commitEditingStyle:UITableViewCellEditingStyleDelete + forRowAtIndexPath:indexPath]; +} + +@end diff --git a/Classes/LinphoneUI/UIContactDetailsFooter.h b/Classes/LinphoneUI/UIContactDetailsFooter.h deleted file mode 100644 index 79496261f..000000000 --- a/Classes/LinphoneUI/UIContactDetailsFooter.h +++ /dev/null @@ -1,34 +0,0 @@ -/* UIContactDetailsFooter.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "ContactDetailsDelegate.h" - -@interface UIContactDetailsFooter : UIViewController { -} - -@property (nonatomic, retain) IBOutlet UIButton *removeButton; -@property (nonatomic, retain) IBOutlet id contactDetailsDelegate; - -- (IBAction)onRemoveClick:(id)event; - -+ (CGFloat)height:(BOOL)editing; - -@end diff --git a/Classes/LinphoneUI/UIContactDetailsFooter.m b/Classes/LinphoneUI/UIContactDetailsFooter.m deleted file mode 100644 index e681aac04..000000000 --- a/Classes/LinphoneUI/UIContactDetailsFooter.m +++ /dev/null @@ -1,83 +0,0 @@ -/* UIContactDetailsFooter.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UIContactDetailsFooter.h" - -@implementation UIContactDetailsFooter - -@synthesize removeButton; -@synthesize contactDetailsDelegate; - - -#pragma mark - Lifecycle Functions - -- (void)initUIContactDetailsFooter { -} - -- (id)init { - self = [super init]; - if(self != nil) { - [self initUIContactDetailsFooter]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if(self != nil) { - [self initUIContactDetailsFooter]; - } - return self; -} - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if(self != nil) { - [self initUIContactDetailsFooter]; - } - return self; -} - -- (void)dealloc { - [removeButton release]; - - [super dealloc]; -} - - -#pragma mark - Action Functions - -- (IBAction)onRemoveClick:(id)event { - if(contactDetailsDelegate != nil) { - [contactDetailsDelegate onRemove:event]; - } -} - - -#pragma mark - - -+ (CGFloat)height:(BOOL)editing { - if(editing) { - return 80.0f; - } else { - return 0.000001f; // Hack UITableView = 0 - } -} - -@end diff --git a/Classes/LinphoneUI/UIContactDetailsHeader.h b/Classes/LinphoneUI/UIContactDetailsHeader.h deleted file mode 100644 index e76058bad..000000000 --- a/Classes/LinphoneUI/UIContactDetailsHeader.h +++ /dev/null @@ -1,55 +0,0 @@ -/* UIContactDetailsHeader.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#import - -#import "ImagePickerViewController.h" -#import "ContactDetailsDelegate.h" - -@interface UIContactDetailsHeader : UIViewController { - @private - NSArray *propertyList; - BOOL editing; -} - -@property (nonatomic, assign) ABRecordRef contact; - -@property (nonatomic, retain) IBOutlet UILabel *addressLabel; -@property (nonatomic, retain) IBOutlet UIImageView *avatarImage; - -@property (nonatomic, retain) IBOutlet UIView *normalView; -@property (nonatomic, retain) IBOutlet UIView *editView; -@property (nonatomic, retain) IBOutlet UITableView *tableView; -@property (nonatomic, retain) IBOutlet id contactDetailsDelegate; - -@property (retain, nonatomic) ImagePickerViewController* popoverController; - -@property(nonatomic,getter=isEditing) BOOL editing; - -- (IBAction)onAvatarClick:(id)event; - -+ (CGFloat)height:(BOOL)editing; - -- (void)setEditing:(BOOL)editing animated:(BOOL)animated; -- (void)setEditing:(BOOL)editing; -- (BOOL)isEditing; -- (BOOL)isValid; - -@end diff --git a/Classes/LinphoneUI/UIContactDetailsHeader.m b/Classes/LinphoneUI/UIContactDetailsHeader.m deleted file mode 100644 index 376006b15..000000000 --- a/Classes/LinphoneUI/UIContactDetailsHeader.m +++ /dev/null @@ -1,385 +0,0 @@ -/* UIContactDetailsHeader.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UIContactDetailsHeader.h" -#import "Utils.h" -#import "UIEditableTableViewCell.h" -#import "FastAddressBook.h" -#import "UILinphone.h" -#import "PhoneMainView.h" -#import "DTActionSheet.h" - -#import - -@implementation UIContactDetailsHeader - -@synthesize avatarImage; -@synthesize addressLabel; -@synthesize contact; -@synthesize normalView; -@synthesize editView; -@synthesize tableView; -@synthesize contactDetailsDelegate; -@synthesize popoverController; - -#pragma mark - Lifecycle Functions - -- (void)initUIContactDetailsHeader { - propertyList = [[NSArray alloc] initWithObjects: - [NSNumber numberWithInt:kABPersonFirstNameProperty], - [NSNumber numberWithInt:kABPersonLastNameProperty], - [NSNumber numberWithInt:kABPersonOrganizationProperty], nil]; - editing = FALSE; -} - -- (id)init { - self = [super init]; - if(self != nil) { - [self initUIContactDetailsHeader]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if(self != nil) { - [self initUIContactDetailsHeader]; - } - return self; -} - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if(self != nil) { - [self initUIContactDetailsHeader]; - } - return self; -} - -- (void)dealloc { - [avatarImage release]; - [addressLabel release]; - [normalView release]; - [editView release]; - [tableView release]; - - [propertyList release]; - - [super dealloc]; -} - - -#pragma mark - ViewController Functions - -- (void)viewDidLoad { - [super viewDidLoad]; - [tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4 - [tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4 - [normalView setAlpha:1.0f]; - [editView setAlpha:0.0f]; - [tableView setEditing:TRUE animated:false]; - tableView.accessibilityIdentifier = @"Contact Name Table"; -} - - -#pragma mark - Propery Functions - -- (void)setContact:(ABRecordRef)acontact { - contact = acontact; - [self update]; -} - - -#pragma mark - - -- (BOOL)isValid { - for (int i = 0; i < [propertyList count]; ++i) { - UIEditableTableViewCell *cell = (UIEditableTableViewCell *)[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]]; - if([cell.detailTextField.text length] > 0) - return true; - } - return false; -} - -- (void)update { - if(contact == NULL) { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update contact details header: null contact"]; - return; - } - - // Avatar image - { - UIImage *image = [FastAddressBook getContactImage:contact thumbnail:false]; - if(image == nil) { - image = [UIImage imageNamed:@"avatar_unknown_small.png"]; - } - [avatarImage setImage:image]; - } - - // Contact label - { - [addressLabel setText:[FastAddressBook getContactDisplayName:contact]]; - } - - [tableView reloadData]; -} - -+ (CGFloat)height:(BOOL)editing { - if(editing) { - return 170.0f; - } else { - return 80.0f; - } -} - -- (void)setEditing:(BOOL)aediting animated:(BOOL)animated { - editing = aediting; - // Resign keyboard - if(!editing) { - [LinphoneUtils findAndResignFirstResponder:[self tableView]]; - [self update]; - } - if(animated) { - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:0.3]; - } - if(editing) { - [editView setAlpha:1.0f]; - [normalView setAlpha:0.0f]; - } else { - [editView setAlpha:0.0f]; - [normalView setAlpha:1.0f]; - } - if(animated) { - [UIView commitAnimations]; - } -} - -- (void)setEditing:(BOOL)aediting { - [self setEditing:aediting animated:FALSE]; -} - -- (BOOL)isEditing { - return editing; -} - -- (void)updateModification { - [contactDetailsDelegate onModification:nil]; -} - -+ (NSString*)localizeLabel:(NSString*)str { - CFStringRef lLocalizedLabel = ABAddressBookCopyLocalizedLabel((CFStringRef) str); - NSString * retStr = [NSString stringWithString:(NSString*) lLocalizedLabel]; - CFRelease(lLocalizedLabel); - return retStr; -} - -#pragma mark - UITableViewDataSource Functions - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return [propertyList count]; -} - -- (UITableViewCell *)tableView:(UITableView *)atableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - static NSString *kCellId = @"ContactDetailsHeaderCell"; - UIEditableTableViewCell *cell = [atableView dequeueReusableCellWithIdentifier:kCellId]; - if (cell == nil) { - cell = [[[UIEditableTableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:kCellId] autorelease]; - [cell.detailTextField setAutocapitalizationType:UITextAutocapitalizationTypeWords]; - [cell.detailTextField setAutocorrectionType:UITextAutocorrectionTypeNo]; - [cell.detailTextField setKeyboardType:UIKeyboardTypeDefault]; - [cell setBackgroundColor:[UIColor whiteColor]]; - } - - // setup placeholder - ABPropertyID property = [[propertyList objectAtIndex:[indexPath row]] intValue]; - if(property == kABPersonFirstNameProperty) { - [cell.detailTextField setPlaceholder:NSLocalizedString(@"First name", nil)]; - } else if (property == kABPersonLastNameProperty) { - [cell.detailTextField setPlaceholder:NSLocalizedString(@"Last name", nil)]; - } else if (property == kABPersonOrganizationProperty) { - [cell.detailTextField setPlaceholder:NSLocalizedString(@"Company name", nil)]; - } - - [cell.detailTextField setKeyboardType:UIKeyboardTypeDefault]; - - // setup values, if they exist - if(contact) { - CFStringRef lValue = ABRecordCopyValue(contact, property); - if(lValue != NULL) { - [cell.detailTextLabel setText:(NSString*)lValue]; - [cell.detailTextField setText:(NSString*)lValue]; - CFRelease(lValue); - } else { - [cell.detailTextLabel setText:@""]; - [cell.detailTextField setText:@""]; - } - } - [cell.detailTextField setDelegate:self]; - - return cell; -} - - -#pragma mark - Action Functions - -- (IBAction)onAvatarClick:(id)event { - if(self.isEditing) { - void (^showAppropriateController)(UIImagePickerControllerSourceType) = ^(UIImagePickerControllerSourceType type) { - UICompositeViewDescription *description = [ImagePickerViewController compositeViewDescription]; - ImagePickerViewController *controller; - if([LinphoneManager runningOnIpad]) { - controller = DYNAMIC_CAST([[PhoneMainView instance].mainViewController getCachedController:description.content], ImagePickerViewController); - // keep a reference to this controller so that in case of memory pressure we keep it - self.popoverController = controller; - } else { - controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:description push:TRUE], ImagePickerViewController); - } - if(controller != nil) { - controller.sourceType = type; - - // Displays a control that allows the user to choose picture or - // movie capture, if both are available: - controller.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage]; - - // Hides the controls for moving & scaling pictures, or for - // trimming movies. To instead show the controls, use YES. - controller.allowsEditing = NO; - controller.imagePickerDelegate = self; - - if([LinphoneManager runningOnIpad]) { - [controller.popoverController presentPopoverFromRect:[avatarImage frame] 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:^(){ - showAppropriateController(UIImagePickerControllerSourceTypeCamera); - }]; - } - if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { - [sheet addButtonWithTitle:NSLocalizedString(@"Photo library",nil) block:^(){ - showAppropriateController(UIImagePickerControllerSourceTypePhotoLibrary); - }]; - } - if([FastAddressBook getContactImage:contact thumbnail:true] != nil) { - [sheet addDestructiveButtonWithTitle:NSLocalizedString(@"Remove", nil) block:^(){ - NSError* error = NULL; - if(!ABPersonRemoveImageData(contact, (CFErrorRef*)error)) { - [LinphoneLogger log:LinphoneLoggerLog format:@"Can't remove entry: %@", [error localizedDescription]]; - } - [self update]; - }]; - } - [sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel",nil) block:^{ - self.popoverController = nil; - }]; - - [sheet showInView:[PhoneMainView instance].view]; - } -} - - -#pragma mark - ContactDetailsImagePickerDelegate Functions - -- (void)imagePickerDelegateImage:(UIImage*)image info:(NSDictionary *)info{ - // Dismiss popover on iPad - if([LinphoneManager runningOnIpad]) { - UICompositeViewDescription *description = [ImagePickerViewController compositeViewDescription]; - ImagePickerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance].mainViewController getCachedController:description.content], ImagePickerViewController); - if(controller != nil) { - [controller.popoverController dismissPopoverAnimated:TRUE]; - self.popoverController = nil; - } - } - FastAddressBook* fab = [LinphoneManager instance].fastAddressBook; - NSError* error = NULL; - if(!ABPersonRemoveImageData(contact, (CFErrorRef*)error)) { - [LinphoneLogger log:LinphoneLoggerLog format:@"Can't remove entry: %@", [error localizedDescription]]; - } - NSData *dataRef = UIImageJPEGRepresentation(image, 0.9f); - CFDataRef cfdata = CFDataCreate(NULL,[dataRef bytes], [dataRef length]); - - [fab saveAddressBook]; - - if(!ABPersonSetImageData(contact, cfdata, (CFErrorRef*)error)) { - [LinphoneLogger log:LinphoneLoggerLog format:@"Can't add entry: %@", [error localizedDescription]]; - } else { - [fab saveAddressBook]; - } - - CFRelease(cfdata); - - [self update]; -} - - -#pragma mark - UITableViewDelegate Functions - -- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { - return UITableViewCellEditingStyleNone; -} - - -#pragma mark - UITextFieldDelegate Functions - -- (BOOL)textFieldShouldReturn:(UITextField *)textField { - [textField resignFirstResponder]; - return YES; -} - -- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { - if(contactDetailsDelegate != nil) { - //add a mini delay to have the text updated BEFORE notifying the selector - [self performSelector:@selector(updateModification) withObject:nil afterDelay:0.1]; - } - return YES; -} - -- (BOOL)textFieldShouldEndEditing:(UITextField *)textField { - UIView *view = [textField superview]; - // Find TableViewCell - while(view != nil && ![view isKindOfClass:[UIEditableTableViewCell class]]) view = [view superview]; - - if(view != nil) { - UIEditableTableViewCell *cell = (UIEditableTableViewCell*)view; - NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; - ABPropertyID property = [[propertyList objectAtIndex:[indexPath row]] intValue]; - [cell.detailTextLabel setText:[textField text]]; - NSError* error = NULL; - ABRecordSetValue(contact, property, [textField text], (CFErrorRef*)&error); - if (error != NULL) { - [LinphoneLogger log:LinphoneLoggerError format:@"Error when saving property %i in contact %p: Fail(%@)", property, contact, [error localizedDescription]]; - } - } else { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Not valid UIEditableTableViewCell"]; - } - if(contactDetailsDelegate != nil) { - //add a mini delay to have the text updated BEFORE notifying the selector - [self performSelector:@selector(updateModification) withObject:nil afterDelay:0.1]; - } - return TRUE; -} - -@end diff --git a/Classes/LinphoneUI/UIDigitButton.h b/Classes/LinphoneUI/UIDigitButton.h index b680bab2c..8bfb2b923 100644 --- a/Classes/LinphoneUI/UIDigitButton.h +++ b/Classes/LinphoneUI/UIDigitButton.h @@ -19,13 +19,12 @@ #import -#import "UILongTouchButton.h" +#import "UIIconButton.h" - -@interface UIDigitButton : UILongTouchButton { +@interface UIDigitButton : UIIconButton { } -@property (nonatomic, retain) IBOutlet UITextField* addressField; +@property(nonatomic, strong) IBOutlet UITextField *addressField; @property char digit; @property bool dtmf; diff --git a/Classes/LinphoneUI/UIDigitButton.m b/Classes/LinphoneUI/UIDigitButton.m index 9f2f59127..700b15faa 100644 --- a/Classes/LinphoneUI/UIDigitButton.m +++ b/Classes/LinphoneUI/UIDigitButton.m @@ -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 "UIDigitButton.h" #include "linphone/linphonecore.h" @@ -27,59 +27,54 @@ @synthesize digit; @synthesize addressField; - #pragma mark - Lifecycle Functions - (void)initUIDigitButton { - dtmf = FALSE; + dtmf = FALSE; [self addTarget:self action:@selector(touchDown:) forControlEvents:UIControlEventTouchDown]; - [self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside|UIControlEventTouchUpOutside]; + [self addTarget:self + action:@selector(touchUp:) + forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside]; } - (id)init { - self = [super init]; - if (self) { + self = [super init]; + if (self) { [self initUIDigitButton]; - } - return self; + } + return self; } - (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { + self = [super initWithFrame:frame]; + if (self) { [self initUIDigitButton]; - } - return self; + } + return self; } - (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { + self = [super initWithCoder:decoder]; + if (self) { [self initUIDigitButton]; } - return self; -} - -- (void)dealloc { - [addressField release]; - [super dealloc]; + return self; } - #pragma mark - Actions Functions -- (void)touchDown:(id) sender { - if (addressField && (!dtmf || !linphone_core_in_call([LinphoneManager getLc]))) { - NSString* newAddress = [NSString stringWithFormat:@"%@%c",addressField.text, digit]; +- (void)touchDown:(id)sender { + 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); } else { - linphone_core_send_dtmf([LinphoneManager getLc], digit); + linphone_call_send_dtmf(linphone_core_get_current_call([LinphoneManager getLc]), digit); linphone_core_play_dtmf([LinphoneManager getLc], digit, 100); } } -- (void)touchUp:(id) sender { +- (void)touchUp:(id)sender { linphone_core_stop_dtmf([LinphoneManager getLc]); } diff --git a/Classes/LinphoneUI/UIDigitButtonLongVoiceMail.m b/Classes/LinphoneUI/UIDigitButtonLongVoiceMail.m deleted file mode 100644 index ad1838bd2..000000000 --- a/Classes/LinphoneUI/UIDigitButtonLongVoiceMail.m +++ /dev/null @@ -1,55 +0,0 @@ -/* UIDigitButton.m - * - * Copyright (C) 2011 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU 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 "UIDigitButtonLongVoiceMail.h" -#import "Utils.h" -#include "LinphoneManager.h" - -@implementation UIDigitButtonLongVoiceMail - -#pragma mark - UILongTouchButtonDelegate Functions - -- (void)onRepeatTouch { -} - -- (void)onLongTouch { - 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 diff --git a/Classes/LinphoneUI/UIEditableTableViewCell.h b/Classes/LinphoneUI/UIEditableTableViewCell.h deleted file mode 100644 index c75b046c8..000000000 --- a/Classes/LinphoneUI/UIEditableTableViewCell.h +++ /dev/null @@ -1,29 +0,0 @@ -/* UIEditableTableViewCell.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#import "UITransparentTVCell.h" - -@interface UIEditableTableViewCell : UITransparentTVCell { -} - -@property (nonatomic, retain) IBOutlet UIView *verticalSep; -@property (nonatomic, retain) IBOutlet UITextField *detailTextField; - -@end diff --git a/Classes/LinphoneUI/UIEditableTableViewCell.m b/Classes/LinphoneUI/UIEditableTableViewCell.m deleted file mode 100644 index 0d450c642..000000000 --- a/Classes/LinphoneUI/UIEditableTableViewCell.m +++ /dev/null @@ -1,120 +0,0 @@ -/* UIEditableTableViewCell.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UIEditableTableViewCell.h" - -@implementation UIEditableTableViewCell - -@synthesize detailTextField; -@synthesize verticalSep; - - -#pragma mark - Lifecycle Functions - -- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier -{ - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - if (self) { - UITextField* tf = [[UITextField alloc] init]; - [tf setHidden:TRUE]; - [tf setClearButtonMode: UITextFieldViewModeWhileEditing]; - [tf setContentVerticalAlignment: UIControlContentVerticalAlignmentCenter]; - self.detailTextField = tf; - - UIFont *font = [UIFont fontWithName:@"Helvetica-Bold" size:[UIFont systemFontSize]]; - [self.detailTextLabel setFont:font]; - [self.detailTextField setFont:font]; - [self.contentView addSubview:detailTextField]; - - // a vertical separator that will come between the text and detailed text - UIView* v = [[UIView alloc] initWithFrame:CGRectMake(80, 5, 1, 34)]; - [v setBackgroundColor:[UIColor lightGrayColor]]; - [v setHidden:TRUE]; - - self.verticalSep = v; - - [self.contentView addSubview:verticalSep]; - - [tf release]; - [v release]; - } - return self; -} - -- (void)dealloc { - self.detailTextField = nil; - [super dealloc]; -} - - -#pragma mark - View Functions - -- (void)layoutSubviews { - [super layoutSubviews]; - - CGRect detailEditFrame; - detailEditFrame.origin.x = 15; - detailEditFrame.origin.y = 0; - detailEditFrame.size.height = 44; - - if([[self.textLabel text] length] != 0) { - detailEditFrame.origin.x += [self.textLabel frame].size.width + 8; - - // shrink left text width by 10px - CGRect leftLabelFrame = [self.textLabel frame]; - leftLabelFrame.size.width -= 10; - [self.textLabel setFrame:leftLabelFrame]; - - // place separator between left text and detailed text - CGRect separatorFrame = [self.verticalSep frame]; - separatorFrame.origin.x = leftLabelFrame.size.width + leftLabelFrame.origin.x + 5; - [self.verticalSep setFrame:separatorFrame]; - [self.verticalSep setHidden:FALSE]; - } - - // put the detailed text edit view at the correct position - CGRect superframe = [[self.detailTextField superview] frame]; - detailEditFrame.size.width = superframe.size.width - detailEditFrame.origin.x; - [self.detailTextField setFrame:detailEditFrame]; -} - - -#pragma mark - UITableViewCell Functions - -- (void)setEditing:(BOOL)editing animated:(BOOL)animated { - [super setEditing:editing animated:animated]; - if(editing) { - [self.detailTextField setHidden:FALSE]; - [self.detailTextLabel setHidden:TRUE]; - } else { - [self.detailTextField setHidden:TRUE]; - [self.detailTextLabel setHidden:FALSE]; - } -} - -- (void)setEditing:(BOOL)editing { - [self setEditing:editing animated:FALSE]; -} - -- (void)setSelected:(BOOL)selected animated:(BOOL)animated -{ - [super setSelected:selected animated:animated]; -} - -@end diff --git a/Classes/LinphoneUI/UIEraseButton.h b/Classes/LinphoneUI/UIEraseButton.h deleted file mode 100644 index 7baced2e6..000000000 --- a/Classes/LinphoneUI/UIEraseButton.h +++ /dev/null @@ -1,29 +0,0 @@ -/* UIEraseButton.h - * - * Copyright (C) 2011 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UILongTouchButton.h" - -@interface UIEraseButton : UILongTouchButton { -} - -@property (nonatomic, retain) IBOutlet UITextField* addressField; - -@end diff --git a/Classes/LinphoneUI/UIEraseButton.m b/Classes/LinphoneUI/UIEraseButton.m deleted file mode 100644 index d271a2727..000000000 --- a/Classes/LinphoneUI/UIEraseButton.m +++ /dev/null @@ -1,82 +0,0 @@ -/* UIEraseButton.m - * - * Copyright (C) 2011 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU 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 "UIEraseButton.h" - - -@implementation UIEraseButton - -@synthesize addressField; - - -#pragma mark - Lifecycle Functions - -- (void)initUIEraseButton { - [self addTarget:self action:@selector(touchDown:) forControlEvents:UIControlEventTouchDown]; -} - -- (id)init { - self = [super init]; - if (self) { - [self initUIEraseButton]; - } - return self; -} - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - [self initUIEraseButton]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { - [self initUIEraseButton]; - } - return self; -} - -- (void)dealloc { - [super dealloc]; - [addressField release]; -} - - -#pragma mark - Action Functions - --(void) touchDown:(id) sender { - if ([addressField.text length] > 0) { - [addressField setText:[addressField.text substringToIndex:[addressField.text length]-1]]; - } -} - - -#pragma mark - UILongTouchButtonDelegate Functions - -- (void)onRepeatTouch { -} - -- (void)onLongTouch { - [addressField setText:@""]; -} - -@end diff --git a/Classes/LinphoneUI/UIHangUpButton.h b/Classes/LinphoneUI/UIHangUpButton.h index 596a81213..0be37a753 100644 --- a/Classes/LinphoneUI/UIHangUpButton.h +++ b/Classes/LinphoneUI/UIHangUpButton.h @@ -19,8 +19,9 @@ #import -@interface UIHangUpButton : UIButton { +#import "UIIconButton.h" +@interface UIHangUpButton : UIIconButton { } - (void)update; diff --git a/Classes/LinphoneUI/UIHangUpButton.m b/Classes/LinphoneUI/UIHangUpButton.m index 899df975c..47e4b2c3b 100644 --- a/Classes/LinphoneUI/UIHangUpButton.m +++ b/Classes/LinphoneUI/UIHangUpButton.m @@ -4,116 +4,107 @@ * * 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 "UIHangUpButton.h" #import "LinphoneManager.h" - @implementation UIHangUpButton - #pragma mark - Static Functions -+ (bool)isInConference:(LinphoneCall*) call { - if (!call) - return false; - return linphone_call_is_in_conference(call); ++ (bool)isInConference:(LinphoneCall *)call { + if (!call) + return false; + return linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call)); } -+ (int)callCount:(LinphoneCore*) lc { - int count = 0; - const MSList* calls = linphone_core_get_calls(lc); - - while (calls != 0) { - if (![UIHangUpButton isInConference:((LinphoneCall*)calls->data)]) { - count++; - } - calls = calls->next; - } - return count; -} ++ (int)callCount:(LinphoneCore *)lc { + int count = 0; + const MSList *calls = linphone_core_get_calls(lc); + while (calls != 0) { + if (![UIHangUpButton isInConference:((LinphoneCall *)calls->data)]) { + count++; + } + calls = calls->next; + } + return count; +} #pragma mark - Lifecycle Functions - (void)initUIHangUpButton { - [self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside]; + [self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside]; } -- (id)init{ - self = [super init]; - if (self) { +- (id)init { + self = [super init]; + if (self) { [self initUIHangUpButton]; - } - return self; + } + return self; } - (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { + self = [super initWithCoder:decoder]; + if (self) { [self initUIHangUpButton]; } - return self; -} + return self; +} - (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { + self = [super initWithFrame:frame]; + if (self) { [self initUIHangUpButton]; - } - return self; + } + return self; } -- (void)dealloc { - [super dealloc]; -} - - -#pragma mark - +#pragma mark - - (void)update { - 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]; + 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]; } - #pragma mark - Action Functions --(void) touchUp:(id) sender { - 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)); - } - } +- (void)touchUp:(id)sender { + 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)); + } + } } @end diff --git a/Classes/LinphoneUI/UIHistoryCell.h b/Classes/LinphoneUI/UIHistoryCell.h index 85e619235..8cba9e8da 100644 --- a/Classes/LinphoneUI/UIHistoryCell.h +++ b/Classes/LinphoneUI/UIHistoryCell.h @@ -19,22 +19,22 @@ #import -#import "UITransparentTVCell.h" +#import "UIRoundedImageView.h" +#import "UIIconButton.h" + #include "linphone/linphonecore.h" -@interface UIHistoryCell : UITransparentTVCell { -} +@interface UIHistoryCell : UITableViewCell @property (nonatomic, assign) LinphoneCallLog *callLog; -@property (nonatomic, retain) IBOutlet UIImageView* imageView; -@property (nonatomic, retain) IBOutlet UILabel* addressLabel; -@property (nonatomic, retain) IBOutlet UIButton* detailsButton; -@property (nonatomic, retain) IBOutlet UIButton* deleteButton; +@property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage; +@property(nonatomic, strong) IBOutlet UILabel *displayNameLabel; +@property(weak, nonatomic) IBOutlet UIImageView *stateImage; +@property(weak, nonatomic) IBOutlet UIIconButton *detailsButton; - (id)initWithIdentifier:(NSString*)identifier; -- (IBAction)onDetails:(id) event; -- (IBAction)onDelete:(id) event; +- (IBAction)onDetails:(id)event; @end diff --git a/Classes/LinphoneUI/UIHistoryCell.m b/Classes/LinphoneUI/UIHistoryCell.m index 2f9b9d82d..f34708b5b 100644 --- a/Classes/LinphoneUI/UIHistoryCell.m +++ b/Classes/LinphoneUI/UIHistoryCell.m @@ -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 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 + * 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 "UIHistoryCell.h" #import "LinphoneManager.h" @@ -25,158 +25,104 @@ @implementation UIHistoryCell @synthesize callLog; -@synthesize addressLabel; -@synthesize imageView; -@synthesize deleteButton; -@synthesize detailsButton; +@synthesize displayNameLabel; #pragma mark - Lifecycle Functions -- (id)initWithIdentifier:(NSString*)identifier { - if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) { - NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"UIHistoryCell" - owner:self - options:nil]; - - if ([arrayOfViews count] >= 1) { - [self.contentView addSubview:[arrayOfViews objectAtIndex:0]]; - } - - self->callLog = NULL; - } - return self; -} +- (id)initWithIdentifier:(NSString *)identifier { + if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) { + NSArray *arrayOfViews = + [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; -- (void) dealloc { - [detailsButton release]; - [deleteButton release]; - [addressLabel release]; - [imageView release]; - - [super dealloc]; + // 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]; + _detailsButton.hidden = IPAD; + callLog = NULL; + } + return self; } - #pragma mark - Action Functions - (void)setCallLog:(LinphoneCallLog *)acallLog { - callLog = acallLog; - [self update]; -} + callLog = acallLog; + [self update]; +} #pragma mark - Action Functions -- (IBAction)onDetails:(id) event { - if(callLog != NULL && linphone_call_log_get_call_id(callLog) != NULL) { - // Go to History details view - HistoryDetailsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[HistoryDetailsViewController compositeViewDescription] push:TRUE], HistoryDetailsViewController); - if(controller != nil) { - [controller setCallLogId: [NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)]]; - } - } +- (IBAction)onDetails:(id)event { + if (callLog != NULL && linphone_call_log_get_call_id(callLog) != NULL) { + // Go to History details view + HistoryDetailsView *view = VIEW(HistoryDetailsView); + [view setCallLogId:[NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)]]; + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE]; + } } -- (IBAction)onDelete:(id)event { - if(callLog != NULL) { - UIView *view = [self superview]; - // Find TableViewCell - while(view != nil && ![view isKindOfClass:[UITableView class]]) view = [view superview]; - if(view != nil) { - UITableView *tableView = (UITableView*) view; - NSIndexPath *indexPath = [tableView indexPathForCell:self]; - [[tableView dataSource] tableView:tableView commitEditingStyle:UITableViewCellEditingStyleDelete forRowAtIndexPath:indexPath]; - } - } -} - - -#pragma mark - +#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]; + BOOL incoming = linphone_call_log_get_dir(callLog) == LinphoneCallIncoming; + BOOL missed = linphone_call_log_get_status(callLog) == LinphoneCallMissed; + NSString *call_type = incoming ? (missed ? @"Missed" : @"Incoming") : @"Outgoing"; + return [NSString stringWithFormat:@"%@ call from %@", call_type, displayNameLabel.text]; } - (void)update { - if(callLog == NULL) { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update history cell: null callLog"]; - return; - } - - // Set up the cell... - LinphoneAddress* addr; + if (callLog == NULL) { + LOGW(@"Cannot update history cell: null callLog"); + return; + } + + // Set up the cell... + const LinphoneAddress *addr; UIImage *image; if (linphone_call_log_get_dir(callLog) == LinphoneCallIncoming) { - if (linphone_call_log_get_status(callLog) != LinphoneCallMissed) { - image = [UIImage imageNamed:@"call_status_incoming.png"]; - } else { - image = [UIImage imageNamed:@"call_status_missed.png"]; - } - addr = linphone_call_log_get_from(callLog); + if (linphone_call_log_get_status(callLog) != LinphoneCallMissed) { + image = [UIImage imageNamed:@"call_status_incoming.png"]; + } else { + image = [UIImage imageNamed:@"call_status_missed.png"]; + } + addr = linphone_call_log_get_from_address(callLog); } else { image = [UIImage imageNamed:@"call_status_outgoing.png"]; - addr = linphone_call_log_get_to(callLog); + addr = linphone_call_log_get_to_address(callLog); } - - NSString* address = nil; - if(addr != NULL) { - BOOL useLinphoneAddress = true; - // contact name - char* lAddress = linphone_address_as_string_uri_only(addr); - if(lAddress) { - NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:lAddress]]; - ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress]; - if(contact) { - address = [FastAddressBook getContactDisplayName:contact]; - useLinphoneAddress = false; - } - ms_free(lAddress); - } - if(useLinphoneAddress) { - const char* lDisplayName = linphone_address_get_display_name(addr); - const char* lUserName = linphone_address_get_username(addr); - if (lDisplayName) - address = [NSString stringWithUTF8String:lDisplayName]; - else if(lUserName) - address = [NSString stringWithUTF8String:lUserName]; - } - } - if(address == nil) { - address = NSLocalizedString(@"Unknown", nil); - } + _stateImage.image = image; - [addressLabel setText:address]; - [imageView setImage: image]; + [ContactDisplay setDisplayNameLabel:displayNameLabel forAddress:addr]; + + int count = ms_list_size(linphone_call_log_get_user_data(callLog)) + 1; + if (count > 1) { + displayNameLabel.text = + [displayNameLabel.text stringByAppendingString:[NSString stringWithFormat:@" (%d)", count]]; + } + + [_avatarImage setImage:[FastAddressBook imageForAddress:addr thumbnail:YES] bordered:NO withRoundedRadius:YES]; } - (void)setEditing:(BOOL)editing { - [self setEditing:editing animated:FALSE]; + [self setEditing:editing animated:FALSE]; } - (void)setEditing:(BOOL)editing animated:(BOOL)animated { - if(animated) { - [UIView beginAnimations:nil context:nil]; - [UIView setAnimationDuration:0.3]; - } - if(editing) { - [deleteButton setAlpha:1.0f]; - [detailsButton setAlpha:0.0f]; - } else { - [detailsButton setAlpha:1.0f]; - [deleteButton setAlpha:0.0f]; - } - if(animated) { - [UIView commitAnimations]; - } + if (animated) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.3]; + } + if (editing) { + [_detailsButton setAlpha:0.0f]; + } else { + [_detailsButton setAlpha:1.0f]; + } + if (animated) { + [UIView commitAnimations]; + } } @end diff --git a/Classes/LinphoneUI/UIIconButton.h b/Classes/LinphoneUI/UIIconButton.h new file mode 100644 index 000000000..641d06ad0 --- /dev/null +++ b/Classes/LinphoneUI/UIIconButton.h @@ -0,0 +1,13 @@ +// +// UIIconButton.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 22/07/15. +// +// + +#import + +@interface UIIconButton : UIButton + +@end diff --git a/Classes/LinphoneUI/UIIconButton.m b/Classes/LinphoneUI/UIIconButton.m new file mode 100644 index 000000000..b10a24947 --- /dev/null +++ b/Classes/LinphoneUI/UIIconButton.m @@ -0,0 +1,48 @@ +// +// UIIconButton.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 22/07/15. +// +// + +#import "UIIconButton.h" + +#import "Utils.h" + +@implementation UIIconButton + +- (id)fixBackgroundImageForState { + + [super setImage:[self imageForState:UIControlStateSelected] + forState:(UIControlStateHighlighted | UIControlStateSelected)]; + [super setImage:[self imageForState:UIControlStateDisabled] + forState:(UIControlStateDisabled | UIControlStateSelected)]; + + [self setBackgroundImage:[self backgroundImageForState:UIControlStateHighlighted] + forState:(UIControlStateHighlighted | UIControlStateSelected)]; + [self setBackgroundImage:[self backgroundImageForState:UIControlStateDisabled] + forState:(UIControlStateDisabled | UIControlStateSelected)]; + [LinphoneUtils buttonFixStates:self]; + [self.titleLabel setAdjustsFontSizeToFitWidth:TRUE]; + + return self; +} + +- (id)init { + return [[super init] fixBackgroundImageForState]; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + return [[super initWithCoder:aDecoder] fixBackgroundImageForState]; +} + +- (id)initWithFrame:(CGRect)frame { + return [[super initWithFrame:frame] fixBackgroundImageForState]; +} + +- (void)setImage:(UIImage *)image forState:(UIControlState)state { + [super setImage:image forState:state]; + [self fixBackgroundImageForState]; +} +@end diff --git a/Classes/LinphoneUI/UILabel+Boldify.h b/Classes/LinphoneUI/UILabel+Boldify.h new file mode 100644 index 000000000..53a06eb84 --- /dev/null +++ b/Classes/LinphoneUI/UILabel+Boldify.h @@ -0,0 +1,17 @@ +// +// UILabel+Boldify.h +// linphone +// +// Created by guillaume on 20/05/2015. +// Copyright (c) 2015 Urmet. All rights reserved. +// + +#import +#import + +@interface UILabel (Boldify) + +- (void)boldSubstring:(NSString *)substring; +- (void)boldRange:(NSRange)range; + +@end diff --git a/Classes/LinphoneUI/UILabel+Boldify.m b/Classes/LinphoneUI/UILabel+Boldify.m new file mode 100644 index 000000000..2980bac61 --- /dev/null +++ b/Classes/LinphoneUI/UILabel+Boldify.m @@ -0,0 +1,31 @@ +// +// UILabel+Boldify.m +// linphone +// +// Created by guillaume on 20/05/2015. +// +// + +#import "UILabel+Boldify.h" + +@implementation UILabel (Boldify) + +- (void)boldRange:(NSRange)range { + if (![self respondsToSelector:@selector(setAttributedText:)]) { + return; + } + NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:self.text]; + [attributedText setAttributes:@{ + NSFontAttributeName : [UIFont boldSystemFontOfSize:self.font.pointSize] + } + range:range]; + + self.attributedText = attributedText; +} + +- (void)boldSubstring:(NSString *)substring { + NSRange range = [self.text rangeOfString:substring]; + [self boldRange:range]; +} + +@end diff --git a/Classes/LinphoneUI/UILinphone.h b/Classes/LinphoneUI/UILinphone.h deleted file mode 100644 index 5b3d50d5b..000000000 --- a/Classes/LinphoneUI/UILinphone.h +++ /dev/null @@ -1,43 +0,0 @@ -/* UILinphone.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#define LINPHONE_MAIN_COLOR [UIColor colorWithRed:207.0f/255.0f green:76.0f/255.0f blue:41.0f/255.0f alpha:1.0f] -#define LINPHONE_SETTINGS_BG_IOS7 [UIColor colorWithRed:164/255. green:175/255. blue:183/255. alpha:1.0]//[UIColor colorWithWhite:0.88 alpha:1.0] -#define LINPHONE_TABLE_CELL_BACKGROUND_COLOR [UIColor colorWithRed:207.0f/255.0f green:76.0f/255.0f blue:41.0f/255.0f alpha:1.0f] - -@interface UIColor (LightAndDark) - -- (UIColor *)adjustHue:(float)hm saturation:(float)sm brightness:(float)bm alpha:(float)am; - -- (UIColor *)lumColor:(float)mult; - -- (UIColor *)lighterColor; - -- (UIColor *)darkerColor; - -@end - - -@interface UIImage (ForceDecode) - -+ (UIImage *)decodedImageWithImage:(UIImage *)image; - -@end diff --git a/Classes/LinphoneUI/UILinphone.m b/Classes/LinphoneUI/UILinphone.m deleted file mode 100644 index edc2d5b51..000000000 --- a/Classes/LinphoneUI/UILinphone.m +++ /dev/null @@ -1,128 +0,0 @@ -/* UILinphone.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UILinphone.h" -#import "ColorSpaceUtilities.h" -#import "Utils.h" - -#import - -@implementation UIColor (LightAndDark) - -- (UIColor *)lumColor:(float)mult { - float hsbH, hsbS, hsbB; - float rgbaR, rgbaG, rgbaB, rgbaA; - - // Get RGB - CGColorRef cgColor = [self CGColor]; - CGColorSpaceRef cgColorSpace = CGColorGetColorSpace(cgColor); - if(CGColorSpaceGetModel(cgColorSpace) != kCGColorSpaceModelRGB) { - [LinphoneLogger log:LinphoneLoggerWarning format:@"Can't convert not RGB color"]; - return self; - } else { - const CGFloat *colors = CGColorGetComponents(cgColor); - rgbaR = colors[0]; - rgbaG = colors[1]; - rgbaB = colors[2]; - rgbaA = CGColorGetAlpha(cgColor); - } - - RGB2HSL(rgbaR, rgbaG, rgbaB, &hsbH, &hsbS, &hsbB); - - hsbB = MIN(MAX(hsbB * mult, 0.0), 1.0); - - HSL2RGB(hsbH, hsbS, hsbB, &rgbaR, &rgbaG, &rgbaB); - - return [UIColor colorWithRed:rgbaR green:rgbaG blue:rgbaB alpha:rgbaA]; -} - -- (UIColor *)adjustHue:(float)hm saturation:(float)sm brightness:(float)bm alpha:(float)am { - float hsbH, hsbS, hsbB; - float rgbaR, rgbaG, rgbaB, rgbaA; - - - // Get RGB - CGColorRef cgColor = [self CGColor]; - CGColorSpaceRef cgColorSpace = CGColorGetColorSpace(cgColor); - if(CGColorSpaceGetModel(cgColorSpace) != kCGColorSpaceModelRGB) { - [LinphoneLogger log:LinphoneLoggerWarning format:@"Can't convert not RGB color"]; - return self; - } else { - const CGFloat *colors = CGColorGetComponents(cgColor); - rgbaR = colors[0]; - rgbaG = colors[1]; - rgbaB = colors[2]; - rgbaA = CGColorGetAlpha(cgColor); - } - - RGB2HSL(rgbaR, rgbaG, rgbaB, &hsbH, &hsbS, &hsbB); - - hsbH = MIN(MAX(hsbH + hm, 0.0), 1.0); - hsbS = MIN(MAX(hsbS + sm, 0.0), 1.0); - hsbB = MIN(MAX(hsbB + bm, 0.0), 1.0); - rgbaA = MIN(MAX(rgbaA + am, 0.0), 1.0); - - HSL2RGB(hsbH, hsbS, hsbB, &rgbaR, &rgbaG, &rgbaB); - - return [UIColor colorWithRed:rgbaR green:rgbaG blue:rgbaB alpha:rgbaA]; -} - -- (UIColor *)lighterColor { - return [self lumColor:1.3]; -} - -- (UIColor *)darkerColor { - return [self lumColor:0.75]; -} - -@end - -@implementation UIImage (ForceDecode) - -+ (UIImage *)decodedImageWithImage:(UIImage *)image -{ - CGImageRef imageRef = image.CGImage; - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGContextRef context = CGBitmapContextCreate(NULL, - CGImageGetWidth(imageRef), - CGImageGetHeight(imageRef), - 8, - // Just always return width * 4 will be enough - CGImageGetWidth(imageRef) * 4, - // System only supports RGB, set explicitly - colorSpace, - // Makes system don't need to do extra conversion when displayed. - // NOTE: here we remove the alpha channel for performance. Most of the time, images loaded - // from the network are jpeg with no alpha channel. As a TODO, finding a way to detect - // if alpha channel is necessary would be nice. - kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Little); - CGColorSpaceRelease(colorSpace); - if (!context) return nil; - - CGRect rect = (CGRect){CGPointZero,{CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)}}; - CGContextDrawImage(context, rect, imageRef); - CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context); - CGContextRelease(context); - - UIImage *decompressedImage = [[UIImage alloc] initWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation]; - CGImageRelease(decompressedImageRef); - return [decompressedImage autorelease]; -} - -@end diff --git a/Classes/LinphoneUI/UILinphoneButton.m b/Classes/LinphoneUI/UILinphoneButton.m deleted file mode 100644 index 530044db1..000000000 --- a/Classes/LinphoneUI/UILinphoneButton.m +++ /dev/null @@ -1,78 +0,0 @@ -/* UILinphoneButton.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#import "UILinphoneButton.h" - -@implementation UILinphoneButton - -@synthesize backgroundNinePatch; -@synthesize backgroundOverNinePatch; - - -#pragma mark - Lifecycle Functions - -- (void)initUILinphoneButton { - self.backgroundNinePatch = [TUNinePatch ninePatchNamed:@"button_background_default"]; - self.backgroundOverNinePatch = [TUNinePatch ninePatchNamed:@"button_background_over"]; - [self setBackgroundImage:nil forState:UIControlStateNormal]; - [self setBackgroundImage:nil forState:UIControlStateHighlighted]; - [self setContentMode:UIViewContentModeRedraw]; -} - -- (id)init { - self = [super init]; - if(self != nil) { - [self initUILinphoneButton]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if(self != nil) { - [self initUILinphoneButton]; - } - return self; -} - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if(self != nil) { - [self initUILinphoneButton]; - } - return self; -} - -- (void)setHighlighted:(BOOL)highlighted { - [super setHighlighted:highlighted]; - [self setNeedsDisplay]; -} - -- (void)drawRect:(CGRect)rect { - // we ignore the rect and redraw the entire view - CGContextRef context = UIGraphicsGetCurrentContext(); - if (context) { - if(self.highlighted) { - [self.backgroundOverNinePatch inContext:context drawInRect:[self bounds]]; - } else { - [self.backgroundNinePatch inContext:context drawInRect:[self bounds]]; - } - } -} - -@end diff --git a/Classes/LinphoneUI/UILinphoneTextField.m b/Classes/LinphoneUI/UILinphoneTextField.m deleted file mode 100644 index 8eaf12fc4..000000000 --- a/Classes/LinphoneUI/UILinphoneTextField.m +++ /dev/null @@ -1,85 +0,0 @@ -/* UILinphoneTextField.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UILinphoneTextField.h" - -@implementation UILinphoneTextField - -@synthesize backgroundNinePatch; - - -#pragma mark - Lifecycle Functions - -- (void)initUILinphoneTextField { - self.backgroundNinePatch = [TUNinePatch ninePatchNamed:@"field_background"]; - self.background = nil; - [self setContentMode:UIViewContentModeRedraw]; -} - -- (id)init { - self = [super init]; - if(self != nil) { - [self initUILinphoneTextField]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if(self != nil) { - [self initUILinphoneTextField]; - } - return self; -} - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if(self != nil) { - [self initUILinphoneTextField]; - } - return self; -} - -- (void)dealloc { - [backgroundNinePatch release]; - - [super dealloc]; -} - -- (CGRect)textRectForBounds:(CGRect)bounds { - return CGRectInset(bounds, 6, 4); -} - -- (CGRect)placeholderRectForBounds:(CGRect)bounds { - return CGRectInset(bounds, 6, 4); -} - -- (CGRect)editingRectForBounds:(CGRect)bounds { - return CGRectInset(bounds, 6, 4); -} - -- (void)drawRect:(CGRect)rect { - // we ignore the rect and redraw the entire view - CGContextRef context = UIGraphicsGetCurrentContext(); - if (context) { - [self.backgroundNinePatch inContext:context drawInRect:[self bounds]]; - } -} - -@end diff --git a/Classes/LinphoneUI/UILoadingImageView.h b/Classes/LinphoneUI/UILoadingImageView.h index 5fcfe2f7e..be8d0e738 100644 --- a/Classes/LinphoneUI/UILoadingImageView.h +++ b/Classes/LinphoneUI/UILoadingImageView.h @@ -28,7 +28,7 @@ - (BOOL)isLoading; - (void)stopLoading; -@property (nonatomic, retain) ALAsset* fullImageUrl; +@property(nonatomic, strong) ALAsset *fullImageUrl; @property (nonatomic, readonly) IBOutlet UIActivityIndicatorView *waitIndicatorView; @end diff --git a/Classes/LinphoneUI/UILoadingImageView.m b/Classes/LinphoneUI/UILoadingImageView.m index ceaaa06e5..c02acb2b9 100644 --- a/Classes/LinphoneUI/UILoadingImageView.m +++ b/Classes/LinphoneUI/UILoadingImageView.m @@ -21,80 +21,72 @@ @implementation UILoadingImageView - @synthesize waitIndicatorView; - #pragma mark - Lifecycle Functions - (void)initUIRemoteImageView { - waitIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; - waitIndicatorView.hidesWhenStopped = TRUE; - waitIndicatorView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | - UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; - waitIndicatorView.center = self.center; - [self addSubview:waitIndicatorView]; + waitIndicatorView = + [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; + waitIndicatorView.hidesWhenStopped = TRUE; + waitIndicatorView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | + UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; + waitIndicatorView.center = self.center; + [self addSubview:waitIndicatorView]; } - (id)init { - self = [super init]; - if(self != nil) { - [self initUIRemoteImageView]; - } - return self; + self = [super init]; + if (self != nil) { + [self initUIRemoteImageView]; + } + return self; } - (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if(self != nil) { - [self initUIRemoteImageView]; - } - return self; + self = [super initWithCoder:aDecoder]; + if (self != nil) { + [self initUIRemoteImageView]; + } + return self; } - (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if(self != nil) { - [self initUIRemoteImageView]; - } - return self; + self = [super initWithFrame:frame]; + if (self != nil) { + [self initUIRemoteImageView]; + } + return self; } - (id)initWithImage:(UIImage *)image { - self = [super initWithImage:image]; - if(self != nil) { - [self initUIRemoteImageView]; - } - return self; + self = [super initWithImage:image]; + if (self != nil) { + [self initUIRemoteImageView]; + } + return self; } - (id)initWithImage:(UIImage *)image highlightedImage:(UIImage *)highlightedImage { - self = [super initWithImage:image highlightedImage:highlightedImage]; - if(self != nil) { - [self initUIRemoteImageView]; - } - return self; + self = [super initWithImage:image highlightedImage:highlightedImage]; + if (self != nil) { + [self initUIRemoteImageView]; + } + return self; } -- (void)dealloc { - [waitIndicatorView release]; - - [super dealloc]; -} - - #pragma mark - - (void)startLoading { - [waitIndicatorView startAnimating]; + [waitIndicatorView startAnimating]; } - (void)stopLoading { - [waitIndicatorView stopAnimating]; + [waitIndicatorView stopAnimating]; } - (BOOL)isLoading { - return [waitIndicatorView isAnimating]; + return [waitIndicatorView isAnimating]; } @end diff --git a/Classes/LinphoneUI/UILongTouchButton.h b/Classes/LinphoneUI/UILongTouchButton.h deleted file mode 100644 index e7fa2efb8..000000000 --- a/Classes/LinphoneUI/UILongTouchButton.h +++ /dev/null @@ -1,31 +0,0 @@ -/* UILongTouchButton.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -@protocol UILongTouchButtonDelegate --(void) onRepeatTouch; --(void) onLongTouch; -@end - -@interface UILongTouchButton : UIButton { - -} - -@end diff --git a/Classes/LinphoneUI/UILongTouchButton.m b/Classes/LinphoneUI/UILongTouchButton.m deleted file mode 100644 index c4f1b0a21..000000000 --- a/Classes/LinphoneUI/UILongTouchButton.m +++ /dev/null @@ -1,89 +0,0 @@ -/* UILongTouchButton.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UILongTouchButton.h" - -@implementation UILongTouchButton - - -#pragma mark - Lifecycle Functions - -- (id)initUILongTouchButton { - [self addTarget:self action:@selector(___touchDown:) forControlEvents:UIControlEventTouchDown]; - [self addTarget:self action:@selector(___touchUp:) forControlEvents:UIControlEventTouchUpInside|UIControlEventTouchUpOutside]; - return self; -} - -- (id)init { - self = [super init]; - if (self) { - [self initUILongTouchButton]; - } - return self; -} - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - [self initUILongTouchButton]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { - [self initUILongTouchButton]; - } - return self; -} - -- (void)dealloc { - [self removeTarget:self action:@selector(___touchDown:) forControlEvents:UIControlEventTouchDown]; - [self removeTarget:self action:@selector(___touchUp:) forControlEvents:UIControlEventTouchUpInside|UIControlEventTouchUpOutside]; - [super dealloc]; -} - -- (void)___touchDown:(id) sender { - [self performSelector:@selector(doLongTouch) withObject:nil afterDelay:0.5]; -} - -- (void)___touchUp:(id) sender { - [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(doLongTouch) object:nil]; - [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(doRepeatTouch) object:nil]; -} - -- (void)doLongTouch { - [self onLongTouch]; - [self onRepeatTouch]; - [self performSelector:@selector(doRepeatTouch) withObject:nil afterDelay:0.1]; -} - -- (void)doRepeatTouch { - [self onRepeatTouch]; - [self performSelector:@selector(doRepeatTouch) withObject:nil afterDelay:0.1]; -} - -- (void)onRepeatTouch { -} - -- (void)onLongTouch { -} - -@end diff --git a/Classes/LinphoneUI/UIMainBar.h b/Classes/LinphoneUI/UIMainBar.h deleted file mode 100644 index 7038ba394..000000000 --- a/Classes/LinphoneUI/UIMainBar.h +++ /dev/null @@ -1,42 +0,0 @@ -/* UIMainBar.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#import "TPMultiLayoutViewController.h" - -@interface UIMainBar : TPMultiLayoutViewController { -} - -@property (nonatomic, retain) IBOutlet UIButton* historyButton; -@property (nonatomic, retain) IBOutlet UIButton* contactsButton; -@property (nonatomic, retain) IBOutlet UIButton* dialerButton; -@property (nonatomic, retain) IBOutlet UIButton* settingsButton; -@property (nonatomic, retain) IBOutlet UIButton* chatButton; -@property (nonatomic, retain) IBOutlet UIView *historyNotificationView; -@property (nonatomic, retain) IBOutlet UILabel *historyNotificationLabel; -@property (nonatomic, retain) IBOutlet UIView *chatNotificationView; -@property (nonatomic, retain) IBOutlet UILabel *chatNotificationLabel; - --(IBAction) onHistoryClick: (id) event; --(IBAction) onContactsClick: (id) event; --(IBAction) onDialerClick: (id) event; --(IBAction) onSettingsClick: (id) event; --(IBAction) onChatClick: (id) event; - -@end diff --git a/Classes/LinphoneUI/UIMainBar.m b/Classes/LinphoneUI/UIMainBar.m deleted file mode 100644 index 749158525..000000000 --- a/Classes/LinphoneUI/UIMainBar.m +++ /dev/null @@ -1,470 +0,0 @@ -/* UIMainBar.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UIMainBar.h" -#import "PhoneMainView.h" -#import "CAAnimation+Blocks.h" - -@implementation UIMainBar - - -static NSString * const kBounceAnimation = @"bounce"; -static NSString * const kAppearAnimation = @"appear"; -static NSString * const kDisappearAnimation = @"disappear"; - -@synthesize historyButton; -@synthesize contactsButton; -@synthesize dialerButton; -@synthesize settingsButton; -@synthesize chatButton; -@synthesize historyNotificationView; -@synthesize historyNotificationLabel; -@synthesize chatNotificationView; -@synthesize chatNotificationLabel; - -#pragma mark - Lifecycle Functions - -- (id)init { - return [super initWithNibName:@"UIMainBar" bundle:[NSBundle mainBundle]]; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [historyButton release]; - [contactsButton release]; - [dialerButton release]; - [settingsButton release]; - [chatButton release]; - [historyNotificationView release]; - [historyNotificationLabel release]; - [chatNotificationView release]; - [chatNotificationLabel release]; - - [super dealloc]; -} - - -#pragma mark - ViewController Functions - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(changeViewEvent:) - name:kLinphoneMainViewChange - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(callUpdate:) - name:kLinphoneCallUpdate - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(textReceived:) - name:kLinphoneTextReceived - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(settingsUpdate:) - name:kLinphoneSettingsUpdate - object:nil]; - [self update:FALSE]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneMainViewChange - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneCallUpdate - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneTextReceived - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneSettingsUpdate - 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:) - name:UIApplicationWillEnterForegroundNotification - object:nil]; - - { - UIButton *historyButtonLandscape = (UIButton*) [landscapeView viewWithTag:[historyButton tag]]; - // Set selected+over background: IB lack ! - [historyButton setBackgroundImage:[UIImage imageNamed:@"history_selected.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - // Set selected+over background: IB lack ! - [historyButtonLandscape setBackgroundImage:[UIImage imageNamed:@"history_selected_landscape.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStatesForTabs:historyButton]; - [LinphoneUtils buttonFixStatesForTabs:historyButtonLandscape]; - } - - { - UIButton *contactsButtonLandscape = (UIButton*) [landscapeView viewWithTag:[contactsButton tag]]; - // Set selected+over background: IB lack ! - [contactsButton setBackgroundImage:[UIImage imageNamed:@"contacts_selected.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - // Set selected+over background: IB lack ! - [contactsButtonLandscape setBackgroundImage:[UIImage imageNamed:@"contacts_selected_landscape.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStatesForTabs:contactsButton]; - [LinphoneUtils buttonFixStatesForTabs:contactsButtonLandscape]; - } - { - UIButton *dialerButtonLandscape = (UIButton*) [landscapeView viewWithTag:[dialerButton tag]]; - // Set selected+over background: IB lack ! - [dialerButton setBackgroundImage:[UIImage imageNamed:@"dialer_selected.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - // Set selected+over background: IB lack ! - [dialerButtonLandscape setBackgroundImage:[UIImage imageNamed:@"dialer_selected_landscape.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStatesForTabs:dialerButton]; - [LinphoneUtils buttonFixStatesForTabs:dialerButtonLandscape]; - } - { - UIButton *settingsButtonLandscape = (UIButton*) [landscapeView viewWithTag:[settingsButton tag]]; - // Set selected+over background: IB lack ! - [settingsButton setBackgroundImage:[UIImage imageNamed:@"settings_selected.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - // Set selected+over background: IB lack ! - [settingsButtonLandscape setBackgroundImage:[UIImage imageNamed:@"settings_selected_landscape.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [LinphoneUtils buttonFixStatesForTabs:settingsButton]; - [LinphoneUtils buttonFixStatesForTabs:settingsButtonLandscape]; - } - - { - UIButton *chatButtonLandscape = (UIButton*) [landscapeView viewWithTag:[chatButton tag]]; - // Set selected+over background: IB lack ! - [chatButton setBackgroundImage:[UIImage imageNamed:@"chat_selected.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - // Set selected+over background: IB lack ! - [chatButtonLandscape setBackgroundImage:[UIImage imageNamed:@"chat_selected_landscape.png"] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - [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 -} - -- (void)viewDidUnload { - [super viewDidUnload]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIApplicationWillEnterForegroundNotification - object:nil]; -} - -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - // Force the animations - [[self.view layer] removeAllAnimations]; - [historyNotificationView.layer setTransform:CATransform3DIdentity]; - [chatNotificationView.layer setTransform:CATransform3DIdentity]; -} - -- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { - [chatNotificationView setHidden:TRUE]; - [historyNotificationView setHidden:TRUE]; - [self update:FALSE]; -} - - - - -#pragma mark - Event Functions - -- (void)applicationWillEnterForeground:(NSNotification*)notif { - // Force the animations - [[self.view layer] removeAllAnimations]; - [historyNotificationView.layer setTransform:CATransform3DIdentity]; - [chatNotificationView.layer setTransform:CATransform3DIdentity]; - [chatNotificationView setHidden:TRUE]; - [historyNotificationView setHidden:TRUE]; - [self update:FALSE]; -} - -- (void)callUpdate:(NSNotification*)notif { - //LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue]; - //LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue]; - [self updateMissedCall:linphone_core_get_missed_calls_count([LinphoneManager getLc]) appear:TRUE]; -} - -- (void)changeViewEvent:(NSNotification*)notif { - //UICompositeViewDescription *view = [notif.userInfo objectForKey: @"view"]; - //if(view != nil) - [self updateView:[[PhoneMainView instance] firstView]]; -} - -- (void)settingsUpdate:(NSNotification*)notif { - if([[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"] == false) { - [self stopBounceAnimation:kBounceAnimation target:chatNotificationView]; - chatNotificationView.layer.transform = CATransform3DIdentity; - [self stopBounceAnimation:kBounceAnimation target:historyNotificationView]; - historyNotificationView.layer.transform = CATransform3DIdentity; - } else { - if(![chatNotificationView isHidden] && [chatNotificationView.layer animationForKey:kBounceAnimation] == nil) { - [self startBounceAnimation:kBounceAnimation target:chatNotificationView]; - } - if(![historyNotificationView isHidden] && [historyNotificationView.layer animationForKey:kBounceAnimation] == nil) { - [self startBounceAnimation:kBounceAnimation target:historyNotificationView]; - } - } -} - -- (void)textReceived:(NSNotification*)notif { - [self updateUnreadMessage:TRUE]; -} - - -#pragma mark - - -- (void)update:(BOOL)appear{ - [self updateView:[[PhoneMainView instance] firstView]]; - [self updateMissedCall:linphone_core_get_missed_calls_count([LinphoneManager getLc]) appear:appear]; - [self updateUnreadMessage:appear]; -} - -- (void)updateUnreadMessage:(BOOL)appear{ - int unreadMessage = [LinphoneManager unreadMessageCount]; - if (unreadMessage > 0) { - if([chatNotificationView isHidden]) { - [chatNotificationView setHidden:FALSE]; - if([[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"] == true) { - if(appear) { - [self appearAnimation:kAppearAnimation target:chatNotificationView completion:^(BOOL finished){ - [self startBounceAnimation:kBounceAnimation target:chatNotificationView]; - [chatNotificationView.layer removeAnimationForKey:kAppearAnimation]; - }]; - } else { - [self startBounceAnimation:kBounceAnimation target:chatNotificationView]; - } - } - } - [chatNotificationLabel setText:[NSString stringWithFormat:@"%i", unreadMessage]]; - } else { - if(![chatNotificationView isHidden]) { - [self stopBounceAnimation:kBounceAnimation target:chatNotificationView]; - if(appear) { - [self disappearAnimation:kDisappearAnimation target:chatNotificationView completion:^(BOOL finished){ - [chatNotificationView setHidden:TRUE]; - [chatNotificationView.layer removeAnimationForKey:kDisappearAnimation]; - }]; - } else { - [chatNotificationView setHidden:TRUE]; - } - } - } -} - -- (void)updateMissedCall:(int)missedCall appear:(BOOL)appear{ - if (missedCall > 0) { - if([historyNotificationView isHidden]) { - [historyNotificationView setHidden:FALSE]; - if([[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"] == true) { - if(appear) { - [self appearAnimation:kAppearAnimation target:historyNotificationView completion:^(BOOL finished){ - [self startBounceAnimation:kBounceAnimation target:historyNotificationView]; - [historyNotificationView.layer removeAnimationForKey:kAppearAnimation]; - }]; - } else { - [self startBounceAnimation:kBounceAnimation target:historyNotificationView]; - } - } - } - [historyNotificationLabel setText:[NSString stringWithFormat:@"%i", missedCall]]; - } else { - if(![historyNotificationView isHidden]) { - [self stopBounceAnimation:kBounceAnimation target:historyNotificationView]; - if(appear) { - [self disappearAnimation:kDisappearAnimation target:historyNotificationView completion:^(BOOL finished){ - [historyNotificationView setHidden:TRUE]; - [historyNotificationView.layer removeAnimationForKey:kDisappearAnimation]; - }]; - } else { - [historyNotificationView setHidden:TRUE]; - } - } - } -} - -- (void)appearAnimation:(NSString*)animationID target:(UIView*)target completion:(void (^)(BOOL finished))completion { - CABasicAnimation *appear = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; - appear.duration = 0.4; - appear.fromValue = [NSNumber numberWithDouble:0.0f]; - appear.toValue = [NSNumber numberWithDouble:1.0f]; - appear.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; - appear.fillMode = kCAFillModeForwards; - appear.removedOnCompletion = NO; - [appear setCompletion:completion]; - [target.layer addAnimation:appear forKey:animationID]; -} - -- (void)disappearAnimation:(NSString*)animationID target:(UIView*)target completion:(void (^)(BOOL finished))completion { - CABasicAnimation *disappear = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; - disappear.duration = 0.4; - disappear.fromValue = [NSNumber numberWithDouble:1.0f]; - disappear.toValue = [NSNumber numberWithDouble:0.0f]; - disappear.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; - disappear.fillMode = kCAFillModeForwards; - disappear.removedOnCompletion = NO; - [disappear setCompletion:completion]; - [target.layer addAnimation:disappear forKey:animationID]; -} - -- (void)startBounceAnimation:(NSString *)animationID target:(UIView *)target { - CABasicAnimation *bounce = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"]; - bounce.duration = 0.3; - bounce.fromValue = [NSNumber numberWithDouble:0.0f]; - bounce.toValue = [NSNumber numberWithDouble:8.0f]; - bounce.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; - bounce.autoreverses = TRUE; - bounce.repeatCount = HUGE_VALF; - [target.layer addAnimation:bounce forKey:animationID]; - -} - -- (void)stopBounceAnimation:(NSString *)animationID target:(UIView *)target { - [target.layer removeAnimationForKey:animationID]; -} - -- (void)updateView:(UICompositeViewDescription*) view { - // Update buttons - if([view equal:[HistoryViewController compositeViewDescription]]) { - historyButton.selected = TRUE; - } else { - historyButton.selected = FALSE; - } - if([view equal:[ContactsViewController compositeViewDescription]]) { - contactsButton.selected = TRUE; - } else { - contactsButton.selected = FALSE; - } - if([view equal:[DialerViewController compositeViewDescription]]) { - dialerButton.selected = TRUE; - } else { - dialerButton.selected = FALSE; - } - if([view equal:[SettingsViewController compositeViewDescription]]) { - settingsButton.selected = TRUE; - } else { - settingsButton.selected = FALSE; - } - if([view equal:[ChatViewController compositeViewDescription]]) { - chatButton.selected = TRUE; - } else { - chatButton.selected = FALSE; - } -} - - -#pragma mark - Action Functions - -- (IBAction)onHistoryClick:(id)event { - [[PhoneMainView instance] changeCurrentView:[HistoryViewController compositeViewDescription]]; -} - -- (IBAction)onContactsClick:(id)event { - [ContactSelection setSelectionMode:ContactSelectionModeNone]; - [ContactSelection setAddAddress:nil]; - [ContactSelection setSipFilter:nil]; - [ContactSelection enableEmailFilter:FALSE]; - [ContactSelection setNameOrEmailFilter:nil]; - [[PhoneMainView instance] changeCurrentView:[ContactsViewController compositeViewDescription]]; -} - -- (IBAction)onDialerClick:(id)event { - [[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]]; -} - -- (IBAction)onSettingsClick:(id)event { - [[PhoneMainView instance] changeCurrentView:[SettingsViewController compositeViewDescription]]; -} - -- (IBAction)onChatClick:(id)event { - [[PhoneMainView instance] changeCurrentView:[ChatViewController compositeViewDescription]]; -} - - -#pragma mark - TPMultiLayoutViewController Functions - -- (NSDictionary*)attributesForView:(UIView*)view { - NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; - - [attributes setObject:[NSValue valueWithCGRect:view.frame] forKey:@"frame"]; - [attributes setObject:[NSValue valueWithCGRect:view.bounds] forKey:@"bounds"]; - if([view isKindOfClass:[UIButton class]]) { - UIButton *button = (UIButton *)view; - [LinphoneUtils buttonMultiViewAddAttributes:attributes button:button]; - } - [attributes setObject:[NSNumber numberWithInteger:view.autoresizingMask] forKey:@"autoresizingMask"]; - - return attributes; -} - -- (void)applyAttributes:(NSDictionary*)attributes toView:(UIView*)view { - view.frame = [[attributes objectForKey:@"frame"] CGRectValue]; - view.bounds = [[attributes objectForKey:@"bounds"] CGRectValue]; - if([view isKindOfClass:[UIButton class]]) { - UIButton *button = (UIButton *)view; - [LinphoneUtils buttonMultiViewApplyAttributes:attributes button:button]; - } - view.autoresizingMask = [[attributes objectForKey:@"autoresizingMask"] integerValue]; -} - -@end diff --git a/Classes/LinphoneUI/UIMicroButton.m b/Classes/LinphoneUI/UIMicroButton.m index 312d238d8..80a1cc13e 100644 --- a/Classes/LinphoneUI/UIMicroButton.m +++ b/Classes/LinphoneUI/UIMicroButton.m @@ -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 "UIMicroButton.h" @@ -24,19 +24,15 @@ @implementation UIMicroButton - (void)onOn { - linphone_core_mute_mic([LinphoneManager getLc], false); + linphone_core_enable_mic([LinphoneManager getLc], false); } - (void)onOff { - linphone_core_mute_mic([LinphoneManager getLc], true); + linphone_core_enable_mic([LinphoneManager getLc], true); } - (bool)onUpdate { - return linphone_core_is_mic_muted([LinphoneManager getLc]) == false; -} - -- (void)dealloc { - [super dealloc]; + return !linphone_core_mic_enabled([LinphoneManager getLc]); } @end diff --git a/Classes/LinphoneUI/UIPauseButton.m b/Classes/LinphoneUI/UIPauseButton.m index adf20f954..586de121d 100644 --- a/Classes/LinphoneUI/UIPauseButton.m +++ b/Classes/LinphoneUI/UIPauseButton.m @@ -4,210 +4,178 @@ * * 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 "UIPauseButton.h" #import "LinphoneManager.h" - -#include "linphone/linphonecore.h" - +#import "Utils.h" @implementation UIPauseButton - #pragma mark - Lifecycle Functions - (void)initUIPauseButton { - type = UIPauseButtonType_CurrentCall; + type = UIPauseButtonType_CurrentCall; } -- (id)init{ - self = [super init]; - if (self) { +- (id)init { + self = [super init]; + if (self) { [self initUIPauseButton]; - } - return self; + } + return self; } - (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { + self = [super initWithCoder:decoder]; + if (self) { [self initUIPauseButton]; } - return self; -} - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - [self initUIPauseButton]; - } - return self; + return self; } +- (id)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self initUIPauseButton]; + } + return self; +} #pragma mark - Static Functions -+ (bool)isInConference: (LinphoneCall*) call { - if (!call) - return false; - return linphone_call_is_in_conference(call); ++ (bool)isInConference:(LinphoneCall *)call { + if (!call) + return false; + return linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call)); } -+ (int)notInConferenceCallCount: (LinphoneCore*) lc { - int count = 0; - const MSList* calls = linphone_core_get_calls(lc); - - while (calls != 0) { - if (![UIPauseButton isInConference: (LinphoneCall*)calls->data]) { - count++; - } - calls = calls->next; - } - return count; ++ (int)notInConferenceCallCount:(LinphoneCore *)lc { + int count = 0; + const MSList *calls = linphone_core_get_calls(lc); + + while (calls != 0) { + if (![UIPauseButton isInConference:(LinphoneCall *)calls->data]) { + count++; + } + calls = calls->next; + } + return count; } -+ (LinphoneCall*)getCall { - LinphoneCore* lc = [LinphoneManager getLc]; - LinphoneCall* currentCall = linphone_core_get_current_call(lc); ++ (LinphoneCall *)getCall { + LinphoneCore *lc = [LinphoneManager getLc]; + LinphoneCall *currentCall = linphone_core_get_current_call(lc); if (currentCall == nil && linphone_core_get_calls_nb(lc) == 1) { - currentCall = (LinphoneCall*) linphone_core_get_calls(lc)->data; - } - return currentCall; + currentCall = (LinphoneCall *)linphone_core_get_calls(lc)->data; + } + return currentCall; } +#pragma mark - -#pragma mark - - -- (void)setType:(UIPauseButtonType) atype call:(LinphoneCall*)acall { - type = atype; - call = acall; +- (void)setType:(UIPauseButtonType)atype call:(LinphoneCall *)acall { + type = atype; + call = acall; } - #pragma mark - UIToggleButtonDelegate Functions - (void)onOn { - switch (type) { - case UIPauseButtonType_Call: - { - if (call != nil) { - linphone_core_pause_call([LinphoneManager getLc], call); - } else { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle pause buttton, because no current call"]; - } - break; - } - case UIPauseButtonType_Conference: - { - linphone_core_leave_conference([LinphoneManager getLc]); - - // Fake event - [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCallUpdate object:self]; - break; - } - case UIPauseButtonType_CurrentCall: - { - LinphoneCall* currentCall = [UIPauseButton getCall]; - if (currentCall != nil) { - linphone_core_pause_call([LinphoneManager getLc], currentCall); - } else { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle pause buttton, because no current call"]; - } - break; - } - } + switch (type) { + case UIPauseButtonType_Call: { + if (call != nil) { + linphone_core_pause_call([LinphoneManager getLc], call); + } else { + LOGW(@"Cannot toggle pause buttton, because no current call"); + } + break; + } + case UIPauseButtonType_Conference: { + linphone_core_leave_conference([LinphoneManager getLc]); + + // Fake event + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCallUpdate object:self]; + break; + } + case UIPauseButtonType_CurrentCall: { + LinphoneCall *currentCall = [UIPauseButton getCall]; + if (currentCall != nil) { + linphone_core_pause_call([LinphoneManager getLc], currentCall); + } else { + LOGW(@"Cannot toggle pause buttton, because no current call"); + } + break; + } + } } - (void)onOff { - switch (type) { - case UIPauseButtonType_Call: - { - if (call != nil) { - linphone_core_resume_call([LinphoneManager getLc], call); - } else { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle pause buttton, because no current call"]; - } - break; - } - case UIPauseButtonType_Conference: - { - linphone_core_enter_conference([LinphoneManager getLc]); - // Fake event - [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCallUpdate object:self]; - break; - } - case UIPauseButtonType_CurrentCall: - { - LinphoneCall* currentCall = [UIPauseButton getCall]; - if (currentCall != nil) { - linphone_core_resume_call([LinphoneManager getLc], currentCall); - } else { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle pause buttton, because no current call"]; - } - break; - } - } + switch (type) { + case UIPauseButtonType_Call: { + if (call != nil) { + linphone_core_resume_call([LinphoneManager getLc], call); + } else { + LOGW(@"Cannot toggle pause buttton, because no current call"); + } + break; + } + case UIPauseButtonType_Conference: { + linphone_core_enter_conference([LinphoneManager getLc]); + // Fake event + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneCallUpdate object:self]; + break; + } + case UIPauseButtonType_CurrentCall: { + LinphoneCall *currentCall = [UIPauseButton getCall]; + if (currentCall != nil) { + linphone_core_resume_call([LinphoneManager getLc], currentCall); + } else { + LOGW(@"Cannot toggle pause buttton, because no current call"); + } + break; + } + } } - (bool)onUpdate { - bool ret = false; - // TODO: disable pause on not running call - LinphoneCore *lc = [LinphoneManager getLc]; - switch (type) { - case UIPauseButtonType_Call: - { - if (call != nil) { - LinphoneCallState state = linphone_call_get_state(call); - if(state == LinphoneCallPaused || state == LinphoneCallPausing) { - ret = true; - } - [self setEnabled:TRUE]; - } else { - [self setEnabled:FALSE]; - } - break; - } - case UIPauseButtonType_Conference: - { - if(linphone_core_get_conference_size(lc) > 0) { - if (!linphone_core_is_in_conference(lc)) { - ret = true; - } - [self setEnabled:TRUE]; - } else { - [self setEnabled:FALSE]; - } - break; - } - case UIPauseButtonType_CurrentCall: - { - LinphoneCall* currentCall = [UIPauseButton getCall]; - if (currentCall != nil) { - LinphoneCallState state = linphone_call_get_state(currentCall); - if(state == LinphoneCallPaused || state == LinphoneCallPausing) { - ret = true; - } - [self setEnabled:TRUE]; - } else { - [self setEnabled:FALSE]; - } - break; - } - } - - return ret; + bool ret = false; + LinphoneCore *lc = [LinphoneManager getLc]; + LinphoneCall *c = call; + switch (type) { + case UIPauseButtonType_Conference: { + self.enabled = (linphone_core_get_conference_size(lc) > 0); + if (self.enabled) { + ret = (!linphone_core_is_in_conference(lc)); + } + break; + } + case UIPauseButtonType_CurrentCall: + c = [UIPauseButton getCall]; + case UIPauseButtonType_Call: { + if (c != nil) { + LinphoneCallState state = linphone_call_get_state(c); + ret = (state == LinphoneCallPaused || state == LinphoneCallPausing); + self.enabled = (state == LinphoneCallPaused || state == LinphoneCallPausing || + state == LinphoneCallStreamsRunning); + } else { + self.enabled = FALSE; + } + break; + } + } + return ret; } @end diff --git a/Classes/LinphoneUI/UIPlusDigitButton.m b/Classes/LinphoneUI/UIPlusDigitButton.m deleted file mode 100644 index 4e3c72211..000000000 --- a/Classes/LinphoneUI/UIPlusDigitButton.m +++ /dev/null @@ -1,12 +0,0 @@ -// -// UIPlusDigitButton.m -// linphone -// -// Created by Gautier Pelloux-Prayer on 24/09/14. -// -// - -#import - -@interface UIDigitButton : UILongTouchButton { -} \ No newline at end of file diff --git a/Classes/LinphoneUI/UIRightImageButton.h b/Classes/LinphoneUI/UIRightImageButton.h new file mode 100644 index 000000000..8699e4d3a --- /dev/null +++ b/Classes/LinphoneUI/UIRightImageButton.h @@ -0,0 +1,13 @@ +// +// UIRightImageButton.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 28/10/15. +// +// + +#import + +@interface UIRightImageButton : UIButton + +@end diff --git a/Classes/LinphoneUI/UIRightImageButton.m b/Classes/LinphoneUI/UIRightImageButton.m new file mode 100644 index 000000000..c9383d011 --- /dev/null +++ b/Classes/LinphoneUI/UIRightImageButton.m @@ -0,0 +1,35 @@ +// +// UIRightImageButton.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 28/10/15. +// +// + +#import "UIRightImageButton.h" + +@implementation UIRightImageButton + +- (instancetype)invertImage { + self.transform = CGAffineTransformMakeScale(-1.0, 1.0); + self.titleLabel.transform = CGAffineTransformMakeScale(-1.0, 1.0); + self.imageView.transform = CGAffineTransformMakeScale(-1.0, 1.0); + + self.contentHorizontalAlignment = (self.contentHorizontalAlignment == UIControlContentHorizontalAlignmentLeft) + ? UIControlContentHorizontalAlignmentRight + : UIControlContentHorizontalAlignmentLeft; + + return self; +} +- (instancetype)init { + return [[super init] invertImage]; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + return [[super initWithCoder:aDecoder] invertImage]; +} + +- (instancetype)initWithFrame:(CGRect)frame { + return [[super initWithFrame:frame] invertImage]; +} +@end diff --git a/Classes/LinphoneUI/UIRoundBorderedButton.h b/Classes/LinphoneUI/UIRoundBorderedButton.h new file mode 100644 index 000000000..ce7b60718 --- /dev/null +++ b/Classes/LinphoneUI/UIRoundBorderedButton.h @@ -0,0 +1,14 @@ +// +// UIRoundBorderedButton.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 22/07/15. +// +// +#import + +#import "UIIconButton.h" + +@interface UIRoundBorderedButton : UIIconButton + +@end diff --git a/Classes/LinphoneUI/UIRoundBorderedButton.m b/Classes/LinphoneUI/UIRoundBorderedButton.m new file mode 100644 index 000000000..91ed97758 --- /dev/null +++ b/Classes/LinphoneUI/UIRoundBorderedButton.m @@ -0,0 +1,55 @@ +// +// UIRoundBorderedButton.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 22/07/15. +// +// + +#import "UIRoundBorderedButton.h" + +#import "Utils.h" + +@implementation UIRoundBorderedButton + +- (id)initBorders { + self.layer.borderWidth = .8; + self.layer.borderColor = [self.titleLabel.textColor CGColor]; + self.layer.cornerRadius = 4.f; + self.layer.masksToBounds = YES; + + // capitalize title (should be already done though) + UIControlState states[] = {UIControlStateNormal, + UIControlStateHighlighted, + UIControlStateSelected, + UIControlStateDisabled, + UIControlStateDisabled | UIControlStateHighlighted, + UIControlStateSelected | UIControlStateHighlighted, + UIControlStateSelected | UIControlStateDisabled}; + for (int i = 0; i < sizeof(states) / sizeof(UIControlState); i++) { + if (![[self titleForState:UIControlStateNormal] + .uppercaseString isEqualToString:[self titleForState:states[i]]]) { + [self setTitle:[[self titleForState:states[i]] uppercaseString] forState:states[i]]; + } + } + return self; +} + +- (id)init { + return [[super init] initBorders]; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + return [[super initWithCoder:aDecoder] initBorders]; +} + +- (id)initWithFrame:(CGRect)frame { + return [[super initWithFrame:frame] initBorders]; +} + +- (void)setEnabled:(BOOL)enabled { + [super setEnabled:enabled]; + self.layer.borderColor = [self.titleLabel.textColor CGColor]; +} + +@end diff --git a/Classes/LinphoneUI/UIRoundedImageView.h b/Classes/LinphoneUI/UIRoundedImageView.h index 7d165c143..ed66e9d41 100644 --- a/Classes/LinphoneUI/UIRoundedImageView.h +++ b/Classes/LinphoneUI/UIRoundedImageView.h @@ -10,7 +10,10 @@ @interface UIRoundedImageView : UIImageView -- (void) setImage:(UIImage *)image; -- (void) setImage:(UIImage *)image withRoundedRadius:(BOOL)rounded; +- (void)setImage:(UIImage *)image; +- (void)setImage:(UIImage *)image bordered:(BOOL)bordered withRoundedRadius:(BOOL)rounded; + +- (void)setBordered:(BOOL)bordered; +- (void)setRoundRadius; @end diff --git a/Classes/LinphoneUI/UIRoundedImageView.m b/Classes/LinphoneUI/UIRoundedImageView.m index ed33f80e6..cf8202a3f 100644 --- a/Classes/LinphoneUI/UIRoundedImageView.m +++ b/Classes/LinphoneUI/UIRoundedImageView.m @@ -8,38 +8,74 @@ #import "UIRoundedImageView.h" #import +#import "Utils.h" -@implementation UIRoundedImageView - - -- (id) init { - self = [super init]; - if (self ){ - [self setRoundRadius:TRUE]; - } - return self; +@implementation UIRoundedImageView { + UIView *borderView; } -- (void) setImage:(UIImage *)image { - [self setImage:image withRoundedRadius:TRUE]; +INIT_WITH_COMMON { + borderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; + borderView.layer.borderWidth = 10; + borderView.layer.borderColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_A.png"]].CGColor; + borderView.hidden = YES; + [self addSubview:borderView]; + + [self setBordered:NO]; + [self setRoundRadius]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(orientationDidChange:) + name:@"UIDeviceOrientationDidChangeNotification" + object:nil]; + return self; } -- (void) setImage:(UIImage *)image withRoundedRadius:(BOOL)rounded { - [super setImage:image]; - [self setRoundRadius:rounded]; +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; } -// warning: for non-squared image, this function will generate an ellipsoidal image, not a round image! -- (void)setRoundRadius:(BOOL)radius { - CALayer *imageLayer = self.layer; - CGFloat height = imageLayer.frame.size.height; - CGFloat width = imageLayer.frame.size.width; - CGFloat roundRadius = height > width ? width / 2 : height / 2; - - [imageLayer setCornerRadius:roundRadius]; - [imageLayer setBorderWidth:0]; - [imageLayer setMasksToBounds:YES]; +- (void)orientationDidChange:(NSNotification *)k { + [self setRoundRadius]; + [self layoutSubviews]; } +- (void)setImage:(UIImage *)image { + [self setImage:image bordered:NO withRoundedRadius:TRUE]; +} +- (void)setImage:(UIImage *)image bordered:(BOOL)bordered withRoundedRadius:(BOOL)rounded { + // We have to scale image to layers limits so that when we round image, we have a proper circle + [super setImage:[image squareCrop]]; + [self setBordered:bordered]; + [self setRoundRadius]; +} + +- (void)setBordered:(BOOL)bordered { + borderView.hidden = !bordered; +} +- (CGRect)computeBox { + CGFloat min = MIN(self.frame.size.width, self.frame.size.height); + CGRect box = CGRectMake((self.frame.size.width - min) / 2, (self.frame.size.height - min) / 2, min, min); + return box; +} +- (void)setRoundRadius { + CGRect box = [self computeBox]; + + borderView.frame = box; + borderView.layer.cornerRadius = borderView.frame.size.height / 2; + + CGPathRef path = CGPathCreateWithEllipseInRect(box, NULL); + UIBezierPath *maskPath = [UIBezierPath bezierPathWithCGPath:path]; + CGPathRelease(path); + CAShapeLayer *maskLayer = [CAShapeLayer layer]; + maskLayer.frame = self.bounds; + maskLayer.path = maskPath.CGPath; + self.layer.mask = maskLayer; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + borderView.frame = [self computeBox]; + borderView.layer.cornerRadius = borderView.frame.size.height / 2; +} @end diff --git a/Classes/LinphoneUI/UISpeakerButton.m b/Classes/LinphoneUI/UISpeakerButton.m index 2fd073c60..791d3f7d8 100644 --- a/Classes/LinphoneUI/UISpeakerButton.m +++ b/Classes/LinphoneUI/UISpeakerButton.m @@ -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 #import "UISpeakerButton.h" @@ -26,60 +26,59 @@ @implementation UISpeakerButton - #pragma mark - Static Functions -static void audioRouteChangeListenerCallback ( - void *inUserData, // 1 - AudioSessionPropertyID inPropertyID, // 2 - UInt32 inPropertyValueSize, // 3 - const void *inPropertyValue // 4 - ) { - if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return; // 5 - UISpeakerButton* button = (UISpeakerButton*)inUserData; - [button update]; +static void audioRouteChangeListenerCallback(void *inUserData, // 1 + AudioSessionPropertyID inPropertyID, // 2 + UInt32 inPropertyValueSize, // 3 + const void *inPropertyValue // 4 + ) { + if (inPropertyID != kAudioSessionProperty_AudioRouteChange) + return; // 5 + UISpeakerButton *button = (__bridge UISpeakerButton *)inUserData; + [button update]; } - (void)initUISpeakerButton { - AudioSessionInitialize(NULL, NULL, NULL, NULL); - OSStatus lStatus = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self); - if (lStatus) { - [LinphoneLogger logc:LinphoneLoggerError format:"cannot register route change handler [%ld]",lStatus]; - } + AudioSessionInitialize(NULL, NULL, NULL, NULL); + OSStatus lStatus = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, + audioRouteChangeListenerCallback, (__bridge void *)(self)); + if (lStatus) { + LOGE(@"cannot register route change handler [%ld]", lStatus); + } } - (id)init { - self = [super init]; - if (self) { + self = [super init]; + if (self) { [self initUISpeakerButton]; - } - return self; + } + return self; } - (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { + self = [super initWithFrame:frame]; + if (self) { [self initUISpeakerButton]; - } - return self; + } + return self; } - (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { + self = [super initWithCoder:decoder]; + if (self) { [self initUISpeakerButton]; } - return self; -} - -- (void)dealloc { - OSStatus lStatus = AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self); - if (lStatus) { - [LinphoneLogger logc:LinphoneLoggerError format:"cannot un register route change handler [%ld]", lStatus]; - } - [super dealloc]; + return self; } +- (void)dealloc { + OSStatus lStatus = AudioSessionRemovePropertyListenerWithUserData( + kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, (__bridge void *)(self)); + if (lStatus) { + LOGE(@"cannot un register route change handler [%ld]", lStatus); + } +} #pragma mark - UIToggleButtonDelegate Functions @@ -88,12 +87,12 @@ static void audioRouteChangeListenerCallback ( } - (void)onOff { - [[LinphoneManager instance] setSpeakerEnabled:FALSE]; + [[LinphoneManager instance] setSpeakerEnabled:FALSE]; } - (bool)onUpdate { - [self setEnabled:[[LinphoneManager instance] allowSpeaker]]; - return [[LinphoneManager instance] speakerEnabled]; + [self setEnabled:[[LinphoneManager instance] allowSpeaker]]; + return [[LinphoneManager instance] speakerEnabled]; } @end diff --git a/Classes/LinphoneUI/UIStateBar.m b/Classes/LinphoneUI/UIStateBar.m deleted file mode 100644 index 80c36f97a..000000000 --- a/Classes/LinphoneUI/UIStateBar.m +++ /dev/null @@ -1,382 +0,0 @@ -/* UIStateBar.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UIStateBar.h" -#import "LinphoneManager.h" -#import "PhoneMainView.h" - -@implementation UIStateBar - -@synthesize registrationStateImage; -@synthesize registrationStateLabel; -@synthesize callQualityImage; -@synthesize callSecurityImage; -@synthesize callSecurityButton; - -NSTimer *callQualityTimer; -NSTimer *callSecurityTimer; -int messagesUnreadCount; - -#pragma mark - Lifecycle Functions - -- (id)init { - self = [super initWithNibName:@"UIStateBar" bundle:[NSBundle mainBundle]]; - if(self != nil) { - self->callSecurityImage = nil; - self->callQualityImage = nil; - self->securitySheet = nil; - } - return self; -} - -- (void) dealloc { - if(securitySheet) { - [securitySheet release]; - } - [registrationStateImage release]; - [registrationStateLabel release]; - [callQualityImage release]; - [callSecurityImage release]; - [callSecurityButton release]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [callQualityTimer invalidate]; - [callQualityTimer release]; - [_voicemailCount release]; - [super dealloc]; -} - - -#pragma mark - ViewController Functions - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - // Set callQualityTimer - callQualityTimer = [NSTimer scheduledTimerWithTimeInterval:1 - target:self - selector:@selector(callQualityUpdate) - userInfo:nil - repeats:YES]; - - // Set callQualityTimer - callSecurityTimer = [NSTimer scheduledTimerWithTimeInterval:1 - target:self - selector:@selector(callSecurityUpdate) - userInfo:nil - repeats:YES]; - - // Set observer - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(registrationUpdate:) - name:kLinphoneRegistrationUpdate - object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(globalStateUpdate:) - name:kLinphoneGlobalStateUpdate - object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(notifyReceived:) - name:kLinphoneNotifyReceived - object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(callUpdate:) - name:kLinphoneCallUpdate - object:nil]; - - - [callQualityImage setHidden: true]; - [callSecurityImage setHidden: true]; - - // Update to default state - LinphoneProxyConfig* config = NULL; - linphone_core_get_default_proxy([LinphoneManager getLc], &config); - messagesUnreadCount = lp_config_get_int(linphone_core_get_config([LinphoneManager getLc]), "app", "voice_mail_messages_count", 0); - - [self proxyConfigUpdate: config]; - [self updateVoicemail]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - - - // Remove observer - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneRegistrationUpdate - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneGlobalStateUpdate - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneNotifyReceived - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneCallUpdate - object:nil]; - - if(callQualityTimer != nil) { - [callQualityTimer invalidate]; - callQualityTimer = nil; - } - if(callSecurityTimer != nil) { - [callSecurityTimer invalidate]; - callSecurityTimer = nil; - } -} - - -#pragma mark - Event Functions - -- (void)registrationUpdate: (NSNotification*) notif { - LinphoneProxyConfig* config = NULL; - linphone_core_get_default_proxy([LinphoneManager getLc], &config); - [self proxyConfigUpdate:config]; -} - -- (void) globalStateUpdate:(NSNotification*) notif { - [self registrationUpdate:notif]; -} - -- (void) notifyReceived:(NSNotification*) notif { - const LinphoneContent * content = [[notif.userInfo objectForKey: @"content"] pointerValue]; - - if ((content == NULL) - || (strcmp("application", linphone_content_get_type(content)) != 0) - || (strcmp("simple-message-summary", linphone_content_get_subtype(content)) != 0) - || (linphone_content_get_buffer(content) == NULL)) { - return; - } - const char* body = linphone_content_get_buffer(content); - if ((body = strstr(body, "voice-message: ")) == NULL) { - [LinphoneLogger log:LinphoneLoggerWarning format:@"Received new NOTIFY from voice mail but could not find 'voice-message' in BODY. Ignoring it."]; - return; - } - - sscanf(body, "voice-message: %d", &messagesUnreadCount); - - [LinphoneLogger log:LinphoneLoggerLog format:@"Received new NOTIFY from voice mail: there is/are now %d message(s) unread", messagesUnreadCount]; - - // save in lpconfig for future - lp_config_set_int(linphone_core_get_config([LinphoneManager getLc]), "app", "voice_mail_messages_count", messagesUnreadCount); - - [self updateVoicemail]; -} - -- (void) updateVoicemail { - if (messagesUnreadCount > 0) { - self.voicemailCount.hidden = (linphone_core_get_calls([LinphoneManager getLc]) != NULL); - self.voicemailCount.text = [[NSString stringWithFormat:NSLocalizedString(@"%d unread messages", @"%d"), messagesUnreadCount] uppercaseString]; - } else { - self.voicemailCount.hidden = TRUE; - } -} - -- (void) callUpdate:(NSNotification*) notif { - //show voice mail only when there is no call - [self updateVoicemail]; -} - - -#pragma mark - - -- (void)proxyConfigUpdate: (LinphoneProxyConfig*) config { - LinphoneRegistrationState state = LinphoneRegistrationNone; - NSString* message = nil; - UIImage* image = nil; - LinphoneCore* lc = [LinphoneManager getLc]; - LinphoneGlobalState gstate = linphone_core_get_global_state(lc); - - if( gstate == LinphoneGlobalConfiguring ){ - message = NSLocalizedString(@"Fetching remote configuration", nil); - } else if (config == NULL) { - state = LinphoneRegistrationNone; - if(linphone_core_is_network_reachable([LinphoneManager getLc])) - message = NSLocalizedString(@"No SIP account configured", nil); - else - message = NSLocalizedString(@"Network down", nil); - } else { - state = linphone_proxy_config_get_state(config); - - switch (state) { - case LinphoneRegistrationOk: - message = NSLocalizedString(@"Registered", nil); break; - case LinphoneRegistrationNone: - case LinphoneRegistrationCleared: - message = NSLocalizedString(@"Not registered", nil); break; - case LinphoneRegistrationFailed: - message = NSLocalizedString(@"Registration failed", nil); break; - case LinphoneRegistrationProgress: - message = NSLocalizedString(@"Registration in progress", nil); break; - default: break; - } - } - - registrationStateLabel.hidden = NO; - switch(state) { - case LinphoneRegistrationFailed: - registrationStateImage.hidden = NO; - image = [UIImage imageNamed:@"led_error.png"]; - break; - case LinphoneRegistrationCleared: - case LinphoneRegistrationNone: - registrationStateImage.hidden = NO; - image = [UIImage imageNamed:@"led_disconnected.png"]; - break; - case LinphoneRegistrationProgress: - registrationStateImage.hidden = NO; - image = [UIImage imageNamed:@"led_inprogress.png"]; - break; - case LinphoneRegistrationOk: - registrationStateImage.hidden = NO; - image = [UIImage imageNamed:@"led_connected.png"]; - break; - } - [registrationStateLabel setText:message]; - [registrationStateImage setImage:image]; -} - - -#pragma mark - - -- (void)callSecurityUpdate { - BOOL pending = false; - BOOL security = true; - - const MSList *list = linphone_core_get_calls([LinphoneManager getLc]); - - if(list == NULL) { - if(securitySheet) { - [securitySheet dismissWithClickedButtonIndex:securitySheet.destructiveButtonIndex animated:TRUE]; - } - [callSecurityImage setHidden:true]; - return; - } - while(list != NULL) { - LinphoneCall *call = (LinphoneCall*) list->data; - LinphoneMediaEncryption enc = linphone_call_params_get_media_encryption(linphone_call_get_current_params(call)); - if(enc == LinphoneMediaEncryptionNone) - security = false; - else if(enc == LinphoneMediaEncryptionZRTP) { - if(!linphone_call_get_authentication_token_verified(call)) { - pending = true; - } - } - list = list->next; - } - - if(security) { - if(pending) { - [callSecurityImage setImage:[UIImage imageNamed:@"security_pending.png"]]; - } else { - [callSecurityImage setImage:[UIImage imageNamed:@"security_ok.png"]]; - } - } else { - [callSecurityImage setImage:[UIImage imageNamed:@"security_ko.png"]]; - } - [callSecurityImage setHidden: false]; -} - -- (void)callQualityUpdate { - UIImage *image = nil; - LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); - if(call != NULL) { - //FIXME double check call state before computing, may cause core dump - float quality = linphone_call_get_average_quality(call); - if(quality < 1) { - image = [UIImage imageNamed:@"call_quality_indicator_0.png"]; - } else if (quality < 2) { - image = [UIImage imageNamed:@"call_quality_indicator_1.png"]; - } else if (quality < 3) { - image = [UIImage imageNamed:@"call_quality_indicator_2.png"]; - } else { - image = [UIImage imageNamed:@"call_quality_indicator_3.png"]; - } - } - if(image != nil) { - [callQualityImage setHidden:false]; - [callQualityImage setImage:image]; - } else { - [callQualityImage setHidden:true]; - } -} - - -#pragma mark - Action Functions - -- (IBAction)doSecurityClick:(id)sender { - if(linphone_core_get_calls_nb([LinphoneManager getLc])) { - LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); - if(call != NULL) { - LinphoneMediaEncryption enc = linphone_call_params_get_media_encryption(linphone_call_get_current_params(call)); - if(enc == LinphoneMediaEncryptionZRTP) { - bool valid = linphone_call_get_authentication_token_verified(call); - NSString *message = nil; - if(valid) { - message = NSLocalizedString(@"Remove trust in the peer?",nil); - } else { - message = [NSString stringWithFormat:NSLocalizedString(@"Confirm the following SAS with the peer:\n%s",nil), - linphone_call_get_authentication_token(call)]; - } - if( securitySheet == nil ){ - securitySheet = [[DTActionSheet alloc] initWithTitle:message]; - [securitySheet setDelegate:self]; - [securitySheet addButtonWithTitle:NSLocalizedString(@"Ok",nil) block:^(){ - linphone_call_set_authentication_token_verified(call, !valid); - [securitySheet release]; - securitySheet = nil; - }]; - - [securitySheet addDestructiveButtonWithTitle:NSLocalizedString(@"Cancel",nil) block:^(){ - [securitySheet release]; - securitySheet = nil; - }]; - [securitySheet showInView:[PhoneMainView instance].view]; - } - } - } - } -} - --(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex{ - [securitySheet release]; - securitySheet = nil; -} - -#pragma mark - TPMultiLayoutViewController Functions - -- (NSDictionary*)attributesForView:(UIView*)view { - NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; - - [attributes setObject:[NSValue valueWithCGRect:view.frame] forKey:@"frame"]; - [attributes setObject:[NSValue valueWithCGRect:view.bounds] forKey:@"bounds"]; - [attributes setObject:[NSNumber numberWithInteger:view.autoresizingMask] forKey:@"autoresizingMask"]; - - return attributes; -} - -- (void)applyAttributes:(NSDictionary*)attributes toView:(UIView*)view { - view.frame = [[attributes objectForKey:@"frame"] CGRectValue]; - view.bounds = [[attributes objectForKey:@"bounds"] CGRectValue]; - view.autoresizingMask = [[attributes objectForKey:@"autoresizingMask"] integerValue]; -} - -@end diff --git a/Classes/LinphoneUI/UITextField+DoneButton.h b/Classes/LinphoneUI/UITextField+DoneButton.h new file mode 100644 index 000000000..d596019bc --- /dev/null +++ b/Classes/LinphoneUI/UITextField+DoneButton.h @@ -0,0 +1,14 @@ +// +// UITextField+DoneButton.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 14/10/14. +// +// + +#import +#import + +@interface UITextField (DoneButton) +- (void)addDoneButton; +@end diff --git a/Classes/LinphoneUI/UITextField+DoneButton.m b/Classes/LinphoneUI/UITextField+DoneButton.m new file mode 100644 index 000000000..b90f0ec6d --- /dev/null +++ b/Classes/LinphoneUI/UITextField+DoneButton.m @@ -0,0 +1,46 @@ +// +// UITextField+DoneButton.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 14/10/14. +// +// + +#import "UITextField+DoneButton.h" + +#import "LinphoneManager.h" + +@implementation UITextField (DoneButton) + +- (void)addDoneButton { + // actually on iPad there is a done button + if (!IPAD) { + UIToolbar *numberToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 50)]; + numberToolbar.items = [NSArray + arrayWithObjects:[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Cancel", nil) + style:UIBarButtonItemStyleBordered + target:self + action:@selector(cancelNumberPad)], + [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace + target:nil + action:nil], + [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Done", nil) + style:UIBarButtonItemStyleDone + target:self + action:@selector(doneWithNumberPad)], + nil]; + [numberToolbar sizeToFit]; + + self.inputAccessoryView = numberToolbar; + } +} + +- (void)cancelNumberPad { + [self resignFirstResponder]; + self.text = @""; +} + +- (void)doneWithNumberPad { + [self resignFirstResponder]; +} +@end diff --git a/Classes/LinphoneUI/UITextViewNoDefine.m b/Classes/LinphoneUI/UITextViewNoDefine.m index cc7215e10..14c188248 100644 --- a/Classes/LinphoneUI/UITextViewNoDefine.m +++ b/Classes/LinphoneUI/UITextViewNoDefine.m @@ -12,15 +12,15 @@ @synthesize allowSelectAll; -- (BOOL)canPerformAction:(SEL)action withSender:(id)sender{ - // disable "define" option, since it messes with the keyboard - if ([[NSStringFromSelector(action) lowercaseString] rangeOfString:@"define"].location != NSNotFound) { - return NO; - } else if(action == @selector(selectAll:) && allowSelectAll ) { - return YES; - } else { - return [super canPerformAction:action withSender:sender]; - } +- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { + // disable "define" option, since it messes with the keyboard + if ([[NSStringFromSelector(action) lowercaseString] rangeOfString:@"define"].location != NSNotFound) { + return NO; + } else if (action == @selector(selectAll:) && allowSelectAll) { + return YES; + } else { + return [super canPerformAction:action withSender:sender]; + } } @end diff --git a/Classes/LinphoneUI/UIToggleButton.h b/Classes/LinphoneUI/UIToggleButton.h index f3265e903..26828b9b3 100644 --- a/Classes/LinphoneUI/UIToggleButton.h +++ b/Classes/LinphoneUI/UIToggleButton.h @@ -19,13 +19,15 @@ #import +#import "UIIconButton.h" + @protocol UIToggleButtonDelegate - (void)onOn; - (void)onOff; - (bool)onUpdate; @end -@interface UIToggleButton : UIButton { +@interface UIToggleButton : UIIconButton { } - (bool)update; diff --git a/Classes/LinphoneUI/UIToggleButton.m b/Classes/LinphoneUI/UIToggleButton.m index a8b92feab..2d34b7298 100644 --- a/Classes/LinphoneUI/UIToggleButton.m +++ b/Classes/LinphoneUI/UIToggleButton.m @@ -4,72 +4,66 @@ * * 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 "UIToggleButton.h" @implementation UIToggleButton - #pragma mark - Lifecycle Functions - (void)initUIToggleButton { - [self update]; + [self update]; [self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside]; } - (id)init { - self = [super init]; - if (self) { + self = [super init]; + if (self) { [self initUIToggleButton]; - } - return self; + } + return self; } - (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { + self = [super initWithFrame:frame]; + if (self) { [self initUIToggleButton]; - } - return self; + } + return self; } - (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { + self = [super initWithCoder:decoder]; + if (self) { [self initUIToggleButton]; } - return self; -} - -- (void)dealloc { - [super dealloc]; + return self; } +#pragma mark - -#pragma mark - - -- (void)touchUp:(id) sender { +- (void)touchUp:(id)sender { [self toggle]; } - (bool)toggle { if (self.selected) { - self.selected=!self.selected; + self.selected = !self.selected; [self onOff]; } else { - self.selected=!self.selected; + self.selected = !self.selected; [self onOn]; } return self.selected; @@ -92,23 +86,22 @@ return self.selected; } - #pragma mark - UIToggleButtonDelegate Functions --(void) onOn { - /*[NSException raise:NSInternalInconsistencyException - format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)];*/ +- (void)onOn { + /*[NSException raise:NSInternalInconsistencyException + format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)];*/ } --(void) onOff { - /*[NSException raise:NSInternalInconsistencyException - format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)];*/ +- (void)onOff { + /*[NSException raise:NSInternalInconsistencyException + format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)];*/ } --(bool) onUpdate { - /*[NSException raise:NSInternalInconsistencyException - format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)];*/ - return false; +- (bool)onUpdate { + /*[NSException raise:NSInternalInconsistencyException + format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)];*/ + return false; } @end diff --git a/Classes/LinphoneUI/UITransferButton.h b/Classes/LinphoneUI/UITransferButton.h index 451ff75d4..c6884ba4e 100644 --- a/Classes/LinphoneUI/UITransferButton.h +++ b/Classes/LinphoneUI/UITransferButton.h @@ -19,9 +19,10 @@ #import -@interface UITransferButton : UIButton { -} +#import "UIIconButton.h" -@property (nonatomic, retain) IBOutlet UITextField* addressField; +@interface UITransferButton : UIIconButton + +@property(nonatomic, strong) IBOutlet UITextField *addressField; @end diff --git a/Classes/LinphoneUI/UITransferButton.m b/Classes/LinphoneUI/UITransferButton.m index 564e14a4f..809336ee8 100644 --- a/Classes/LinphoneUI/UITransferButton.m +++ b/Classes/LinphoneUI/UITransferButton.m @@ -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 "UITransferButton.h" #import "LinphoneManager.h" @@ -28,44 +28,37 @@ #pragma mark - Lifecycle Functions - (void)initUICallButton { - [self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside]; + [self addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside]; } - (id)init { - self = [super init]; - if (self) { + self = [super init]; + if (self) { [self initUICallButton]; - } - return self; + } + return self; } - (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { + self = [super initWithFrame:frame]; + if (self) { [self initUICallButton]; - } - return self; + } + return self; } - (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { + self = [super initWithCoder:decoder]; + if (self) { [self initUICallButton]; } - return self; -} - -- (void)dealloc { - [addressField release]; - - [super dealloc]; + return self; } - #pragma mark - -- (void)touchUp:(id) sender { - [[LinphoneManager instance] call:[addressField text] displayName:nil transfer:TRUE]; +- (void)touchUp:(id)sender { + [[LinphoneManager instance] call:[addressField text] displayName:nil transfer:TRUE]; } @end diff --git a/Classes/LinphoneUI/UITransparentView.h b/Classes/LinphoneUI/UITransparentView.h deleted file mode 100644 index 8d12e22b6..000000000 --- a/Classes/LinphoneUI/UITransparentView.h +++ /dev/null @@ -1,24 +0,0 @@ -/* UITransparentView.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -@interface UITransparentView : UIView - -@end diff --git a/Classes/LinphoneUI/UITransparentView.m b/Classes/LinphoneUI/UITransparentView.m deleted file mode 100644 index 40326e77b..000000000 --- a/Classes/LinphoneUI/UITransparentView.m +++ /dev/null @@ -1,44 +0,0 @@ -/* UITransparentView.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UITransparentView.h" - -@implementation UITransparentView - -- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { - BOOL pointInside = NO; - - for(UIView *child in [self subviews]) { - if(![child isHidden]) { - if(CGRectContainsPoint(child.frame, point)) { - CGPoint newPoint = point; - newPoint.x -= child.frame.origin.x; - newPoint.y -= child.frame.origin.y; - if([child pointInside:newPoint withEvent:event]) { - pointInside = YES; - break; - } - } - } - } - - return pointInside; -} - -@end diff --git a/Classes/LinphoneUI/UIVideoButton.h b/Classes/LinphoneUI/UIVideoButton.h index a7b4be5db..4686face6 100644 --- a/Classes/LinphoneUI/UIVideoButton.h +++ b/Classes/LinphoneUI/UIVideoButton.h @@ -24,6 +24,6 @@ @interface UIVideoButton : UIToggleButton { } -@property (nonatomic, retain) IBOutlet UIActivityIndicatorView* waitView; +@property(nonatomic, strong) IBOutlet UIActivityIndicatorView *waitView; @end diff --git a/Classes/LinphoneUI/UIVideoButton.m b/Classes/LinphoneUI/UIVideoButton.m index 1edd7f0b3..d78a50656 100644 --- a/Classes/LinphoneUI/UIVideoButton.m +++ b/Classes/LinphoneUI/UIVideoButton.m @@ -4,125 +4,97 @@ * * 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 + * 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 "UIVideoButton.h" #include "LinphoneManager.h" +#import "Utils.h" @implementation UIVideoButton { - BOOL last_update_state; + BOOL last_update_state; } @synthesize waitView; -- (void)initUIVideoButton { - last_update_state = FALSE; -} - -- (id)init{ - self = [super init]; - if (self) { - [self initUIVideoButton]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { - [self initUIVideoButton]; - } - return self; -} - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - [self initUIVideoButton]; - } - return self; +INIT_WITH_COMMON { + last_update_state = FALSE; + return self; } - (void)onOn { - LinphoneCore* lc = [LinphoneManager getLc]; - - if (!linphone_core_video_enabled(lc)) - return; - - [self setEnabled: FALSE]; - [waitView startAnimating]; - - LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); + LinphoneCore *lc = [LinphoneManager getLc]; + + if (!linphone_core_video_display_enabled(lc)) + return; + + [self setEnabled:FALSE]; + [waitView startAnimating]; + + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); if (call) { - LinphoneCallAppData* callAppData = (LinphoneCallAppData*)linphone_call_get_user_pointer(call); - callAppData->videoRequested=TRUE; /* will be used later to notify user if video was not activated because of the linphone core*/ - LinphoneCallParams* call_params = linphone_call_params_copy(linphone_call_get_current_params(call)); - linphone_call_params_enable_video(call_params, TRUE); - linphone_core_update_call(lc, call, call_params); + LinphoneCallAppData *callAppData = (__bridge LinphoneCallAppData *)linphone_call_get_user_pointer(call); + callAppData->videoRequested = + TRUE; /* will be used later to notify user if video was not activated because of the linphone core*/ + LinphoneCallParams *call_params = linphone_call_params_copy(linphone_call_get_current_params(call)); + linphone_call_params_enable_video(call_params, TRUE); + linphone_core_update_call(lc, call, call_params); linphone_call_params_destroy(call_params); - } else { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle video button, because no current call"]; - } + } else { + LOGW(@"Cannot toggle video button, because no current call"); + } } - (void)onOff { - LinphoneCore* lc = [LinphoneManager getLc]; - - if (!linphone_core_video_enabled(lc)) - return; - - [self setEnabled: FALSE]; - [waitView startAnimating]; - - LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); - if (call) { - LinphoneCallParams* call_params = linphone_call_params_copy(linphone_call_get_current_params(call)); - linphone_call_params_enable_video(call_params, FALSE); - linphone_core_update_call(lc, call, call_params); + LinphoneCore *lc = [LinphoneManager getLc]; + + if (!linphone_core_video_display_enabled(lc)) + return; + + [self setEnabled:FALSE]; + [waitView startAnimating]; + + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); + if (call) { + LinphoneCallParams *call_params = linphone_call_params_copy(linphone_call_get_current_params(call)); + linphone_call_params_enable_video(call_params, FALSE); + linphone_core_update_call(lc, call, call_params); linphone_call_params_destroy(call_params); - } else { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot toggle video button, because no current call"]; + } else { + LOGW(@"Cannot toggle video button, because no current call"); } } - (bool)onUpdate { - bool video_enabled = false; + bool video_enabled = false; + LinphoneCore *lc = [LinphoneManager getLc]; + LinphoneCall *currentCall = linphone_core_get_current_call(lc); + if (linphone_core_video_supported(lc)) { + if (linphone_core_video_display_enabled(lc) && currentCall && !linphone_call_media_in_progress(currentCall) && + linphone_call_get_state(currentCall) == LinphoneCallStreamsRunning) { + video_enabled = TRUE; + } + } -#ifdef VIDEO_ENABLED - LinphoneCall* currentCall = linphone_core_get_current_call([LinphoneManager getLc]); - if( linphone_core_video_enabled([LinphoneManager getLc]) - && currentCall - && !linphone_call_media_in_progress(currentCall) - && linphone_call_get_state(currentCall) == LinphoneCallStreamsRunning) { - video_enabled = TRUE; - } -#endif //VIDEO_ENABLED + [self setEnabled:video_enabled]; + if (last_update_state != video_enabled) + [waitView stopAnimating]; + if (video_enabled) { + video_enabled = linphone_call_params_video_enabled(linphone_call_get_current_params(currentCall)); + } + last_update_state = video_enabled; - [self setEnabled:video_enabled]; - if( last_update_state != video_enabled ) - [waitView stopAnimating]; - if( video_enabled ){ - video_enabled = linphone_call_params_video_enabled(linphone_call_get_current_params(currentCall)); - } - last_update_state = video_enabled; - - return video_enabled; -} - -- (void)dealloc { - [waitView release]; - [super dealloc]; + return video_enabled; } @end diff --git a/Classes/LinphoneUI/VideoZoomHandler.h b/Classes/LinphoneUI/VideoZoomHandler.h index 2b4bb3a86..01f6a9cb3 100644 --- a/Classes/LinphoneUI/VideoZoomHandler.h +++ b/Classes/LinphoneUI/VideoZoomHandler.h @@ -18,6 +18,7 @@ */ #import +#import @interface VideoZoomHandler : NSObject { float zoomLevel, cx, cy; diff --git a/Classes/LinphoneUI/VideoZoomHandler.m b/Classes/LinphoneUI/VideoZoomHandler.m index 4cc86ba11..85c4940f8 100644 --- a/Classes/LinphoneUI/VideoZoomHandler.m +++ b/Classes/LinphoneUI/VideoZoomHandler.m @@ -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 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 + * 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 "VideoZoomHandler.h" #include "linphone/linphonecore.h" @@ -23,92 +23,89 @@ @implementation VideoZoomHandler -- (void)zoomInOut:(UITapGestureRecognizer*) reco { - if (zoomLevel != 1) - zoomLevel = 1; - else - zoomLevel = 2; - - if (zoomLevel != 1) { - CGPoint point = [reco locationInView:videoView]; - cx = point.x / videoView.frame.size.width; - cy = 1 - point.y / videoView.frame.size.height; - } else { - cx = cy = 0.5; - } - linphone_call_zoom_video(linphone_core_get_current_call([LinphoneManager getLc]), zoomLevel, &cx, &cy); +- (void)zoomInOut:(UITapGestureRecognizer *)reco { + if (zoomLevel != 1) + zoomLevel = 1; + else + zoomLevel = 2; + + if (zoomLevel != 1) { + CGPoint point = [reco locationInView:videoView]; + cx = point.x / videoView.frame.size.width; + cy = 1 - point.y / videoView.frame.size.height; + } else { + cx = cy = 0.5; + } + linphone_call_zoom_video(linphone_core_get_current_call([LinphoneManager getLc]), zoomLevel, &cx, &cy); } -- (void)videoPan:(UIPanGestureRecognizer*) reco { - if (zoomLevel <= 1.0) - return; - - float x,y; - CGPoint translation = [reco translationInView:videoView]; - if ([reco state] == UIGestureRecognizerStateEnded) { - cx -= translation.x / videoView.frame.size.width; - cy += translation.y / videoView.frame.size.height; - x = cx; - y = cy; - } else if ([reco state] == UIGestureRecognizerStateChanged) { - x = cx - translation.x / videoView.frame.size.width; - y = cy + translation.y / videoView.frame.size.height; - [reco setTranslation:CGPointMake(0, 0) inView:videoView]; - } else { - return; - } - - linphone_call_zoom_video(linphone_core_get_current_call([LinphoneManager getLc]), zoomLevel, &x, &y); - cx = x; - cy = y; +- (void)videoPan:(UIPanGestureRecognizer *)reco { + if (zoomLevel <= 1.0) + return; + + float x, y; + CGPoint translation = [reco translationInView:videoView]; + if ([reco state] == UIGestureRecognizerStateEnded) { + cx -= translation.x / videoView.frame.size.width; + cy += translation.y / videoView.frame.size.height; + x = cx; + y = cy; + } else if ([reco state] == UIGestureRecognizerStateChanged) { + x = cx - translation.x / videoView.frame.size.width; + y = cy + translation.y / videoView.frame.size.height; + [reco setTranslation:CGPointMake(0, 0) inView:videoView]; + } else { + return; + } + + linphone_call_zoom_video(linphone_core_get_current_call([LinphoneManager getLc]), zoomLevel, &x, &y); + cx = x; + cy = y; } -- (void)pinch:(UIPinchGestureRecognizer*) reco { - float s = zoomLevel; - // CGPoint point = [reco locationInView:videoGroup]; - // float ccx = cx + (point.x / videoGroup.frame.size.width - 0.5) / s; - // float ccy = cy - (point.y / videoGroup.frame.size.height - 0.5) / s; - if ([reco state] == UIGestureRecognizerStateEnded) { - zoomLevel = MAX(MIN(zoomLevel * reco.scale, 3.0), 1.0); - s = zoomLevel; - // cx = ccx; - // cy = ccy; - } else if ([reco state] == UIGestureRecognizerStateChanged) { - s = zoomLevel * reco.scale; - s = MAX(MIN(s, 3.0), 1.0); - } else if ([reco state] == UIGestureRecognizerStateBegan) { - - } else { - return; - } - - - linphone_call_zoom_video(linphone_core_get_current_call([LinphoneManager getLc]), s, &cx, &cy); +- (void)pinch:(UIPinchGestureRecognizer *)reco { + float s = zoomLevel; + // CGPoint point = [reco locationInView:videoGroup]; + // float ccx = cx + (point.x / videoGroup.frame.size.width - 0.5) / s; + // float ccy = cy - (point.y / videoGroup.frame.size.height - 0.5) / s; + if ([reco state] == UIGestureRecognizerStateEnded) { + zoomLevel = MAX(MIN(zoomLevel * reco.scale, 3.0), 1.0); + s = zoomLevel; + // cx = ccx; + // cy = ccy; + } else if ([reco state] == UIGestureRecognizerStateChanged) { + s = zoomLevel * reco.scale; + s = MAX(MIN(s, 3.0), 1.0); + } else if ([reco state] == UIGestureRecognizerStateBegan) { + + } else { + return; + } + + linphone_call_zoom_video(linphone_core_get_current_call([LinphoneManager getLc]), s, &cx, &cy); } - (void)resetZoom { - zoomLevel = 1; - cx = cy = 0.5; + zoomLevel = 1; + cx = cy = 0.5; } -- (void)setup: (UIView*) view { - videoView = view; - - UITapGestureRecognizer* doubleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(zoomInOut:)]; - [doubleFingerTap setNumberOfTapsRequired:2]; - [doubleFingerTap setNumberOfTouchesRequired:1]; - [videoView addGestureRecognizer:doubleFingerTap]; +- (void)setup:(UIView *)view { + videoView = view; - UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(videoPan:)]; - [videoView addGestureRecognizer:pan]; - UIPinchGestureRecognizer* pinchReco = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)]; - [videoView addGestureRecognizer:pinchReco]; + UITapGestureRecognizer *doubleFingerTap = + [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(zoomInOut:)]; + [doubleFingerTap setNumberOfTapsRequired:2]; + [doubleFingerTap setNumberOfTouchesRequired:1]; + [videoView addGestureRecognizer:doubleFingerTap]; - [doubleFingerTap release]; - [pan release]; - [pinchReco release]; - - [self resetZoom]; + UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(videoPan:)]; + [videoView addGestureRecognizer:pan]; + UIPinchGestureRecognizer *pinchReco = + [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)]; + [videoView addGestureRecognizer:pinchReco]; + + [self resetZoom]; } @end diff --git a/Classes/LinphoneUI/ar.lproj/StatusBarView.strings b/Classes/LinphoneUI/ar.lproj/StatusBarView.strings new file mode 100644 index 000000000..fa7b6f321 Binary files /dev/null and b/Classes/LinphoneUI/ar.lproj/StatusBarView.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/TabBarView.strings b/Classes/LinphoneUI/ar.lproj/TabBarView.strings new file mode 100644 index 000000000..f25d2a044 Binary files /dev/null and b/Classes/LinphoneUI/ar.lproj/TabBarView.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/UICallBar.strings b/Classes/LinphoneUI/ar.lproj/UICallBar.strings deleted file mode 100644 index 5dcac01dc..000000000 Binary files a/Classes/LinphoneUI/ar.lproj/UICallBar.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ar.lproj/UICallBar.strings2 b/Classes/LinphoneUI/ar.lproj/UICallBar.strings2 deleted file mode 100644 index 5dcac01dc..000000000 Binary files a/Classes/LinphoneUI/ar.lproj/UICallBar.strings2 and /dev/null differ diff --git a/Classes/LinphoneUI/ar.lproj/UICallBar~ipad.strings b/Classes/LinphoneUI/ar.lproj/UICallBar~ipad.strings deleted file mode 100644 index 348a50688..000000000 Binary files a/Classes/LinphoneUI/ar.lproj/UICallBar~ipad.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ar.lproj/UICallCell.strings b/Classes/LinphoneUI/ar.lproj/UICallCell.strings deleted file mode 100644 index 5867d40e5..000000000 Binary files a/Classes/LinphoneUI/ar.lproj/UICallCell.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ar.lproj/UICallCell.xib b/Classes/LinphoneUI/ar.lproj/UICallCell.xib deleted file mode 100644 index be7cfac55..000000000 --- a/Classes/LinphoneUI/ar.lproj/UICallCell.xib +++ /dev/null @@ -1,480 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/LinphoneUI/ar.lproj/UICallConferenceCell.strings b/Classes/LinphoneUI/ar.lproj/UICallConferenceCell.strings new file mode 100644 index 000000000..b8345ba09 Binary files /dev/null and b/Classes/LinphoneUI/ar.lproj/UICallConferenceCell.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/UICallPausedCell.strings b/Classes/LinphoneUI/ar.lproj/UICallPausedCell.strings new file mode 100644 index 000000000..4ffa7cda9 Binary files /dev/null and b/Classes/LinphoneUI/ar.lproj/UICallPausedCell.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/ar.lproj/UIChatBubblePhotoCell.strings new file mode 100644 index 000000000..055097106 Binary files /dev/null and b/Classes/LinphoneUI/ar.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/ar.lproj/UIChatBubbleTextCell.strings new file mode 100644 index 000000000..c415c2246 Binary files /dev/null and b/Classes/LinphoneUI/ar.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/UIChatCell.strings b/Classes/LinphoneUI/ar.lproj/UIChatCell.strings index 1b8be8beb..764554385 100644 Binary files a/Classes/LinphoneUI/ar.lproj/UIChatCell.strings and b/Classes/LinphoneUI/ar.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/UIChatRoomCell.strings b/Classes/LinphoneUI/ar.lproj/UIChatRoomCell.strings deleted file mode 100644 index 77b8494d0..000000000 Binary files a/Classes/LinphoneUI/ar.lproj/UIChatRoomCell.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ar.lproj/UICompositeViewController.strings b/Classes/LinphoneUI/ar.lproj/UICompositeView.strings similarity index 100% rename from Classes/LinphoneUI/ar.lproj/UICompositeViewController.strings rename to Classes/LinphoneUI/ar.lproj/UICompositeView.strings diff --git a/Classes/LinphoneUI/ar.lproj/UIConferenceHeader.strings b/Classes/LinphoneUI/ar.lproj/UIConferenceHeader.strings deleted file mode 100644 index bdbef46b7..000000000 Binary files a/Classes/LinphoneUI/ar.lproj/UIConferenceHeader.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ar.lproj/UIContactCell.strings b/Classes/LinphoneUI/ar.lproj/UIContactCell.strings index d55ca37e2..377f67974 100644 Binary files a/Classes/LinphoneUI/ar.lproj/UIContactCell.strings and b/Classes/LinphoneUI/ar.lproj/UIContactCell.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/ar.lproj/UIContactDetailsCell.strings new file mode 100644 index 000000000..8d911cc2a Binary files /dev/null and b/Classes/LinphoneUI/ar.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/UIContactDetailsFooter.strings b/Classes/LinphoneUI/ar.lproj/UIContactDetailsFooter.strings deleted file mode 100644 index 3a42d27f0..000000000 Binary files a/Classes/LinphoneUI/ar.lproj/UIContactDetailsFooter.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ar.lproj/UIContactDetailsHeader.strings b/Classes/LinphoneUI/ar.lproj/UIContactDetailsHeader.strings deleted file mode 100644 index bd8aa1e2b..000000000 Binary files a/Classes/LinphoneUI/ar.lproj/UIContactDetailsHeader.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ar.lproj/UIHistoryCell.strings b/Classes/LinphoneUI/ar.lproj/UIHistoryCell.strings index 9ce20e630..e5bade567 100644 Binary files a/Classes/LinphoneUI/ar.lproj/UIHistoryCell.strings and b/Classes/LinphoneUI/ar.lproj/UIHistoryCell.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/UIMainBar.strings b/Classes/LinphoneUI/ar.lproj/UIMainBar.strings deleted file mode 100644 index 35fcf5bc1..000000000 Binary files a/Classes/LinphoneUI/ar.lproj/UIMainBar.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ar.lproj/UIMainBar~ipad.strings b/Classes/LinphoneUI/ar.lproj/UIMainBar~ipad.strings deleted file mode 100644 index 5eca8a60a..000000000 Binary files a/Classes/LinphoneUI/ar.lproj/UIMainBar~ipad.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ar.lproj/UIStateBar.strings b/Classes/LinphoneUI/ar.lproj/UIStateBar.strings deleted file mode 100644 index c570eb63f..000000000 Binary files a/Classes/LinphoneUI/ar.lproj/UIStateBar.strings and /dev/null differ diff --git a/Classes/LinphoneUI/de.lproj/StatusBarView.strings b/Classes/LinphoneUI/de.lproj/StatusBarView.strings new file mode 100644 index 000000000..7cdf73030 Binary files /dev/null and b/Classes/LinphoneUI/de.lproj/StatusBarView.strings differ diff --git a/Classes/LinphoneUI/de.lproj/TabBarView.strings b/Classes/LinphoneUI/de.lproj/TabBarView.strings new file mode 100644 index 000000000..a4002c3a8 Binary files /dev/null and b/Classes/LinphoneUI/de.lproj/TabBarView.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UICallBar.strings b/Classes/LinphoneUI/de.lproj/UICallBar.strings deleted file mode 100644 index 9718eddb7..000000000 Binary files a/Classes/LinphoneUI/de.lproj/UICallBar.strings and /dev/null differ diff --git a/Classes/LinphoneUI/de.lproj/UICallBar~ipad.strings b/Classes/LinphoneUI/de.lproj/UICallBar~ipad.strings deleted file mode 100644 index 8a761615d..000000000 Binary files a/Classes/LinphoneUI/de.lproj/UICallBar~ipad.strings and /dev/null differ diff --git a/Classes/LinphoneUI/de.lproj/UICallCell.strings b/Classes/LinphoneUI/de.lproj/UICallCell.strings index 114e59720..3329cc3f6 100644 Binary files a/Classes/LinphoneUI/de.lproj/UICallCell.strings and b/Classes/LinphoneUI/de.lproj/UICallCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UICallConferenceCell.strings b/Classes/LinphoneUI/de.lproj/UICallConferenceCell.strings new file mode 100644 index 000000000..091e75f64 Binary files /dev/null and b/Classes/LinphoneUI/de.lproj/UICallConferenceCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UICallPausedCell.strings b/Classes/LinphoneUI/de.lproj/UICallPausedCell.strings new file mode 100644 index 000000000..70ae8c971 Binary files /dev/null and b/Classes/LinphoneUI/de.lproj/UICallPausedCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/de.lproj/UIChatBubblePhotoCell.strings new file mode 100644 index 000000000..8fb25e86a Binary files /dev/null and b/Classes/LinphoneUI/de.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/de.lproj/UIChatBubbleTextCell.strings new file mode 100644 index 000000000..45da00f43 Binary files /dev/null and b/Classes/LinphoneUI/de.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIChatCell.strings b/Classes/LinphoneUI/de.lproj/UIChatCell.strings index 1908ed7aa..4423a4eab 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIChatCell.strings and b/Classes/LinphoneUI/de.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIChatRoomCell.strings b/Classes/LinphoneUI/de.lproj/UIChatRoomCell.strings index 9c4254d7b..e2110e9a8 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIChatRoomCell.strings and b/Classes/LinphoneUI/de.lproj/UIChatRoomCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIConferenceHeader.strings b/Classes/LinphoneUI/de.lproj/UIConferenceHeader.strings deleted file mode 100644 index 678efd3b0..000000000 Binary files a/Classes/LinphoneUI/de.lproj/UIConferenceHeader.strings and /dev/null differ diff --git a/Classes/LinphoneUI/de.lproj/UIContactCell.strings b/Classes/LinphoneUI/de.lproj/UIContactCell.strings index 1ea1a345f..fc5a3c17d 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIContactCell.strings and b/Classes/LinphoneUI/de.lproj/UIContactCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/de.lproj/UIContactDetailsCell.strings new file mode 100644 index 000000000..117388c0c Binary files /dev/null and b/Classes/LinphoneUI/de.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIContactDetailsFooter.strings b/Classes/LinphoneUI/de.lproj/UIContactDetailsFooter.strings index 2582e2927..9dc62be3d 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIContactDetailsFooter.strings and b/Classes/LinphoneUI/de.lproj/UIContactDetailsFooter.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIContactDetailsHeader.strings b/Classes/LinphoneUI/de.lproj/UIContactDetailsHeader.strings index 2d8554414..8ec7e8bdb 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIContactDetailsHeader.strings and b/Classes/LinphoneUI/de.lproj/UIContactDetailsHeader.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIHistoryCell.strings b/Classes/LinphoneUI/de.lproj/UIHistoryCell.strings index f39ce0b0f..3a21159a9 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIHistoryCell.strings and b/Classes/LinphoneUI/de.lproj/UIHistoryCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIMainBar.strings b/Classes/LinphoneUI/de.lproj/UIMainBar.strings index 05d5ba216..1396b82fd 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIMainBar.strings and b/Classes/LinphoneUI/de.lproj/UIMainBar.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIMainBar~ipad.strings b/Classes/LinphoneUI/de.lproj/UIMainBar~ipad.strings index 02fe15f5c..f5c0b2c61 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIMainBar~ipad.strings and b/Classes/LinphoneUI/de.lproj/UIMainBar~ipad.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIStateBar.strings b/Classes/LinphoneUI/de.lproj/UIStateBar.strings index bf63879ec..8be33cdc4 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIStateBar.strings and b/Classes/LinphoneUI/de.lproj/UIStateBar.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/StatusBarView.strings b/Classes/LinphoneUI/fr.lproj/StatusBarView.strings new file mode 100644 index 000000000..332db0f25 Binary files /dev/null and b/Classes/LinphoneUI/fr.lproj/StatusBarView.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/TabBarView.strings b/Classes/LinphoneUI/fr.lproj/TabBarView.strings new file mode 100644 index 000000000..c206807e2 Binary files /dev/null and b/Classes/LinphoneUI/fr.lproj/TabBarView.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UICallBar.strings b/Classes/LinphoneUI/fr.lproj/UICallBar.strings deleted file mode 100644 index 0f84ed8b1..000000000 Binary files a/Classes/LinphoneUI/fr.lproj/UICallBar.strings and /dev/null differ diff --git a/Classes/LinphoneUI/fr.lproj/UICallBar~ipad.strings b/Classes/LinphoneUI/fr.lproj/UICallBar~ipad.strings deleted file mode 100644 index 30642cc26..000000000 Binary files a/Classes/LinphoneUI/fr.lproj/UICallBar~ipad.strings and /dev/null differ diff --git a/Classes/LinphoneUI/fr.lproj/UICallCell.strings b/Classes/LinphoneUI/fr.lproj/UICallCell.strings deleted file mode 100644 index 94dbc6b13..000000000 Binary files a/Classes/LinphoneUI/fr.lproj/UICallCell.strings and /dev/null differ diff --git a/Classes/LinphoneUI/fr.lproj/UICallConferenceCell.strings b/Classes/LinphoneUI/fr.lproj/UICallConferenceCell.strings new file mode 100644 index 000000000..629130fa2 Binary files /dev/null and b/Classes/LinphoneUI/fr.lproj/UICallConferenceCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UICallPausedCell.strings b/Classes/LinphoneUI/fr.lproj/UICallPausedCell.strings new file mode 100644 index 000000000..4d0eb9bb9 Binary files /dev/null and b/Classes/LinphoneUI/fr.lproj/UICallPausedCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/fr.lproj/UIChatBubblePhotoCell.strings new file mode 100644 index 000000000..4388780d7 Binary files /dev/null and b/Classes/LinphoneUI/fr.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/fr.lproj/UIChatBubbleTextCell.strings new file mode 100644 index 000000000..1125a27b4 Binary files /dev/null and b/Classes/LinphoneUI/fr.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIChatCell.strings b/Classes/LinphoneUI/fr.lproj/UIChatCell.strings index 5dd1d1f5a..68b814db2 100644 Binary files a/Classes/LinphoneUI/fr.lproj/UIChatCell.strings and b/Classes/LinphoneUI/fr.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIChatCreateCell.strings b/Classes/LinphoneUI/fr.lproj/UIChatCreateCell.strings new file mode 100644 index 000000000..ac8173e78 Binary files /dev/null and b/Classes/LinphoneUI/fr.lproj/UIChatCreateCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIChatRoomCell.strings b/Classes/LinphoneUI/fr.lproj/UIChatRoomCell.strings index 35daf8f29..de063b598 100644 Binary files a/Classes/LinphoneUI/fr.lproj/UIChatRoomCell.strings and b/Classes/LinphoneUI/fr.lproj/UIChatRoomCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIConferenceHeader.strings b/Classes/LinphoneUI/fr.lproj/UIConferenceHeader.strings deleted file mode 100644 index f9bbfb438..000000000 Binary files a/Classes/LinphoneUI/fr.lproj/UIConferenceHeader.strings and /dev/null differ diff --git a/Classes/LinphoneUI/fr.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/fr.lproj/UIConfirmationDialog.strings new file mode 100644 index 000000000..8fce37804 Binary files /dev/null and b/Classes/LinphoneUI/fr.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIContactCell.strings b/Classes/LinphoneUI/fr.lproj/UIContactCell.strings index 0fc8f680a..6099fa96e 100644 Binary files a/Classes/LinphoneUI/fr.lproj/UIContactCell.strings and b/Classes/LinphoneUI/fr.lproj/UIContactCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/fr.lproj/UIContactDetailsCell.strings new file mode 100644 index 000000000..2a6b8f684 Binary files /dev/null and b/Classes/LinphoneUI/fr.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIContactDetailsFooter.strings b/Classes/LinphoneUI/fr.lproj/UIContactDetailsFooter.strings deleted file mode 100644 index 549eedd4e..000000000 Binary files a/Classes/LinphoneUI/fr.lproj/UIContactDetailsFooter.strings and /dev/null differ diff --git a/Classes/LinphoneUI/fr.lproj/UIContactDetailsHeader.strings b/Classes/LinphoneUI/fr.lproj/UIContactDetailsHeader.strings deleted file mode 100644 index 6c1d42070..000000000 Binary files a/Classes/LinphoneUI/fr.lproj/UIContactDetailsHeader.strings and /dev/null differ diff --git a/Classes/LinphoneUI/fr.lproj/UIHistoryCell.strings b/Classes/LinphoneUI/fr.lproj/UIHistoryCell.strings index e9756d3d5..c0f90ab0f 100644 Binary files a/Classes/LinphoneUI/fr.lproj/UIHistoryCell.strings and b/Classes/LinphoneUI/fr.lproj/UIHistoryCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIMainBar.strings b/Classes/LinphoneUI/fr.lproj/UIMainBar.strings deleted file mode 100644 index 9f451e2ac..000000000 Binary files a/Classes/LinphoneUI/fr.lproj/UIMainBar.strings and /dev/null differ diff --git a/Classes/LinphoneUI/fr.lproj/UIMainBar~ipad.strings b/Classes/LinphoneUI/fr.lproj/UIMainBar~ipad.strings deleted file mode 100644 index 6c89376e5..000000000 Binary files a/Classes/LinphoneUI/fr.lproj/UIMainBar~ipad.strings and /dev/null differ diff --git a/Classes/LinphoneUI/fr.lproj/UIStateBar.strings b/Classes/LinphoneUI/fr.lproj/UIStateBar.strings index 60601dbf6..c1ef43fcb 100644 Binary files a/Classes/LinphoneUI/fr.lproj/UIStateBar.strings and b/Classes/LinphoneUI/fr.lproj/UIStateBar.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/StatusBarView.strings b/Classes/LinphoneUI/ja.lproj/StatusBarView.strings new file mode 100644 index 000000000..e4df9ea43 Binary files /dev/null and b/Classes/LinphoneUI/ja.lproj/StatusBarView.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/TabBarView.strings b/Classes/LinphoneUI/ja.lproj/TabBarView.strings new file mode 100644 index 000000000..c4d9013ae Binary files /dev/null and b/Classes/LinphoneUI/ja.lproj/TabBarView.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UICallBar.strings b/Classes/LinphoneUI/ja.lproj/UICallBar.strings deleted file mode 100644 index c8218d65e..000000000 Binary files a/Classes/LinphoneUI/ja.lproj/UICallBar.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ja.lproj/UICallBar~ipad.strings b/Classes/LinphoneUI/ja.lproj/UICallBar~ipad.strings deleted file mode 100644 index 9d115a80d..000000000 Binary files a/Classes/LinphoneUI/ja.lproj/UICallBar~ipad.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ja.lproj/UICallCell.strings b/Classes/LinphoneUI/ja.lproj/UICallCell.strings index 1d9525a61..a5a987148 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UICallCell.strings and b/Classes/LinphoneUI/ja.lproj/UICallCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UICallConferenceCell.strings b/Classes/LinphoneUI/ja.lproj/UICallConferenceCell.strings new file mode 100644 index 000000000..20a98486c Binary files /dev/null and b/Classes/LinphoneUI/ja.lproj/UICallConferenceCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UICallPausedCell.strings b/Classes/LinphoneUI/ja.lproj/UICallPausedCell.strings new file mode 100644 index 000000000..860e87800 Binary files /dev/null and b/Classes/LinphoneUI/ja.lproj/UICallPausedCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/ja.lproj/UIChatBubblePhotoCell.strings new file mode 100644 index 000000000..4c19dc953 Binary files /dev/null and b/Classes/LinphoneUI/ja.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/ja.lproj/UIChatBubbleTextCell.strings new file mode 100644 index 000000000..d63a348ef Binary files /dev/null and b/Classes/LinphoneUI/ja.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIChatCell.strings b/Classes/LinphoneUI/ja.lproj/UIChatCell.strings index 8cfdc970d..8991b3394 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIChatCell.strings and b/Classes/LinphoneUI/ja.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIChatRoomCell.strings b/Classes/LinphoneUI/ja.lproj/UIChatRoomCell.strings index 317551c24..1c2582d0b 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIChatRoomCell.strings and b/Classes/LinphoneUI/ja.lproj/UIChatRoomCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIConferenceHeader.strings b/Classes/LinphoneUI/ja.lproj/UIConferenceHeader.strings deleted file mode 100644 index f8a7e0e7c..000000000 Binary files a/Classes/LinphoneUI/ja.lproj/UIConferenceHeader.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ja.lproj/UIContactCell.strings b/Classes/LinphoneUI/ja.lproj/UIContactCell.strings index 1b6462d6c..d3c268b97 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIContactCell.strings and b/Classes/LinphoneUI/ja.lproj/UIContactCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/ja.lproj/UIContactDetailsCell.strings new file mode 100644 index 000000000..cec1d7d62 Binary files /dev/null and b/Classes/LinphoneUI/ja.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIContactDetailsFooter.strings b/Classes/LinphoneUI/ja.lproj/UIContactDetailsFooter.strings index a708d76f7..c80219512 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIContactDetailsFooter.strings and b/Classes/LinphoneUI/ja.lproj/UIContactDetailsFooter.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIContactDetailsHeader.strings b/Classes/LinphoneUI/ja.lproj/UIContactDetailsHeader.strings index 101df1338..365a60206 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIContactDetailsHeader.strings and b/Classes/LinphoneUI/ja.lproj/UIContactDetailsHeader.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIHistoryCell.strings b/Classes/LinphoneUI/ja.lproj/UIHistoryCell.strings index 7ab3dc1cc..ffe51fc89 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIHistoryCell.strings and b/Classes/LinphoneUI/ja.lproj/UIHistoryCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIMainBar.strings b/Classes/LinphoneUI/ja.lproj/UIMainBar.strings index 673ebc56f..71c32926d 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIMainBar.strings and b/Classes/LinphoneUI/ja.lproj/UIMainBar.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIMainBar~ipad.strings b/Classes/LinphoneUI/ja.lproj/UIMainBar~ipad.strings index ff93e7151..8dacacba8 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIMainBar~ipad.strings and b/Classes/LinphoneUI/ja.lproj/UIMainBar~ipad.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIStateBar.strings b/Classes/LinphoneUI/ja.lproj/UIStateBar.strings index 7498eed6b..07eaea128 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIStateBar.strings and b/Classes/LinphoneUI/ja.lproj/UIStateBar.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/StatusBarView.strings b/Classes/LinphoneUI/nl.lproj/StatusBarView.strings new file mode 100644 index 000000000..64396588d Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/StatusBarView.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/TabBarView.strings b/Classes/LinphoneUI/nl.lproj/TabBarView.strings new file mode 100644 index 000000000..539a1bd73 Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/TabBarView.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UICallCell.strings b/Classes/LinphoneUI/nl.lproj/UICallCell.strings new file mode 100644 index 000000000..bc7116b5f Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UICallCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UICallConferenceCell.strings b/Classes/LinphoneUI/nl.lproj/UICallConferenceCell.strings new file mode 100644 index 000000000..b4ef1be4e Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UICallConferenceCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UICallPausedCell.strings b/Classes/LinphoneUI/nl.lproj/UICallPausedCell.strings new file mode 100644 index 000000000..15274b5ed Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UICallPausedCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/nl.lproj/UIChatBubblePhotoCell.strings new file mode 100644 index 000000000..48990cd90 Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/nl.lproj/UIChatBubbleTextCell.strings new file mode 100644 index 000000000..1ae790e79 Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIChatCell.strings b/Classes/LinphoneUI/nl.lproj/UIChatCell.strings new file mode 100644 index 000000000..064b7ca46 Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIChatRoomCell.strings b/Classes/LinphoneUI/nl.lproj/UIChatRoomCell.strings new file mode 100644 index 000000000..254e8b072 Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UIChatRoomCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIContactCell.strings b/Classes/LinphoneUI/nl.lproj/UIContactCell.strings new file mode 100644 index 000000000..b54f1b4f4 Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UIContactCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/nl.lproj/UIContactDetailsCell.strings new file mode 100644 index 000000000..7c015f94d Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIContactDetailsFooter.strings b/Classes/LinphoneUI/nl.lproj/UIContactDetailsFooter.strings new file mode 100644 index 000000000..047ac0813 Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UIContactDetailsFooter.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIContactDetailsHeader.strings b/Classes/LinphoneUI/nl.lproj/UIContactDetailsHeader.strings new file mode 100644 index 000000000..a2145195e Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UIContactDetailsHeader.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIHistoryCell.strings b/Classes/LinphoneUI/nl.lproj/UIHistoryCell.strings new file mode 100644 index 000000000..bc4787143 Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UIHistoryCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIMainBar.strings b/Classes/LinphoneUI/nl.lproj/UIMainBar.strings new file mode 100644 index 000000000..e9c155f5d Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UIMainBar.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIMainBar~ipad.strings b/Classes/LinphoneUI/nl.lproj/UIMainBar~ipad.strings new file mode 100644 index 000000000..86a7400f9 Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UIMainBar~ipad.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIStateBar.strings b/Classes/LinphoneUI/nl.lproj/UIStateBar.strings new file mode 100644 index 000000000..9d9e3299b Binary files /dev/null and b/Classes/LinphoneUI/nl.lproj/UIStateBar.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/StatusBarView.strings b/Classes/LinphoneUI/ru.lproj/StatusBarView.strings new file mode 100644 index 000000000..dd4d7dadc Binary files /dev/null and b/Classes/LinphoneUI/ru.lproj/StatusBarView.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/TabBarView.strings b/Classes/LinphoneUI/ru.lproj/TabBarView.strings new file mode 100644 index 000000000..ed635fcaa Binary files /dev/null and b/Classes/LinphoneUI/ru.lproj/TabBarView.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UICallBar.strings b/Classes/LinphoneUI/ru.lproj/UICallBar.strings deleted file mode 100644 index c85035a65..000000000 Binary files a/Classes/LinphoneUI/ru.lproj/UICallBar.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ru.lproj/UICallBar~ipad.strings b/Classes/LinphoneUI/ru.lproj/UICallBar~ipad.strings deleted file mode 100644 index 5a247ab58..000000000 Binary files a/Classes/LinphoneUI/ru.lproj/UICallBar~ipad.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ru.lproj/UICallCell.strings b/Classes/LinphoneUI/ru.lproj/UICallCell.strings deleted file mode 100644 index 8dad3a8a4..000000000 Binary files a/Classes/LinphoneUI/ru.lproj/UICallCell.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ru.lproj/UICallConferenceCell.strings b/Classes/LinphoneUI/ru.lproj/UICallConferenceCell.strings new file mode 100644 index 000000000..f8f9c3150 Binary files /dev/null and b/Classes/LinphoneUI/ru.lproj/UICallConferenceCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UICallPausedCell.strings b/Classes/LinphoneUI/ru.lproj/UICallPausedCell.strings new file mode 100644 index 000000000..12ea9ab12 Binary files /dev/null and b/Classes/LinphoneUI/ru.lproj/UICallPausedCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/ru.lproj/UIChatBubblePhotoCell.strings new file mode 100644 index 000000000..31e39ca0f Binary files /dev/null and b/Classes/LinphoneUI/ru.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/ru.lproj/UIChatBubbleTextCell.strings new file mode 100644 index 000000000..f695a8271 Binary files /dev/null and b/Classes/LinphoneUI/ru.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIChatCell.strings b/Classes/LinphoneUI/ru.lproj/UIChatCell.strings index c16425967..20c2bc60b 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UIChatCell.strings and b/Classes/LinphoneUI/ru.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIConferenceHeader.strings b/Classes/LinphoneUI/ru.lproj/UIConferenceHeader.strings deleted file mode 100644 index e97e13fa3..000000000 Binary files a/Classes/LinphoneUI/ru.lproj/UIConferenceHeader.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ru.lproj/UIContactCell.strings b/Classes/LinphoneUI/ru.lproj/UIContactCell.strings new file mode 100644 index 000000000..aca210d0b Binary files /dev/null and b/Classes/LinphoneUI/ru.lproj/UIContactCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/ru.lproj/UIContactDetailsCell.strings new file mode 100644 index 000000000..ab04faacd Binary files /dev/null and b/Classes/LinphoneUI/ru.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIContactDetailsFooter.strings b/Classes/LinphoneUI/ru.lproj/UIContactDetailsFooter.strings deleted file mode 100644 index af98b48fc..000000000 Binary files a/Classes/LinphoneUI/ru.lproj/UIContactDetailsFooter.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ru.lproj/UIContactDetailsHeader.strings b/Classes/LinphoneUI/ru.lproj/UIContactDetailsHeader.strings deleted file mode 100644 index 793dfe07b..000000000 Binary files a/Classes/LinphoneUI/ru.lproj/UIContactDetailsHeader.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ru.lproj/UIHistoryCell.strings b/Classes/LinphoneUI/ru.lproj/UIHistoryCell.strings index 5eb42767a..731db2b00 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UIHistoryCell.strings and b/Classes/LinphoneUI/ru.lproj/UIHistoryCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIMainBar.strings b/Classes/LinphoneUI/ru.lproj/UIMainBar.strings deleted file mode 100644 index e59c27e99..000000000 Binary files a/Classes/LinphoneUI/ru.lproj/UIMainBar.strings and /dev/null differ diff --git a/Classes/LinphoneUI/ru.lproj/UIMainBar~ipad.strings b/Classes/LinphoneUI/ru.lproj/UIMainBar~ipad.strings deleted file mode 100644 index 373faf833..000000000 Binary files a/Classes/LinphoneUI/ru.lproj/UIMainBar~ipad.strings and /dev/null differ diff --git a/Classes/LinphoneUI/sv.lproj/StatusBarView.strings b/Classes/LinphoneUI/sv.lproj/StatusBarView.strings new file mode 100644 index 000000000..179d2bab3 Binary files /dev/null and b/Classes/LinphoneUI/sv.lproj/StatusBarView.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/TabBarView.strings b/Classes/LinphoneUI/sv.lproj/TabBarView.strings new file mode 100644 index 000000000..3b36c511c Binary files /dev/null and b/Classes/LinphoneUI/sv.lproj/TabBarView.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UICallConferenceCell.strings b/Classes/LinphoneUI/sv.lproj/UICallConferenceCell.strings new file mode 100644 index 000000000..59189566f Binary files /dev/null and b/Classes/LinphoneUI/sv.lproj/UICallConferenceCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UICallPausedCell.strings b/Classes/LinphoneUI/sv.lproj/UICallPausedCell.strings new file mode 100644 index 000000000..ea73a7198 Binary files /dev/null and b/Classes/LinphoneUI/sv.lproj/UICallPausedCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/sv.lproj/UIChatBubblePhotoCell.strings new file mode 100644 index 000000000..3b0b8866d Binary files /dev/null and b/Classes/LinphoneUI/sv.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/sv.lproj/UIChatBubbleTextCell.strings new file mode 100644 index 000000000..5659420f7 Binary files /dev/null and b/Classes/LinphoneUI/sv.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIChatCell.strings b/Classes/LinphoneUI/sv.lproj/UIChatCell.strings new file mode 100644 index 000000000..f09880909 Binary files /dev/null and b/Classes/LinphoneUI/sv.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIChatCreateCell.strings b/Classes/LinphoneUI/sv.lproj/UIChatCreateCell.strings new file mode 100644 index 000000000..ac8173e78 Binary files /dev/null and b/Classes/LinphoneUI/sv.lproj/UIChatCreateCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/sv.lproj/UIConfirmationDialog.strings new file mode 100644 index 000000000..2d9b3c980 Binary files /dev/null and b/Classes/LinphoneUI/sv.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIContactCell.strings b/Classes/LinphoneUI/sv.lproj/UIContactCell.strings new file mode 100644 index 000000000..c672025c5 Binary files /dev/null and b/Classes/LinphoneUI/sv.lproj/UIContactCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/sv.lproj/UIContactDetailsCell.strings new file mode 100644 index 000000000..a5de17a75 Binary files /dev/null and b/Classes/LinphoneUI/sv.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIHistoryCell.strings b/Classes/LinphoneUI/sv.lproj/UIHistoryCell.strings new file mode 100644 index 000000000..8d91da573 Binary files /dev/null and b/Classes/LinphoneUI/sv.lproj/UIHistoryCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/StatusBarView.strings b/Classes/LinphoneUI/zh_TW.lproj/StatusBarView.strings new file mode 100644 index 000000000..3ca9a0d25 Binary files /dev/null and b/Classes/LinphoneUI/zh_TW.lproj/StatusBarView.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/TabBarView.strings b/Classes/LinphoneUI/zh_TW.lproj/TabBarView.strings new file mode 100644 index 000000000..cf4ea9723 Binary files /dev/null and b/Classes/LinphoneUI/zh_TW.lproj/TabBarView.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UICallBar.strings b/Classes/LinphoneUI/zh_TW.lproj/UICallBar.strings deleted file mode 100644 index 4b627577c..000000000 Binary files a/Classes/LinphoneUI/zh_TW.lproj/UICallBar.strings and /dev/null differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UICallBar~ipad.strings b/Classes/LinphoneUI/zh_TW.lproj/UICallBar~ipad.strings deleted file mode 100644 index 7bda03e1b..000000000 Binary files a/Classes/LinphoneUI/zh_TW.lproj/UICallBar~ipad.strings and /dev/null differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UICallCell.strings b/Classes/LinphoneUI/zh_TW.lproj/UICallCell.strings index 7fb608a6d..df97e341e 100644 Binary files a/Classes/LinphoneUI/zh_TW.lproj/UICallCell.strings and b/Classes/LinphoneUI/zh_TW.lproj/UICallCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UICallConferenceCell.strings b/Classes/LinphoneUI/zh_TW.lproj/UICallConferenceCell.strings new file mode 100644 index 000000000..7252ee5f2 Binary files /dev/null and b/Classes/LinphoneUI/zh_TW.lproj/UICallConferenceCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UICallPausedCell.strings b/Classes/LinphoneUI/zh_TW.lproj/UICallPausedCell.strings new file mode 100644 index 000000000..1f92d38e1 Binary files /dev/null and b/Classes/LinphoneUI/zh_TW.lproj/UICallPausedCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/zh_TW.lproj/UIChatBubblePhotoCell.strings new file mode 100644 index 000000000..6cd310a09 Binary files /dev/null and b/Classes/LinphoneUI/zh_TW.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/zh_TW.lproj/UIChatBubbleTextCell.strings new file mode 100644 index 000000000..6192ed2bf Binary files /dev/null and b/Classes/LinphoneUI/zh_TW.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIChatCell.strings b/Classes/LinphoneUI/zh_TW.lproj/UIChatCell.strings index c16425967..20c2bc60b 100644 Binary files a/Classes/LinphoneUI/zh_TW.lproj/UIChatCell.strings and b/Classes/LinphoneUI/zh_TW.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIContactCell.strings b/Classes/LinphoneUI/zh_TW.lproj/UIContactCell.strings new file mode 100644 index 000000000..aca210d0b Binary files /dev/null and b/Classes/LinphoneUI/zh_TW.lproj/UIContactCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsCell.strings new file mode 100644 index 000000000..1c3e5ecc2 Binary files /dev/null and b/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsFooter.strings b/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsFooter.strings new file mode 100644 index 000000000..d8404ad2e Binary files /dev/null and b/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsFooter.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsHeader.strings b/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsHeader.strings index 20b1a62e9..29afde9b2 100644 Binary files a/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsHeader.strings and b/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsHeader.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIHistoryCell.strings b/Classes/LinphoneUI/zh_TW.lproj/UIHistoryCell.strings new file mode 100644 index 000000000..731db2b00 Binary files /dev/null and b/Classes/LinphoneUI/zh_TW.lproj/UIHistoryCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIMainBar.strings b/Classes/LinphoneUI/zh_TW.lproj/UIMainBar.strings new file mode 100644 index 000000000..7dcd85f93 Binary files /dev/null and b/Classes/LinphoneUI/zh_TW.lproj/UIMainBar.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIMainBar~ipad.strings b/Classes/LinphoneUI/zh_TW.lproj/UIMainBar~ipad.strings new file mode 100644 index 000000000..670e50eb1 Binary files /dev/null and b/Classes/LinphoneUI/zh_TW.lproj/UIMainBar~ipad.strings differ diff --git a/Classes/MainStoryboard.storyboard b/Classes/MainStoryboard.storyboard index dc493538e..d720f290a 100644 --- a/Classes/MainStoryboard.storyboard +++ b/Classes/MainStoryboard.storyboard @@ -1,8 +1,7 @@ - + - - + @@ -13,11 +12,11 @@ - + - - + + @@ -32,7 +31,7 @@ - + @@ -40,9 +39,6 @@ - - - diff --git a/Classes/PhoneMainView.h b/Classes/PhoneMainView.h index 2816df501..034e8cb60 100644 --- a/Classes/PhoneMainView.h +++ b/Classes/PhoneMainView.h @@ -4,53 +4,64 @@ * * 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 #import -#import "LinphoneManager.h" -#import "UICompositeViewController.h" - /* These imports are here so that we can import PhoneMainView.h without bothering to import all the rest of the view headers */ -#import "AboutViewController.h" -#import "FirstLoginViewController.h" -#import "IncomingCallViewController.h" -#import "ChatRoomViewController.h" -#import "ChatViewController.h" -#import "DialerViewController.h" -#import "ContactsViewController.h" -#import "ContactDetailsViewController.h" -#import "ContactDetailsLabelViewController.h" -#import "ImagePickerViewController.h" -#import "HistoryViewController.h" -#import "HistoryDetailsViewController.h" -#import "InCallViewController.h" -#import "SettingsViewController.h" -#import "FirstLoginViewController.h" -#import "WizardViewController.h" -#import "IncomingCallViewController.h" -#import "ImageViewController.h" +#import "StatusBarView.h" +#import "TabBarView.h" +#import "AboutView.h" +#import "ChatConversationView.h" +#import "ChatConversationCreateView.h" +#import "ChatsListView.h" +#import "ContactDetailsView.h" +#import "ContactsListView.h" +#import "DialerView.h" +#import "HistoryDetailsView.h" +#import "HistoryListView.h" +#import "ImageView.h" +#import "CallView.h" +#import "CallIncomingView.h" +#import "CallOutgoingView.h" +#import "FirstLoginView.h" +#import "SettingsView.h" +#import "SideMenuView.h" +#import "AssistantView.h" +#import "CallSideMenuView.h" +#import "UIConfirmationDialog.h" +#import "DTAlertView.h" +#import "DTActionSheet.h" +#import "Utils.h" + +#define DYNAMIC_CAST(x, cls) \ + ({ \ + cls *inst_ = (cls *)(x); \ + [inst_ isKindOfClass:[cls class]] ? inst_ : nil; \ + }) + +#define VIEW(x) \ + DYNAMIC_CAST([PhoneMainView.instance.mainViewController getCachedController:x.compositeViewDescription.name], x) @class PhoneMainView; @interface RootViewManager : NSObject -@property (nonatomic, retain) PhoneMainView* portraitViewController; -@property (nonatomic, retain) PhoneMainView* rotatingViewController; -@property (nonatomic, retain) NSMutableArray* viewDescriptionStack; +@property(nonatomic, strong) PhoneMainView *portraitViewController; +@property(nonatomic, strong) PhoneMainView *rotatingViewController; +@property(nonatomic, strong) NSMutableArray *viewDescriptionStack; +(RootViewManager*)instance; + (void)setupWithPortrait:(PhoneMainView*)portrait; @@ -63,19 +74,20 @@ NSMutableArray *inhibitedEvents; } -@property (nonatomic, retain) IBOutlet UIView *statusBarBG; -@property (nonatomic, retain) IBOutlet UICompositeViewController *mainViewController; +@property(nonatomic, strong) IBOutlet UIView *statusBarBG; +@property(nonatomic, strong) IBOutlet UICompositeView *mainViewController; -@property (nonatomic, retain) NSString* name; -@property (readonly) UICompositeViewDescription *currentView; -@property (readonly, retain) MPVolumeView* volumeView; +@property(nonatomic, strong) NSString *name; +@property(weak, readonly) UICompositeViewDescription *currentView; +@property(readonly, strong) MPVolumeView *volumeView; -- (UIViewController*)changeCurrentView:(UICompositeViewDescription *)currentView; -- (UIViewController*)changeCurrentView:(UICompositeViewDescription *)currentView push:(BOOL)push; +- (void)changeCurrentView:(UICompositeViewDescription *)currentView; +- (void)changeCurrentView:(UICompositeViewDescription *)currentView push:(BOOL)push; +- (void)changeCurrentView:(UICompositeViewDescription *)view push:(BOOL)push animated:(BOOL)animated; - (UIViewController*)popCurrentView; -- (void)popToView:(UICompositeViewDescription *)currentView; +- (UIViewController *)popToView:(UICompositeViewDescription *)currentView; - (UICompositeViewDescription *)firstView; -- (void)showStateBar:(BOOL)show; +- (void)showStatusBar:(BOOL)show; - (void)showTabBar:(BOOL)show; - (void)fullScreen:(BOOL)enabled; - (void)updateStatusBar:(UICompositeViewDescription*)to_view; diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m index b4c070454..758385878 100644 --- a/Classes/PhoneMainView.m +++ b/Classes/PhoneMainView.m @@ -4,101 +4,113 @@ * * 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 #import #import "LinphoneAppDelegate.h" #import "PhoneMainView.h" -#import "Utils.h" -#import "DTActionSheet.h" - -static RootViewManager* rootViewManagerInstance = nil; +static RootViewManager *rootViewManagerInstance = nil; @implementation RootViewManager { - PhoneMainView* currentViewController; + PhoneMainView *currentViewController; } -+ (void)setupWithPortrait:(PhoneMainView*)portrait { - assert(rootViewManagerInstance == nil); - rootViewManagerInstance = [[RootViewManager alloc]initWithPortrait:portrait]; ++ (void)setupWithPortrait:(PhoneMainView *)portrait { + assert(rootViewManagerInstance == nil); + rootViewManagerInstance = [[RootViewManager alloc] initWithPortrait:portrait]; } -- (instancetype)initWithPortrait:(PhoneMainView*)portrait { - self = [super init]; - if ( self ){ - self.portraitViewController = portrait; - self.rotatingViewController = [[[PhoneMainView alloc] init] autorelease]; +- (instancetype)initWithPortrait:(PhoneMainView *)portrait { + self = [super init]; + if (self) { + self.portraitViewController = portrait; + self.rotatingViewController = [[PhoneMainView alloc] init]; - self.portraitViewController.name = @"Portrait"; - self.rotatingViewController.name = @"Rotating"; + self.portraitViewController.name = @"Portrait"; + self.rotatingViewController.name = @"Rotating"; - currentViewController = portrait; - self.viewDescriptionStack = [NSMutableArray array]; - - } - return self; + currentViewController = portrait; + self.viewDescriptionStack = [NSMutableArray array]; + } + return self; } + (RootViewManager *)instance { - if( !rootViewManagerInstance ){ - @throw [NSException exceptionWithName:@"RootViewManager" reason:@"nil instance" userInfo:nil]; - } - return rootViewManagerInstance; + if (!rootViewManagerInstance) { + @throw [NSException exceptionWithName:@"RootViewManager" reason:@"nil instance" userInfo:nil]; + } + return rootViewManagerInstance; } -- (PhoneMainView*)currentView { - return currentViewController; +- (PhoneMainView *)currentView { + return currentViewController; } -- (PhoneMainView*)setViewControllerForDescription:(UICompositeViewDescription*)description { - PhoneMainView* newMainView = description.landscapeMode ? self.rotatingViewController : self.portraitViewController; +- (PhoneMainView *)setViewControllerForDescription:(UICompositeViewDescription *)description { + return currentViewController; - if( [LinphoneManager runningOnIpad] ) return currentViewController; +// not sure what this code was doing... but since iphone does support rotation as well now... +#if 0 + if (IPAD) + return currentViewController; - if( newMainView != currentViewController ) - { - PhoneMainView* previousMainView = currentViewController; - UIInterfaceOrientation nextViewOrientation = newMainView.interfaceOrientation; - UIInterfaceOrientation previousOrientation = currentViewController.interfaceOrientation; + PhoneMainView *newMainView = description.landscapeMode ? self.rotatingViewController : self.portraitViewController; + if (newMainView != currentViewController) { + PhoneMainView *previousMainView = currentViewController; + UIInterfaceOrientation nextViewOrientation = newMainView.interfaceOrientation; + UIInterfaceOrientation previousOrientation = currentViewController.interfaceOrientation; - Linphone_log(@"Changing rootViewController: %@ -> %@", currentViewController.name, newMainView.name); - currentViewController = newMainView; - LinphoneAppDelegate* delegate = (LinphoneAppDelegate*)[UIApplication sharedApplication].delegate; + LOGI(@"Changing rootViewController: %@ -> %@", currentViewController.name, newMainView.name); + currentViewController = newMainView; + LinphoneAppDelegate *delegate = (LinphoneAppDelegate *)[UIApplication sharedApplication].delegate; - [UIView transitionWithView:delegate.window - duration:0.3 - options:UIViewAnimationOptionTransitionFlipFromLeft|UIViewAnimationOptionAllowAnimatedContent - animations:^{ - delegate.window.rootViewController = newMainView; - // when going to landscape-enabled view, we have to get the current portrait frame and orientation, - // because it could still have landscape-based size - if( nextViewOrientation != previousOrientation && newMainView == self.rotatingViewController ){ - newMainView.view.frame = previousMainView.view.frame; - [newMainView.mainViewController.view setFrame:previousMainView.mainViewController.view.frame]; - [newMainView willRotateToInterfaceOrientation:previousOrientation duration:0.3]; - [newMainView willAnimateRotationToInterfaceOrientation:previousOrientation duration:0.3]; - [newMainView didRotateFromInterfaceOrientation:nextViewOrientation]; - } - - } - completion:^(BOOL finished) { - }]; - } - return currentViewController; + if ([[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"] == true) { + [UIView transitionWithView:delegate.window + duration:0.3 + options:UIViewAnimationOptionTransitionFlipFromLeft | UIViewAnimationOptionAllowAnimatedContent + animations:^{ + delegate.window.rootViewController = newMainView; + // when going to landscape-enabled view, we have to get the current portrait frame and orientation, + // because it could still have landscape-based size + if (nextViewOrientation != previousOrientation && newMainView == self.rotatingViewController) { + newMainView.view.frame = previousMainView.view.frame; + [newMainView.mainViewController.view setFrame:previousMainView.mainViewController.view.frame]; + [newMainView willRotateToInterfaceOrientation:previousOrientation duration:0.3]; + [newMainView willAnimateRotationToInterfaceOrientation:previousOrientation duration:0.3]; + [newMainView didRotateFromInterfaceOrientation:nextViewOrientation]; + } + } + completion:^(BOOL finished){ + }]; + } else { + delegate.window.rootViewController = newMainView; + // when going to landscape-enabled view, we have to get the current portrait frame and orientation, + // because it could still have landscape-based size + if (nextViewOrientation != previousOrientation && newMainView == self.rotatingViewController) { + newMainView.view.frame = previousMainView.view.frame; + [newMainView.mainViewController.view setFrame:previousMainView.mainViewController.view.frame]; + [newMainView willRotateToInterfaceOrientation:previousOrientation duration:0.]; + [newMainView willAnimateRotationToInterfaceOrientation:previousOrientation duration:0.]; + [newMainView didRotateFromInterfaceOrientation:nextViewOrientation]; + } + } + } + return currentViewController; +#endif } @end @@ -110,638 +122,648 @@ static RootViewManager* rootViewManagerInstance = nil; @synthesize statusBarBG; @synthesize volumeView; - #pragma mark - Lifecycle Functions - (void)initPhoneMainView { - currentView = nil; - inhibitedEvents = [[NSMutableArray alloc] init]; + currentView = nil; + inhibitedEvents = [[NSMutableArray alloc] init]; } - (id)init { - self = [super init]; - if (self) { + self = [super init]; + if (self) { [self initPhoneMainView]; - } - return self; + } + return self; } - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { [self initPhoneMainView]; - } - return self; + } + return self; } - (id)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { + self = [super initWithCoder:decoder]; + if (self) { [self initPhoneMainView]; } - return self; + return self; } - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [mainViewController release]; - [inhibitedEvents release]; - - [super dealloc]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } - #pragma mark - ViewController Functions - (void)viewDidLoad { - [super viewDidLoad]; + [super viewDidLoad]; - volumeView = [[MPVolumeView alloc] initWithFrame: CGRectMake(-100,-100,16,16)]; - volumeView.showsRouteButton = false; - volumeView.userInteractionEnabled = false; + volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(-100, -100, 16, 16)]; + volumeView.showsRouteButton = false; + volumeView.userInteractionEnabled = false; - [self.view addSubview:mainViewController.view]; + [self.view addSubview:mainViewController.view]; } - (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - // Set observers - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(callUpdate:) - name:kLinphoneCallUpdate - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(registrationUpdate:) - name:kLinphoneRegistrationUpdate - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(textReceived:) - name:kLinphoneTextReceived - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(onGlobalStateChanged:) - name:kLinphoneGlobalStateUpdate - object:nil]; - [[UIDevice currentDevice] setBatteryMonitoringEnabled:YES]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(batteryLevelChanged:) - name:UIDeviceBatteryLevelDidChangeNotification - object:nil]; + [super viewWillAppear:animated]; + // Set observers + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(callUpdate:) + name:kLinphoneCallUpdate + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(registrationUpdate:) + name:kLinphoneRegistrationUpdate + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(textReceived:) + name:kLinphoneMessageReceived + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(onGlobalStateChanged:) + name:kLinphoneGlobalStateUpdate + object:nil]; + [[UIDevice currentDevice] setBatteryMonitoringEnabled:YES]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(batteryLevelChanged:) + name:UIDeviceBatteryLevelDidChangeNotification + object:nil]; } - (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; + [super viewWillDisappear:animated]; - // Remove observers - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneCallUpdate - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneRegistrationUpdate - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneTextReceived - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneConfiguringStateUpdate - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIDeviceBatteryLevelDidChangeNotification - object:nil]; + // Remove observers + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneCallUpdate object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneRegistrationUpdate object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:kLinphoneMessageReceived object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UIDeviceBatteryLevelDidChangeNotification + object:nil]; [[UIDevice currentDevice] setBatteryMonitoringEnabled:NO]; - } --(void)viewDidAppear:(BOOL)animated { +- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; } - (void)setVolumeHidden:(BOOL)hidden { - // sometimes when placing a call, the volume view will appear. Inserting a - // carefully hidden MPVolumeView into the view hierarchy will hide it - if( hidden ){ - if ( !(volumeView.superview == self.view) ){ - [self.view addSubview:volumeView]; - } - } else { - if( volumeView.superview == self.view ){ - [volumeView removeFromSuperview]; - } - } -} - - -- (NSUInteger)supportedInterfaceOrientations { - if( [LinphoneManager runningOnIpad ] || [mainViewController currentViewSupportsLandscape] ) - return UIInterfaceOrientationMaskAll; - else { - return UIInterfaceOrientationMaskPortrait; - } -} - -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; - [mainViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; - [self orientationUpdate:toInterfaceOrientation]; -} - -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; - [mainViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; -} - -- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { - [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; - [mainViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; -} - -- (UIInterfaceOrientation)interfaceOrientation { - return [mainViewController currentOrientation]; -} - -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - [mainViewController clearCache:[RootViewManager instance].viewDescriptionStack]; -} - -#pragma mark - Event Functions - -- (void)textReceived:(NSNotification*)notif { - LinphoneAddress* from = [[notif.userInfo objectForKey:@"from_address"] pointerValue]; - NSString* callID = [notif.userInfo objectForKey:@"call-id"]; - if(from != nil) { - [self playMessageSoundForCallID:callID]; - } - [self updateApplicationBadgeNumber]; -} - -- (void)registrationUpdate:(NSNotification*)notif { - LinphoneRegistrationState state = [[notif.userInfo objectForKey: @"state"] intValue]; - LinphoneProxyConfig *cfg = [[notif.userInfo objectForKey: @"cfg"] pointerValue]; - //Only report bad credential issue - if (state == LinphoneRegistrationFailed - &&[UIApplication sharedApplication].applicationState == UIApplicationStateBackground - && linphone_proxy_config_get_error(cfg) == LinphoneReasonBadCredentials ) { - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Registration failure",nil) - message:NSLocalizedString(@"Bad credentials, check your account settings", nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil,nil]; - [error show]; - [error release]; - } -} - -- (void)onGlobalStateChanged:(NSNotification*)notif { - LinphoneGlobalState state = (LinphoneGlobalState)[[[notif userInfo] valueForKey:@"state"] integerValue]; - static BOOL already_shown = FALSE; - if( state == LinphoneGlobalOn && !already_shown && [LinphoneManager instance].wasRemoteProvisioned ){ - LinphoneProxyConfig* conf = NULL; - linphone_core_get_default_proxy([LinphoneManager getLc], &conf); - if( [[LinphoneManager instance] lpConfigBoolForKey:@"show_login_view" forSection:@"app"] && conf == NULL){ - already_shown = TRUE; - WizardViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[WizardViewController compositeViewDescription]], WizardViewController); - if(controller != nil) { - [controller fillDefaultValues]; - } - } - } -} - -- (void)callUpdate:(NSNotification*)notif { - LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue]; - LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue]; - NSString *message = [notif.userInfo objectForKey: @"message"]; - - bool canHideInCallView = (linphone_core_get_calls([LinphoneManager getLc]) == NULL); - - // Don't handle call state during incoming call view - if([[self currentView] equal:[IncomingCallViewController compositeViewDescription]] && state != LinphoneCallError && state != LinphoneCallEnd) { - return; - } - - switch (state) { - case LinphoneCallIncomingReceived: - case LinphoneCallIncomingEarlyMedia: - { - [self displayIncomingCall:call]; - break; - } - case LinphoneCallOutgoingInit: - case LinphoneCallPausedByRemote: - case LinphoneCallConnected: - case LinphoneCallStreamsRunning: - { - [self changeCurrentView:[InCallViewController compositeViewDescription]]; - break; - } - case LinphoneCallUpdatedByRemote: - { - const LinphoneCallParams* current = linphone_call_get_current_params(call); - const LinphoneCallParams* remote = linphone_call_get_remote_params(call); - - if (linphone_call_params_video_enabled(current) && !linphone_call_params_video_enabled(remote)) { - [self changeCurrentView:[InCallViewController compositeViewDescription]]; - } - break; - } - case LinphoneCallError: - { - [self displayCallError:call message: message]; - } - case LinphoneCallEnd: - { - if (canHideInCallView) { - // Go to dialer view - DialerViewController *controller = DYNAMIC_CAST([self changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController); - if(controller != nil) { - [controller setAddress:@""]; - [controller setTransferMode:FALSE]; - } - } else { - [self changeCurrentView:[InCallViewController compositeViewDescription]]; - } - break; - } - default: - break; - } - [self updateApplicationBadgeNumber]; -} - - -#pragma mark - - -- (void)orientationUpdate:(UIInterfaceOrientation)orientation { - int oldLinphoneOrientation = linphone_core_get_device_rotation([LinphoneManager getLc]); - int newRotation = 0; - switch (orientation) { - case UIInterfaceOrientationPortrait: - newRotation = 0; - break; - case UIInterfaceOrientationPortraitUpsideDown: - newRotation = 180; - break; - case UIInterfaceOrientationLandscapeRight: - newRotation = 270; - break; - case UIInterfaceOrientationLandscapeLeft: - newRotation = 90; - break; - default: - newRotation = oldLinphoneOrientation; - } - if (oldLinphoneOrientation != newRotation) { - linphone_core_set_device_rotation([LinphoneManager getLc], newRotation); - LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); - if (call && linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { - //Orientation has changed, must call update call - linphone_core_update_call([LinphoneManager getLc], call, NULL); - } - } -} - -- (void)startUp { - LinphoneCore* core = nil; - @try { - core = [LinphoneManager getLc]; - LinphoneManager* lm = [LinphoneManager instance]; - if( linphone_core_get_global_state(core) != LinphoneGlobalOn ){ - [self changeCurrentView: [DialerViewController compositeViewDescription]]; - } else if ([[LinphoneManager instance] lpConfigBoolForKey:@"enable_first_login_view_preference"] == true) { - // Change to fist login view - [self changeCurrentView: [FirstLoginViewController compositeViewDescription]]; - } else { - // always start to dialer when testing - // Change to default view - const MSList *list = linphone_core_get_proxy_config_list(core); - if(list != NULL || ([lm lpConfigBoolForKey:@"hide_wizard_preference"] == true) || lm.isTesting) { - [self changeCurrentView: [DialerViewController compositeViewDescription]]; - } else { - WizardViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[WizardViewController compositeViewDescription]], WizardViewController); - if(controller != nil) { - [controller reset]; - } - } - } - [self updateApplicationBadgeNumber]; // Update Badge at startup - } - @catch (NSException *exception) { - // we'll wait until the app transitions correctly - } -} - -- (void)updateApplicationBadgeNumber { - int count = 0; - count += linphone_core_get_missed_calls_count([LinphoneManager getLc]); - count += [LinphoneManager unreadMessageCount]; - count += linphone_core_get_calls_nb([LinphoneManager getLc]); - [[UIApplication sharedApplication] setApplicationIconBadgeNumber:count]; -} - -+ (CATransition*)getBackwardTransition { - BOOL RTL = [LinphoneManager langageDirectionIsRTL]; - NSString* transition = RTL? kCATransitionFromRight : kCATransitionFromLeft; - CATransition* trans = [CATransition animation]; - [trans setType:kCATransitionPush]; - [trans setDuration:0.35]; - [trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; - [trans setSubtype:transition]; - - return trans; -} - -+ (CATransition*)getForwardTransition { - BOOL RTL = [LinphoneManager langageDirectionIsRTL]; - NSString* transition = RTL? kCATransitionFromLeft : kCATransitionFromRight; - CATransition* trans = [CATransition animation]; - [trans setType:kCATransitionPush]; - [trans setDuration:0.35]; - [trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; - [trans setSubtype:transition]; - - return trans; -} - -+ (CATransition*)getTransition:(UICompositeViewDescription *)old new:(UICompositeViewDescription *)new { - bool left = false; - - if([old equal:[ChatViewController compositeViewDescription]]) { - if([new equal:[ContactsViewController compositeViewDescription]] || - [new equal:[DialerViewController compositeViewDescription]] || - [new equal:[HistoryViewController compositeViewDescription]]) { - left = true; - } - } else if([old equal:[SettingsViewController compositeViewDescription]]) { - if([new equal:[DialerViewController compositeViewDescription]] || - [new equal:[ContactsViewController compositeViewDescription]] || - [new equal:[HistoryViewController compositeViewDescription]] || - [new equal:[ChatViewController compositeViewDescription]]) { - left = true; - } - } else if([old equal:[DialerViewController compositeViewDescription]]) { - if([new equal:[ContactsViewController compositeViewDescription]] || - [new equal:[HistoryViewController compositeViewDescription]]) { - left = true; - } - } else if([old equal:[ContactsViewController compositeViewDescription]]) { - if([new equal:[HistoryViewController compositeViewDescription]]) { - left = true; - } - } - - if(left) { - return [PhoneMainView getBackwardTransition]; - } else { - return [PhoneMainView getForwardTransition]; - } -} - -+ (PhoneMainView *) instance { - return [[RootViewManager instance] currentView]; -} - -- (void) showTabBar:(BOOL)show { - [mainViewController setToolBarHidden:!show]; -} - -- (void) showStateBar:(BOOL)show { - [mainViewController setStateBarHidden:!show]; -} - -- (void)updateStatusBar:(UICompositeViewDescription*)to_view { -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 - // In iOS7, the app has a black background on dialer, incoming and incall, so we have to adjust the - // status bar style for each transition to/from these views - BOOL toLightStatus = (to_view != NULL) && ![to_view darkBackground]; - if( !toLightStatus ) { - // black bg: white text on black background - [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; - - - [UIView animateWithDuration:0.3f - animations:^{statusBarBG.backgroundColor = [UIColor blackColor];} ]; - - } else { - // light bg: black text on white bg - [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault]; - [UIView animateWithDuration:0.3f - animations:^{ statusBarBG.backgroundColor = [UIColor colorWithWhite:0.935 alpha:1]; }]; - - } -#endif -} - - -- (void)fullScreen:(BOOL)enabled { - [statusBarBG setHidden:enabled]; - [mainViewController setFullScreen:enabled]; -} - -- (UIViewController*)changeCurrentView:(UICompositeViewDescription *)view { - return [self changeCurrentView:view push:FALSE]; -} - -- (UIViewController*)changeCurrentView:(UICompositeViewDescription*)view push:(BOOL)push { - BOOL force = push; - NSMutableArray* viewStack = [RootViewManager instance].viewDescriptionStack; - if(!push ) { - force = [viewStack count] > 1; - [viewStack removeAllObjects]; - } - [viewStack addObject:view]; - return [self _changeCurrentView:view transition:nil force:force]; -} - -- (UIViewController*)_changeCurrentView:(UICompositeViewDescription*)view transition:(CATransition*)transition force:(BOOL)force { - [LinphoneLogger logc:LinphoneLoggerLog format:"PhoneMainView: Change current view to %@", [view name]]; - - PhoneMainView* vc = [[RootViewManager instance] setViewControllerForDescription:view]; - - if(force || ![view equal:vc.currentView] || vc != self) { - if(transition == nil) - transition = [PhoneMainView getTransition:vc.currentView new:view]; - if ([[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"] == true) { - [vc.mainViewController setViewTransition:transition]; - } else { - [vc.mainViewController setViewTransition:nil]; - } - [vc updateStatusBar:view]; - [vc.mainViewController changeView:view]; - vc->currentView = view; - } - - //[[RootViewManager instance] setViewControllerForDescription:view]; - - NSDictionary* mdict = [NSMutableDictionary dictionaryWithObject:vc->currentView forKey:@"view"]; - [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneMainViewChange object:self userInfo:mdict]; - - return [vc->mainViewController getCurrentViewController]; -} - -- (void)popToView:(UICompositeViewDescription*)view { - NSMutableArray* viewStack = [RootViewManager instance].viewDescriptionStack; - while([viewStack count] > 1 && ![[viewStack lastObject] equal:view]) { - [viewStack removeLastObject]; - } - [self _changeCurrentView:[viewStack lastObject] transition:[PhoneMainView getBackwardTransition] force:TRUE]; -} - -- (UICompositeViewDescription *)firstView { - UICompositeViewDescription *view = nil; - NSArray* viewStack = [RootViewManager instance].viewDescriptionStack; - if([viewStack count]) { - view = [viewStack objectAtIndex:0]; - } - return view; -} - -- (UIViewController*)popCurrentView { - [LinphoneLogger logc:LinphoneLoggerLog format:"PhoneMainView: Pop view"]; - NSMutableArray* viewStack = [RootViewManager instance].viewDescriptionStack; - if([viewStack count] > 1) { - [viewStack removeLastObject]; - [self _changeCurrentView:[viewStack lastObject] transition:[PhoneMainView getBackwardTransition] force:TRUE]; - return [mainViewController getCurrentViewController]; - } - return nil; -} - -- (void)displayCallError:(LinphoneCall*) call message:(NSString*) message { - const char* lUserNameChars=linphone_address_get_username(linphone_call_get_remote_address(call)); - NSString* lUserName = lUserNameChars?[[[NSString alloc] initWithUTF8String:lUserNameChars] autorelease]:NSLocalizedString(@"Unknown",nil); - NSString* lMessage; - NSString* lTitle; - - //get default proxy - LinphoneProxyConfig* proxyCfg; - linphone_core_get_default_proxy([LinphoneManager getLc],&proxyCfg); - if (proxyCfg == nil) { - lMessage = NSLocalizedString(@"Please make sure your device is connected to the internet and double check your SIP account configuration in the settings.", nil); - } else { - lMessage = [NSString stringWithFormat : NSLocalizedString(@"Cannot call %@", nil), lUserName]; - } - - if (linphone_call_get_reason(call) == LinphoneReasonNotFound) { - lMessage = [NSString stringWithFormat : NSLocalizedString(@"'%@' not registered", nil), lUserName]; - } else { - if (message != nil) { - lMessage = [NSString stringWithFormat : NSLocalizedString(@"%@\nReason was: %@", nil), lMessage, message]; - } - } - lTitle = NSLocalizedString(@"Call failed",nil); - UIAlertView* error = [[UIAlertView alloc] initWithTitle:lTitle - message:lMessage - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Dismiss",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; -} - -- (void)addInhibitedEvent:(id)event { - [inhibitedEvents addObject:event]; -} - -- (BOOL)removeInhibitedEvent:(id)event { - NSUInteger index = [inhibitedEvents indexOfObject:event]; - if(index != NSNotFound) { - [inhibitedEvents removeObjectAtIndex:index]; - return TRUE; - } - return FALSE; -} - -#pragma mark - ActionSheet Functions - -- (void)playMessageSoundForCallID:(NSString*)callID { - if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) { - LinphoneManager* lm = [LinphoneManager instance]; - // if the message was already received through a push notif, we don't need to ring - if( ![lm popPushCallID:callID] ) { - [lm playMessageSound]; - } - } -} - -- (void)displayIncomingCall:(LinphoneCall*) call{ - LinphoneCallLog* callLog = linphone_call_get_call_log(call); - NSString* callId = [NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)]; - - if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) { - LinphoneManager* lm = [LinphoneManager instance]; - BOOL callIDFromPush = [lm popPushCallID:callId]; - BOOL autoAnswer = [lm lpConfigBoolForKey:@"autoanswer_notif_preference"]; - - if (callIDFromPush && autoAnswer){ - // accept call automatically - [lm acceptCall:call]; - - } else { - - IncomingCallViewController *controller = nil; - if( ![currentView.name isEqualToString:[IncomingCallViewController compositeViewDescription].name]){ - controller = DYNAMIC_CAST([self changeCurrentView:[IncomingCallViewController compositeViewDescription] push:TRUE],IncomingCallViewController); - } else { - // controller is already presented, don't bother animating a transition - controller = DYNAMIC_CAST([self.mainViewController getCurrentViewController],IncomingCallViewController); - } - AudioServicesPlaySystemSound(lm.sounds.vibrate); - if(controller != nil) { - [controller setCall:call]; - [controller setDelegate:self]; - } - + // sometimes when placing a call, the volume view will appear. Inserting a + // carefully hidden MPVolumeView into the view hierarchy will hide it + if (hidden) { + if (!(volumeView.superview == self.view)) { + [self.view addSubview:volumeView]; + } + } else { + if (volumeView.superview == self.view) { + [volumeView removeFromSuperview]; } } } -- (void)batteryLevelChanged:(NSNotification*)notif { - float level = [UIDevice currentDevice].batteryLevel; - UIDeviceBatteryState state = [UIDevice currentDevice].batteryState; - [LinphoneLogger log:LinphoneLoggerDebug format:@"Battery state:%d level:%.2f", state, level]; - - LinphoneCall* call = linphone_core_get_current_call([LinphoneManager getLc]); - if (call && linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { - LinphoneCallAppData* callData = (LinphoneCallAppData*) linphone_call_get_user_pointer(call); - if(callData != nil) { - if (state == UIDeviceBatteryStateUnplugged) { - if (level <= 0.2f && !callData->batteryWarningShown) { - [LinphoneLogger log:LinphoneLoggerLog format:@"Battery warning"]; - DTActionSheet *sheet = [[[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Battery is running low. Stop video ?",nil)] autorelease]; - [sheet addCancelButtonWithTitle:NSLocalizedString(@"Continue video", nil) block:nil]; - [sheet addDestructiveButtonWithTitle:NSLocalizedString(@"Stop video", nil) block:^() { - LinphoneCallParams* paramsCopy = linphone_call_params_copy(linphone_call_get_current_params(call)); - // stop video - linphone_call_params_enable_video(paramsCopy, FALSE); - linphone_core_update_call([LinphoneManager getLc], call, paramsCopy); - }]; - [sheet showInView:self.view]; - callData->batteryWarningShown = TRUE; - } - } - if (level > 0.2f) { - callData->batteryWarningShown = FALSE; - } - } - } +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 +- (UIInterfaceOrientationMask)supportedInterfaceOrientations +#else +- (NSUInteger)supportedInterfaceOrientations +#endif +{ + return UIInterfaceOrientationMaskAll; } +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation + duration:(NSTimeInterval)duration { + [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [mainViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [self orientationUpdate:toInterfaceOrientation]; +} + +- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation + duration:(NSTimeInterval)duration { + [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; + [mainViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; +} + +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { + [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; + [mainViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; +} + +- (UIInterfaceOrientation)interfaceOrientation { + return [mainViewController currentOrientation]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + [mainViewController clearCache:[RootViewManager instance].viewDescriptionStack]; +} + +#pragma mark - Event Functions + +- (void)textReceived:(NSNotification *)notif { + LinphoneAddress *from = [[notif.userInfo objectForKey:@"from_address"] pointerValue]; + NSString *callID = [notif.userInfo objectForKey:@"call-id"]; + if (from != nil) { + [self playMessageSoundForCallID:callID]; + } + [self updateApplicationBadgeNumber]; +} + +- (void)registrationUpdate:(NSNotification *)notif { + LinphoneRegistrationState state = [[notif.userInfo objectForKey:@"state"] intValue]; + LinphoneProxyConfig *cfg = [[notif.userInfo objectForKey:@"cfg"] pointerValue]; + // Only report bad credential issue + if (state == LinphoneRegistrationFailed && + [UIApplication sharedApplication].applicationState == UIApplicationStateBackground && + linphone_proxy_config_get_error(cfg) == LinphoneReasonBadCredentials) { + UIAlertView *error = + [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Registration failure", nil) + message:NSLocalizedString(@"Bad credentials, check your account settings", nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Continue", nil) + otherButtonTitles:nil, nil]; + [error show]; + } +} + +- (void)onGlobalStateChanged:(NSNotification *)notif { + LinphoneGlobalState state = (LinphoneGlobalState)[[[notif userInfo] valueForKey:@"state"] integerValue]; + static BOOL already_shown = FALSE; + if (state == LinphoneGlobalOn && !already_shown && [LinphoneManager instance].wasRemoteProvisioned) { + LinphoneProxyConfig *conf = linphone_core_get_default_proxy_config([LinphoneManager getLc]); + if ([[LinphoneManager instance] lpConfigBoolForKey:@"show_login_view" inSection:@"app"] && conf == NULL) { + already_shown = TRUE; + AssistantView *view = VIEW(AssistantView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; + [view fillDefaultValues]; + } + } +} + +- (void)callUpdate:(NSNotification *)notif { + LinphoneCall *call = [[notif.userInfo objectForKey:@"call"] pointerValue]; + LinphoneCallState state = [[notif.userInfo objectForKey:@"state"] intValue]; + NSString *message = [notif.userInfo objectForKey:@"message"]; + + // Don't handle call state during incoming call view + if ([[self currentView] equal:CallIncomingView.compositeViewDescription] && state != LinphoneCallError && + state != LinphoneCallEnd) { + return; + } + + switch (state) { + case LinphoneCallIncomingReceived: + case LinphoneCallIncomingEarlyMedia: { + [self displayIncomingCall:call]; + break; + } + case LinphoneCallOutgoingInit: { + [self changeCurrentView:CallOutgoingView.compositeViewDescription]; + break; + } + case LinphoneCallPausedByRemote: + case LinphoneCallConnected: + case LinphoneCallStreamsRunning: { + [self changeCurrentView:CallView.compositeViewDescription push:NO]; + break; + } + case LinphoneCallUpdatedByRemote: { + const LinphoneCallParams *current = linphone_call_get_current_params(call); + const LinphoneCallParams *remote = linphone_call_get_remote_params(call); + + if (linphone_call_params_video_enabled(current) && !linphone_call_params_video_enabled(remote)) { + [self changeCurrentView:CallView.compositeViewDescription]; + } + break; + } + case LinphoneCallError: { + [self displayCallError:call message:message]; + } + case LinphoneCallEnd: { + const MSList *calls = linphone_core_get_calls([LinphoneManager getLc]); + if (calls == NULL) { + // if ((currentView == CallView.compositeViewDescription) || + // (currentView == CallIncomingView.compositeViewDescription) || + // (currentView == CallOutgoingView.compositeViewDescription)) { + DialerView *view = VIEW(DialerView); + [view setAddress:@""]; + [view setTransferMode:FALSE]; + [self changeCurrentView:view.compositeViewDescription push:NO]; + // [self popCurrentView]; + // } + } else { + linphone_core_resume_call([LinphoneManager getLc], (LinphoneCall *)calls->data); + [self changeCurrentView:CallView.compositeViewDescription]; + } + break; + } + case LinphoneCallEarlyUpdatedByRemote: + case LinphoneCallEarlyUpdating: + case LinphoneCallIdle: + case LinphoneCallOutgoingEarlyMedia: + case LinphoneCallOutgoingProgress: + case LinphoneCallOutgoingRinging: + case LinphoneCallPaused: + case LinphoneCallPausing: + case LinphoneCallRefered: + case LinphoneCallReleased: + case LinphoneCallResuming: + case LinphoneCallUpdating: + break; + } + [self updateApplicationBadgeNumber]; +} + +#pragma mark - + +- (void)orientationUpdate:(UIInterfaceOrientation)orientation { + int oldLinphoneOrientation = linphone_core_get_device_rotation([LinphoneManager getLc]); + int newRotation = 0; + switch (orientation) { + case UIInterfaceOrientationPortrait: + newRotation = 0; + break; + case UIInterfaceOrientationPortraitUpsideDown: + newRotation = 180; + break; + case UIInterfaceOrientationLandscapeRight: + newRotation = 270; + break; + case UIInterfaceOrientationLandscapeLeft: + newRotation = 90; + break; + default: + newRotation = oldLinphoneOrientation; + } + if (oldLinphoneOrientation != newRotation) { + linphone_core_set_device_rotation([LinphoneManager getLc], newRotation); + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); + if (call && linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { + // Orientation has changed, must call update call + linphone_core_update_call([LinphoneManager getLc], call, NULL); + } + } +} +- (void)startUp { + LinphoneCore *core = nil; + @try { + core = [LinphoneManager getLc]; + LinphoneManager *lm = [LinphoneManager instance]; + if (linphone_core_get_global_state(core) != LinphoneGlobalOn) { + [self changeCurrentView:DialerView.compositeViewDescription]; + } else if ([[LinphoneManager instance] lpConfigBoolForKey:@"enable_first_login_view_preference"] == true) { + [PhoneMainView.instance changeCurrentView:FirstLoginView.compositeViewDescription]; + } else { + // always start to dialer when testing + // Change to default view + const MSList *list = linphone_core_get_proxy_config_list(core); + if (list != NULL || ([lm lpConfigBoolForKey:@"hide_assistant_preference"] == true) || lm.isTesting) { + [self changeCurrentView:DialerView.compositeViewDescription]; + } else { + AssistantView *view = VIEW(AssistantView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; + [view reset]; + } + } + [self updateApplicationBadgeNumber]; // Update Badge at startup + } @catch (NSException *exception) { + // we'll wait until the app transitions correctly + } +} + +- (void)updateApplicationBadgeNumber { + int count = 0; + count += linphone_core_get_missed_calls_count([LinphoneManager getLc]); + count += [LinphoneManager unreadMessageCount]; + count += linphone_core_get_calls_nb([LinphoneManager getLc]); + [[UIApplication sharedApplication] setApplicationIconBadgeNumber:count]; +} + ++ (CATransition *)getBackwardTransition { + BOOL RTL = [LinphoneManager langageDirectionIsRTL]; + BOOL land = UIInterfaceOrientationIsLandscape([self.instance interfaceOrientation]); + NSString *transition = land ? kCATransitionFromBottom : (RTL ? kCATransitionFromRight : kCATransitionFromLeft); + CATransition *trans = [CATransition animation]; + [trans setType:kCATransitionPush]; + [trans setDuration:0.35]; + [trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; + [trans setSubtype:transition]; + + return trans; +} + ++ (CATransition *)getForwardTransition { + BOOL RTL = [LinphoneManager langageDirectionIsRTL]; + BOOL land = UIInterfaceOrientationIsLandscape([self.instance interfaceOrientation]); + NSString *transition = land ? kCATransitionFromTop : (RTL ? kCATransitionFromLeft : kCATransitionFromRight); + CATransition *trans = [CATransition animation]; + [trans setType:kCATransitionPush]; + [trans setDuration:0.35]; + [trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; + [trans setSubtype:transition]; + + return trans; +} + ++ (CATransition *)getTransition:(UICompositeViewDescription *)old new:(UICompositeViewDescription *) new { + bool left = false; + + if ([old equal:ChatsListView.compositeViewDescription]) { + if ([new equal:ContactsListView.compositeViewDescription] || [new equal:DialerView.compositeViewDescription] || + [new equal:HistoryListView.compositeViewDescription]) { + left = true; + } + } else if ([old equal:SettingsView.compositeViewDescription]) { + if ([new equal:DialerView.compositeViewDescription] || [new equal:ContactsListView.compositeViewDescription] || + [new equal:HistoryListView.compositeViewDescription] || + [new equal:ChatsListView.compositeViewDescription]) { + left = true; + } + } else if ([old equal:DialerView.compositeViewDescription]) { + if ([new equal:ContactsListView.compositeViewDescription] || + [new equal:HistoryListView.compositeViewDescription]) { + left = true; + } + } else if ([old equal:ContactsListView.compositeViewDescription]) { + if ([new equal:HistoryListView.compositeViewDescription]) { + left = true; + } + } + + if (left) { + return [PhoneMainView getBackwardTransition]; + } else { + return [PhoneMainView getForwardTransition]; + } +} + ++ (PhoneMainView *)instance { + return [[RootViewManager instance] currentView]; +} + +- (void)showTabBar:(BOOL)show { + [mainViewController hideTabBar:!show]; +} + +- (void)showStatusBar:(BOOL)show { + [mainViewController hideStatusBar:!show]; +} + +- (void)updateStatusBar:(UICompositeViewDescription *)to_view { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 + // In iOS7, the app has a black background on dialer, incoming and incall, so we have to adjust the + // status bar style for each transition to/from these views + BOOL toLightStatus = (to_view != NULL) && ![to_view darkBackground]; + if (!toLightStatus) { + // black bg: white text on black background + [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; + + [UIView animateWithDuration:0.3f + animations:^{ + statusBarBG.backgroundColor = [UIColor blackColor]; + }]; + + } else { + // light bg: black text on white bg + [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault]; + [UIView animateWithDuration:0.3f + animations:^{ + statusBarBG.backgroundColor = [UIColor colorWithWhite:0.935 alpha:1]; + }]; + } +#endif +} + +- (void)fullScreen:(BOOL)enabled { + [statusBarBG setHidden:enabled]; + [mainViewController setFullscreen:enabled]; +} + +- (void)changeCurrentView:(UICompositeViewDescription *)view { + [self changeCurrentView:view push:TRUE]; +} + +- (void)changeCurrentView:(UICompositeViewDescription *)view push:(BOOL)push { + [self changeCurrentView:view + push:push + animated:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; +} + +- (void)changeCurrentView:(UICompositeViewDescription *)view push:(BOOL)push animated:(BOOL)animated { + NSMutableArray *viewStack = [RootViewManager instance].viewDescriptionStack; + if (push && view) { + [viewStack addObject:view]; + } + [self _changeCurrentView:view transition:nil animated:animated]; +} + +- (BOOL)isUnauthorizedView:(UICompositeViewDescription *)view { + return [[LinphoneManager.instance lpConfigStringForKey:@"unauthorized_views"] containsString:view.name]; +} + +- (UIViewController *)_changeCurrentView:(UICompositeViewDescription *)view + transition:(CATransition *)transition + animated:(BOOL)animated { + PhoneMainView *vc = [[RootViewManager instance] setViewControllerForDescription:view]; + + if ([self isUnauthorizedView:view]) { + NSString *fallback = [LinphoneManager.instance lpConfigStringForKey:@"fallback_view"]; + UICompositeViewDescription *fallback_view = DialerView.compositeViewDescription; + if (fallback && [NSClassFromString(fallback) respondsToSelector:@selector(compositeViewDescription)]) { + fallback_view = [NSClassFromString(fallback) performSelector:@selector(compositeViewDescription)]; + } + LOGW(@"Trying to access unauthorized view %@, going back to %@", view.name, fallback_view.name); + view = fallback_view; + } + if (![view equal:vc.currentView] || vc != self) { + LOGI(@"Change current view to %@", view.name); + if (animated && transition == nil) + transition = [PhoneMainView getTransition:vc.currentView new:view]; + [vc.mainViewController setViewTransition:(animated ? transition : nil)]; + [vc updateStatusBar:view]; + [vc.mainViewController changeView:view]; + vc->currentView = view; + } + + //[[RootViewManager instance] setViewControllerForDescription:view]; + + NSDictionary *mdict = [NSMutableDictionary dictionaryWithObject:vc->currentView forKey:@"view"]; + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneMainViewChange object:self userInfo:mdict]; + + return [vc->mainViewController getCurrentViewController]; +} + +- (UIViewController *)popToView:(UICompositeViewDescription *)view { + NSMutableArray *viewStack = [RootViewManager instance].viewDescriptionStack; + while ([viewStack count] > 1 && ![[viewStack lastObject] equal:view]) { + [viewStack removeLastObject]; + } + return [self _changeCurrentView:[viewStack lastObject] + transition:[PhoneMainView getBackwardTransition] + animated:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; +} + +- (UICompositeViewDescription *)firstView { + UICompositeViewDescription *view = nil; + NSArray *viewStack = [RootViewManager instance].viewDescriptionStack; + if ([viewStack count]) { + view = [viewStack objectAtIndex:0]; + } + return view; +} + +- (UIViewController *)popCurrentView { + NSMutableArray *viewStack = [RootViewManager instance].viewDescriptionStack; + if ([viewStack count] > 1) { + LOGI(@"PhoneMainView: Pop view"); + [viewStack removeLastObject]; + [self _changeCurrentView:[viewStack lastObject] + transition:[PhoneMainView getBackwardTransition] + animated:[[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"]]; + return [mainViewController getCurrentViewController]; + } + LOGW(@"PhoneMainView: Trying to pop view but none stacked!"); + return nil; +} + +- (void)displayCallError:(LinphoneCall *)call message:(NSString *)message { + const char *lUserNameChars = linphone_address_get_username(linphone_call_get_remote_address(call)); + NSString *lUserName = + lUserNameChars ? [[NSString alloc] initWithUTF8String:lUserNameChars] : NSLocalizedString(@"Unknown", nil); + NSString *lMessage; + NSString *lTitle; + + // get default proxy + LinphoneProxyConfig *proxyCfg = linphone_core_get_default_proxy_config([LinphoneManager getLc]); + if (proxyCfg == nil) { + lMessage = NSLocalizedString(@"Please make sure your device is connected to the internet and double check your " + @"SIP account configuration in the settings.", + nil); + } else { + lMessage = [NSString stringWithFormat:NSLocalizedString(@"Cannot call %@.", nil), lUserName]; + } + + switch (linphone_call_get_reason(call)) { + case LinphoneReasonNotFound: + lMessage = [NSString stringWithFormat:NSLocalizedString(@"%@ is not registered.", nil), lUserName]; + break; + case LinphoneReasonBusy: + lMessage = [NSString stringWithFormat:NSLocalizedString(@"%@ is busy.", nil), lUserName]; + break; + default: + if (message != nil) { + lMessage = [NSString stringWithFormat:NSLocalizedString(@"%@\nReason was: %@", nil), lMessage, message]; + } + break; + } + + lTitle = NSLocalizedString(@"Call failed", nil); + UIAlertView *error = [[UIAlertView alloc] initWithTitle:lTitle + message:lMessage + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Cancel", nil) + otherButtonTitles:nil]; + [error show]; +} + +- (void)addInhibitedEvent:(id)event { + [inhibitedEvents addObject:event]; +} + +- (BOOL)removeInhibitedEvent:(id)event { + NSUInteger index = [inhibitedEvents indexOfObject:event]; + if (index != NSNotFound) { + [inhibitedEvents removeObjectAtIndex:index]; + return TRUE; + } + return FALSE; +} + +#pragma mark - ActionSheet Functions + +- (void)playMessageSoundForCallID:(NSString *)callID { + if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) { + LinphoneManager *lm = [LinphoneManager instance]; + // if the message was already received through a push notif, we don't need to ring + if (![lm popPushCallID:callID]) { + [lm playMessageSound]; + } + } +} + +- (void)displayIncomingCall:(LinphoneCall *)call { + LinphoneCallLog *callLog = linphone_call_get_call_log(call); + NSString *callId = [NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)]; + + if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) { + LinphoneManager *lm = [LinphoneManager instance]; + BOOL callIDFromPush = [lm popPushCallID:callId]; + BOOL autoAnswer = [lm lpConfigBoolForKey:@"autoanswer_notif_preference"]; + + if (callIDFromPush && autoAnswer) { + // accept call automatically + [lm acceptCall:call evenWithVideo:YES]; + } else { + AudioServicesPlaySystemSound(lm.sounds.vibrate); + CallIncomingView *view = VIEW(CallIncomingView); + [self changeCurrentView:view.compositeViewDescription push:TRUE]; + [view setCall:call]; + [view setDelegate:self]; + } + } +} + +- (void)batteryLevelChanged:(NSNotification *)notif { + float level = [UIDevice currentDevice].batteryLevel; + UIDeviceBatteryState state = [UIDevice currentDevice].batteryState; + LOGD(@"Battery state:%d level:%.2f", state, level); + + LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); + if (call && linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { + LinphoneCallAppData *callData = (__bridge LinphoneCallAppData *)linphone_call_get_user_pointer(call); + if (callData != nil) { + if (state == UIDeviceBatteryStateUnplugged) { + if (level <= 0.2f && !callData->batteryWarningShown) { + LOGI(@"Battery warning"); + DTActionSheet *sheet = [[DTActionSheet alloc] + initWithTitle:NSLocalizedString(@"Battery is running low. Stop video ?", nil)]; + [sheet addCancelButtonWithTitle:NSLocalizedString(@"Continue video", nil) block:nil]; + [sheet + addDestructiveButtonWithTitle:NSLocalizedString(@"Stop video", nil) + block:^() { + LinphoneCallParams *paramsCopy = + linphone_call_params_copy(linphone_call_get_current_params(call)); + // stop video + linphone_call_params_enable_video(paramsCopy, FALSE); + linphone_core_update_call([LinphoneManager getLc], call, paramsCopy); + }]; + [sheet showInView:self.view]; + callData->batteryWarningShown = TRUE; + } + } + if (level > 0.2f) { + callData->batteryWarningShown = FALSE; + } + } + } +} #pragma mark - IncomingCallDelegate Functions -- (void)incomingCallAborted:(LinphoneCall*)call { +- (void)incomingCallAborted:(LinphoneCall *)call { } -- (void)incomingCallAccepted:(LinphoneCall*)call { - [[LinphoneManager instance] acceptCall:call]; +- (void)incomingCallAccepted:(LinphoneCall *)call evenWithVideo:(BOOL)video { + [[LinphoneManager instance] acceptCall:call evenWithVideo:video]; } -- (void)incomingCallDeclined:(LinphoneCall*)call { - linphone_core_terminate_call([LinphoneManager getLc], call); +- (void)incomingCallDeclined:(LinphoneCall *)call { + linphone_core_terminate_call([LinphoneManager getLc], call); } -@end \ No newline at end of file +@end diff --git a/Classes/SettingsView.h b/Classes/SettingsView.h new file mode 100644 index 000000000..ebadd2576 --- /dev/null +++ b/Classes/SettingsView.h @@ -0,0 +1,41 @@ +/* SettingsViewController.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import + +#import "UICompositeView.h" +#import "IASKAppSettingsViewController.h" +#import "LinphoneCoreSettingsStore.h" + +@interface SettingsView + : UIViewController { + @private + LinphoneCoreSettingsStore *settingsStore; +} + +@property(nonatomic, strong) IBOutlet UINavigationController *navigationController; +@property(nonatomic, strong) IBOutlet IASKAppSettingsViewController *settingsController; +@property(weak, nonatomic) IBOutlet UIView *subView; +@property(weak, nonatomic) IBOutlet UIButton *backButton; +@property(weak, nonatomic) IBOutlet UILabel *titleLabel; + +- (IBAction)onDialerBackClick:(id)sender; +- (IBAction)onBackClick:(id)sender; + +@end diff --git a/Classes/SettingsView.m b/Classes/SettingsView.m new file mode 100644 index 000000000..e6ab35b6f --- /dev/null +++ b/Classes/SettingsView.m @@ -0,0 +1,839 @@ +/* SettingsViewController.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "SettingsView.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" +#import "Utils.h" + +#import "DCRoundSwitch.h" + +#import "IASKSpecifierValuesViewController.h" +#import "IASKPSTextFieldSpecifierViewCell.h" +#import "IASKPSTitleValueSpecifierViewCell.h" +#import "IASKSpecifier.h" +#import "IASKTextField.h" +#include "linphone/lpconfig.h" + +#ifdef DEBUG +@interface UIDevice (debug) + +- (void)_setBatteryLevel:(float)level; +- (void)_setBatteryState:(int)state; + +@end +#endif + +@interface SettingsView (private) + ++ (IASKSpecifier *)filterSpecifier:(IASKSpecifier *)specifier; + +@end + +#pragma mark - IASKSwitchEx Class + +@interface IASKSwitchEx : DCRoundSwitch { + NSString *_key; +} + +@property(nonatomic, strong) NSString *key; + +@end + +@implementation IASKSwitchEx + +@synthesize key = _key; + +- (void)dealloc { + _key = nil; +} + +@end + +#pragma mark - IASKSpecifierValuesViewControllerEx Class + +// Patch IASKSpecifierValuesViewController +@interface IASKSpecifierValuesViewControllerEx : IASKSpecifierValuesViewController + +@end + +@implementation IASKSpecifierValuesViewControllerEx + +- (void)initIASKSpecifierValuesViewControllerEx { + [self.view setBackgroundColor:[UIColor clearColor]]; +} + +- (id)init { + self = [super init]; + if (self != nil) { + [self initIASKSpecifierValuesViewControllerEx]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self != nil) { + [self initIASKSpecifierValuesViewControllerEx]; + } + return self; +} + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self != nil) { + [self initIASKSpecifierValuesViewControllerEx]; + } + return self; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; + return cell; +} + +@end + +#pragma mark - IASKAppSettingsViewControllerEx Class + +@interface IASKAppSettingsViewController (PrivateInterface) +- (UITableViewCell *)newCellForIdentifier:(NSString *)identifier; +@end +; + +@interface IASKAppSettingsViewControllerEx : IASKAppSettingsViewController + +@end + +@implementation IASKAppSettingsViewControllerEx + +- (UITableViewCell *)newCellForIdentifier:(NSString *)identifier { + UITableViewCell *cell = nil; + if ([identifier isEqualToString:kIASKPSToggleSwitchSpecifier]) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault + reuseIdentifier:kIASKPSToggleSwitchSpecifier]; + cell.accessoryView = [[IASKSwitchEx alloc] initWithFrame:CGRectMake(0, 0, 79, 27)]; + [((IASKSwitchEx *)cell.accessoryView) addTarget:self + action:@selector(toggledValue:) + forControlEvents:UIControlEventValueChanged]; + [((IASKSwitchEx *)cell.accessoryView) setOnTintColor:LINPHONE_MAIN_COLOR]; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.textLabel.minimumScaleFactor = kIASKMinimumFontSize / [UIFont systemFontSize]; + cell.detailTextLabel.minimumScaleFactor = kIASKMinimumFontSize / [UIFont systemFontSize]; + } else { + cell = [super newCellForIdentifier:identifier]; + } + return cell; +} + +- (void)toggledValue:(id)sender { + IASKSwitchEx *toggle = (IASKSwitchEx *)sender; + IASKSpecifier *spec = [_settingsReader specifierForKey:[toggle key]]; + + if ([toggle isOn]) { + if ([spec trueValue] != nil) { + [self.settingsStore setObject:[spec trueValue] forKey:[toggle key]]; + } else { + [self.settingsStore setBool:YES forKey:[toggle key]]; + } + } else { + if ([spec falseValue] != nil) { + [self.settingsStore setObject:[spec falseValue] forKey:[toggle key]]; + } else { + [self.settingsStore setBool:NO forKey:[toggle key]]; + } + } + // Start notification after animation of DCRoundSwitch + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] + postNotificationName:kIASKAppSettingChanged + object:[toggle key] + userInfo:[NSDictionary dictionaryWithObject:[self.settingsStore objectForKey:[toggle key]] + forKey:[toggle key]]]; + }); +} + +- (void)initIASKAppSettingsViewControllerEx { + [self.view setBackgroundColor:[UIColor clearColor]]; + + // Force kIASKSpecifierValuesViewControllerIndex + static int kIASKSpecifierValuesViewControllerIndex = 0; + _viewList = [[NSMutableArray alloc] init]; + [_viewList addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"IASKSpecifierValuesView", @"ViewName", nil]]; + [_viewList addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"IASKAppSettingsView", @"ViewName", nil]]; + + NSMutableDictionary *newItemDict = [NSMutableDictionary dictionaryWithCapacity:3]; + [newItemDict addEntriesFromDictionary:[_viewList objectAtIndex:kIASKSpecifierValuesViewControllerIndex]]; // copy + // the + // title + // and + // explain + // strings + + IASKSpecifierValuesViewController *targetViewController = [[IASKSpecifierValuesViewControllerEx alloc] init]; + // add the new view controller to the dictionary and then to the 'viewList' array + [newItemDict setObject:targetViewController forKey:@"viewController"]; + [_viewList replaceObjectAtIndex:kIASKSpecifierValuesViewControllerIndex withObject:newItemDict]; +} + +- (IASKSettingsReader *)settingsReader { + IASKSettingsReader *r = [super settingsReader]; + NSMutableArray *dataSource = [NSMutableArray arrayWithArray:[r dataSource]]; + for (int i = 0; i < [dataSource count]; ++i) { + NSMutableArray *specifiers = [NSMutableArray arrayWithArray:[dataSource objectAtIndex:i]]; + for (int j = 0; j < [specifiers count]; ++j) { + id sp = [specifiers objectAtIndex:j]; + if ([sp isKindOfClass:[IASKSpecifier class]]) { + sp = [SettingsView filterSpecifier:sp]; + } + [specifiers replaceObjectAtIndex:j withObject:sp]; + } + + [dataSource replaceObjectAtIndex:i withObject:specifiers]; + } + [r setDataSource:dataSource]; + return r; +} + +- (id)initWithStyle:(UITableViewStyle)style { + self = [super initWithStyle:style]; + if (self != nil) { + [self initIASKAppSettingsViewControllerEx]; + } + return self; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + UIEdgeInsets inset = {0, 0, 10, 0}; + UIScrollView *scrollView = self.tableView; + [scrollView setContentInset:inset]; + [scrollView setScrollIndicatorInsets:inset]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; + + if ([cell isKindOfClass:[IASKPSTextFieldSpecifierViewCell class]]) { + UITextField *field = ((IASKPSTextFieldSpecifierViewCell *)cell).textField; + [field setTextColor:LINPHONE_MAIN_COLOR]; + } + + if ([cell isKindOfClass:[IASKPSTitleValueSpecifierViewCell class]]) { + cell.detailTextLabel.textColor = [UIColor grayColor]; + } else { + cell.detailTextLabel.textColor = LINPHONE_MAIN_COLOR; + } + return cell; +} +@end + +#pragma mark - UINavigationBarEx Class + +@interface UINavigationBarEx : UINavigationBar +@end + +@implementation UINavigationBarEx + +INIT_WITH_COMMON { + [self setTintColor:[LINPHONE_MAIN_COLOR adjustHue:5.0f / 180.0f saturation:0.0f brightness:0.0f alpha:0.0f]]; + return self; +} + +@end + +#pragma mark - UINavigationControllerEx Class + +@interface UINavigationControllerEx : UINavigationController + +@end + +@implementation UINavigationControllerEx + +- (id)initWithRootViewController:(UIViewController *)rootViewController { + [UINavigationControllerEx removeBackground:rootViewController.view]; + return [self initWithRootViewController:rootViewController]; +} + ++ (void)removeBackground:(UIView *)view { + // iOS7 transparent background is *really* transparent: with an alpha != 0 + // it messes up the transitions. Use non-transparent BG for iOS7 + if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) + [view setBackgroundColor:LINPHONE_SETTINGS_BG_IOS7]; + else + [view setBackgroundColor:[UIColor clearColor]]; +} + +- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { + [UINavigationControllerEx removeBackground:viewController.view]; + + [viewController view]; // Force view + UILabel *labelTitleView = [[UILabel alloc] init]; + labelTitleView.backgroundColor = [UIColor clearColor]; + labelTitleView.textColor = [UIColor colorWithRed:0x41 / 255.0f green:0x48 / 255.0f blue:0x4f / 255.0f alpha:1.0]; + labelTitleView.shadowColor = [UIColor colorWithWhite:1.0 alpha:0.5]; + labelTitleView.font = [UIFont boldSystemFontOfSize:20]; + labelTitleView.shadowOffset = CGSizeMake(0, 1); + labelTitleView.textAlignment = NSTextAlignmentCenter; + labelTitleView.text = viewController.title; + [labelTitleView sizeToFit]; + viewController.navigationItem.titleView = labelTitleView; + + [super pushViewController:viewController animated:animated]; +} + +- (void)setViewControllers:(NSArray *)viewControllers { + for (UIViewController *controller in viewControllers) { + [UINavigationControllerEx removeBackground:controller.view]; + } + [super setViewControllers:viewControllers]; +} + +- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated { + for (UIViewController *controller in viewControllers) { + [UINavigationControllerEx removeBackground:controller.view]; + } + [super setViewControllers:viewControllers animated:animated]; +} + +@end + +@implementation SettingsView + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:nil + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:YES + fragmentWith:nil]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - ViewController Functions + +- (void)viewDidLoad { + [super viewDidLoad]; + + settingsStore = [[LinphoneCoreSettingsStore alloc] init]; + + _settingsController.showDoneButton = FALSE; + _settingsController.delegate = self; + _settingsController.showCreditsFooter = FALSE; + _settingsController.settingsStore = settingsStore; + + [_navigationController.view setBackgroundColor:[UIColor clearColor]]; + + _navigationController.view.frame = self.subView.frame; + [_navigationController pushViewController:_settingsController animated:FALSE]; + [self.view addSubview:_navigationController.view]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [_settingsController dismiss:self]; + // Set observer + [[NSNotificationCenter defaultCenter] removeObserver:self name:kIASKAppSettingChanged object:nil]; + + if (linphone_ringtoneplayer_is_started(linphone_core_get_ringtoneplayer([LinphoneManager getLc]))) { + linphone_core_stop_ringing([LinphoneManager getLc]); + } +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + // Sync settings with linphone core settings + [settingsStore transformLinphoneCoreToKeys]; + [self recomputeAccountLabelsAndSync]; + + // Set observer + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(appSettingChanged:) + name:kIASKAppSettingChanged + object:nil]; +} + +#pragma mark - Event Functions + +- (void)appSettingChanged:(NSNotification *)notif { + NSMutableSet *hiddenKeys = [NSMutableSet setWithSet:[_settingsController hiddenKeys]]; + NSMutableArray *keys = [NSMutableArray array]; + BOOL removeFromHiddenKeys = TRUE; + + if ([@"enable_video_preference" compare:notif.object] == NSOrderedSame) { + removeFromHiddenKeys = [[notif.userInfo objectForKey:@"enable_video_preference"] boolValue]; + [keys addObject:@"video_menu"]; + } else if ([@"random_port_preference" compare:notif.object] == NSOrderedSame) { + removeFromHiddenKeys = ![[notif.userInfo objectForKey:@"random_port_preference"] boolValue]; + [keys addObject:@"port_preference"]; + } else if ([@"backgroundmode_preference" compare:notif.object] == NSOrderedSame) { + removeFromHiddenKeys = [[notif.userInfo objectForKey:@"backgroundmode_preference"] boolValue]; + [keys addObject:@"start_at_boot_preference"]; + } else if ([@"stun_preference" compare:notif.object] == NSOrderedSame) { + NSString *stun_server = [notif.userInfo objectForKey:@"stun_preference"]; + removeFromHiddenKeys = (stun_server && ([stun_server length] > 0)); + [keys addObject:@"ice_preference"]; + } else if ([@"debugenable_preference" compare:notif.object] == NSOrderedSame) { + BOOL debugEnabled = [[notif.userInfo objectForKey:@"debugenable_preference"] boolValue]; + removeFromHiddenKeys = debugEnabled; + [keys addObject:@"send_logs_button"]; + [keys addObject:@"reset_logs_button"]; + [[LinphoneManager instance] setLogsEnabled:debugEnabled]; + } else if ([@"account_mandatory_advanced_preference" compare:notif.object] == NSOrderedSame) { + removeFromHiddenKeys = [[notif.userInfo objectForKey:@"account_mandatory_advanced_preference"] boolValue]; + for (NSString *key in settingsStore->dict) { + if (([key hasPrefix:@"account_"]) && (![key hasPrefix:@"account_mandatory_"])) { + [keys addObject:key]; + } + } + } else if ([@"video_preset_preference" compare:notif.object] == NSOrderedSame) { + NSString *video_preset = [notif.userInfo objectForKey:@"video_preset_preference"]; + removeFromHiddenKeys = [video_preset isEqualToString:@"custom"]; + [keys addObject:@"video_preferred_fps_preference"]; + [keys addObject:@"download_bandwidth_preference"]; + } + + for (NSString *key in keys) { + if (removeFromHiddenKeys) + [hiddenKeys removeObject:key]; + else + [hiddenKeys addObject:key]; + } + + [_settingsController setHiddenKeys:hiddenKeys animated:TRUE]; +} + +#pragma mark - + ++ (IASKSpecifier *)filterSpecifier:(IASKSpecifier *)specifier { + if (!linphone_core_sip_transport_supported([LinphoneManager getLc], LinphoneTransportTls)) { + if ([[specifier key] isEqualToString:@"account_transport_preference"]) { + NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[specifier specifierDict]]; + NSMutableArray *titles = [NSMutableArray arrayWithArray:[dict objectForKey:@"Titles"]]; + [titles removeObject:@"TLS"]; + [dict setObject:titles forKey:@"Titles"]; + NSMutableArray *values = [NSMutableArray arrayWithArray:[dict objectForKey:@"Values"]]; + [values removeObject:@"tls"]; + [dict setObject:values forKey:@"Values"]; + return [[IASKSpecifier alloc] initWithSpecifier:dict]; + } + } else { + if ([[specifier key] isEqualToString:@"media_encryption_preference"]) { + NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[specifier specifierDict]]; + if (!linphone_core_media_encryption_supported([LinphoneManager getLc], LinphoneMediaEncryptionZRTP)) { + NSMutableArray *titles = [NSMutableArray arrayWithArray:[dict objectForKey:@"Titles"]]; + [titles removeObject:@"ZRTP"]; + [dict setObject:titles forKey:@"Titles"]; + NSMutableArray *values = [NSMutableArray arrayWithArray:[dict objectForKey:@"Values"]]; + [values removeObject:@"ZRTP"]; + [dict setObject:values forKey:@"Values"]; + } + if (!linphone_core_media_encryption_supported([LinphoneManager getLc], LinphoneMediaEncryptionSRTP)) { + NSMutableArray *titles = [NSMutableArray arrayWithArray:[dict objectForKey:@"Titles"]]; + [titles removeObject:@"SRTP"]; + [dict setObject:titles forKey:@"Titles"]; + NSMutableArray *values = [NSMutableArray arrayWithArray:[dict objectForKey:@"Values"]]; + [values removeObject:@"SRTP"]; + [dict setObject:values forKey:@"Values"]; + } + if (!linphone_core_media_encryption_supported([LinphoneManager getLc], LinphoneMediaEncryptionDTLS)) { + NSMutableArray *titles = [NSMutableArray arrayWithArray:[dict objectForKey:@"Titles"]]; + [titles removeObject:@"DTLS"]; + [dict setObject:titles forKey:@"Titles"]; + NSMutableArray *values = [NSMutableArray arrayWithArray:[dict objectForKey:@"Values"]]; + [values removeObject:@"DTLS"]; + [dict setObject:values forKey:@"Values"]; + } + return [[IASKSpecifier alloc] initWithSpecifier:dict]; + } + } + + if ([specifier.key hasPrefix:@"menu_account_"]) { + const MSList *accounts = linphone_core_get_proxy_config_list([LinphoneManager getLc]); + int index = [specifier.key substringFromIndex:@"menu_account_".length].intValue - 1; + if (index < ms_list_size(accounts)) { + LinphoneProxyConfig *proxy = (LinphoneProxyConfig *)ms_list_nth_data(accounts, index); + NSString *name = [NSString + stringWithUTF8String:linphone_address_get_username(linphone_proxy_config_get_identity_address(proxy))]; + [specifier.specifierDict setValue:name forKey:kIASKTitle]; + } + } + + return specifier; +} + +- (NSSet *)findHiddenKeys { + LinphoneManager *lm = [LinphoneManager instance]; + NSMutableSet *hiddenKeys = [NSMutableSet set]; + + const MSList *accounts = linphone_core_get_proxy_config_list([LinphoneManager getLc]); + for (int i = ms_list_size(accounts) + 1; i <= 5; i++) { + [hiddenKeys addObject:[NSString stringWithFormat:@"menu_account_%d", i]]; + } + + if (!linphone_core_sip_transport_supported([LinphoneManager getLc], LinphoneTransportTls)) { + [hiddenKeys addObject:@"media_encryption_preference"]; + } + +#ifndef DEBUG + [hiddenKeys addObject:@"debug_actions_group"]; + [hiddenKeys addObject:@"release_button"]; + [hiddenKeys addObject:@"clear_cache_button"]; + [hiddenKeys addObject:@"battery_alert_button"]; + [hiddenKeys addObject:@"enable_auto_answer_preference"]; + [hiddenKeys addObject:@"flush_images_button"]; +#endif + + if (![[LinphoneManager instance] lpConfigBoolForKey:@"debugenable_preference"]) { + [hiddenKeys addObject:@"send_logs_button"]; + [hiddenKeys addObject:@"reset_logs_button"]; + } + + [hiddenKeys addObject:@"playback_gain_preference"]; + [hiddenKeys addObject:@"microphone_gain_preference"]; + + [hiddenKeys addObject:@"network_limit_group"]; + + [hiddenKeys addObject:@"incoming_call_timeout_preference"]; + [hiddenKeys addObject:@"in_call_timeout_preference"]; + + [hiddenKeys addObject:@"wifi_only_preference"]; + + [hiddenKeys addObject:@"quit_button"]; // Hide for the moment + [hiddenKeys addObject:@"about_button"]; // Hide for the moment + + if (!linphone_core_video_supported([LinphoneManager getLc])) { + [hiddenKeys addObject:@"video_menu"]; + } + + if (![LinphoneManager isCodecSupported:"h264"]) { + [hiddenKeys addObject:@"h264_preference"]; + } + if (![LinphoneManager isCodecSupported:"mp4v-es"]) { + [hiddenKeys addObject:@"mp4v-es_preference"]; + } + + if (![LinphoneManager isNotIphone3G]) + [hiddenKeys addObject:@"silk_24k_preference"]; + + UIDevice *device = [UIDevice currentDevice]; + if (![device respondsToSelector:@selector(isMultitaskingSupported)] || ![device isMultitaskingSupported]) { + [hiddenKeys addObject:@"backgroundmode_preference"]; + [hiddenKeys addObject:@"start_at_boot_preference"]; + } else { + if (![lm lpConfigBoolForKey:@"backgroundmode_preference"]) { + [hiddenKeys addObject:@"start_at_boot_preference"]; + } + } + + [hiddenKeys addObject:@"enable_first_login_view_preference"]; + + if (!linphone_core_video_supported([LinphoneManager getLc])) { + [hiddenKeys addObject:@"enable_video_preference"]; + } + + if (!linphone_core_video_display_enabled([LinphoneManager getLc])) { + [hiddenKeys addObject:@"video_menu"]; + } + + if (!linphone_core_get_video_preset([LinphoneManager getLc]) || + strcmp(linphone_core_get_video_preset([LinphoneManager getLc]), "custom") != 0) { + [hiddenKeys addObject:@"video_preferred_fps_preference"]; + [hiddenKeys addObject:@"download_bandwidth_preference"]; + } + + [hiddenKeys addObjectsFromArray:[[LinphoneManager unsupportedCodecs] allObjects]]; + + BOOL random_port = [lm lpConfigBoolForKey:@"random_port_preference"]; + if (random_port) { + [hiddenKeys addObject:@"port_preference"]; + } + + if (linphone_core_get_stun_server([LinphoneManager getLc]) == NULL) { + [hiddenKeys addObject:@"ice_preference"]; + } + + if (![lm lpConfigBoolForKey:@"debugenable_preference"]) { + [hiddenKeys addObject:@"console_button"]; + } + + if (!IPAD) { + [hiddenKeys addObject:@"preview_preference"]; + } + if ([lm lpConfigBoolForKey:@"hide_run_assistant_preference"]) { + [hiddenKeys addObject:@"assistant_button"]; + } + + if (!linphone_core_tunnel_available()) { + [hiddenKeys addObject:@"tunnel_menu"]; + } + + if (![lm lpConfigBoolForKey:@"account_mandatory_advanced_preference"]) { + for (NSString *key in settingsStore->dict) { + if (([key hasPrefix:@"account_"]) && (![key hasPrefix:@"account_mandatory_"])) { + [hiddenKeys addObject:key]; + } + } + } + + if (![[[LinphoneManager instance] iapManager] enabled]) { + [hiddenKeys addObject:@"in_app_products_button"]; + } + + if ([[UIDevice currentDevice].systemVersion floatValue] < 8) { + [hiddenKeys addObject:@"repeat_call_notification_preference"]; + } + + return hiddenKeys; +} + +- (void)recomputeAccountLabelsAndSync { + // it's a bit violent... but IASK is not designed to dynamically change subviews' name + _settingsController.hiddenKeys = [self findHiddenKeys]; + [_settingsController.settingsReader indexPathForKey:@"menu_account_1"]; // force refresh username' + [_settingsController.settingsReader indexPathForKey:@"menu_account_2"]; // force refresh username' + [_settingsController.settingsReader indexPathForKey:@"menu_account_3"]; // force refresh username' + [_settingsController.settingsReader indexPathForKey:@"menu_account_4"]; // force refresh username' + [_settingsController.settingsReader indexPathForKey:@"menu_account_5"]; // force refresh username' + [[_settingsController tableView] reloadData]; +} + +#pragma mark - IASKSettingsDelegate Functions + +- (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController *)sender { +} + +- (void)settingsViewControllerWillAppear:(IASKAppSettingsViewController *)sender { + _backButton.hidden = (sender.file == nil || [sender.file isEqualToString:@"Root"]); + _titleLabel.text = sender.title; + + // going to account: fill account specific info + if ([sender.file isEqualToString:@"Account"]) { + LOGI(@"Going editting account %@", sender.title); + [settingsStore transformAccountToKeys:sender.title]; + // coming back to default: if we were in account, we must synchronize account now + } else if ([sender.file isEqualToString:@"Root"]) { + [settingsStore synchronize]; + [self recomputeAccountLabelsAndSync]; + } +} + +- (void)settingsViewController:(IASKAppSettingsViewController *)sender + buttonTappedForSpecifier:(IASKSpecifier *)specifier { + NSString *key = [specifier.specifierDict objectForKey:kIASKKey]; +#ifdef DEBUG + if ([key isEqual:@"release_button"]) { + [UIApplication sharedApplication].keyWindow.rootViewController = nil; + [[UIApplication sharedApplication].keyWindow setRootViewController:nil]; + [[LinphoneManager instance] destroyLinphoneCore]; + [LinphoneManager instanceRelease]; + } else if ([key isEqual:@"clear_cache_button"]) { + [PhoneMainView.instance.mainViewController + clearCache:[NSArray arrayWithObject:[PhoneMainView.instance currentView]]]; + } else if ([key isEqual:@"battery_alert_button"]) { + [[UIDevice currentDevice] _setBatteryState:UIDeviceBatteryStateUnplugged]; + [[UIDevice currentDevice] _setBatteryLevel:0.01f]; + [[NSNotificationCenter defaultCenter] postNotificationName:UIDeviceBatteryLevelDidChangeNotification + object:self]; + } else if ([key isEqual:@"flush_images_button"]) { + const MSList *rooms = linphone_core_get_chat_rooms([LinphoneManager getLc]); + while (rooms) { + const MSList *messages = linphone_chat_room_get_history(rooms->data, 0); + while (messages) { + LinphoneChatMessage *msg = messages->data; + if (!linphone_chat_message_is_outgoing(msg)) { + [LinphoneManager setValueInMessageAppData:nil forKey:@"localimage" inMessage:messages->data]; + } + messages = messages->next; + } + rooms = rooms->next; + } + } +#endif + if ([key isEqual:@"assistant_button"]) { + [PhoneMainView.instance changeCurrentView:AssistantView.compositeViewDescription]; + return; + } else if ([key isEqual:@"account_mandatory_remove_button"]) { + DTAlertView *alert = [[DTAlertView alloc] + initWithTitle:NSLocalizedString(@"Warning", nil) + message:NSLocalizedString(@"Are you sure to want to remove your proxy setup?", nil)]; + + [alert addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; + [alert addButtonWithTitle:NSLocalizedString(@"Yes", nil) + block:^{ + [settingsStore removeAccount]; + [self recomputeAccountLabelsAndSync]; + [_settingsController.navigationController popViewControllerAnimated:NO]; + }]; + [alert show]; + } else if ([key isEqual:@"about_button"]) { + [PhoneMainView.instance changeCurrentView:AboutView.compositeViewDescription push:TRUE]; + } else if ([key isEqual:@"reset_logs_button"]) { + linphone_core_reset_log_collection(); + } else if ([key isEqual:@"send_logs_button"]) { + NSString *message; + + if ([LinphoneManager.instance lpConfigBoolForKey:@"send_logs_include_linphonerc_and_chathistory"]) { + message = NSLocalizedString( + @"Warning: an email will be created with 3 attachments:\n- Application " + @"logs\n- Linphone configuration\n- Chats history.\nThey may contain " + @"private informations (MIGHT contain clear-text password!).\nYou can remove one or several " + @"of these attachments before sending your email, however there are all " + @"important to diagnostize your issue.", + nil); + } else { + message = NSLocalizedString(@"Warning: an email will be created with application " + @"logs. It may contain " + @"private informations (but no password!).\nThese logs are " + @"important to diagnostize your issue.", + nil); + } + + DTAlertView *alert = + [[DTAlertView alloc] initWithTitle:NSLocalizedString(@"Sending logs", nil) message:message]; + [alert addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; + [alert addButtonWithTitle:NSLocalizedString(@"I got it, continue", nil) + block:^{ + [self sendEmailWithDebugAttachments]; + }]; + [alert show]; + } else if ([key isEqual:@"preview_ringtone_button"]) { + LinphoneCore *lc = [LinphoneManager getLc]; + if (linphone_ringtoneplayer_is_started(linphone_core_get_ringtoneplayer(lc))) { + linphone_core_stop_ringing(lc); + } else { + linphone_core_preview_ring(lc, linphone_core_get_ring(lc), NULL, NULL); + } + } +} + +#pragma mark - Mail composer for sending logs + +- (void)sendEmailWithDebugAttachments { + NSMutableArray *attachments = [[NSMutableArray alloc] initWithCapacity:3]; + + // retrieve linphone logs if available + char *filepath = linphone_core_compress_log_collection(); + if (filepath != NULL) { + NSString *filename = [[NSString stringWithUTF8String:filepath] componentsSeparatedByString:@"/"].lastObject; + NSString *mimeType = nil; + if ([filename hasSuffix:@".txt"]) { + mimeType = @"text/plain"; + } else if ([filename hasSuffix:@".gz"]) { + mimeType = @"application/gzip"; + } else { + LOGE(@"Unknown extension type: %@, not attaching logs", filename); + } + + if (mimeType != nil) { + [attachments addObject:@[ [NSString stringWithUTF8String:filepath], mimeType, filename ]]; + } + } + + if ([LinphoneManager.instance lpConfigBoolForKey:@"send_logs_include_linphonerc_and_chathistory"]) { + // retrieve linphone rc + [attachments + addObject:@[ [LinphoneManager documentFile:@"linphonerc"], @"text/plain", @"linphone-configuration.rc" ]]; + + // retrieve historydb + [attachments addObject:@[ + [LinphoneManager documentFile:@"linphone_chats.db"], + @"application/x-sqlite3", + @"linphone-chats-history.db" + ]]; + } + + [self emailAttachments:attachments]; + ms_free(filepath); +} +- (void)emailAttachments:(NSArray *)attachments { + NSString *error = nil; +#if TARGET_IPHONE_SIMULATOR + error = @"Cannot send emails on the Simulator. To test this feature, please use a real device."; +#else + if ([MFMailComposeViewController canSendMail] == NO) { + error = NSLocalizedString( + @"Your device is not configured to send emails. Please configure mail application prior to send logs.", + nil); + } +#endif + + if (error != nil) { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Cannot send email", nil) + message:error + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Continue", nil) + otherButtonTitles:nil]; + [alert show]; + } else { + MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init]; + picker.mailComposeDelegate = self; + + [picker setSubject:@"Linphone iOS Logs"]; + [picker setToRecipients:[NSArray arrayWithObjects:@"linphone-iphone@belledonne-communications.com", nil]]; + [picker setMessageBody:@"Here are information about an issue I had on my device.\nI was " + @"doing ...\nI expected Linphone to ...\nInstead, I got an " + @"unexpected result: ..." + isHTML:NO]; + for (NSArray *attachment in attachments) { + if ([[NSFileManager defaultManager] fileExistsAtPath:attachment[0]]) { + [picker addAttachmentData:[NSData dataWithContentsOfFile:attachment[0]] + mimeType:attachment[1] + fileName:attachment[2]]; + } + } + [self presentViewController:picker animated:true completion:nil]; + } +} + +- (void)mailComposeController:(MFMailComposeViewController *)controller + didFinishWithResult:(MFMailComposeResult)result + error:(NSError *)error { + if (error != nil) { + LOGW(@"Error while sending mail: %@", error); + } else { + LOGI(@"Mail completed with status: %d", result); + } + [self dismissViewControllerAnimated:true completion:nil]; +} + +- (IBAction)onDialerBackClick:(id)sender { + [_settingsController.navigationController popViewControllerAnimated:NO]; + + DialerView *view = VIEW(DialerView); + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; +} + +- (IBAction)onBackClick:(id)sender { + [_settingsController.navigationController popViewControllerAnimated:YES]; +} +@end diff --git a/Classes/SettingsViewController.h b/Classes/SettingsViewController.h deleted file mode 100644 index 91dd60905..000000000 --- a/Classes/SettingsViewController.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SettingsViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import - -#import "UICompositeViewController.h" -#import "IASKAppSettingsViewController.h" -#import "LinphoneCoreSettingsStore.h" - -@interface SettingsViewController: UIViewController { - @private - LinphoneCoreSettingsStore* settingsStore; -} - -@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; -@property (nonatomic, retain) IBOutlet IASKAppSettingsViewController *settingsController; - -@end diff --git a/Classes/SettingsViewController.m b/Classes/SettingsViewController.m deleted file mode 100644 index 909a8fb39..000000000 --- a/Classes/SettingsViewController.m +++ /dev/null @@ -1,833 +0,0 @@ -/* SettingsViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "SettingsViewController.h" -#import "LinphoneManager.h" -#import "PhoneMainView.h" -#import "UILinphone.h" -#import "UACellBackgroundView.h" - -#import "DCRoundSwitch.h" - -#import "IASKSpecifierValuesViewController.h" -#import "IASKPSTextFieldSpecifierViewCell.h" -#import "IASKPSTitleValueSpecifierViewCell.h" -#import "IASKSpecifier.h" -#import "IASKTextField.h" -#include "linphone/lpconfig.h" - -#import "DTAlertView.h" - -#ifdef DEBUG -@interface UIDevice (debug) - -- (void)_setBatteryLevel:(float)level; -- (void)_setBatteryState:(int)state; - -@end -#endif - -@interface SettingsViewController (private) - -+ (IASKSpecifier*)filterSpecifier:(IASKSpecifier *)specifier; - -@end - - -#pragma mark - IASKSwitchEx Class - -@interface IASKSwitchEx : DCRoundSwitch { - NSString *_key; -} - -@property (nonatomic, retain) NSString *key; - -@end - -@implementation IASKSwitchEx - -@synthesize key=_key; - -- (void)dealloc { - [_key release], _key = nil; - - [super dealloc]; -} - -@end - - -#pragma mark - IASKSpecifierValuesViewControllerEx Class - -// Patch IASKSpecifierValuesViewController -@interface IASKSpecifierValuesViewControllerEx: IASKSpecifierValuesViewController - -@end - -@implementation IASKSpecifierValuesViewControllerEx - -- (void)initIASKSpecifierValuesViewControllerEx { - [self.view setBackgroundColor:[UIColor clearColor]]; -} - -- (id)init { - self = [super init]; - if(self != nil) { - [self initIASKSpecifierValuesViewControllerEx]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if(self != nil) { - [self initIASKSpecifierValuesViewControllerEx]; - } - return self; -} - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if(self != nil) { - [self initIASKSpecifierValuesViewControllerEx]; - } - return self; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell * cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; - - // Background View - UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease]; - cell.selectedBackgroundView = selectedBackgroundView; - [selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR]; - return cell; -} - -@end - - -#pragma mark - IASKAppSettingsViewControllerEx Class - -@interface IASKAppSettingsViewController(PrivateInterface) -- (UITableViewCell*)newCellForIdentifier:(NSString*)identifier; -@end; - -@interface IASKAppSettingsViewControllerEx : IASKAppSettingsViewController - -@end - -@implementation IASKAppSettingsViewControllerEx - -- (UITableViewCell*)newCellForIdentifier:(NSString*)identifier { - UITableViewCell *cell = nil; - if ([identifier isEqualToString:kIASKPSToggleSwitchSpecifier]) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kIASKPSToggleSwitchSpecifier]; - cell.accessoryView = [[[IASKSwitchEx alloc] initWithFrame:CGRectMake(0, 0, 79, 27)] autorelease]; - [((IASKSwitchEx*)cell.accessoryView) addTarget:self action:@selector(toggledValue:) forControlEvents:UIControlEventValueChanged]; - [((IASKSwitchEx*)cell.accessoryView) setOnTintColor:LINPHONE_MAIN_COLOR]; - cell.selectionStyle = UITableViewCellSelectionStyleNone; - cell.textLabel.minimumScaleFactor = kIASKMinimumFontSize/[UIFont systemFontSize]; - cell.detailTextLabel.minimumScaleFactor = kIASKMinimumFontSize/[UIFont systemFontSize]; - } else { - cell = [super newCellForIdentifier:identifier]; - } - return cell; -} - -- (void)toggledValue:(id)sender { - IASKSwitchEx *toggle = [[(IASKSwitchEx*)sender retain] autorelease]; - IASKSpecifier *spec = [_settingsReader specifierForKey:[toggle key]]; - - if ([toggle isOn]) { - if ([spec trueValue] != nil) { - [self.settingsStore setObject:[spec trueValue] forKey:[toggle key]]; - } - else { - [self.settingsStore setBool:YES forKey:[toggle key]]; - } - } - else { - if ([spec falseValue] != nil) { - [self.settingsStore setObject:[spec falseValue] forKey:[toggle key]]; - } - else { - [self.settingsStore setBool:NO forKey:[toggle key]]; - } - } - // Start notification after animation of DCRoundSwitch - dispatch_async(dispatch_get_main_queue(), ^{ - [[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged - object:[toggle key] - userInfo:[NSDictionary dictionaryWithObject:[self.settingsStore objectForKey:[toggle key]] - forKey:[toggle key]]]; - }); -} - -- (void)initIASKAppSettingsViewControllerEx { - [self.view setBackgroundColor:[UIColor clearColor]]; - - // Force kIASKSpecifierValuesViewControllerIndex - static int kIASKSpecifierValuesViewControllerIndex = 0; - _viewList = [[NSMutableArray alloc] init]; - [_viewList addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"IASKSpecifierValuesView", @"ViewName",nil]]; - [_viewList addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"IASKAppSettingsView", @"ViewName",nil]]; - - NSMutableDictionary *newItemDict = [NSMutableDictionary dictionaryWithCapacity:3]; - [newItemDict addEntriesFromDictionary: [_viewList objectAtIndex:kIASKSpecifierValuesViewControllerIndex]]; // copy the title and explain strings - - IASKSpecifierValuesViewController *targetViewController = [[IASKSpecifierValuesViewControllerEx alloc] init]; - // add the new view controller to the dictionary and then to the 'viewList' array - [newItemDict setObject:targetViewController forKey:@"viewController"]; - [_viewList replaceObjectAtIndex:kIASKSpecifierValuesViewControllerIndex withObject:newItemDict]; - [targetViewController release]; -} - -- (IASKSettingsReader*)settingsReader { - IASKSettingsReader *r = [super settingsReader]; - NSMutableArray *dataSource = [NSMutableArray arrayWithArray:[r dataSource]]; - for (int i = 0; i < [dataSource count]; ++i) { - NSMutableArray *specifiers = [NSMutableArray arrayWithArray:[dataSource objectAtIndex:i]]; - for (int j = 0; j < [specifiers count]; ++j) { - id sp = [specifiers objectAtIndex:j]; - if ([sp isKindOfClass:[IASKSpecifier class]]) { - sp = [SettingsViewController filterSpecifier:sp]; - } - [specifiers replaceObjectAtIndex:j withObject:sp]; - } - - [dataSource replaceObjectAtIndex:i withObject:specifiers]; - } - [r setDataSource:dataSource]; - return r; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - - [self.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4 - [self.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4 -} - -- (id)initWithStyle:(UITableViewStyle)style { - self = [super initWithStyle:style]; - if(self != nil) { - [self initIASKAppSettingsViewControllerEx]; - } - return self; -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - - UIEdgeInsets inset = {0, 0, 10, 0}; - UIScrollView *scrollView = self.tableView; - [scrollView setContentInset:inset]; - [scrollView setScrollIndicatorInsets:inset]; -} - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"About", nil) style:UIBarButtonItemStyleBordered target:self action:@selector(onAboutClick:)]; - self.navigationItem.rightBarButtonItem = buttonItem; - [buttonItem release]; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell * cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; - - if([cell isKindOfClass:[IASKPSTextFieldSpecifierViewCell class]]) { - UITextField *field = ((IASKPSTextFieldSpecifierViewCell*)cell).textField; - [field setTextColor:LINPHONE_MAIN_COLOR]; - } - - if([cell isKindOfClass:[IASKPSTitleValueSpecifierViewCell class]]) { - cell.detailTextLabel.textColor = [UIColor grayColor]; - } else { - cell.detailTextLabel.textColor = LINPHONE_MAIN_COLOR; - } - - // Background View - UACellBackgroundView *selectedBackgroundView = [[[UACellBackgroundView alloc] initWithFrame:CGRectZero] autorelease]; - cell.selectedBackgroundView = selectedBackgroundView; - [selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR]; - return cell; -} - -- (IBAction)onAboutClick: (id)sender { - [[PhoneMainView instance] changeCurrentView:[AboutViewController compositeViewDescription] push:TRUE]; -} - -@end - - -#pragma mark - UINavigationBarEx Class - -@interface UINavigationBarEx: UINavigationBar { - -} -@end - -@implementation UINavigationBarEx - - -#pragma mark - Lifecycle Functions - -- (void)initUINavigationBarEx { - [self setTintColor:[LINPHONE_MAIN_COLOR adjustHue:5.0f/180.0f saturation:0.0f brightness:0.0f alpha:0.0f]]; -} - -- (id)init { - self = [super init]; - if (self) { - [self initUINavigationBarEx]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if (self) { - [self initUINavigationBarEx]; - } - return self; -} - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - [self initUINavigationBarEx]; - } - return self; -} - -- (void)drawRect:(CGRect)rect { - UIImage *img = [UIImage imageNamed:@"toolsbar_background.png"]; - [img drawInRect:rect]; -} - -@end - - -#pragma mark - UINavigationControllerEx Class - -@interface UINavigationControllerEx : UINavigationController - -@end - -@implementation UINavigationControllerEx - -- (id)initWithRootViewController:(UIViewController *)rootViewController { - [UINavigationControllerEx removeBackground:rootViewController.view]; - return [self initWithRootViewController:rootViewController]; -} - -+ (void)removeBackground:(UIView*)view { - // iOS7 transparent background is *really* transparent: with an alpha != 0 - // it messes up the transitions. Use non-transparent BG for iOS7 - if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) - [view setBackgroundColor:LINPHONE_SETTINGS_BG_IOS7]; - else - [view setBackgroundColor:[UIColor clearColor]]; -} - -- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { - [UINavigationControllerEx removeBackground:viewController.view]; - - [viewController viewWillAppear:animated]; // Force view - UILabel *labelTitleView = [[UILabel alloc] init]; - labelTitleView.backgroundColor = [UIColor clearColor]; - labelTitleView.textColor = [UIColor colorWithRed:0x41/255.0f green:0x48/255.0f blue:0x4f/255.0f alpha:1.0]; - labelTitleView.shadowColor = [UIColor colorWithWhite:1.0 alpha:0.5]; - labelTitleView.font = [UIFont boldSystemFontOfSize:20]; - labelTitleView.shadowOffset = CGSizeMake(0,1); - labelTitleView.textAlignment = NSTextAlignmentCenter; - labelTitleView.text = viewController.title; - [labelTitleView sizeToFit]; - viewController.navigationItem.titleView = labelTitleView; - [labelTitleView release]; - [super pushViewController:viewController animated:animated]; -} - -- (void)setViewControllers:(NSArray *)viewControllers { - for(UIViewController *controller in viewControllers) { - [UINavigationControllerEx removeBackground:controller.view]; - } - [super setViewControllers:viewControllers]; -} - -- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated { - for(UIViewController *controller in viewControllers) { - [UINavigationControllerEx removeBackground:controller.view]; - } - [super setViewControllers:viewControllers animated:animated]; -} - -@end - - -@implementation SettingsViewController - -@synthesize settingsController; -@synthesize navigationController; - -#pragma mark - Lifecycle Functions - -- (id)init { - return [super initWithNibName:@"SettingsViewController" bundle:[NSBundle mainBundle]]; -} - - -- (void)dealloc { - // Remove all observer - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [settingsStore release]; - [settingsController release]; - [navigationController release]; - [super dealloc]; -} - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"Settings" - content:@"SettingsViewController" - stateBar:nil - stateBarEnabled:false - tabBar: @"UIMainBar" - tabBarEnabled:true - fullscreen:false - landscapeMode:[LinphoneManager runningOnIpad] - portraitMode:true]; - } - return compositeDescription; -} - - -#pragma mark - ViewController Functions - -- (void)viewDidLoad { - [super viewDidLoad]; - - settingsStore = [[LinphoneCoreSettingsStore alloc] init]; - - settingsController.showDoneButton = FALSE; - settingsController.delegate = self; - settingsController.showCreditsFooter = FALSE; - settingsController.settingsStore = settingsStore; - - [navigationController.view setBackgroundColor:[UIColor clearColor]]; - - navigationController.view.frame = self.view.frame; - [navigationController pushViewController:settingsController animated:FALSE]; - [self.view addSubview: navigationController.view]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [settingsController dismiss:self]; - // Set observer - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kIASKAppSettingChanged - object:nil]; -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - [settingsStore transformLinphoneCoreToKeys]; // Sync settings with linphone core settings - settingsController.hiddenKeys = [self findHiddenKeys]; - [settingsController.tableView reloadData]; - - // Set observer - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(appSettingChanged:) - name:kIASKAppSettingChanged - object:nil]; -} - - -#pragma mark - Event Functions - -- (void)appSettingChanged:(NSNotification*) notif { - NSMutableSet *hiddenKeys = [NSMutableSet setWithSet:[settingsController hiddenKeys]]; - NSMutableArray* keys = [NSMutableArray array]; - BOOL removeFromHiddenKeys = TRUE; - - if([@"enable_video_preference" compare: notif.object] == NSOrderedSame) { - removeFromHiddenKeys = [[notif.userInfo objectForKey:@"enable_video_preference"] boolValue]; - [keys addObject:@"video_menu"]; - } else if ([@"random_port_preference" compare: notif.object] == NSOrderedSame) { - removeFromHiddenKeys = ! [[notif.userInfo objectForKey:@"random_port_preference"] boolValue]; - [keys addObject:@"port_preference"]; - } else if ([@"backgroundmode_preference" compare: notif.object] == NSOrderedSame) { - removeFromHiddenKeys = [[notif.userInfo objectForKey:@"backgroundmode_preference"] boolValue]; - [keys addObject:@"start_at_boot_preference"]; - } else if ([@"stun_preference" compare: notif.object] == NSOrderedSame) { - NSString *stun_server = [notif.userInfo objectForKey:@"stun_preference"]; - removeFromHiddenKeys = (stun_server && ([stun_server length] > 0)); - [keys addObject:@"ice_preference"]; - } else if ([@"debugenable_preference" compare: notif.object] == NSOrderedSame) { - BOOL debugEnabled = [[notif.userInfo objectForKey:@"debugenable_preference"] boolValue]; - removeFromHiddenKeys = debugEnabled; - [keys addObject:@"send_logs_button"]; - [keys addObject:@"reset_logs_button"]; - [[LinphoneManager instance] setLogsEnabled:debugEnabled]; - } else if( [@"advanced_account_preference" compare:notif.object] == NSOrderedSame) { - removeFromHiddenKeys = [[notif.userInfo objectForKey:@"advanced_account_preference"] boolValue]; - - [keys addObject:@"userid_preference"]; - [keys addObject:@"proxy_preference"]; - [keys addObject:@"outbound_proxy_preference"]; - [keys addObject:@"avpf_preference"]; - } - - for(NSString* key in keys){ - if( removeFromHiddenKeys ) [hiddenKeys removeObject:key]; - else [hiddenKeys addObject:key]; - } - - [settingsController setHiddenKeys:hiddenKeys animated:TRUE]; - -} - - -#pragma mark - - -+ (IASKSpecifier*)disableCodecSpecifier:(IASKSpecifier *)specifier { - NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[specifier specifierDict]]; - - NSMutableString *type = [NSMutableString stringWithString:[dict objectForKey:kIASKType]]; - [type setString:kIASKPSTitleValueSpecifier]; - [dict setObject:type forKey:kIASKType]; - - NSMutableArray *values = [NSMutableArray arrayWithObjects:[NSNumber numberWithInt:0], [NSNumber numberWithInt:1], nil ]; - [dict setObject:values forKey:kIASKValues]; - - NSString* title = NSLocalizedString(@"Disabled, build from sources to enable", nil); - NSMutableArray *titles = [NSMutableArray arrayWithObjects:title, title, nil]; - [dict setObject:titles forKey:kIASKTitles]; - - return [[[IASKSpecifier alloc] initWithSpecifier:dict] autorelease]; -} - -+ (IASKSpecifier*)filterSpecifier:(IASKSpecifier *)specifier { -#ifndef HAVE_SSL - if ([[specifier key] isEqualToString:@"transport_preference"]) { - NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[specifier specifierDict]]; - NSMutableArray *titles = [NSMutableArray arrayWithArray:[dict objectForKey:@"Titles"]]; - [titles removeObject:@"TLS"]; - [dict setObject:titles forKey:@"Titles"]; - NSMutableArray *values = [NSMutableArray arrayWithArray:[dict objectForKey:@"Values"]]; - [values removeObject:@"tls"]; - [dict setObject:values forKey:@"Values"]; - return [[[IASKSpecifier alloc] initWithSpecifier:dict] autorelease]; - } -#else - if ([[specifier key] isEqualToString:@"media_encryption_preference"]) { - NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[specifier specifierDict]]; - if(!linphone_core_media_encryption_supported([LinphoneManager getLc], LinphoneMediaEncryptionZRTP)) { - NSMutableArray *titles = [NSMutableArray arrayWithArray:[dict objectForKey:@"Titles"]]; - [titles removeObject:@"ZRTP"]; - [dict setObject:titles forKey:@"Titles"]; - NSMutableArray *values = [NSMutableArray arrayWithArray:[dict objectForKey:@"Values"]]; - [values removeObject:@"ZRTP"]; - [dict setObject:values forKey:@"Values"]; - } - if(!linphone_core_media_encryption_supported([LinphoneManager getLc], LinphoneMediaEncryptionSRTP)) { - NSMutableArray *titles = [NSMutableArray arrayWithArray:[dict objectForKey:@"Titles"]]; - [titles removeObject:@"SRTP"]; - [dict setObject:titles forKey:@"Titles"]; - NSMutableArray *values = [NSMutableArray arrayWithArray:[dict objectForKey:@"Values"]]; - [values removeObject:@"SRTP"]; - [dict setObject:values forKey:@"Values"]; - } - if(!linphone_core_media_encryption_supported([LinphoneManager getLc], LinphoneMediaEncryptionDTLS)) { - NSMutableArray *titles = [NSMutableArray arrayWithArray:[dict objectForKey:@"Titles"]]; - [titles removeObject:@"DTLS"]; - [dict setObject:titles forKey:@"Titles"]; - NSMutableArray *values = [NSMutableArray arrayWithArray:[dict objectForKey:@"Values"]]; - [values removeObject:@"DTLS"]; - [dict setObject:values forKey:@"Values"]; - } - return [[[IASKSpecifier alloc] initWithSpecifier:dict] autorelease]; - } - -#endif //HAVE_SSL - - - // Add "build from source" if MPEG4 or H264 disabled - if ([[specifier key] isEqualToString:@"h264_preference"] && ![LinphoneManager isCodecSupported:"h264"]) { - return [SettingsViewController disableCodecSpecifier:specifier]; - } - if ([[specifier key] isEqualToString:@"mp4v-es_preference"] && ![LinphoneManager isCodecSupported:"mp4v-es"]) { - return [SettingsViewController disableCodecSpecifier:specifier]; - } - - return specifier; -} - -- (NSSet*)findHiddenKeys { - LinphoneManager* lm = [LinphoneManager instance]; - NSMutableSet *hiddenKeys = [NSMutableSet set]; - -#ifndef DEBUG - [hiddenKeys addObject:@"release_button"]; - [hiddenKeys addObject:@"clear_cache_button"]; - [hiddenKeys addObject:@"battery_alert_button"]; -#endif - - if (! [[LinphoneManager instance] lpConfigBoolForKey:@"debugenable_preference"]) { - [hiddenKeys addObject:@"send_logs_button"]; - [hiddenKeys addObject:@"reset_logs_button"]; - } - - [hiddenKeys addObject:@"playback_gain_preference"]; - [hiddenKeys addObject:@"microphone_gain_preference"]; - - [hiddenKeys addObject:@"network_limit_group"]; - [hiddenKeys addObject:@"upload_bandwidth_preference"]; - [hiddenKeys addObject:@"download_bandwidth_preference"]; - - [hiddenKeys addObject:@"incoming_call_timeout_preference"]; - [hiddenKeys addObject:@"in_call_timeout_preference"]; - - [hiddenKeys addObject:@"wifi_only_preference"]; - - [hiddenKeys addObject:@"quit_button"]; // Hide for the moment - [hiddenKeys addObject:@"about_button"]; // Hide for the moment - - if (!linphone_core_video_supported([LinphoneManager getLc])) - [hiddenKeys addObject:@"video_menu"]; - - if (![LinphoneManager isNotIphone3G]) - [hiddenKeys addObject:@"silk_24k_preference"]; - - UIDevice* device = [UIDevice currentDevice]; - if (![device respondsToSelector:@selector(isMultitaskingSupported)] || ![device isMultitaskingSupported]) { - [hiddenKeys addObject:@"backgroundmode_preference"]; - [hiddenKeys addObject:@"start_at_boot_preference"]; - } else { - if(![lm lpConfigBoolForKey:@"backgroundmode_preference"]) { - [hiddenKeys addObject:@"start_at_boot_preference"]; - } - } - - [hiddenKeys addObject:@"enable_first_login_view_preference"]; - -#ifndef VIDEO_ENABLED - [hiddenKeys addObject:@"enable_video_preference"]; -#endif //VIDEO_ENABLED - - if (!linphone_core_video_enabled([LinphoneManager getLc])) { - [hiddenKeys addObject:@"video_menu"]; - } - - - [hiddenKeys addObjectsFromArray:[[LinphoneManager unsupportedCodecs] allObjects]]; - - BOOL random_port = [lm lpConfigBoolForKey:@"random_port_preference"]; - if(random_port) { - [hiddenKeys addObject:@"port_preference"]; - } - - if(linphone_core_get_stun_server([LinphoneManager getLc]) == NULL) { - [hiddenKeys addObject:@"ice_preference"]; - } - - if(![lm lpConfigBoolForKey:@"debugenable_preference"]) { - [hiddenKeys addObject:@"console_button"]; - } - - if(![LinphoneManager runningOnIpad]) { - [hiddenKeys addObject:@"preview_preference"]; - } - if([lm lpConfigBoolForKey:@"hide_run_assistant_preference"]) { - [hiddenKeys addObject:@"wizard_button"]; - } - - if (!linphone_core_tunnel_available()){ - [hiddenKeys addObject:@"tunnel_menu"]; - } - - if( ![lm lpConfigBoolForKey:@"advanced_account_preference"] ){ - [hiddenKeys addObject:@"userid_preference"]; - [hiddenKeys addObject:@"proxy_preference"]; - [hiddenKeys addObject:@"outbound_proxy_preference"]; - [hiddenKeys addObject:@"avpf_preference"]; - } - - return hiddenKeys; -} - -- (void)goToWizard { - WizardViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[WizardViewController compositeViewDescription]], WizardViewController); - if(controller != nil) { - [controller reset]; - } -} - -#pragma mark - IASKSettingsDelegate Functions - -- (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController *)sender { -} - -- (void)settingsViewController:(IASKAppSettingsViewController*)sender buttonTappedForSpecifier:(IASKSpecifier*)specifier { - NSString *key = [specifier.specifierDict objectForKey:kIASKKey]; - LinphoneCore* lc = [LinphoneManager getLc]; -#ifdef DEBUG - if([key isEqual:@"release_button"]) { - [UIApplication sharedApplication].keyWindow.rootViewController = nil; - [[UIApplication sharedApplication].keyWindow setRootViewController:nil]; - [[LinphoneManager instance] destroyLibLinphone]; - [LinphoneManager instanceRelease]; - } else if([key isEqual:@"clear_cache_button"]) { - [[PhoneMainView instance].mainViewController clearCache:[NSArray arrayWithObject:[[PhoneMainView instance] currentView]]]; - } else if([key isEqual:@"battery_alert_button"]) { - [[UIDevice currentDevice] _setBatteryState:UIDeviceBatteryStateUnplugged]; - [[UIDevice currentDevice] _setBatteryLevel:0.01f]; - [[NSNotificationCenter defaultCenter] postNotificationName:UIDeviceBatteryLevelDidChangeNotification object:self]; - } -#endif - if([key isEqual:@"wizard_button"]) { - if (linphone_core_get_default_proxy_config(lc) == NULL ) { - [self goToWizard]; - return; - } - UIAlertView* alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Warning",nil) - message:NSLocalizedString(@"Launching the Wizard will delete any existing proxy config.\nAre you sure to want it?",nil) - delegate:self - cancelButtonTitle:NSLocalizedString(@"Cancel",nil) - otherButtonTitles:NSLocalizedString(@"Launch Wizard",nil), nil]; - [alert show]; - [alert release]; - } else if ( [key isEqual:@"clear_proxy_button"] ) { - if ( linphone_core_get_default_proxy_config(lc) == NULL ) { - return; - } - - DTAlertView* alert = [[DTAlertView alloc] initWithTitle:NSLocalizedString(@"Warning", nil) message:NSLocalizedString(@"Are you sure to want to clear your proxy setup?",nil)]; - - [alert addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; - [alert addButtonWithTitle:NSLocalizedString(@"Yes", nil) - block:^{ - linphone_core_clear_proxy_config(lc); - linphone_core_clear_all_auth_info(lc); - [settingsStore transformLinphoneCoreToKeys]; - [settingsController.tableView reloadData]; - }]; - [alert show]; - [alert release]; - - } else if([key isEqual:@"about_button"]) { - [[PhoneMainView instance] changeCurrentView:[AboutViewController compositeViewDescription] push:TRUE]; - } else if ([key isEqualToString:@"reset_logs_button"]) { - linphone_core_reset_log_collection(); - } else if ([key isEqual:@"send_logs_button"]) { - char * filepath = linphone_core_compress_log_collection(lc); - if (filepath == NULL) { - [LinphoneLogger log:LinphoneLoggerError format:@"Cannot sent logs: file is NULL"]; - return; - } - - NSString *filename = [[NSString stringWithUTF8String:filepath] componentsSeparatedByString:@"/"].lastObject; - NSString *mimeType; - if ([filename hasSuffix:@".jpg"]) { - mimeType = @"image/jpeg"; - } else if ([filename hasSuffix:@".png"]) { - mimeType = @"image/png"; - } else if ([filename hasSuffix:@".pdf"]) { - mimeType = @"application/pdf"; - } else if ([filename hasSuffix:@".txt"]) { - mimeType = @"text/plain"; - } else if ([filename hasSuffix:@".gz"]) { - mimeType = @"application/gzip"; - } else { - [LinphoneLogger log:LinphoneLoggerError format:@"Unknown extension type: %@, cancelling email", filename]; - return; - } - [self emailAttachment:[NSData dataWithContentsOfFile:[NSString stringWithUTF8String:filepath]] mimeType:mimeType name:filename]; - ms_free(filepath); - } -} - -#pragma mark - UIAlertView delegate - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { - if( buttonIndex != 1 ) return; /* cancel */ - else [self goToWizard]; -} - -#pragma mark - Mail composer for send log -- (void)emailAttachment: (NSData*)attachment mimeType:(NSString*)type name:(NSString*)attachmentName -{ - if (attachmentName == nil || type == nil || attachmentName == nil) { - [LinphoneLogger log:LinphoneLoggerError format:@"Trying to email attachment but mandatory field is missing"]; - return; - } - -#if TARGET_IPHONE_SIMULATOR - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Cannot send email",nil) - message:NSLocalizedString(@"Simulator cannot send emails. To test this feature, please use a real device.",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; -#else - if ([MFMailComposeViewController canSendMail] == YES) { - MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init]; - picker.mailComposeDelegate = self; - - [picker setSubject:NSLocalizedString(@"Linphone Logs",nil)]; - [picker setToRecipients:[NSArray arrayWithObjects:@"linphone-iphone@belledonne-communications.com", nil]]; - [picker setMessageBody:NSLocalizedString(@"Linphone logs", nil) isHTML:NO]; - [picker addAttachmentData:attachment mimeType:type fileName:attachmentName]; - - [self presentViewController:picker animated:true completion:nil]; - [picker release]; - } else { - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Cannot send email",nil) - message:NSLocalizedString(@"Your device is not configured to send emails. Please configure mail application prior to send logs.",nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil]; - [error show]; - [error release]; - } -#endif -} - -- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error -{ - if (error != nil) { - [LinphoneLogger log:LinphoneLoggerWarning format:@"Error while sending mail: %@", error]; - } else { - [LinphoneLogger log:LinphoneLoggerLog format:@"Mail completed with status: %d", result]; - } - [self dismissViewControllerAnimated:true completion:nil]; -} - -@end diff --git a/Classes/SideMenuTableView.h b/Classes/SideMenuTableView.h new file mode 100644 index 000000000..6884e6b1c --- /dev/null +++ b/Classes/SideMenuTableView.h @@ -0,0 +1,25 @@ +// +// SideMenuTableViewController.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 28/07/15. +// +// + +#import + +// the block to execute when an entry tapped +typedef void (^SideMenuEntryBlock)(void); + +@interface SideMenuEntry : NSObject { + @public + NSString *title; + SideMenuEntryBlock onTapBlock; +}; +@end + +@interface SideMenuTableView : UITableViewController + +@property(nonatomic, retain) NSMutableArray *sideMenuEntries; + +@end diff --git a/Classes/SideMenuTableView.m b/Classes/SideMenuTableView.m new file mode 100644 index 000000000..40985246b --- /dev/null +++ b/Classes/SideMenuTableView.m @@ -0,0 +1,119 @@ +// +// SideMenuTableViewController.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 28/07/15. +// +// + +#import "SideMenuTableView.h" +#import "Utils.h" + +#import "PhoneMainView.h" +#import "StatusBarView.h" + +@implementation SideMenuEntry + +- (id)initWithTitle:(NSString *)atitle tapBlock:(SideMenuEntryBlock)tapBlock { + if ((self = [super init])) { + title = atitle; + onTapBlock = tapBlock; + } + return self; +} + +@end + +@implementation SideMenuTableView + +- (void)viewDidLoad { + [super viewDidLoad]; + + // remove separators between empty items, cf + // http://stackoverflow.com/questions/1633966/can-i-force-a-uitableview-to-hide-the-separator-between-empty-cells + self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; + + _sideMenuEntries = [[NSMutableArray alloc] init]; + + [_sideMenuEntries + addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"Assistant", nil) + tapBlock:^() { + [PhoneMainView.instance + changeCurrentView:AssistantView.compositeViewDescription + push:NO + animated:NO]; + }]]; + [_sideMenuEntries + addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"Settings", nil) + tapBlock:^() { + [PhoneMainView.instance + changeCurrentView:SettingsView.compositeViewDescription + push:NO + animated:NO]; + }]]; + [_sideMenuEntries addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"About", nil) + tapBlock:^() { + [PhoneMainView.instance + changeCurrentView:AboutView.compositeViewDescription + push:NO + animated:NO]; + + }]]; +} + +#pragma mark - Table View Controller +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 2; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + if (section == 0) { + BOOL hasDefault = (linphone_core_get_default_proxy_config([LinphoneManager getLc]) != NULL); + // default account is shown in the header already + return MAX(0, + ms_list_size(linphone_core_get_proxy_config_list([LinphoneManager getLc])) - (hasDefault ? 1 : 0)); + } else { + return [_sideMenuEntries count]; + } +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [[UITableViewCell alloc] init]; + if (indexPath.section == 0) { + LinphoneProxyConfig *proxy = + ms_list_nth_data(linphone_core_get_proxy_config_list([LinphoneManager getLc]), (int)indexPath.row); + if (proxy) { + cell.textLabel.text = [NSString stringWithUTF8String:linphone_proxy_config_get_identity(proxy)]; + cell.imageView.image = [StatusBarView imageForState:linphone_proxy_config_get_state(proxy)]; + } else { + LOGE(@"Invalid index requested, no proxy for row %d", indexPath.row); + } + cell.transform = CGAffineTransformMakeScale(-1.0, 1.0); + cell.textLabel.transform = CGAffineTransformMakeScale(-1.0, 1.0); + cell.imageView.transform = CGAffineTransformMakeScale(-1.0, 1.0); + cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_G.png"]]; + } else { + SideMenuEntry *entry = [_sideMenuEntries objectAtIndex:indexPath.row]; + cell.textLabel.text = entry->title; + } + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [tableView deselectRowAtIndexPath:indexPath animated:NO]; + + if (indexPath.section == 0) { + [PhoneMainView.instance changeCurrentView:SettingsView.compositeViewDescription]; + } else { + SideMenuEntry *entry = [_sideMenuEntries objectAtIndex:indexPath.row]; + LOGI(@"Entry %@ has been tapped", entry->title); + if (entry->onTapBlock == nil) { + LOGF(@"Entry %@ has no onTapBlock!", entry->title); + } else { + entry->onTapBlock(); + } + } + [PhoneMainView.instance.mainViewController hideSideMenu:YES]; +} + +@end diff --git a/Classes/SideMenuView.h b/Classes/SideMenuView.h new file mode 100644 index 000000000..312c10ec3 --- /dev/null +++ b/Classes/SideMenuView.h @@ -0,0 +1,27 @@ +// +// SideMenuViewController.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 28/07/15. +// +// + +#import + +#import "SideMenuTableView.h" +#import "PhoneMainView.h" + +@interface SideMenuView : UIViewController + +@property(strong, nonatomic) IBOutlet UISwipeGestureRecognizer *swipeGestureRecognizer; +@property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage; +@property(weak, nonatomic) IBOutlet UILabel *nameLabel; +@property(weak, nonatomic) IBOutlet UIButton *addressButton; +@property(strong, nonatomic) IBOutlet SideMenuTableView *sideMenuTableViewController; +@property(weak, nonatomic) IBOutlet UIView *grayBackground; +- (IBAction)onLateralSwipe:(id)sender; +- (IBAction)onHeaderClick:(id)sender; +- (IBAction)onAvatarClick:(id)sender; +- (IBAction)onBackgroundClicked:(id)sender; + +@end diff --git a/Classes/SideMenuView.m b/Classes/SideMenuView.m new file mode 100644 index 000000000..8400bd301 --- /dev/null +++ b/Classes/SideMenuView.m @@ -0,0 +1,109 @@ +// +// SideMenuViewController.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 28/07/15. +// +// + +#import "SideMenuView.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" + +@implementation SideMenuView + +- (void)viewDidLoad { + [super viewDidLoad]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 + // it's better to detect only pan from screen edges + UIScreenEdgePanGestureRecognizer *pan = + [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(onLateralSwipe:)]; + pan.edges = UIRectEdgeRight; + [self.view addGestureRecognizer:pan]; + _swipeGestureRecognizer.enabled = NO; +#endif +} +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(registrationUpdateEvent:) + name:kLinphoneRegistrationUpdate + object:nil]; + + [self updateHeader]; + [_sideMenuTableViewController.tableView reloadData]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + _grayBackground.hidden = NO; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + _grayBackground.hidden = YES; + // should be better than that with alpha animation.. +} + +- (void)updateHeader { + LinphoneProxyConfig *default_proxy = linphone_core_get_default_proxy_config([LinphoneManager getLc]); + + if (default_proxy != NULL) { + const LinphoneAddress *addr = linphone_proxy_config_get_identity_address(default_proxy); + [ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr]; + char *as_string = linphone_address_as_string_uri_only(addr); + [_addressButton setTitle:[NSString stringWithUTF8String:as_string] forState:UIControlStateNormal]; + ms_free(as_string); + [_addressButton setImage:[StatusBarView imageForState:linphone_proxy_config_get_state(default_proxy)] + forState:UIControlStateNormal]; + } else { + _nameLabel.text = @"No account"; + [_addressButton setTitle:NSLocalizedString(@"No address", nil) forState:UIControlStateNormal]; + [_addressButton setImage:nil forState:UIControlStateNormal]; + } + _avatarImage.image = [LinphoneUtils selfAvatar]; +} + +- (void)onLateralSwipe:(UIScreenEdgePanGestureRecognizer *)pan { + [PhoneMainView.instance.mainViewController hideSideMenu:YES]; +} + +- (IBAction)onHeaderClick:(id)sender { + [PhoneMainView.instance changeCurrentView:SettingsView.compositeViewDescription]; + [PhoneMainView.instance.mainViewController hideSideMenu:YES]; +} + +- (IBAction)onAvatarClick:(id)sender { + // hide ourself because we are on top of image picker + if (!IPAD) { + [PhoneMainView.instance.mainViewController hideSideMenu:YES]; + } + [ImagePickerView SelectImageFromDevice:self atPosition:_avatarImage inView:self.view]; +} + +- (IBAction)onBackgroundClicked:(id)sender { + [PhoneMainView.instance.mainViewController hideSideMenu:YES]; +} + +- (void)registrationUpdateEvent:(NSNotification *)notif { + [self updateHeader]; + [_sideMenuTableViewController.tableView reloadData]; +} + +#pragma mark - Image picker delegate + +- (void)imagePickerDelegateImage:(UIImage *)image info:(NSDictionary *)info { + // Dismiss popover on iPad + if (IPAD) { + [VIEW(ImagePickerView).popoverController dismissPopoverAnimated:TRUE]; + } else { + [PhoneMainView.instance.mainViewController hideSideMenu:NO]; + } + + NSURL *url = [info valueForKey:UIImagePickerControllerReferenceURL]; + [LinphoneManager.instance lpConfigSetString:url.absoluteString forKey:@"avatar"]; + _avatarImage.image = [LinphoneUtils selfAvatar]; +} + +@end diff --git a/Classes/Utils/CAAnimationBlocks/CAAnimation+Blocks.m b/Classes/Utils/CAAnimationBlocks/CAAnimation+Blocks.m index f6ce6c738..74566ced8 100755 --- a/Classes/Utils/CAAnimationBlocks/CAAnimation+Blocks.m +++ b/Classes/Utils/CAAnimationBlocks/CAAnimation+Blocks.m @@ -34,12 +34,6 @@ return self; } -- (void)dealloc -{ - self.completion = nil; - self.start = nil; - [super dealloc]; -} - (void)animationDidStart:(CAAnimation *)anim { @@ -69,7 +63,6 @@ CAAnimationDelegate *delegate = [[CAAnimationDelegate alloc] init]; delegate.completion = completion; self.delegate = delegate; - [delegate release]; } } @@ -87,7 +80,6 @@ CAAnimationDelegate *delegate = [[CAAnimationDelegate alloc] init]; delegate.start = start; self.delegate = delegate; - [delegate release]; } } diff --git a/Classes/Utils/ColorSpaceUtilites.m b/Classes/Utils/ColorSpaceUtilites.m index 9071e6160..b6370e731 100644 --- a/Classes/Utils/ColorSpaceUtilites.m +++ b/Classes/Utils/ColorSpaceUtilites.m @@ -1,141 +1,135 @@ /* ColorConverter - + you can use it to convert color from RGB space to HSL space and back. - - HSL2RGB copied from GLPaint Apple sample: http://developer.apple.com/library/ios/#samplecode/GLPaint/Introduction/Intro.html - + + HSL2RGB copied from GLPaint Apple sample: + http://developer.apple.com/library/ios/#samplecode/GLPaint/Introduction/Intro.html + RGB2HSL translated from http://www.geekymonkey.com/Programming/CSharp/RGB2HSL_HSL2RGB.htm - + From: https://github.com/alessani/ColorConverter */ -void HSL2RGB(float h, float s, float l, float* outR, float* outG, float* outB) -{ - float temp1, - temp2; - float temp[3]; - int i; - +void HSL2RGB(float h, float s, float l, float *outR, float *outG, float *outB) { + float temp1, temp2; + float temp[3]; + int i; + // Check for saturation. If there isn't any just return the luminance value for each, which results in gray. - if(s == 0.0) { - if(outR) + if (s == 0.0) { + if (outR) *outR = l; - if(outG) + if (outG) *outG = l; - if(outB) + if (outB) *outB = l; return; } - + // Test for luminance and compute temporary values based on luminance and saturation - if(l < 0.5) + if (l < 0.5) temp2 = l * (1.0 + s); else temp2 = l + s - l * s; - temp1 = 2.0 * l - temp2; - + temp1 = 2.0 * l - temp2; + // Compute intermediate values based on hue temp[0] = h + 1.0 / 3.0; temp[1] = h; temp[2] = h - 1.0 / 3.0; - - for(i = 0; i < 3; ++i) { - + + for (i = 0; i < 3; ++i) { + // Adjust the range - if(temp[i] < 0.0) + if (temp[i] < 0.0) temp[i] += 1.0; - if(temp[i] > 1.0) + if (temp[i] > 1.0) temp[i] -= 1.0; - - - if(6.0 * temp[i] < 1.0) + + if (6.0 * temp[i] < 1.0) temp[i] = temp1 + (temp2 - temp1) * 6.0 * temp[i]; else { - if(2.0 * temp[i] < 1.0) + if (2.0 * temp[i] < 1.0) temp[i] = temp2; else { - if(3.0 * temp[i] < 2.0) + if (3.0 * temp[i] < 2.0) temp[i] = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - temp[i]) * 6.0; else temp[i] = temp1; } } } - + // Assign temporary values to R, G, B - if(outR) + if (outR) *outR = temp[0]; - if(outG) + if (outG) *outG = temp[1]; - if(outB) + if (outB) *outB = temp[2]; } +void RGB2HSL(float r, float g, float b, float *outH, float *outS, float *outL) { + /*r = r/255.0f; + g = g/255.0f; + b = b/255.0f;*/ -void RGB2HSL(float r, float g, float b, float* outH, float* outS, float* outL) -{ - /*r = r/255.0f; - g = g/255.0f; - b = b/255.0f;*/ - - - float h,s, l, v, m, vm, r2, g2, b2; - - h = 0; - s = 0; - - v = MAX(r, g); - v = MAX(v, b); - m = MIN(r, g); - m = MIN(m, b); - - l = (m+v)/2.0f; - - if (l <= 0.0){ - if(outH) + float h, s, l, v, m, vm, r2, g2, b2; + + h = 0; + s = 0; + + v = MAX(r, g); + v = MAX(v, b); + m = MIN(r, g); + m = MIN(m, b); + + l = (m + v) / 2.0f; + + if (l <= 0.0) { + if (outH) *outH = h; - if(outS) + if (outS) *outS = s; - if(outL) + if (outL) *outL = l; - return; - } - - vm = v - m; - s = vm; - - if (s > 0.0f){ - s/= (l <= 0.5f) ? (v + m) : (2.0 - v - m); - }else{ - if(outH) + return; + } + + vm = v - m; + s = vm; + + if (s > 0.0f) { + s /= (l <= 0.5f) ? (v + m) : (2.0 - v - m); + } else { + if (outH) *outH = h; - if(outS) + if (outS) *outS = s; - if(outL) + if (outL) *outL = l; - return; - } - - r2 = (v - r)/vm; - g2 = (v - g)/vm; - b2 = (v - b)/vm; - - if (r == v){ - h = (g == m ? 5.0f + b2 : 1.0f - g2); - }else if (g == v){ - h = (b == m ? 1.0f + r2 : 3.0 - b2); - }else{ - h = (r == m ? 3.0f + g2 : 5.0f - r2); - } - - h/=6.0f; - - if(outH) - *outH = h; - if(outS) - *outS = s; - if(outL) - *outL = l; - + return; + } + + r2 = (v - r) / vm; + g2 = (v - g) / vm; + b2 = (v - b) / vm; + + if (r == v) { + h = (g == m ? 5.0f + b2 : 1.0f - g2); + } else if (g == v) { + h = (b == m ? 1.0f + r2 : 3.0 - b2); + } else { + h = (r == m ? 3.0f + g2 : 5.0f - r2); + } + + h /= 6.0f; + + if (outH) + *outH = h; + if (outS) + *outS = s; + if (outL) + *outL = l; } \ No newline at end of file diff --git a/Classes/Utils/DCRoundSwitch/DCRoundSwitch.h b/Classes/Utils/DCRoundSwitch/DCRoundSwitch.h index dd693de9e..8c3aa100c 100755 --- a/Classes/Utils/DCRoundSwitch/DCRoundSwitch.h +++ b/Classes/Utils/DCRoundSwitch/DCRoundSwitch.h @@ -18,7 +18,7 @@ @interface DCRoundSwitch : UIControl -@property (nonatomic, retain) UIColor *onTintColor; // default: blue (matches normal UISwitch) +@property(nonatomic, strong) UIColor *onTintColor; // default: blue (matches normal UISwitch) @property (nonatomic, getter=isOn) BOOL on; // default: NO @property (nonatomic, copy) NSString *onText; // default: 'ON' - automatically localized @property (nonatomic, copy) NSString *offText; // default: 'OFF' - automatically localized diff --git a/Classes/Utils/DCRoundSwitch/DCRoundSwitch.m b/Classes/Utils/DCRoundSwitch/DCRoundSwitch.m index 8e0549b27..556d8150c 100755 --- a/Classes/Utils/DCRoundSwitch/DCRoundSwitch.m +++ b/Classes/Utils/DCRoundSwitch/DCRoundSwitch.m @@ -16,10 +16,10 @@ @interface DCRoundSwitch () -@property (nonatomic, retain) DCRoundSwitchOutlineLayer *outlineLayer; -@property (nonatomic, retain) DCRoundSwitchToggleLayer *toggleLayer; -@property (nonatomic, retain) DCRoundSwitchKnobLayer *knobLayer; -@property (nonatomic, retain) CAShapeLayer *clipLayer; +@property(nonatomic, strong) DCRoundSwitchOutlineLayer *outlineLayer; +@property(nonatomic, strong) DCRoundSwitchToggleLayer *toggleLayer; +@property(nonatomic, strong) DCRoundSwitchKnobLayer *knobLayer; +@property(nonatomic, strong) CAShapeLayer *clipLayer; @property (nonatomic, assign) BOOL ignoreTap; - (void)setup; @@ -37,19 +37,6 @@ #pragma mark - #pragma mark Init & Memory Managment -- (void)dealloc -{ - [outlineLayer release]; - [toggleLayer release]; - [knobLayer release]; - [clipLayer release]; - - [onTintColor release]; - [onText release]; - [offText release]; - - [super dealloc]; -} - (id)init { @@ -129,7 +116,10 @@ // this is the knob, and sits on top of the layer stack. note that the knob shadow is NOT drawn here, it is drawn on the // toggleLayer so it doesn't bleed out over the outlineLayer. - self.toggleLayer = [[[[[self class] toggleLayerClass] alloc] initWithOnString:self.onText offString:self.offText onTintColor:[UIColor colorWithRed:0.000 green:0.478 blue:0.882 alpha:1.0]] autorelease]; + self.toggleLayer = [[[[self class] toggleLayerClass] alloc] + initWithOnString:self.onText + offString:self.offText + onTintColor:[UIColor colorWithRed:0.000 green:0.478 blue:0.882 alpha:1.0]]; self.toggleLayer.drawOnTint = NO; self.toggleLayer.clip = YES; [self.layer addSublayer:self.toggleLayer]; @@ -146,14 +136,14 @@ self.toggleLayer.contentsScale = self.outlineLayer.contentsScale = self.knobLayer.contentsScale = [[UIScreen mainScreen] scale]; // tap gesture for toggling the switch - UITapGestureRecognizer *tapGestureRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self - action:@selector(tapped:)] autorelease]; + UITapGestureRecognizer *tapGestureRecognizer = + [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)]; [tapGestureRecognizer setDelegate:self]; [self addGestureRecognizer:tapGestureRecognizer]; // pan gesture for moving the switch knob manually - UIPanGestureRecognizer *panGestureRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:self - action:@selector(toggleDragged:)] autorelease]; + UIPanGestureRecognizer *panGestureRecognizer = + [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(toggleDragged:)]; [panGestureRecognizer setDelegate:self]; [self addGestureRecognizer:panGestureRecognizer]; @@ -353,7 +343,6 @@ [self positionLayersAndMask]; // retain all our targets so they don't disappear before the actions get sent at the end of the animation - [[self allTargets] makeObjectsPerformSelector:@selector(retain)]; [CATransaction setCompletionBlock:^{ [CATransaction begin]; @@ -399,7 +388,6 @@ if (previousOn != on && !ignoreControlEvents) [self sendActionsForControlEvents:UIControlEventValueChanged]; - [[self allTargets] makeObjectsPerformSelector:@selector(release)]; }]; [CATransaction commit]; @@ -410,8 +398,7 @@ { if (anOnTintColor != onTintColor) { - [onTintColor release]; - onTintColor = [anOnTintColor retain]; + onTintColor = anOnTintColor; self.toggleLayer.onTintColor = anOnTintColor; [self.toggleLayer setNeedsDisplay]; } @@ -447,7 +434,6 @@ { if (newOnText != onText) { - [onText release]; onText = [newOnText copy]; self.toggleLayer.onString = onText; [self.toggleLayer setNeedsDisplay]; @@ -458,7 +444,6 @@ { if (newOffText != offText) { - [offText release]; offText = [newOffText copy]; self.toggleLayer.offString = offText; [self.toggleLayer setNeedsDisplay]; diff --git a/Classes/Utils/DCRoundSwitch/DCRoundSwitchToggleLayer.h b/Classes/Utils/DCRoundSwitch/DCRoundSwitchToggleLayer.h index e56c631b9..a04f171ca 100755 --- a/Classes/Utils/DCRoundSwitch/DCRoundSwitchToggleLayer.h +++ b/Classes/Utils/DCRoundSwitch/DCRoundSwitchToggleLayer.h @@ -14,10 +14,10 @@ @interface DCRoundSwitchToggleLayer : CALayer -@property (nonatomic, retain) UIColor *onTintColor; -@property (nonatomic, retain) NSString *onString; -@property (nonatomic, retain) NSString *offString; -@property (nonatomic, readonly) UIFont *labelFont; +@property(nonatomic, strong) UIColor *onTintColor; +@property(nonatomic, strong) NSString *onString; +@property(nonatomic, strong) NSString *offString; +@property(weak, nonatomic, readonly) UIFont *labelFont; @property (nonatomic) BOOL drawOnTint; @property (nonatomic) BOOL clip; diff --git a/Classes/Utils/DCRoundSwitch/DCRoundSwitchToggleLayer.m b/Classes/Utils/DCRoundSwitch/DCRoundSwitchToggleLayer.m index 99e0550bf..4c884b6f6 100755 --- a/Classes/Utils/DCRoundSwitch/DCRoundSwitchToggleLayer.m +++ b/Classes/Utils/DCRoundSwitch/DCRoundSwitchToggleLayer.m @@ -17,14 +17,6 @@ @synthesize clip; @synthesize labelFont; -- (void)dealloc -{ - [onString release]; - [offString release]; - [onTintColor release]; - - [super dealloc]; -} - (id)initWithOnString:(NSString *)anOnString offString:(NSString *)anOffString onTintColor:(UIColor *)anOnTintColor { diff --git a/Classes/Utils/DTFoundation/DTActionSheet.m b/Classes/Utils/DTFoundation/DTActionSheet.m index ca43272ec..ae091c824 100755 --- a/Classes/Utils/DTFoundation/DTActionSheet.m +++ b/Classes/Utils/DTFoundation/DTActionSheet.m @@ -71,7 +71,6 @@ { [super setDelegate:nil]; self.actionSheetDelegate = nil; - [super dealloc]; } - (NSInteger)addButtonWithTitle:(NSString *)title block:(DTActionSheetBlock)block diff --git a/Classes/Utils/DTFoundation/DTAlertView.m b/Classes/Utils/DTFoundation/DTAlertView.m index 58fdd1e8f..9bf0211f1 100644 --- a/Classes/Utils/DTFoundation/DTAlertView.m +++ b/Classes/Utils/DTFoundation/DTAlertView.m @@ -23,7 +23,6 @@ { [super setDelegate:nil]; self.alertViewDelegate = nil; - [super dealloc]; } // designated initializer diff --git a/Classes/Utils/FastAddressBook.h b/Classes/Utils/FastAddressBook.h index 34723eecc..c818840d5 100644 --- a/Classes/Utils/FastAddressBook.h +++ b/Classes/Utils/FastAddressBook.h @@ -4,37 +4,53 @@ * * 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 #import +#include "linphone/linphonecore.h" + @interface FastAddressBook : NSObject { - NSMutableDictionary* addressBookMap; - - ABAddressBookRef addressBook; + ABAddressBookRef addressBook; } -+ (BOOL)isSipURI:(NSString*)address; -+ (NSString*)getContactDisplayName:(ABRecordRef)contact; -+ (UIImage*)getContactImage:(ABRecordRef)contact thumbnail:(BOOL)thumbnail; -- (ABRecordRef)getContact:(NSString*)address; +@property(readonly, nonatomic) NSMutableDictionary *addressBookMap; + - (void)reload; - (void)saveAddressBook; +- (int)removeContact:(ABRecordRef)contact; + + (BOOL)isAuthorized; -+ (NSString*)appendCountryCodeIfPossible:(NSString*)number; -+ (NSString*)normalizePhoneNumber:(NSString*)number; -+ (NSString*)normalizeSipURI:(NSString*)address; + +// TOOLS + ++ (ABRecordRef)getContactWithAddress:(const LinphoneAddress *)address; + ++ (UIImage *)imageForContact:(ABRecordRef)contact thumbnail:(BOOL)thumbnail; ++ (UIImage *)imageForAddress:(const LinphoneAddress *)addr thumbnail:(BOOL)thumbnail; + ++ (BOOL)contactHasValidSipDomain:(ABRecordRef)person; + ++ (NSString *)displayNameForContact:(ABRecordRef)person; ++ (NSString *)displayNameForAddress:(const LinphoneAddress *)addr; + ++ (BOOL)isSipURI:(NSString *)address; // should be removed ++ (NSString *)appendCountryCodeIfPossible:(NSString *)number; // should be removed ++ (NSString *)normalizePhoneNumber:(NSString *)number; // should be removed ++ (NSString *)normalizeSipURI:(NSString *)address; // should be removed + ++ (NSString *)localizedLabel:(NSString *)label; @end diff --git a/Classes/Utils/FastAddressBook.m b/Classes/Utils/FastAddressBook.m index c876a277b..6b1979333 100644 --- a/Classes/Utils/FastAddressBook.m +++ b/Classes/Utils/FastAddressBook.m @@ -19,247 +19,352 @@ #import "FastAddressBook.h" #import "LinphoneManager.h" +#import "ContactsListView.h" +#import "Utils.h" @implementation FastAddressBook -static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef info, void *context); +static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void *context); -+ (NSString*)getContactDisplayName:(ABRecordRef)contact { - NSString *retString = nil; - if (contact) { - CFStringRef lDisplayName = ABRecordCopyCompositeName(contact); - if(lDisplayName != NULL) { - retString = [NSString stringWithString:(NSString*)lDisplayName]; - CFRelease(lDisplayName); - } - } - return retString; ++ (UIImage *)imageForContact:(ABRecordRef)contact thumbnail:(BOOL)thumbnail { + UIImage *retImage = nil; + if (contact && ABPersonHasImageData(contact)) { + NSData *imgData = CFBridgingRelease(ABPersonCopyImageDataWithFormat( + contact, thumbnail ? kABPersonImageFormatThumbnail : kABPersonImageFormatOriginalSize)); + + retImage = [UIImage imageWithData:imgData]; + } + if (retImage == nil) { + retImage = [UIImage imageNamed:@"avatar.png"]; + } + if (retImage.size.width != retImage.size.height) { + retImage = [retImage squareCrop]; + } + return retImage; } -+ (UIImage*)squareImageCrop:(UIImage*)image -{ - UIImage *ret = nil; - - // This calculates the crop area. - - float originalWidth = image.size.width; - float originalHeight = image.size.height; - - float edge = fminf(originalWidth, originalHeight); - - float posX = (originalWidth - edge) / 2.0f; - float posY = (originalHeight - edge) / 2.0f; - - - CGRect cropSquare = CGRectMake(posX, posY, - edge, edge); - - - CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropSquare); - ret = [UIImage imageWithCGImage:imageRef - scale:image.scale - orientation:image.imageOrientation]; - - CGImageRelease(imageRef); - - return ret; ++ (UIImage *)imageForAddress:(const LinphoneAddress *)addr thumbnail:(BOOL)thumbnail { + if ([LinphoneManager isMyself:addr] && [LinphoneUtils hasSelfAvatar]) { + return [LinphoneUtils selfAvatar]; + } + return [FastAddressBook imageForContact:[FastAddressBook getContactWithAddress:addr] thumbnail:thumbnail]; } -+ (UIImage*)getContactImage:(ABRecordRef)contact thumbnail:(BOOL)thumbnail { - UIImage* retImage = nil; - if (contact && ABPersonHasImageData(contact)) { - CFDataRef imgData = ABPersonCopyImageDataWithFormat(contact, thumbnail? - kABPersonImageFormatThumbnail: kABPersonImageFormatOriginalSize); - - retImage = [UIImage imageWithData:(NSData *)imgData]; - if(imgData != NULL) { - CFRelease(imgData); - } - - if (retImage != nil && retImage.size.width != retImage.size.height) { - [LinphoneLogger log:LinphoneLoggerLog format:@"Image is not square : cropping it."]; - return [self squareImageCrop:retImage]; ++ (ABRecordRef)getContact:(NSString *)address { + if (LinphoneManager.instance.fastAddressBook != nil) { + @synchronized(LinphoneManager.instance.fastAddressBook.addressBookMap) { + return (__bridge ABRecordRef)[LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:address]; } - } - - return retImage; + } + return nil; } -- (ABRecordRef)getContact:(NSString*)address { - @synchronized (addressBookMap){ - return (ABRecordRef)[addressBookMap objectForKey:address]; - } ++ (ABRecordRef)getContactWithAddress:(const LinphoneAddress *)address { + ABRecordRef contact = nil; + if (address) { + char *uri = linphone_address_as_string_uri_only(address); + NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:uri]]; + contact = [FastAddressBook getContact:normalizedSipAddress]; + ms_free(uri); + } + return contact; } -+ (BOOL)isSipURI:(NSString*)address { - return [address hasPrefix:@"sip:"] || [address hasPrefix:@"sips:"]; ++ (BOOL)isSipURI:(NSString *)address { + return [address hasPrefix:@"sip:"] || [address hasPrefix:@"sips:"]; } -+ (NSString*)appendCountryCodeIfPossible:(NSString*)number { - if (![number hasPrefix:@"+"] && ![number hasPrefix:@"00"]) { - NSString* lCountryCode = [[LinphoneManager instance] lpConfigStringForKey:@"countrycode_preference"]; - if (lCountryCode && [lCountryCode length]>0) { - //append country code - return [lCountryCode stringByAppendingString:number]; - } - } - return number; ++ (NSString *)appendCountryCodeIfPossible:(NSString *)number { + if (![number hasPrefix:@"+"] && ![number hasPrefix:@"00"]) { + NSString *lCountryCode = [[LinphoneManager instance] lpConfigStringForKey:@"countrycode_preference"]; + if (lCountryCode && [lCountryCode length] > 0) { + // append country code + return [lCountryCode stringByAppendingString:number]; + } + } + return number; } -+ (NSString*)normalizeSipURI:(NSString*)address { - // replace all whitespaces (non-breakable, utf8 nbsp etc.) by the "classical" whitespace - address = [[address componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] componentsJoinedByString:@" "]; - NSString *normalizedSipAddress = nil; - LinphoneAddress* linphoneAddress = linphone_core_interpret_url([LinphoneManager getLc], [address UTF8String]); - if(linphoneAddress != NULL) { - char *tmp = linphone_address_as_string_uri_only(linphoneAddress); - if(tmp != NULL) { - normalizedSipAddress = [NSString stringWithUTF8String:tmp]; - // remove transport, if any - NSRange pos = [normalizedSipAddress rangeOfString:@";"]; - if (pos.location != NSNotFound) { - normalizedSipAddress = [normalizedSipAddress substringToIndex:pos.location]; - } - ms_free(tmp); - } - linphone_address_destroy(linphoneAddress); - } - return normalizedSipAddress; ++ (NSString *)normalizeSipURI:(NSString *)address { + // replace all whitespaces (non-breakable, utf8 nbsp etc.) by the "classical" whitespace + address = [[address componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] + componentsJoinedByString:@" "]; + NSString *normalizedSipAddress = nil; + LinphoneAddress *linphoneAddress = linphone_core_interpret_url([LinphoneManager getLc], [address UTF8String]); + if (linphoneAddress != NULL) { + char *tmp = linphone_address_as_string_uri_only(linphoneAddress); + if (tmp != NULL) { + normalizedSipAddress = [NSString stringWithUTF8String:tmp]; + // remove transport, if any + NSRange pos = [normalizedSipAddress rangeOfString:@";"]; + if (pos.location != NSNotFound) { + normalizedSipAddress = [normalizedSipAddress substringToIndex:pos.location]; + } + ms_free(tmp); + } + linphone_address_destroy(linphoneAddress); + } + return normalizedSipAddress; } -+ (NSString*)normalizePhoneNumber:(NSString*)address { - NSMutableString* lNormalizedAddress = [NSMutableString stringWithString:address]; - [lNormalizedAddress replaceOccurrencesOfString:@" " - withString:@"" - options:0 - range:NSMakeRange(0, [lNormalizedAddress length])]; - [lNormalizedAddress replaceOccurrencesOfString:@"(" - withString:@"" - options:0 - range:NSMakeRange(0, [lNormalizedAddress length])]; - [lNormalizedAddress replaceOccurrencesOfString:@")" - withString:@"" - options:0 - range:NSMakeRange(0, [lNormalizedAddress length])]; - [lNormalizedAddress replaceOccurrencesOfString:@"-" - withString:@"" - options:0 - range:NSMakeRange(0, [lNormalizedAddress length])]; - return [FastAddressBook appendCountryCodeIfPossible:lNormalizedAddress]; ++ (NSString *)normalizePhoneNumber:(NSString *)address { + NSMutableString *lNormalizedAddress = [NSMutableString stringWithString:address]; + [lNormalizedAddress replaceOccurrencesOfString:@" " + withString:@"" + options:0 + range:NSMakeRange(0, [lNormalizedAddress length])]; + [lNormalizedAddress replaceOccurrencesOfString:@"(" + withString:@"" + options:0 + range:NSMakeRange(0, [lNormalizedAddress length])]; + [lNormalizedAddress replaceOccurrencesOfString:@")" + withString:@"" + options:0 + range:NSMakeRange(0, [lNormalizedAddress length])]; + [lNormalizedAddress replaceOccurrencesOfString:@"-" + withString:@"" + options:0 + range:NSMakeRange(0, [lNormalizedAddress length])]; + return [FastAddressBook appendCountryCodeIfPossible:lNormalizedAddress]; } + (BOOL)isAuthorized { - return !ABAddressBookGetAuthorizationStatus || ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized; + return ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized; } -- (FastAddressBook*)init { - if ((self = [super init]) != nil) { - addressBookMap = [[NSMutableDictionary alloc] init]; - addressBook = nil; - [self reload]; - } - return self; +- (FastAddressBook *)init { + if ((self = [super init]) != nil) { + _addressBookMap = [NSMutableDictionary dictionary]; + addressBook = nil; + [self reload]; + } + return self; } - (void)saveAddressBook { - if( addressBook != nil ){ - NSError* err = nil; - if( !ABAddressBookSave(addressBook, (CFErrorRef*)err) ){ - Linphone_warn(@"Couldn't save Address Book"); + if (addressBook != nil) { + if (!ABAddressBookSave(addressBook, nil)) { + LOGW(@"Couldn't save Address Book"); } } } - (void)reload { - if(addressBook != nil) { - ABAddressBookUnregisterExternalChangeCallback(addressBook, sync_address_book, self); - CFRelease(addressBook); - addressBook = nil; - } - NSError *error = nil; + CFErrorRef error; - addressBook = ABAddressBookCreateWithOptions(NULL, NULL); - if(addressBook != NULL) { - ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { - ABAddressBookRegisterExternalChangeCallback (addressBook, sync_address_book, self); - [self loadData]; - }); - } else { - [LinphoneLogger log:LinphoneLoggerError format:@"Create AddressBook: Fail(%@)", [error localizedDescription]]; - } + // create if it doesn't exist + if (addressBook == nil) { + addressBook = ABAddressBookCreateWithOptions(NULL, &error); + } + + if (addressBook != nil) { + __weak FastAddressBook *weakSelf = self; + ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { + if (!granted) { + LOGE(@"Permission for address book acces was denied: %@", [(__bridge NSError *)error description]); + return; + } + + ABAddressBookRegisterExternalChangeCallback(addressBook, sync_address_book, (__bridge void *)(weakSelf)); + [weakSelf loadData]; + + }); + } else { + LOGE(@"Create AddressBook failed, reason: %@", [(__bridge NSError *)error localizedDescription]); + } } - (void)loadData { - ABAddressBookRevert(addressBook); - @synchronized (addressBookMap) { - [addressBookMap removeAllObjects]; + @synchronized(_addressBookMap) { + ABAddressBookRevert(addressBook); + [_addressBookMap removeAllObjects]; - NSArray *lContacts = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); - for (id lPerson in lContacts) { - // Phone - { - ABMultiValueRef lMap = ABRecordCopyValue((ABRecordRef)lPerson, kABPersonPhoneProperty); - if(lMap) { - for (int i=0; i + +#import "LinphoneManager.h" + +@interface FileTransferDelegate : NSObject + +- (void)upload:(UIImage *)image withURL:(NSURL *)url forChatRoom:(LinphoneChatRoom *)chatRoom; +- (void)cancel; +- (BOOL)download:(LinphoneChatMessage *)message; +- (void)stopAndDestroy; + +@property() LinphoneChatMessage *message; +@end diff --git a/Classes/Utils/FileTransferDelegate.m b/Classes/Utils/FileTransferDelegate.m new file mode 100644 index 000000000..3ffef5ae6 --- /dev/null +++ b/Classes/Utils/FileTransferDelegate.m @@ -0,0 +1,213 @@ +// +// FileTransferDelegate.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 10/06/15. +// +// + +#import "FileTransferDelegate.h" +#import "Utils.h" + +@interface FileTransferDelegate () +@property(strong) NSMutableData *data; +@end + +@implementation FileTransferDelegate + +- (void)dealloc { + if (_message != nil) { + [self cancel]; + } +} + ++ (FileTransferDelegate *)messageDelegate:(LinphoneChatMessage *)message { + for (FileTransferDelegate *ftd in [[LinphoneManager instance] fileTransferDelegates]) { + if (ftd.message == message) { + return ftd; + } + } + return nil; +} + +static void linphone_iphone_file_transfer_recv(LinphoneChatMessage *message, const LinphoneContent *content, + const LinphoneBuffer *buffer) { + FileTransferDelegate *thiz = [FileTransferDelegate messageDelegate:message]; + size_t size = linphone_buffer_get_size(buffer); + + if (!thiz.data) { + thiz.data = [[NSMutableData alloc] initWithCapacity:linphone_content_get_size(content)]; + } + + if (size == 0) { + LOGI(@"Transfer of %s (%d bytes): download finished", linphone_content_get_name(content), size); + assert([thiz.data length] == linphone_content_get_size(content)); + + // we're finished, save the image and update the message + UIImage *image = [UIImage imageWithData:thiz.data]; + + CFBridgingRetain(thiz); + [[[LinphoneManager instance] fileTransferDelegates] removeObject:thiz]; + + // until image is properly saved, keep a reminder on it so that the + // chat bubble is aware of the fact that image is being saved to device + [LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localimage" inMessage:message]; + + [[LinphoneManager instance] + .photoLibrary + writeImageToSavedPhotosAlbum:image.CGImage + orientation:(ALAssetOrientation)[image imageOrientation] + completionBlock:^(NSURL *assetURL, NSError *error) { + if (error) { + LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]); + [LinphoneManager setValueInMessageAppData:nil forKey:@"localimage" inMessage:message]; + UIAlertView *errorAlert = [[UIAlertView alloc] + initWithTitle:NSLocalizedString(@"Transfer error", nil) + message:NSLocalizedString(@"Cannot write image to photo library", nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Ok", nil) + otherButtonTitles:nil, nil]; + [errorAlert show]; + } else { + LOGI(@"Image saved to [%@]", [assetURL absoluteString]); + [LinphoneManager setValueInMessageAppData:[assetURL absoluteString] + forKey:@"localimage" + inMessage:message]; + } + thiz.message = NULL; + [[NSNotificationCenter defaultCenter] + postNotificationName:kLinphoneFileTransferRecvUpdate + object:thiz + userInfo:@{ + @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to + // trigger + // FileTransferDone here + @"image" : image, + @"progress" : @(1.f), + }]; + + [thiz stopAndDestroy]; + CFRelease((__bridge CFTypeRef)thiz); + }]; + } else { + LOGD(@"Transfer of %s (%d bytes): already %ld sent, adding %ld", linphone_content_get_name(content), + linphone_content_get_size(content), [thiz.data length], size); + [thiz.data appendBytes:linphone_buffer_get_string_content(buffer) length:size]; + [[NSNotificationCenter defaultCenter] + postNotificationName:kLinphoneFileTransferRecvUpdate + object:thiz + userInfo:@{ + @"state" : @(linphone_chat_message_get_state(message)), + @"progress" : @([thiz.data length] * 1.f / linphone_content_get_size(content)), + }]; + } +} + +static LinphoneBuffer *linphone_iphone_file_transfer_send(LinphoneChatMessage *message, const LinphoneContent *content, + size_t offset, size_t size) { + FileTransferDelegate *thiz = [FileTransferDelegate messageDelegate:message]; + size_t total = thiz.data.length; + if (thiz.data) { + size_t remaining = total - offset; + + NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:@{ + @"state" : @(linphone_chat_message_get_state(message)), + @"progress" : @(offset * 1.f / total), + }]; + LOGD(@"Transfer of %s (%d bytes): already sent %ld (%f%%), remaining %ld", linphone_content_get_name(content), + total, offset, offset * 100.f / total, remaining); + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneFileTransferSendUpdate + object:thiz + userInfo:dict]; + + LinphoneBuffer *buffer = NULL; + @try { + buffer = linphone_buffer_new_from_data([thiz.data subdataWithRange:NSMakeRange(offset, size)].bytes, size); + } @catch (NSException *exception) { + LOGE(@"Exception: %@", exception); + } + + // this is the last time we will be notified, so destroy ourselve + if (remaining <= size) { + LOGI(@"Upload ended"); + linphone_chat_message_cbs_set_file_transfer_send(linphone_chat_message_get_callbacks(thiz.message), NULL); + thiz.message = NULL; + [thiz stopAndDestroy]; + } + return buffer; + } else { + LOGE(@"Transfer of %s (%d bytes): %d Error - no upload data in progress!", linphone_content_get_name(content), + total, offset); + } + + return NULL; +} + +- (void)upload:(UIImage *)image withURL:(NSURL *)url forChatRoom:(LinphoneChatRoom *)chatRoom { + [LinphoneManager.instance.fileTransferDelegates addObject:self]; + + LinphoneContent *content = linphone_core_create_content(linphone_chat_room_get_core(chatRoom)); + _data = [NSMutableData dataWithData:UIImageJPEGRepresentation(image, 1.0)]; + linphone_content_set_type(content, "image"); + linphone_content_set_subtype(content, "jpeg"); + linphone_content_set_name( + content, [[NSString stringWithFormat:@"%li-%f.jpg", (long)image.hash, [NSDate timeIntervalSinceReferenceDate]] + UTF8String]); + linphone_content_set_size(content, _data.length); + + _message = linphone_chat_room_create_file_transfer_message(chatRoom, content); + linphone_content_unref(content); + + linphone_chat_message_cbs_set_file_transfer_send(linphone_chat_message_get_callbacks(_message), + linphone_iphone_file_transfer_send); + + if (url) { + // internal url is saved in the appdata for display and later save + [LinphoneManager setValueInMessageAppData:[url absoluteString] forKey:@"localimage" inMessage:_message]; + } + + LOGI(@"%p Uploading content from message %p", self, _message); + + linphone_chat_room_send_chat_message(chatRoom, _message); +} + +- (BOOL)download:(LinphoneChatMessage *)message { + [[[LinphoneManager instance] fileTransferDelegates] addObject:self]; + + _message = message; + + const char *url = linphone_chat_message_get_external_body_url(_message); + LOGI(@"%p Downloading content in %p from %s", self, message, url); + + if (url == nil) + return FALSE; + + linphone_chat_message_cbs_set_file_transfer_recv(linphone_chat_message_get_callbacks(_message), + linphone_iphone_file_transfer_recv); + + linphone_chat_message_download_file(_message); + + return TRUE; +} + +- (void)stopAndDestroy { + [[[LinphoneManager instance] fileTransferDelegates] removeObject:self]; + if (_message != NULL) { + LinphoneChatMessage *msg = _message; + _message = NULL; + LOGI(@"%p Cancelling transfer from %p", self, msg); + linphone_chat_message_cbs_set_file_transfer_send(linphone_chat_message_get_callbacks(msg), NULL); + linphone_chat_message_cbs_set_file_transfer_recv(linphone_chat_message_get_callbacks(msg), NULL); + // when we cancel file transfer, this will automatically trigger NotDelivered callback... recalling ourself a + // second time so we have to unset message BEFORE calling this + linphone_chat_message_cancel_file_transfer(msg); + } + _data = nil; + LOGI(@"%p Destroying", self); +} + +- (void)cancel { + [self stopAndDestroy]; +} + +@end diff --git a/Classes/Utils/GrowingTextView/HPGrowingTextView.m b/Classes/Utils/GrowingTextView/HPGrowingTextView.m deleted file mode 100755 index 6f14c6833..000000000 --- a/Classes/Utils/GrowingTextView/HPGrowingTextView.m +++ /dev/null @@ -1,660 +0,0 @@ -// -// HPTextView.m -// -// Created by Hans Pinckaers on 29-06-10. -// -// MIT License -// -// Copyright (c) 2011 Hans Pinckaers -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#import "HPGrowingTextView.h" -#import "HPTextViewInternal.h" - -@interface HPGrowingTextView(private) --(void)commonInitialiser; --(void)resizeTextView:(NSInteger)newSizeH; --(void)growDidStop; -@end - -@implementation HPGrowingTextView -@synthesize internalTextView; -@synthesize delegate; -@synthesize maxHeight; -@synthesize minHeight; -@synthesize font; -@synthesize textColor; -@synthesize textAlignment; -@synthesize selectedRange; -@synthesize editable; -@synthesize dataDetectorTypes; -@synthesize animateHeightChange; -@synthesize animationDuration; -@synthesize returnKeyType; -@dynamic placeholder; -@dynamic placeholderColor; - -// having initwithcoder allows us to use HPGrowingTextView in a Nib. -- aob, 9/2011 -- (id)initWithCoder:(NSCoder *)aDecoder -{ - if ((self = [super initWithCoder:aDecoder])) { - [self commonInitialiser]; - } - return self; -} - -- (id)initWithFrame:(CGRect)frame { - if ((self = [super initWithFrame:frame])) { - [self commonInitialiser]; - } - return self; -} - --(void)commonInitialiser -{ - // Initialization code - CGRect r = self.frame; - r.origin.y = 0; - r.origin.x = 0; - internalTextView = [[HPTextViewInternal alloc] initWithFrame:r]; - internalTextView.delegate = self; - internalTextView.scrollEnabled = NO; - internalTextView.font = [UIFont fontWithName:@"Helvetica" size:13]; - internalTextView.contentInset = UIEdgeInsetsZero; - internalTextView.showsHorizontalScrollIndicator = NO; - internalTextView.text = @"-"; - [self addSubview:internalTextView]; - - minHeight = internalTextView.frame.size.height; - minNumberOfLines = 1; - - animateHeightChange = YES; - animationDuration = 0.1f; - - internalTextView.text = @""; - - [self setMaxNumberOfLines:3]; - - [self setPlaceholderColor:[UIColor lightGrayColor]]; - internalTextView.displayPlaceHolder = YES; -} - --(CGSize)sizeThatFits:(CGSize)size -{ - if (self.text.length == 0) { - size.height = minHeight; - } - return size; -} - --(void)layoutSubviews -{ - [super layoutSubviews]; - - CGRect r = self.bounds; - r.origin.y = 0; - r.origin.x = contentInset.left; - r.size.width -= contentInset.left + contentInset.right; - - internalTextView.frame = r; -} - --(void)setContentInset:(UIEdgeInsets)inset -{ - contentInset = inset; - - CGRect r = self.frame; - r.origin.y = inset.top - inset.bottom; - r.origin.x = inset.left; - r.size.width -= inset.left + inset.right; - - internalTextView.frame = r; - - [self setMaxNumberOfLines:maxNumberOfLines]; - [self setMinNumberOfLines:minNumberOfLines]; -} - --(UIEdgeInsets)contentInset -{ - return contentInset; -} - --(void)setMaxNumberOfLines:(int)n -{ - if(n == 0 && maxHeight > 0) return; // the user specified a maxHeight themselves. - - // Use internalTextView for height calculations, thanks to Gwynne - NSString *saveText = internalTextView.text, *newText = @"-"; - - internalTextView.delegate = nil; - internalTextView.hidden = YES; - - for (int i = 1; i < n; ++i) - newText = [newText stringByAppendingString:@"\n|W|"]; - - internalTextView.text = newText; - - maxHeight = [self measureHeight]; - - internalTextView.text = saveText; - internalTextView.hidden = NO; - internalTextView.delegate = self; - - [self sizeToFit]; - - maxNumberOfLines = n; -} - --(int)maxNumberOfLines -{ - return maxNumberOfLines; -} - -- (void)setMaxHeight:(int)height -{ - maxHeight = height; - maxNumberOfLines = 0; -} - --(void)setMinNumberOfLines:(int)m -{ - if(m == 0 && minHeight > 0) return; // the user specified a minHeight themselves. - - // Use internalTextView for height calculations, thanks to Gwynne - NSString *saveText = internalTextView.text, *newText = @"-"; - - internalTextView.delegate = nil; - internalTextView.hidden = YES; - - for (int i = 1; i < m; ++i) - newText = [newText stringByAppendingString:@"\n|W|"]; - - internalTextView.text = newText; - - minHeight = [self measureHeight]; - - internalTextView.text = saveText; - internalTextView.hidden = NO; - internalTextView.delegate = self; - - [self sizeToFit]; - - minNumberOfLines = m; -} - --(int)minNumberOfLines -{ - return minNumberOfLines; -} - -- (void)setMinHeight:(int)height -{ - minHeight = height; - minNumberOfLines = 0; -} - -- (NSString *)placeholder -{ - return internalTextView.placeholder; -} - -- (void)setPlaceholder:(NSString *)placeholder -{ - [internalTextView setPlaceholder:placeholder]; -} - -- (UIColor *)placeholderColor -{ - return internalTextView.placeholderColor; -} - -- (void)setPlaceholderColor:(UIColor *)placeholderColor -{ - [internalTextView setPlaceholderColor:placeholderColor]; -} - -- (void)textViewDidChange:(UITextView *)textView -{ - [self refreshHeight]; - if( [delegate respondsToSelector:@selector(growingTextChanged:text:)]) - [delegate growingTextChanged:self text:[textView text]]; -} - -- (void)refreshHeight -{ - //size of content, so we can set the frame of self - NSInteger newSizeH = [self measureHeight]; - if(newSizeH < minHeight || !internalTextView.hasText) newSizeH = minHeight; //not smalles than minHeight - if (internalTextView.frame.size.height > maxHeight) newSizeH = maxHeight; // not taller than maxHeight - - if (internalTextView.frame.size.height != newSizeH) - { - // [fixed] Pasting too much text into the view failed to fire the height change, - // thanks to Gwynne - - if (newSizeH > maxHeight && internalTextView.frame.size.height <= maxHeight) - { - newSizeH = maxHeight; - } - - if (newSizeH <= maxHeight) - { - if(animateHeightChange) { - - if ([UIView resolveClassMethod:@selector(animateWithDuration:animations:)]) { -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000 - [UIView animateWithDuration:animationDuration - delay:0 - options:(UIViewAnimationOptionAllowUserInteraction| - UIViewAnimationOptionBeginFromCurrentState) - animations:^(void) { - [self resizeTextView:newSizeH]; - } - completion:^(BOOL finished) { - if ([delegate respondsToSelector:@selector(growingTextView:didChangeHeight:)]) { - [delegate growingTextView:self didChangeHeight:newSizeH]; - } - }]; -#endif - } else { - [UIView beginAnimations:@"" context:nil]; - [UIView setAnimationDuration:animationDuration]; - [UIView setAnimationDelegate:self]; - [UIView setAnimationDidStopSelector:@selector(growDidStop)]; - [UIView setAnimationBeginsFromCurrentState:YES]; - [self resizeTextView:newSizeH]; - [UIView commitAnimations]; - } - } else { - [self resizeTextView:newSizeH]; - // [fixed] The growingTextView:didChangeHeight: delegate method was not called at all when not animating height changes. - // thanks to Gwynne - - if ([delegate respondsToSelector:@selector(growingTextView:didChangeHeight:)]) { - [delegate growingTextView:self didChangeHeight:newSizeH]; - } - } - } - - // if our new height is greater than the maxHeight - // sets not set the height or move things - // around and enable scrolling - if (newSizeH >= maxHeight) - { - if(!internalTextView.scrollEnabled){ - internalTextView.scrollEnabled = YES; - [internalTextView flashScrollIndicators]; - } - - } else { - internalTextView.scrollEnabled = NO; - } - - // scroll to caret (needed on iOS7) - if ([self respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)]) - { - CGRect r = [internalTextView caretRectForPosition:internalTextView.selectedTextRange.end]; - CGFloat caretY = MAX(r.origin.y - internalTextView.frame.size.height + r.size.height + 8, 0); - if(internalTextView.contentOffset.y < caretY && r.origin.y != INFINITY) - internalTextView.contentOffset = CGPointMake(0, MIN(caretY, internalTextView.contentSize.height)); - } - } - // Display (or not) the placeholder string - - BOOL wasDisplayingPlaceholder = internalTextView.displayPlaceHolder; - internalTextView.displayPlaceHolder = self.internalTextView.text.length == 0; - - if (wasDisplayingPlaceholder != internalTextView.displayPlaceHolder) { - [internalTextView setNeedsDisplay]; - } - - // Tell the delegate that the text view changed - - if ([delegate respondsToSelector:@selector(growingTextViewDidChange:)]) { - [delegate growingTextViewDidChange:self]; - } - -} - -// Code from apple developer forum - @Steve Krulewitz, @Mark Marszal, @Eric Silverberg -- (CGFloat)measureHeight -{ -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 - if ([self respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)]) - { - CGRect frame = internalTextView.bounds; - CGSize fudgeFactor; - // The padding added around the text on iOS6 and iOS7 is different. - fudgeFactor = CGSizeMake(10.0, 16.0); - - frame.size.height -= fudgeFactor.height; - frame.size.width -= fudgeFactor.width; - - NSMutableAttributedString* textToMeasure; - if(internalTextView.attributedText && internalTextView.attributedText.length > 0){ - textToMeasure = [[NSMutableAttributedString alloc] initWithAttributedString:internalTextView.attributedText]; - } - else{ - textToMeasure = [[NSMutableAttributedString alloc] initWithString:internalTextView.text]; - [textToMeasure addAttribute:NSFontAttributeName value:internalTextView.font range:NSMakeRange(0, textToMeasure.length)]; - } - - if ([textToMeasure.string hasSuffix:@"\n"]) - { - [textToMeasure appendAttributedString:[[[NSAttributedString alloc] initWithString:@"-" attributes:@{NSFontAttributeName: internalTextView.font}]autorelease]]; - } - - // NSAttributedString class method: boundingRectWithSize:options:context is - // available only on ios7.0 sdk. - CGRect size = [textToMeasure boundingRectWithSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT) - options:NSStringDrawingUsesLineFragmentOrigin - context:nil]; - [textToMeasure release]; - - return CGRectGetHeight(size) + fudgeFactor.height; - } - else - { - return self.internalTextView.contentSize.height; - } -#else - return self.internalTextView.contentSize.height; -#endif -} - --(void)resizeTextView:(NSInteger)newSizeH -{ - if ([delegate respondsToSelector:@selector(growingTextView:willChangeHeight:)]) { - [delegate growingTextView:self willChangeHeight:newSizeH]; - } - - CGRect internalTextViewFrame = self.frame; - internalTextViewFrame.size.height = newSizeH; // + padding - self.frame = internalTextViewFrame; - - internalTextViewFrame.origin.y = contentInset.top - contentInset.bottom; - internalTextViewFrame.origin.x = contentInset.left; - internalTextViewFrame.size.width = internalTextView.contentSize.width; - - if(!CGRectEqualToRect(internalTextView.frame, internalTextViewFrame)) internalTextView.frame = internalTextViewFrame; -} - -- (void)growDidStop -{ - if ([delegate respondsToSelector:@selector(growingTextView:didChangeHeight:)]) { - [delegate growingTextView:self didChangeHeight:self.frame.size.height]; - } -} - --(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event -{ - [internalTextView becomeFirstResponder]; -} - -- (BOOL)becomeFirstResponder -{ - [super becomeFirstResponder]; - return [self.internalTextView becomeFirstResponder]; -} - --(BOOL)resignFirstResponder -{ - [super resignFirstResponder]; - return [internalTextView resignFirstResponder]; -} - --(BOOL)isFirstResponder -{ - return [self.internalTextView isFirstResponder]; -} - - - -/////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark UITextView properties -/////////////////////////////////////////////////////////////////////////////////////////////////// - --(void)setText:(NSString *)newText -{ - internalTextView.text = newText; - - // include this line to analyze the height of the textview. - // fix from Ankit Thakur - [self performSelector:@selector(textViewDidChange:) withObject:internalTextView]; -} - --(NSString*) text -{ - return internalTextView.text; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - --(void)setFont:(UIFont *)afont -{ - internalTextView.font= afont; - - [self setMaxNumberOfLines:maxNumberOfLines]; - [self setMinNumberOfLines:minNumberOfLines]; -} - --(UIFont *)font -{ - return internalTextView.font; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - --(void)setTextColor:(UIColor *)color -{ - internalTextView.textColor = color; -} - --(UIColor*)textColor{ - return internalTextView.textColor; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - --(void)setBackgroundColor:(UIColor *)backgroundColor -{ - [super setBackgroundColor:backgroundColor]; - internalTextView.backgroundColor = backgroundColor; -} - --(UIColor*)backgroundColor -{ - return internalTextView.backgroundColor; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - --(void)setTextAlignment:(NSTextAlignment)aligment -{ - internalTextView.textAlignment = aligment; -} - --(NSTextAlignment)textAlignment -{ - return internalTextView.textAlignment; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - --(void)setSelectedRange:(NSRange)range -{ - internalTextView.selectedRange = range; -} - --(NSRange)selectedRange -{ - return internalTextView.selectedRange; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -- (void)setIsScrollable:(BOOL)isScrollable -{ - internalTextView.scrollEnabled = isScrollable; -} - -- (BOOL)isScrollable -{ - return internalTextView.scrollEnabled; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - --(void)setEditable:(BOOL)beditable -{ - internalTextView.editable = beditable; -} - --(BOOL)isEditable -{ - return internalTextView.editable; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - --(void)setReturnKeyType:(UIReturnKeyType)keyType -{ - internalTextView.returnKeyType = keyType; -} - --(UIReturnKeyType)returnKeyType -{ - return internalTextView.returnKeyType; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -- (void)setEnablesReturnKeyAutomatically:(BOOL)enablesReturnKeyAutomatically -{ - internalTextView.enablesReturnKeyAutomatically = enablesReturnKeyAutomatically; -} - -- (BOOL)enablesReturnKeyAutomatically -{ - return internalTextView.enablesReturnKeyAutomatically; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - --(void)setDataDetectorTypes:(UIDataDetectorTypes)datadetector -{ - internalTextView.dataDetectorTypes = datadetector; -} - --(UIDataDetectorTypes)dataDetectorTypes -{ - return internalTextView.dataDetectorTypes; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -- (BOOL)hasText{ - return [internalTextView hasText]; -} - -- (void)scrollRangeToVisible:(NSRange)range -{ - [internalTextView scrollRangeToVisible:range]; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// -#pragma mark - -#pragma mark UITextViewDelegate - - -/////////////////////////////////////////////////////////////////////////////////////////////////// -- (BOOL)textViewShouldBeginEditing:(UITextView *)textView { - if ([delegate respondsToSelector:@selector(growingTextViewShouldBeginEditing:)]) { - return [delegate growingTextViewShouldBeginEditing:self]; - - } else { - return YES; - } -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////// -- (BOOL)textViewShouldEndEditing:(UITextView *)textView { - if ([delegate respondsToSelector:@selector(growingTextViewShouldEndEditing:)]) { - return [delegate growingTextViewShouldEndEditing:self]; - - } else { - return YES; - } -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////// -- (void)textViewDidBeginEditing:(UITextView *)textView { - if ([delegate respondsToSelector:@selector(growingTextViewDidBeginEditing:)]) { - [delegate growingTextViewDidBeginEditing:self]; - } -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////// -- (void)textViewDidEndEditing:(UITextView *)textView { - if ([delegate respondsToSelector:@selector(growingTextViewDidEndEditing:)]) { - [delegate growingTextViewDidEndEditing:self]; - } -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////// -- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range - replacementText:(NSString *)atext { - - //weird 1 pixel bug when clicking backspace when textView is empty - if(![textView hasText] && [atext isEqualToString:@""]) return NO; - - //Added by bretdabaker: sometimes we want to handle this ourselves - if ([delegate respondsToSelector:@selector(growingTextView:shouldChangeTextInRange:replacementText:)]) - return [delegate growingTextView:self shouldChangeTextInRange:range replacementText:atext]; - - if ([atext isEqualToString:@"\n"]) { - if ([delegate respondsToSelector:@selector(growingTextViewShouldReturn:)]) { - if (![delegate performSelector:@selector(growingTextViewShouldReturn:) withObject:self]) { - return YES; - } else { - [textView resignFirstResponder]; - return NO; - } - } - } - - return YES; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -- (void)textViewDidChangeSelection:(UITextView *)textView { - if ([delegate respondsToSelector:@selector(growingTextViewDidChangeSelection:)]) { - [delegate growingTextViewDidChangeSelection:self]; - } -} - - - -@end diff --git a/Classes/Utils/GrowingTextView/HPTextViewInternal.m b/Classes/Utils/GrowingTextView/HPTextViewInternal.m deleted file mode 100755 index 19f561311..000000000 --- a/Classes/Utils/GrowingTextView/HPTextViewInternal.m +++ /dev/null @@ -1,110 +0,0 @@ -// -// HPTextViewInternal.m -// -// Created by Hans Pinckaers on 29-06-10. -// -// MIT License -// -// Copyright (c) 2011 Hans Pinckaers -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#import "HPTextViewInternal.h" - - -@implementation HPTextViewInternal - -@synthesize placeholder; -@synthesize placeholderColor; -@synthesize displayPlaceHolder; - --(void)setText:(NSString *)text -{ - BOOL originalValue = self.scrollEnabled; - //If one of GrowingTextView's superviews is a scrollView, and self.scrollEnabled == NO, - //setting the text programatically will cause UIKit to search upwards until it finds a scrollView with scrollEnabled==yes - //then scroll it erratically. Setting scrollEnabled temporarily to YES prevents this. - [self setScrollEnabled:YES]; - [super setText:text]; - [self setScrollEnabled:originalValue]; -} - -- (void)setScrollable:(BOOL)isScrollable -{ - [super setScrollEnabled:isScrollable]; -} - --(void)setContentOffset:(CGPoint)s -{ - if(self.tracking || self.decelerating){ - //initiated by user... - - UIEdgeInsets insets = self.contentInset; - insets.bottom = 0; - insets.top = 0; - self.contentInset = insets; - - } else { - - float bottomOffset = (self.contentSize.height - self.frame.size.height + self.contentInset.bottom); - if(s.y < bottomOffset && self.scrollEnabled){ - UIEdgeInsets insets = self.contentInset; - insets.bottom = 8; - insets.top = 0; - self.contentInset = insets; - } - } - - [super setContentOffset:s]; -} - --(void)setContentInset:(UIEdgeInsets)s -{ - UIEdgeInsets insets = s; - - if(s.bottom>8) insets.bottom = 0; - insets.top = 0; - - [super setContentInset:insets]; -} - --(void)setContentSize:(CGSize)contentSize -{ - // is this an iOS5 bug? Need testing! - if(self.contentSize.height > contentSize.height) - { - UIEdgeInsets insets = self.contentInset; - insets.bottom = 0; - insets.top = 0; - self.contentInset = insets; - } - - [super setContentSize:contentSize]; -} - -- (void)drawRect:(CGRect)rect -{ - [super drawRect:rect]; - if (displayPlaceHolder && placeholder && placeholderColor) { - [placeholderColor set]; - [placeholder drawInRect:CGRectMake(8.0f, 8.0f, self.frame.size.width - 16.0f, self.frame.size.height - 16.0f) withFont:self.font]; - } -} - -@end diff --git a/Classes/Utils/GrowingTextView/HPGrowingTextView.h b/Classes/Utils/HPGrowingTextView/HPGrowingTextView.h similarity index 67% rename from Classes/Utils/GrowingTextView/HPGrowingTextView.h rename to Classes/Utils/HPGrowingTextView/HPGrowingTextView.h index c9238b69d..aea96e69b 100755 --- a/Classes/Utils/GrowingTextView/HPGrowingTextView.h +++ b/Classes/Utils/HPGrowingTextView/HPGrowingTextView.h @@ -28,9 +28,10 @@ #import #if __IPHONE_OS_VERSION_MAX_ALLOWED < 60000 - // UITextAlignment is deprecated in iOS 6.0+, use NSTextAlignment instead. - // Reference: https://developer.apple.com/library/ios/documentation/uikit/reference/NSString_UIKit_Additions/Reference/Reference.html - #define NSTextAlignment UITextAlignment +// UITextAlignment is deprecated in iOS 6.0+, use NSTextAlignment instead. +// Reference: +// https://developer.apple.com/library/ios/documentation/uikit/reference/NSString_UIKit_Additions/Reference/Reference.html +#define NSTextAlignment UITextAlignment #endif @class HPGrowingTextView; @@ -45,9 +46,11 @@ - (void)growingTextViewDidBeginEditing:(HPGrowingTextView *)growingTextView; - (void)growingTextViewDidEndEditing:(HPGrowingTextView *)growingTextView; -- (void)growingTextChanged:(HPGrowingTextView *)growingTextView text:(NSString*)text; +- (void)growingTextChanged:(HPGrowingTextView *)growingTextView text:(NSString *)text; -- (BOOL)growingTextView:(HPGrowingTextView *)growingTextView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text; +- (BOOL)growingTextView:(HPGrowingTextView *)growingTextView +shouldChangeTextInRange:(NSRange)range + replacementText:(NSString *)text; - (void)growingTextViewDidChange:(HPGrowingTextView *)growingTextView; - (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height; @@ -58,57 +61,56 @@ @end @interface HPGrowingTextView : UIView { - HPTextViewInternal *internalTextView; - + HPTextViewInternal *internalTextView; + int minHeight; int maxHeight; - - //class properties + + // class properties int maxNumberOfLines; int minNumberOfLines; - + BOOL animateHeightChange; - NSTimeInterval animationDuration; - - //uitextview properties - NSObject *__unsafe_unretained delegate; + NSTimeInterval animationDuration; + + // uitextview properties + NSObject *__unsafe_unretained delegate; NSTextAlignment textAlignment; NSRange selectedRange; BOOL editable; UIDataDetectorTypes dataDetectorTypes; UIReturnKeyType returnKeyType; - - UIEdgeInsets contentInset; + + UIEdgeInsets contentInset; } -//real class properties +// real class properties @property int maxNumberOfLines; @property int minNumberOfLines; -@property (nonatomic) int maxHeight; -@property (nonatomic) int minHeight; +@property(nonatomic) int maxHeight; +@property(nonatomic) int minHeight; @property BOOL animateHeightChange; @property NSTimeInterval animationDuration; -@property (nonatomic, strong) NSString *placeholder; -@property (nonatomic, strong) UIColor *placeholderColor; -@property (nonatomic, strong) UITextView *internalTextView; +@property(nonatomic, strong) NSString *placeholder; +@property(nonatomic, strong) UIColor *placeholderColor; +@property(nonatomic, strong) UITextView *internalTextView; - -//uitextview properties +// uitextview properties @property(unsafe_unretained) NSObject *delegate; -@property(nonatomic,strong) NSString *text; -@property(nonatomic,strong) UIFont *font; -@property(nonatomic,strong) UIColor *textColor; -@property(nonatomic) NSTextAlignment textAlignment; // default is NSTextAlignmentLeft -@property(nonatomic) NSRange selectedRange; // only ranges of length 0 are supported -@property(nonatomic,getter=isEditable) BOOL editable; +@property(nonatomic, strong) NSString *text; +@property(nonatomic, strong) UIFont *font; +@property(nonatomic, strong) UIColor *textColor; +@property(nonatomic) NSTextAlignment textAlignment; // default is NSTextAlignmentLeft +@property(nonatomic) NSRange selectedRange; // only ranges of length 0 are supported +@property(nonatomic, getter=isEditable) BOOL editable; @property(nonatomic) UIDataDetectorTypes dataDetectorTypes __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_3_0); -@property (nonatomic) UIReturnKeyType returnKeyType; -@property (assign) UIEdgeInsets contentInset; -@property (nonatomic) BOOL isScrollable; +@property(nonatomic) UIReturnKeyType returnKeyType; +@property(assign) UIEdgeInsets contentInset; +@property(nonatomic) BOOL isScrollable; @property(nonatomic) BOOL enablesReturnKeyAutomatically; -//uitextview methods -//need others? use .internalTextView +// uitextview methods +// need others? use .internalTextView - (BOOL)becomeFirstResponder; - (BOOL)resignFirstResponder; - (BOOL)isFirstResponder; diff --git a/Classes/Utils/HPGrowingTextView/HPGrowingTextView.m b/Classes/Utils/HPGrowingTextView/HPGrowingTextView.m new file mode 100755 index 000000000..21e69560c --- /dev/null +++ b/Classes/Utils/HPGrowingTextView/HPGrowingTextView.m @@ -0,0 +1,602 @@ +// +// HPTextView.m +// +// Created by Hans Pinckaers on 29-06-10. +// +// MIT License +// +// Copyright (c) 2011 Hans Pinckaers +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "HPGrowingTextView.h" +#import "HPTextViewInternal.h" + +@interface HPGrowingTextView (private) +- (void)commonInitialiser; +- (void)resizeTextView:(NSInteger)newSizeH; +- (void)growDidStop; +@end + +@implementation HPGrowingTextView +@synthesize internalTextView; +@synthesize delegate; +@synthesize maxHeight; +@synthesize minHeight; +@synthesize font; +@synthesize textColor; +@synthesize textAlignment; +@synthesize selectedRange; +@synthesize editable; +@synthesize dataDetectorTypes; +@synthesize animateHeightChange; +@synthesize animationDuration; +@synthesize returnKeyType; +@dynamic placeholder; +@dynamic placeholderColor; + +// having initwithcoder allows us to use HPGrowingTextView in a Nib. -- aob, 9/2011 +- (id)initWithCoder:(NSCoder *)aDecoder { + if ((self = [super initWithCoder:aDecoder])) { + [self commonInitialiser]; + } + return self; +} + +- (id)initWithFrame:(CGRect)frame { + if ((self = [super initWithFrame:frame])) { + [self commonInitialiser]; + } + return self; +} + +- (void)commonInitialiser { + // Initialization code + CGRect r = self.frame; + r.origin.y = 0; + r.origin.x = 0; + internalTextView = [[HPTextViewInternal alloc] initWithFrame:r]; + internalTextView.delegate = self; + internalTextView.scrollEnabled = NO; + internalTextView.font = [UIFont systemFontOfSize:13]; + internalTextView.contentInset = UIEdgeInsetsZero; + internalTextView.showsHorizontalScrollIndicator = NO; + internalTextView.text = @"-"; + [self addSubview:internalTextView]; + + minHeight = internalTextView.frame.size.height; + minNumberOfLines = 1; + + animateHeightChange = YES; + animationDuration = 0.1f; + + internalTextView.text = @""; + + [self setMaxNumberOfLines:3]; + + [self setPlaceholderColor:[UIColor lightGrayColor]]; + internalTextView.displayPlaceHolder = YES; +} + +- (CGSize)sizeThatFits:(CGSize)size { + if (self.text.length == 0) { + size.height = minHeight; + } + return size; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + + CGRect r = self.bounds; + r.origin.y = 0; + r.origin.x = contentInset.left; + r.size.width -= contentInset.left + contentInset.right; + + internalTextView.frame = r; +} + +- (void)setContentInset:(UIEdgeInsets)inset { + contentInset = inset; + + CGRect r = self.frame; + r.origin.y = inset.top - inset.bottom; + r.origin.x = inset.left; + r.size.width -= inset.left + inset.right; + + internalTextView.frame = r; + + [self setMaxNumberOfLines:maxNumberOfLines]; + [self setMinNumberOfLines:minNumberOfLines]; +} + +- (UIEdgeInsets)contentInset { + return contentInset; +} + +- (void)setMaxNumberOfLines:(int)n { + if (n == 0 && maxHeight > 0) + return; // the user specified a maxHeight themselves. + + // Use internalTextView for height calculations, thanks to Gwynne + NSString *saveText = internalTextView.text, *newText = @"-"; + + internalTextView.delegate = nil; + internalTextView.hidden = YES; + + for (int i = 1; i < n; ++i) + newText = [newText stringByAppendingString:@"\n|W|"]; + + internalTextView.text = newText; + + maxHeight = [self measureHeight]; + + internalTextView.text = saveText; + internalTextView.hidden = NO; + internalTextView.delegate = self; + + [self sizeToFit]; + + maxNumberOfLines = n; +} + +- (int)maxNumberOfLines { + return maxNumberOfLines; +} + +- (void)setMaxHeight:(int)height { + maxHeight = height; + maxNumberOfLines = 0; +} + +- (void)setMinNumberOfLines:(int)m { + if (m == 0 && minHeight > 0) + return; // the user specified a minHeight themselves. + + // Use internalTextView for height calculations, thanks to Gwynne + NSString *saveText = internalTextView.text, *newText = @"-"; + + internalTextView.delegate = nil; + internalTextView.hidden = YES; + + for (int i = 1; i < m; ++i) + newText = [newText stringByAppendingString:@"\n|W|"]; + + internalTextView.text = newText; + + minHeight = [self measureHeight]; + + internalTextView.text = saveText; + internalTextView.hidden = NO; + internalTextView.delegate = self; + + [self sizeToFit]; + + minNumberOfLines = m; +} + +- (int)minNumberOfLines { + return minNumberOfLines; +} + +- (void)setMinHeight:(int)height { + minHeight = height; + minNumberOfLines = 0; +} + +- (NSString *)placeholder { + return internalTextView.placeholder; +} + +- (void)setPlaceholder:(NSString *)placeholder { + [internalTextView setPlaceholder:placeholder]; +} + +- (UIColor *)placeholderColor { + return internalTextView.placeholderColor; +} + +- (void)setPlaceholderColor:(UIColor *)placeholderColor { + [internalTextView setPlaceholderColor:placeholderColor]; +} + +- (void)textViewDidChange:(UITextView *)textView { + [self refreshHeight]; + if ([delegate respondsToSelector:@selector(growingTextChanged:text:)]) + [delegate growingTextChanged:self text:[textView text]]; +} + +- (void)refreshHeight { + // size of content, so we can set the frame of self + NSInteger newSizeH = [self measureHeight]; + if (newSizeH < minHeight || !internalTextView.hasText) + newSizeH = minHeight; // not smalles than minHeight + if (internalTextView.frame.size.height > maxHeight) + newSizeH = maxHeight; // not taller than maxHeight + + if (internalTextView.frame.size.height != newSizeH) { + // [fixed] Pasting too much text into the view failed to fire the height change, + // thanks to Gwynne + + if (newSizeH > maxHeight && internalTextView.frame.size.height <= maxHeight) { + newSizeH = maxHeight; + } + + if (newSizeH <= maxHeight) { + if (animateHeightChange) { + + if ([UIView resolveClassMethod:@selector(animateWithDuration:animations:)]) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000 + [UIView animateWithDuration:animationDuration + delay:0 + options:(UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState) + animations:^(void) { + [self resizeTextView:newSizeH]; + } + completion:^(BOOL finished) { + if ([delegate respondsToSelector:@selector(growingTextView:didChangeHeight:)]) { + [delegate growingTextView:self didChangeHeight:newSizeH]; + } + }]; +#endif + } else { + [UIView beginAnimations:@"" context:nil]; + [UIView setAnimationDuration:animationDuration]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(growDidStop)]; + [UIView setAnimationBeginsFromCurrentState:YES]; + [self resizeTextView:newSizeH]; + [UIView commitAnimations]; + } + } else { + [self resizeTextView:newSizeH]; + // [fixed] The growingTextView:didChangeHeight: delegate method was not called at all when not animating + // height changes. + // thanks to Gwynne + + if ([delegate respondsToSelector:@selector(growingTextView:didChangeHeight:)]) { + [delegate growingTextView:self didChangeHeight:newSizeH]; + } + } + } + + // if our new height is greater than the maxHeight + // sets not set the height or move things + // around and enable scrolling + if (newSizeH >= maxHeight) { + if (!internalTextView.scrollEnabled) { + internalTextView.scrollEnabled = YES; + [internalTextView flashScrollIndicators]; + } + + } else { + internalTextView.scrollEnabled = NO; + } + + // scroll to caret (needed on iOS7) + if ([self respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)]) { + CGRect r = [internalTextView caretRectForPosition:internalTextView.selectedTextRange.end]; + CGFloat caretY = MAX(r.origin.y - internalTextView.frame.size.height + r.size.height + 8, 0); + if (internalTextView.contentOffset.y < caretY && r.origin.y != INFINITY) + internalTextView.contentOffset = CGPointMake(0, MIN(caretY, internalTextView.contentSize.height)); + } + } + // Display (or not) the placeholder string + + BOOL wasDisplayingPlaceholder = internalTextView.displayPlaceHolder; + internalTextView.displayPlaceHolder = self.internalTextView.text.length == 0; + + if (wasDisplayingPlaceholder != internalTextView.displayPlaceHolder) { + [internalTextView setNeedsDisplay]; + } + + // Tell the delegate that the text view changed + + if ([delegate respondsToSelector:@selector(growingTextViewDidChange:)]) { + [delegate growingTextViewDidChange:self]; + } +} + +// Code from apple developer forum - @Steve Krulewitz, @Mark Marszal, @Eric Silverberg +- (CGFloat)measureHeight { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 + if ([self respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)]) { + CGRect frame = internalTextView.bounds; + CGSize fudgeFactor; + // The padding added around the text on iOS6 and iOS7 is different. + fudgeFactor = CGSizeMake(10.0, 16.0); + + frame.size.height -= fudgeFactor.height; + frame.size.width -= fudgeFactor.width; + + NSMutableAttributedString *textToMeasure; + if (internalTextView.attributedText && internalTextView.attributedText.length > 0) { + textToMeasure = + [[NSMutableAttributedString alloc] initWithAttributedString:internalTextView.attributedText]; + } else { + textToMeasure = [[NSMutableAttributedString alloc] initWithString:internalTextView.text]; + [textToMeasure addAttribute:NSFontAttributeName + value:internalTextView.font + range:NSMakeRange(0, textToMeasure.length)]; + } + + if ([textToMeasure.string hasSuffix:@"\n"]) { + [textToMeasure appendAttributedString:[[NSAttributedString alloc] + initWithString:@"-" + attributes:@{NSFontAttributeName : internalTextView.font}]]; + } + + // NSAttributedString class method: boundingRectWithSize:options:context is + // available only on ios7.0 sdk. + CGRect size = [textToMeasure boundingRectWithSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT) + options:NSStringDrawingUsesLineFragmentOrigin + context:nil]; + + return ceil(CGRectGetHeight(size) + fudgeFactor.height); + } else { + return self.internalTextView.contentSize.height; + } +#else + return self.internalTextView.contentSize.height; +#endif +} + +- (void)resizeTextView:(NSInteger)newSizeH { + if ([delegate respondsToSelector:@selector(growingTextView:willChangeHeight:)]) { + [delegate growingTextView:self willChangeHeight:newSizeH]; + } + + CGRect internalTextViewFrame = self.frame; + internalTextViewFrame.size.height = newSizeH; // + padding + self.frame = internalTextViewFrame; + + internalTextViewFrame.origin.y = contentInset.top - contentInset.bottom; + internalTextViewFrame.origin.x = contentInset.left; + internalTextViewFrame.size.width = internalTextView.contentSize.width; + + if (!CGRectEqualToRect(internalTextView.frame, internalTextViewFrame)) + internalTextView.frame = internalTextViewFrame; +} + +- (void)growDidStop { + if ([delegate respondsToSelector:@selector(growingTextView:didChangeHeight:)]) { + [delegate growingTextView:self didChangeHeight:self.frame.size.height]; + } +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + [internalTextView becomeFirstResponder]; +} + +- (BOOL)becomeFirstResponder { + [super becomeFirstResponder]; + return [self.internalTextView becomeFirstResponder]; +} + +- (BOOL)resignFirstResponder { + [super resignFirstResponder]; + return [internalTextView resignFirstResponder]; +} + +- (BOOL)isFirstResponder { + return [self.internalTextView isFirstResponder]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark UITextView properties +/////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)setText:(NSString *)newText { + internalTextView.text = newText; + + // include this line to analyze the height of the textview. + // fix from Ankit Thakur + [self performSelector:@selector(textViewDidChange:) withObject:internalTextView]; +} + +- (NSString *)text { + return internalTextView.text; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)setFont:(UIFont *)afont { + internalTextView.font = afont; + + [self setMaxNumberOfLines:maxNumberOfLines]; + [self setMinNumberOfLines:minNumberOfLines]; +} + +- (UIFont *)font { + return internalTextView.font; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)setTextColor:(UIColor *)color { + internalTextView.textColor = color; +} + +- (UIColor *)textColor { + return internalTextView.textColor; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)setBackgroundColor:(UIColor *)backgroundColor { + [super setBackgroundColor:backgroundColor]; + internalTextView.backgroundColor = backgroundColor; +} + +- (UIColor *)backgroundColor { + return internalTextView.backgroundColor; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)setTextAlignment:(NSTextAlignment)aligment { + internalTextView.textAlignment = aligment; +} + +- (NSTextAlignment)textAlignment { + return internalTextView.textAlignment; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)setSelectedRange:(NSRange)range { + internalTextView.selectedRange = range; +} + +- (NSRange)selectedRange { + return internalTextView.selectedRange; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)setIsScrollable:(BOOL)isScrollable { + internalTextView.scrollEnabled = isScrollable; +} + +- (BOOL)isScrollable { + return internalTextView.scrollEnabled; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)setEditable:(BOOL)beditable { + internalTextView.editable = beditable; +} + +- (BOOL)isEditable { + return internalTextView.editable; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)setReturnKeyType:(UIReturnKeyType)keyType { + internalTextView.returnKeyType = keyType; +} + +- (UIReturnKeyType)returnKeyType { + return internalTextView.returnKeyType; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)setEnablesReturnKeyAutomatically:(BOOL)enablesReturnKeyAutomatically { + internalTextView.enablesReturnKeyAutomatically = enablesReturnKeyAutomatically; +} + +- (BOOL)enablesReturnKeyAutomatically { + return internalTextView.enablesReturnKeyAutomatically; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)setDataDetectorTypes:(UIDataDetectorTypes)datadetector { + internalTextView.dataDetectorTypes = datadetector; +} + +- (UIDataDetectorTypes)dataDetectorTypes { + return internalTextView.dataDetectorTypes; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)hasText { + return [internalTextView hasText]; +} + +- (void)scrollRangeToVisible:(NSRange)range { + [internalTextView scrollRangeToVisible:range]; +} + +///////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark UITextViewDelegate + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)textViewShouldBeginEditing:(UITextView *)textView { + if ([delegate respondsToSelector:@selector(growingTextViewShouldBeginEditing:)]) { + return [delegate growingTextViewShouldBeginEditing:self]; + + } else { + return YES; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)textViewShouldEndEditing:(UITextView *)textView { + if ([delegate respondsToSelector:@selector(growingTextViewShouldEndEditing:)]) { + return [delegate growingTextViewShouldEndEditing:self]; + + } else { + return YES; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)textViewDidBeginEditing:(UITextView *)textView { + if ([delegate respondsToSelector:@selector(growingTextViewDidBeginEditing:)]) { + [delegate growingTextViewDidBeginEditing:self]; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)textViewDidEndEditing:(UITextView *)textView { + if ([delegate respondsToSelector:@selector(growingTextViewDidEndEditing:)]) { + [delegate growingTextViewDidEndEditing:self]; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)atext { + + // weird 1 pixel bug when clicking backspace when textView is empty + if (![textView hasText] && [atext isEqualToString:@""]) + return NO; + + // Added by bretdabaker: sometimes we want to handle this ourselves + if ([delegate respondsToSelector:@selector(growingTextView:shouldChangeTextInRange:replacementText:)]) + return [delegate growingTextView:self shouldChangeTextInRange:range replacementText:atext]; + + if ([atext isEqualToString:@"\n"]) { + if ([delegate respondsToSelector:@selector(growingTextViewShouldReturn:)]) { + if (![delegate performSelector:@selector(growingTextViewShouldReturn:) withObject:self]) { + return YES; + } else { + [textView resignFirstResponder]; + return NO; + } + } + } + + return YES; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +- (void)textViewDidChangeSelection:(UITextView *)textView { + if ([delegate respondsToSelector:@selector(growingTextViewDidChangeSelection:)]) { + [delegate growingTextViewDidChangeSelection:self]; + } +} + +@end diff --git a/Classes/Utils/GrowingTextView/HPTextViewInternal.h b/Classes/Utils/HPGrowingTextView/HPTextViewInternal.h similarity index 89% rename from Classes/Utils/GrowingTextView/HPTextViewInternal.h rename to Classes/Utils/HPGrowingTextView/HPTextViewInternal.h index 175f4d472..712265f06 100755 --- a/Classes/Utils/GrowingTextView/HPTextViewInternal.h +++ b/Classes/Utils/HPGrowingTextView/HPTextViewInternal.h @@ -27,11 +27,10 @@ #import - @interface HPTextViewInternal : UITextView -@property (nonatomic, strong) NSString *placeholder; -@property (nonatomic, strong) UIColor *placeholderColor; -@property (nonatomic) BOOL displayPlaceHolder; +@property(nonatomic, strong) NSString *placeholder; +@property(nonatomic, strong) UIColor *placeholderColor; +@property(nonatomic) BOOL displayPlaceHolder; @end diff --git a/Classes/Utils/HPGrowingTextView/HPTextViewInternal.m b/Classes/Utils/HPGrowingTextView/HPTextViewInternal.m new file mode 100755 index 000000000..70366b87c --- /dev/null +++ b/Classes/Utils/HPGrowingTextView/HPTextViewInternal.m @@ -0,0 +1,105 @@ +// +// HPTextViewInternal.m +// +// Created by Hans Pinckaers on 29-06-10. +// +// MIT License +// +// Copyright (c) 2011 Hans Pinckaers +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "HPTextViewInternal.h" + +@implementation HPTextViewInternal + +@synthesize placeholder; +@synthesize placeholderColor; +@synthesize displayPlaceHolder; + +- (void)setText:(NSString *)text { + BOOL originalValue = self.scrollEnabled; + // If one of GrowingTextView's superviews is a scrollView, and self.scrollEnabled == NO, + // setting the text programatically will cause UIKit to search upwards until it finds a scrollView with + // scrollEnabled==yes + // then scroll it erratically. Setting scrollEnabled temporarily to YES prevents this. + [self setScrollEnabled:YES]; + [super setText:text]; + [self setScrollEnabled:originalValue]; +} + +- (void)setScrollable:(BOOL)isScrollable { + [super setScrollEnabled:isScrollable]; +} + +- (void)setContentOffset:(CGPoint)s { + if (self.tracking || self.decelerating) { + // initiated by user... + + UIEdgeInsets insets = self.contentInset; + insets.bottom = 0; + insets.top = 0; + self.contentInset = insets; + + } else { + + float bottomOffset = (self.contentSize.height - self.frame.size.height + self.contentInset.bottom); + if (s.y < bottomOffset && self.scrollEnabled) { + UIEdgeInsets insets = self.contentInset; + insets.bottom = 8; + insets.top = 0; + self.contentInset = insets; + } + } + + [super setContentOffset:s]; +} + +- (void)setContentInset:(UIEdgeInsets)s { + UIEdgeInsets insets = s; + + if (s.bottom > 8) + insets.bottom = 0; + insets.top = 0; + + [super setContentInset:insets]; +} + +- (void)setContentSize:(CGSize)contentSize { + // is this an iOS5 bug? Need testing! + if (self.contentSize.height > contentSize.height) { + UIEdgeInsets insets = self.contentInset; + insets.bottom = 0; + insets.top = 0; + self.contentInset = insets; + } + + [super setContentSize:contentSize]; +} + +- (void)drawRect:(CGRect)rect { + [super drawRect:rect]; + if (displayPlaceHolder && placeholder && placeholderColor) { + [placeholderColor set]; + [placeholder drawInRect:CGRectMake(8.0f, 8.0f, self.frame.size.width - 16.0f, self.frame.size.height - 16.0f) + withFont:self.font]; + } +} + +@end diff --git a/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h b/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h index 780a084f1..961a92bcb 100755 --- a/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h +++ b/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h @@ -26,6 +26,7 @@ @protocol IASKSettingsDelegate - (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController*)sender; +- (void)settingsViewControllerWillAppear:(IASKAppSettingsViewController *)sender; @optional #pragma mark - UITableView header customization @@ -60,10 +61,10 @@ @interface IASKAppSettingsViewController : UITableViewController { - id _delegate; - - NSMutableArray *_viewList; - + id __weak _delegate; + + NSMutableArray *_viewList; + IASKSettingsReader *_settingsReader; id _settingsStore; NSString *_file; @@ -76,11 +77,11 @@ NSSet *_hiddenKeys; } -@property (nonatomic, assign) IBOutlet id delegate; +@property(nonatomic, weak) IBOutlet id delegate; @property (nonatomic, copy) NSString *file; @property (nonatomic, assign) BOOL showCreditsFooter; @property (nonatomic, assign) BOOL showDoneButton; -@property (nonatomic, retain) NSSet *hiddenKeys; +@property(nonatomic, strong) NSSet *hiddenKeys; - (void)synchronizeSettings; - (void)dismiss:(id)sender; diff --git a/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m b/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m index da7395b1a..79c07b63e 100755 --- a/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m +++ b/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m @@ -41,8 +41,8 @@ static NSString *kIASKCredits = @"Powered by InAppSettingsKit"; // Leave this as CGRect IASKCGRectSwap(CGRect rect); @interface IASKAppSettingsViewController () -@property (nonatomic, retain) NSMutableArray *viewList; -@property (nonatomic, retain) id currentFirstResponder; +@property(nonatomic, strong) NSMutableArray *viewList; +@property(nonatomic, strong) id currentFirstResponder; - (void)_textChanged:(id)sender; - (void)synchronizeSettings; @@ -81,19 +81,18 @@ CGRect IASKCGRectSwap(CGRect rect); if (!_file) { return @"Root"; } - return [[_file retain] autorelease]; + return _file; } - (void)setFile:(NSString *)file { if (file != _file) { - [_file release]; _file = [file copy]; } self.tableView.contentOffset = CGPointMake(0, 0); self.settingsReader = nil; // automatically initializes itself - [_hiddenKeys release], _hiddenKeys = nil; + _hiddenKeys = nil; [self.tableView reloadData]; } @@ -138,9 +137,10 @@ CGRect IASKCGRectSwap(CGRect rect); - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { - [self initWithStyle:UITableViewStyleGrouped]; - } - return self; + if (!(self = [self initWithStyle:UITableViewStyleGrouped])) + return nil; + } + return self; } - (NSMutableArray *)viewList { @@ -164,7 +164,6 @@ CGRect IASKCGRectSwap(CGRect rect); UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapToEndEdit:)]; tapGesture.cancelsTouchesInView = NO; [self.tableView addGestureRecognizer:tapGesture]; - [tapGesture release]; } - (void)viewDidUnload { @@ -193,7 +192,6 @@ CGRect IASKCGRectSwap(CGRect rect); target:self action:@selector(dismiss:)]; self.navigationItem.rightBarButtonItem = buttonItem; - [buttonItem release]; } if (!self.title) { self.title = NSLocalizedString(@"Settings", @""); @@ -206,6 +204,12 @@ CGRect IASKCGRectSwap(CGRect rect); object:[NSUserDefaults standardUserDefaults]]; [self userDefaultsDidChange]; // force update in case of changes while we were hidden } + + // hack gautier: be notified when changing page + if (self.delegate && [self.delegate conformsToProtocol:@protocol(IASKSettingsDelegate)]) { + [self.delegate settingsViewControllerWillAppear:self]; + } + [super viewWillAppear:animated]; } @@ -255,12 +259,12 @@ CGRect IASKCGRectSwap(CGRect rect); - (void)setHiddenKeys:(NSSet*)theHiddenKeys animated:(BOOL)animated { if (_hiddenKeys != theHiddenKeys) { NSSet *oldHiddenKeys = _hiddenKeys; - _hiddenKeys = [theHiddenKeys retain]; - - if (animated) { - [self.tableView beginUpdates]; - - NSMutableSet *showKeys = [NSMutableSet setWithSet:oldHiddenKeys]; + _hiddenKeys = theHiddenKeys; + + if (animated) { + [self.tableView beginUpdates]; + + NSMutableSet *showKeys = [NSMutableSet setWithSet:oldHiddenKeys]; [showKeys minusSet:theHiddenKeys]; NSMutableSet *hideKeys = [NSMutableSet setWithSet:theHiddenKeys]; @@ -326,7 +330,6 @@ CGRect IASKCGRectSwap(CGRect rect); self.settingsReader.hiddenKeys = theHiddenKeys; [self.tableView reloadData]; } - [oldHiddenKeys release]; IASKAppSettingsViewController *targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierChildViewControllerIndex] objectForKey:@"viewController"]; if(targetViewController != nil) { @@ -339,16 +342,15 @@ CGRect IASKCGRectSwap(CGRect rect); - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [_viewList release], _viewList = nil; - [_file release], _file = nil; - [_currentFirstResponder release], _currentFirstResponder = nil; - [_settingsReader release], _settingsReader = nil; - [_settingsStore release], _settingsStore = nil; - [_hiddenKeys release], _hiddenKeys = nil; - + _viewList = nil; + _file = nil; + _currentFirstResponder = nil; + _settingsReader = nil; + _settingsStore = nil; + _hiddenKeys = nil; + _delegate = nil; - [super dealloc]; } @@ -364,11 +366,11 @@ CGRect IASKCGRectSwap(CGRect rect); } - (void)toggledValue:(id)sender { - IASKSwitch *toggle = [[(IASKSwitch*)sender retain] autorelease]; - IASKSpecifier *spec = [_settingsReader specifierForKey:[toggle key]]; - - if ([toggle isOn]) { - if ([spec trueValue] != nil) { + IASKSwitch *toggle = (IASKSwitch *)sender; + IASKSpecifier *spec = [_settingsReader specifierForKey:[toggle key]]; + + if ([toggle isOn]) { + if ([spec trueValue] != nil) { [self.settingsStore setObject:[spec trueValue] forKey:[toggle key]]; } else { @@ -390,12 +392,13 @@ CGRect IASKCGRectSwap(CGRect rect); } - (void)sliderChangedValue:(id)sender { - IASKSlider *slider = [[(IASKSlider*)sender retain] autorelease]; - [self.settingsStore setFloat:[slider value] forKey:[slider key]]; - [[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged - object:[slider key] - userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:[slider value]] - forKey:[slider key]]]; + IASKSlider *slider = (IASKSlider *)sender; + [self.settingsStore setFloat:[slider value] forKey:[slider key]]; + [[NSNotificationCenter defaultCenter] + postNotificationName:kIASKAppSettingChanged + object:[slider key] + userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:[slider value]] + forKey:[slider key]]]; } @@ -480,7 +483,7 @@ CGRect IASKCGRectSwap(CGRect rect); UITableViewCell *cell = nil; if ([identifier isEqualToString:kIASKPSToggleSwitchSpecifier]) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kIASKPSToggleSwitchSpecifier]; - cell.accessoryView = [[[IASKSwitch alloc] initWithFrame:CGRectMake(0, 0, 79, 27)] autorelease]; + cell.accessoryView = [[IASKSwitch alloc] initWithFrame:CGRectMake(0, 0, 79, 27)]; [((IASKSwitch*)cell.accessoryView) addTarget:self action:@selector(toggledValue:) forControlEvents:UIControlEventValueChanged]; cell.selectionStyle = UITableViewCellSelectionStyleNone; } @@ -518,7 +521,7 @@ CGRect IASKCGRectSwap(CGRect rect); UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:specifier.type]; if(nil == cell) { - cell = [[self newCellForIdentifier:specifier.type] autorelease]; + cell = [self newCellForIdentifier:specifier.type]; } if ([specifier.type isEqualToString:kIASKPSToggleSwitchSpecifier]) { @@ -627,7 +630,7 @@ CGRect IASKCGRectSwap(CGRect rect); //create a set of specifier types that can't be selected static NSSet* noSelectionTypes = nil; if(nil == noSelectionTypes) { - noSelectionTypes = [[NSSet setWithObjects:kIASKPSToggleSwitchSpecifier, kIASKPSSliderSpecifier, nil] retain]; + noSelectionTypes = [NSSet setWithObjects:kIASKPSToggleSwitchSpecifier, kIASKPSSliderSpecifier, nil]; } IASKSpecifier *specifier = [self.settingsReader specifierForIndexPath:indexPath]; @@ -658,7 +661,6 @@ CGRect IASKCGRectSwap(CGRect rect); // add the new view controller to the dictionary and then to the 'viewList' array [newItemDict setObject:targetViewController forKey:@"viewController"]; [self.viewList replaceObjectAtIndex:kIASKSpecifierValuesViewControllerIndex withObject:newItemDict]; - [targetViewController release]; // load the view controll back in to push it targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierValuesViewControllerIndex] objectForKey:@"viewController"]; @@ -681,8 +683,11 @@ CGRect IASKCGRectSwap(CGRect rect); if (!initSelector) { initSelector = @selector(init); } - UIViewController * vc = [vcClass performSelector:@selector(alloc)]; - [vc performSelector:initSelector withObject:[specifier file] withObject:[specifier key]]; + UIViewController *vc = [vcClass alloc]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + vc = [vc performSelector:initSelector withObject:[specifier file] withObject:specifier]; +#pragma clang diagnostic pop if ([vc respondsToSelector:@selector(setDelegate:)]) { [vc performSelector:@selector(setDelegate:) withObject:self.delegate]; } @@ -690,7 +695,6 @@ CGRect IASKCGRectSwap(CGRect rect); [vc performSelector:@selector(setSettingsStore:) withObject:self.settingsStore]; } [self.navigationController pushViewController:vc animated:YES]; - [vc performSelector:@selector(release)]; return; } @@ -715,7 +719,6 @@ CGRect IASKCGRectSwap(CGRect rect); // add the new view controller to the dictionary and then to the 'viewList' array [newItemDict setObject:targetViewController forKey:@"viewController"]; [self.viewList replaceObjectAtIndex:kIASKSpecifierChildViewControllerIndex withObject:newItemDict]; - [targetViewController release]; // load the view controll back in to push it targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierChildViewControllerIndex] objectForKey:@"viewController"]; @@ -725,8 +728,8 @@ CGRect IASKCGRectSwap(CGRect rect); targetViewController.title = specifier.title; targetViewController.showCreditsFooter = NO; [[self navigationController] pushViewController:targetViewController animated:YES]; - } else if ([[specifier type] isEqualToString:kIASKOpenURLSpecifier]) { - [tableView deselectRowAtIndexPath:indexPath animated:YES]; + } else if ([[specifier type] isEqualToString:kIASKOpenURLSpecifier]) { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; [[UIApplication sharedApplication] openURL:[NSURL URLWithString:specifier.file]]; } else if ([[specifier type] isEqualToString:kIASKButtonSpecifier]) { [tableView deselectRowAtIndexPath:indexPath animated:YES]; @@ -742,7 +745,10 @@ CGRect IASKCGRectSwap(CGRect rect); Class buttonClass = [specifier buttonClass]; SEL buttonAction = [specifier buttonAction]; if ([buttonClass respondsToSelector:buttonAction]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" [buttonClass performSelector:buttonAction withObject:self withObject:[specifier key]]; +#pragma clang diagnostic pop NSLog(@"InAppSettingsKit Warning: Using IASKButtonSpecifier without implementing the delegate method is deprecated"); } } @@ -792,7 +798,6 @@ CGRect IASKCGRectSwap(CGRect rect); mailViewController.mailComposeDelegate = vc; [vc presentModalViewController:mailViewController animated:YES]; - [mailViewController release]; } else { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Mail not configured", @"InAppSettingsKit") @@ -801,7 +806,6 @@ CGRect IASKCGRectSwap(CGRect rect); cancelButtonTitle:NSLocalizedString(@"OK", @"InAppSettingsKit") otherButtonTitles:nil]; [alert show]; - [alert release]; } } else if ([[specifier type] isEqualToString:kIASKCustomViewSpecifier] && [self.delegate respondsToSelector:@selector(settingsViewController:tableView:didSelectCustomViewSpecifier:)]) { @@ -838,12 +842,12 @@ CGRect IASKCGRectSwap(CGRect rect); } - (void)_textChanged:(id)sender { - IASKTextField *text = [[(IASKTextField*)sender retain] autorelease]; - [_settingsStore setObject:[text text] forKey:[text key]]; - [[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged - object:[text key] - userInfo:[NSDictionary dictionaryWithObject:[text text] - forKey:[text key]]]; + IASKTextField *text = (IASKTextField *)sender; + [_settingsStore setObject:[text text] forKey:[text key]]; + [[NSNotificationCenter defaultCenter] + postNotificationName:kIASKAppSettingChanged + object:[text key] + userInfo:[NSDictionary dictionaryWithObject:[text text] forKey:[text key]]]; } - (BOOL)textFieldShouldReturn:(UITextField *)textField{ @@ -874,9 +878,8 @@ static NSDictionary *oldUserDefaults = nil; } } } - [oldUserDefaults release], oldUserDefaults = [currentDict retain]; - - + oldUserDefaults = currentDict; + for (UITableViewCell *cell in self.tableView.visibleCells) { if ([cell isKindOfClass:[IASKPSTextFieldSpecifierViewCell class]] && [((IASKPSTextFieldSpecifierViewCell*)cell).textField isFirstResponder]) { [indexPathsToUpdate removeObject:[self.tableView indexPathForCell:cell]]; diff --git a/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.h b/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.h index 4805ddf3c..fbda2a1d6 100755 --- a/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.h +++ b/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.h @@ -24,7 +24,7 @@ - (id)initWithFile:(NSString*)htmlFileName key:(NSString*)key; -@property (nonatomic, retain) UIWebView *webView; -@property (nonatomic, retain) NSURL *url; +@property(nonatomic, strong) UIWebView *webView; +@property(nonatomic, strong) NSURL *url; @end diff --git a/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.m b/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.m index feb95ddc9..725fe1a25 100755 --- a/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.m +++ b/Classes/Utils/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.m @@ -47,13 +47,12 @@ } - (void)dealloc { - [webView release], webView = nil; - [url release], url = nil; - - [super dealloc]; + webView = nil; + url = nil; } -- (void)viewWillAppear:(BOOL)animated { +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; [webView loadRequest:[NSURLRequest requestWithURL:self.url]]; } @@ -101,13 +100,10 @@ } NSString *key = [[keyValue objectAtIndex:0] lowercaseString]; NSString *value = [keyValue objectAtIndex:1]; - - value = (NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, - (CFStringRef)value, - CFSTR(""), - kCFStringEncodingUTF8); - [value autorelease]; - + + value = (NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding( + kCFAllocatorDefault, (CFStringRef)value, CFSTR(""), kCFStringEncodingUTF8)); + if ([key isEqualToString:@"subject"]) { [mailViewController setSubject:value]; } @@ -135,7 +131,6 @@ [mailViewController setToRecipients:toRecipients]; [self presentModalViewController:mailViewController animated:YES]; - [mailViewController release]; return NO; } diff --git a/Classes/Utils/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.h b/Classes/Utils/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.h index 85f6d9fc2..99b2ef14d 100755 --- a/Classes/Utils/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.h +++ b/Classes/Utils/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.h @@ -29,8 +29,8 @@ id _settingsStore; } -@property (nonatomic, retain) UITableView *tableView; -@property (nonatomic, retain) NSIndexPath *checkedItem; -@property (nonatomic, retain) IASKSpecifier *currentSpecifier; +@property(nonatomic, strong) UITableView *tableView; +@property(nonatomic, strong) NSIndexPath *checkedItem; +@property(nonatomic, strong) IASKSpecifier *currentSpecifier; @end diff --git a/Classes/Utils/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m b/Classes/Utils/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m index bd0b82ac6..cda7126b4 100755 --- a/Classes/Utils/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m +++ b/Classes/Utils/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m @@ -105,6 +105,7 @@ } - (void)viewDidUnload { + [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; self.tableView = nil; @@ -112,12 +113,11 @@ - (void)dealloc { - [_currentSpecifier release], _currentSpecifier = nil; - [_checkedItem release], _checkedItem = nil; - [_settingsReader release], _settingsReader = nil; - [_settingsStore release], _settingsStore = nil; - [_tableView release], _tableView = nil; - [super dealloc]; + _currentSpecifier = nil; + _checkedItem = nil; + _settingsReader = nil; + _settingsStore = nil; + _tableView = nil; } @@ -151,9 +151,9 @@ NSArray *titles = [_currentSpecifier multipleTitles]; if (!cell) { - cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellValue] autorelease]; - } - + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellValue]; + } + if ([indexPath isEqual:[self checkedItem]]) { [self selectCell:cell]; } else { @@ -197,7 +197,7 @@ #pragma mark Notifications - (void)userDefaultsDidChange { - NSIndexPath *oldCheckedItem = [[self.checkedItem retain] autorelease]; + NSIndexPath *oldCheckedItem = self.checkedItem; if(_currentSpecifier) { [self updateCheckedItem]; } diff --git a/Classes/Utils/InAppSettingsKit/Models/IASKSettingsReader.h b/Classes/Utils/InAppSettingsKit/Models/IASKSettingsReader.h index a05ddb202..628320900 100755 --- a/Classes/Utils/InAppSettingsKit/Models/IASKSettingsReader.h +++ b/Classes/Utils/InAppSettingsKit/Models/IASKSettingsReader.h @@ -152,11 +152,11 @@ __VA_ARGS__ \ - (NSString*)titleForStringId:(NSString*)stringId; - (NSString*)pathForImageNamed:(NSString*)image; -@property (nonatomic, retain) NSString *path; -@property (nonatomic, retain) NSString *localizationTable; -@property (nonatomic, retain) NSString *bundlePath; -@property (nonatomic, retain) NSDictionary *settingsBundle; -@property (nonatomic, retain) NSArray *dataSource; -@property (nonatomic, retain) NSSet *hiddenKeys; +@property(nonatomic, strong) NSString *path; +@property(nonatomic, strong) NSString *localizationTable; +@property(nonatomic, strong) NSString *bundlePath; +@property(nonatomic, strong) NSDictionary *settingsBundle; +@property(nonatomic, strong) NSArray *dataSource; +@property(nonatomic, strong) NSSet *hiddenKeys; @end diff --git a/Classes/Utils/InAppSettingsKit/Models/IASKSettingsReader.m b/Classes/Utils/InAppSettingsKit/Models/IASKSettingsReader.m index 7e15fce1e..124e0a818 100755 --- a/Classes/Utils/InAppSettingsKit/Models/IASKSettingsReader.m +++ b/Classes/Utils/InAppSettingsKit/Models/IASKSettingsReader.m @@ -45,8 +45,8 @@ hiddenKeys = _hiddenKeys; self.path = [self locateSettingsFile: file]; [self setSettingsBundle:[NSDictionary dictionaryWithContentsOfFile:self.path]]; self.bundlePath = [self.path stringByDeletingLastPathComponent]; - _bundle = [[NSBundle bundleWithPath:[self bundlePath]] retain]; - + _bundle = [NSBundle bundleWithPath:[self bundlePath]]; + // Look for localization file self.localizationTable = [self.settingsBundle objectForKey:@"StringsTable"]; if (!self.localizationTable) @@ -70,24 +70,20 @@ hiddenKeys = _hiddenKeys; } - (void)dealloc { - [_path release], _path = nil; - [_localizationTable release], _localizationTable = nil; - [_bundlePath release], _bundlePath = nil; - [_settingsBundle release], _settingsBundle = nil; - [_dataSource release], _dataSource = nil; - [_bundle release], _bundle = nil; - [_hiddenKeys release], _hiddenKeys = nil; - - [super dealloc]; + _path = nil; + _localizationTable = nil; + _bundlePath = nil; + _settingsBundle = nil; + _dataSource = nil; + _bundle = nil; + _hiddenKeys = nil; } - (void)setHiddenKeys:(NSSet *)anHiddenKeys { if (_hiddenKeys != anHiddenKeys) { - id old = _hiddenKeys; - _hiddenKeys = [anHiddenKeys retain]; - [old release]; - + _hiddenKeys = anHiddenKeys; + if (_settingsBundle) { [self _reinterpretBundle:_settingsBundle]; } @@ -98,8 +94,8 @@ hiddenKeys = _hiddenKeys; - (void)_reinterpretBundle:(NSDictionary*)settingsBundle { NSArray *preferenceSpecifiers = [settingsBundle objectForKey:kIASKPreferenceSpecifiers]; NSInteger sectionCount = -1; - NSMutableArray *dataSource = [[[NSMutableArray alloc] init] autorelease]; - + NSMutableArray *dataSource = [[NSMutableArray alloc] init]; + for (NSDictionary *specifier in preferenceSpecifiers) { if ([self.hiddenKeys containsObject:[specifier objectForKey:kIASKKey]]) { continue; @@ -109,20 +105,17 @@ hiddenKeys = _hiddenKeys; [newArray addObject:specifier]; [dataSource addObject:newArray]; - [newArray release]; sectionCount++; } else { if (sectionCount == -1) { NSMutableArray *newArray = [[NSMutableArray alloc] init]; [dataSource addObject:newArray]; - [newArray release]; sectionCount++; } IASKSpecifier *newSpecifier = [[IASKSpecifier alloc] initWithSpecifier:specifier]; [(NSMutableArray*)[dataSource objectAtIndex:sectionCount] addObject:newSpecifier]; - [newSpecifier release]; } } [self setDataSource:dataSource]; diff --git a/Classes/Utils/InAppSettingsKit/Models/IASKSettingsStoreFile.m b/Classes/Utils/InAppSettingsKit/Models/IASKSettingsStoreFile.m index 104642d7e..a5fc41933 100755 --- a/Classes/Utils/InAppSettingsKit/Models/IASKSettingsStoreFile.m +++ b/Classes/Utils/InAppSettingsKit/Models/IASKSettingsStoreFile.m @@ -22,20 +22,18 @@ - (id)initWithPath:(NSString*)path { if((self = [super init])) { - _filePath = [path retain]; - _dict = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; - if(_dict == nil) { - _dict = [[NSMutableDictionary alloc] init]; + _filePath = path; + _dict = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; + if (_dict == nil) { + _dict = [[NSMutableDictionary alloc] init]; } } return self; } - (void)dealloc { - [_dict release], _dict = nil; - [_filePath release], _filePath = nil; - - [super dealloc]; + _dict = nil; + _filePath = nil; } diff --git a/Classes/Utils/InAppSettingsKit/Models/IASKSpecifier.h b/Classes/Utils/InAppSettingsKit/Models/IASKSpecifier.h index 5eeec3596..cec727d9f 100755 --- a/Classes/Utils/InAppSettingsKit/Models/IASKSpecifier.h +++ b/Classes/Utils/InAppSettingsKit/Models/IASKSpecifier.h @@ -22,10 +22,10 @@ @interface IASKSpecifier : NSObject { NSDictionary *_specifierDict; NSDictionary *_multipleValuesDict; - IASKSettingsReader *_settingsReader; + IASKSettingsReader *__weak _settingsReader; } -@property (nonatomic, retain) NSDictionary *specifierDict; -@property (nonatomic, assign) IASKSettingsReader *settingsReader; +@property(nonatomic, strong) NSDictionary *specifierDict; +@property(nonatomic, weak) IASKSettingsReader *settingsReader; - (id)initWithSpecifier:(NSDictionary*)specifier; - (NSString*)localizedObjectForKey:(NSString*)key; @@ -58,5 +58,5 @@ - (UIImage *)cellImage; - (UIImage *)highlightedCellImage; - (BOOL)adjustsFontSizeToFitWidth; -- (UITextAlignment)textAlignment; +- (NSTextAlignment)textAlignment; @end diff --git a/Classes/Utils/InAppSettingsKit/Models/IASKSpecifier.m b/Classes/Utils/InAppSettingsKit/Models/IASKSpecifier.m index d76beb4ab..503b71a8b 100755 --- a/Classes/Utils/InAppSettingsKit/Models/IASKSpecifier.m +++ b/Classes/Utils/InAppSettingsKit/Models/IASKSpecifier.m @@ -18,7 +18,7 @@ #import "IASKSettingsReader.h" @interface IASKSpecifier () -@property (nonatomic, retain) NSDictionary *multipleValuesDict; +@property(nonatomic, strong) NSDictionary *multipleValuesDict; - (void)_reinterpretValues:(NSDictionary*)specifierDict; @end @@ -41,21 +41,20 @@ } - (void)dealloc { - [_specifierDict release], _specifierDict = nil; - [_multipleValuesDict release], _multipleValuesDict = nil; - + _specifierDict = nil; + _multipleValuesDict = nil; + _settingsReader = nil; - [super dealloc]; } - (void)_reinterpretValues:(NSDictionary*)specifierDict { NSArray *values = [_specifierDict objectForKey:kIASKValues]; NSArray *titles = [_specifierDict objectForKey:kIASKTitles]; - - NSMutableDictionary *multipleValuesDict = [[[NSMutableDictionary alloc] init] autorelease]; - - if (values) { + + NSMutableDictionary *multipleValuesDict = [[NSMutableDictionary alloc] init]; + + if (values) { [multipleValuesDict setObject:values forKey:kIASKValues]; } @@ -252,20 +251,19 @@ return !boxedResult || [boxedResult boolValue]; } -- (UITextAlignment)textAlignment -{ - if ([[_specifierDict objectForKey:kIASKTextLabelAlignment] isEqualToString:kIASKTextLabelAlignmentLeft]) { - return UITextAlignmentLeft; - } else if ([[_specifierDict objectForKey:kIASKTextLabelAlignment] isEqualToString:kIASKTextLabelAlignmentCenter]) { - return UITextAlignmentCenter; - } else if ([[_specifierDict objectForKey:kIASKTextLabelAlignment] isEqualToString:kIASKTextLabelAlignmentRight]) { - return UITextAlignmentRight; - } - if ([self.type isEqualToString:kIASKButtonSpecifier] && !self.cellImage) { - return UITextAlignmentCenter; - } else if ([self.type isEqualToString:kIASKPSMultiValueSpecifier] || [self.type isEqualToString:kIASKPSTitleValueSpecifier]) { - return UITextAlignmentRight; +- (NSTextAlignment)textAlignment { + if ([[_specifierDict objectForKey:kIASKTextLabelAlignment] isEqualToString:kIASKTextLabelAlignmentLeft]) { + return NSTextAlignmentLeft; + } else if ([[_specifierDict objectForKey:kIASKTextLabelAlignment] isEqualToString:kIASKTextLabelAlignmentCenter]) { + return NSTextAlignmentCenter; + } else if ([[_specifierDict objectForKey:kIASKTextLabelAlignment] isEqualToString:kIASKTextLabelAlignmentRight]) { + return NSTextAlignmentRight; } - return UITextAlignmentLeft; + if ([self.type isEqualToString:kIASKButtonSpecifier] && !self.cellImage) { + return NSTextAlignmentCenter; + } else if ([self.type isEqualToString:kIASKPSMultiValueSpecifier] || [self.type isEqualToString:kIASKPSTitleValueSpecifier]) { + return NSTextAlignmentRight; + } + return NSTextAlignmentLeft; } @end diff --git a/Classes/Utils/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.h b/Classes/Utils/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.h index 1aca0cfe1..ed2f606a6 100755 --- a/Classes/Utils/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.h +++ b/Classes/Utils/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.h @@ -18,14 +18,10 @@ @class IASKSlider; -@interface IASKPSSliderSpecifierViewCell : UITableViewCell { - IASKSlider *_slider; - UIImageView *_minImage; - UIImageView *_maxImage; -} +@interface IASKPSSliderSpecifierViewCell : UITableViewCell -@property (nonatomic, assign) IASKSlider *slider; -@property (nonatomic, assign) UIImageView *minImage; -@property (nonatomic, assign) UIImageView *maxImage; +@property(nonatomic, strong) IASKSlider *slider; +@property(nonatomic, strong) UIImageView *minImage; +@property(nonatomic, strong) UIImageView *maxImage; @end diff --git a/Classes/Utils/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.m b/Classes/Utils/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.m index dc2130d85..44617e15b 100755 --- a/Classes/Utils/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.m +++ b/Classes/Utils/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.m @@ -19,36 +19,28 @@ #import "IASKSettingsReader.h" @implementation IASKPSSliderSpecifierViewCell - -@synthesize slider=_slider, - minImage=_minImage, - maxImage=_maxImage; - - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // Setting only frame data that will not be overwritten by layoutSubviews // Slider - _slider = [[[IASKSlider alloc] initWithFrame:CGRectMake(0, 0, 0, 23)] autorelease]; - _slider.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | - UIViewAutoresizingFlexibleWidth; - _slider.continuous = NO; - [self.contentView addSubview:_slider]; + _slider = [[IASKSlider alloc] initWithFrame:CGRectMake(0, 0, 0, 23)]; + _slider.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth; + _slider.continuous = NO; + [self.contentView addSubview:_slider]; // MinImage - _minImage = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 21, 21)] autorelease]; - _minImage.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | - UIViewAutoresizingFlexibleBottomMargin; - [self.contentView addSubview:_minImage]; + _minImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 21, 21)]; + _minImage.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; + [self.contentView addSubview:_minImage]; - // MaxImage - _maxImage = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 21, 21)] autorelease]; - _maxImage.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | - UIViewAutoresizingFlexibleBottomMargin; - [self.contentView addSubview:_maxImage]; + // MaxImage + _maxImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 21, 21)]; + _maxImage.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin; + [self.contentView addSubview:_maxImage]; - self.selectionStyle = UITableViewCellSelectionStyleNone; + self.selectionStyle = UITableViewCellSelectionStyleNone; } return self; } @@ -90,7 +82,6 @@ - (void)dealloc { _minImage.image = nil; _maxImage.image = nil; - [super dealloc]; } - (void)prepareForReuse { diff --git a/Classes/Utils/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.h b/Classes/Utils/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.h index 16b90ed94..8958ee26a 100755 --- a/Classes/Utils/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.h +++ b/Classes/Utils/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.h @@ -18,10 +18,8 @@ @class IASKTextField; -@interface IASKPSTextFieldSpecifierViewCell : UITableViewCell { - IASKTextField *_textField; -} +@interface IASKPSTextFieldSpecifierViewCell : UITableViewCell -@property (nonatomic, assign) IASKTextField *textField; +@property(nonatomic, strong) IASKTextField *textField; @end diff --git a/Classes/Utils/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.m b/Classes/Utils/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.m index e2db77660..f7cb92aba 100755 --- a/Classes/Utils/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.m +++ b/Classes/Utils/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.m @@ -29,11 +29,10 @@ self.textLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin; // TextField - _textField = [[[IASKTextField alloc] initWithFrame:CGRectMake(0, 0, 200, 21)] autorelease]; - _textField.autoresizingMask = UIViewAutoresizingFlexibleWidth | - UIViewAutoresizingFlexibleBottomMargin | - UIViewAutoresizingFlexibleLeftMargin; - _textField.font = [UIFont systemFontOfSize:17.0f]; + _textField = [[IASKTextField alloc] initWithFrame:CGRectMake(0, 0, 200, 21)]; + _textField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin | + UIViewAutoresizingFlexibleLeftMargin; + _textField.font = [UIFont systemFontOfSize:17.0f]; _textField.minimumFontSize = kIASKMinimumFontSize; _textField.textColor = [UIColor colorWithRed:0.275 green:0.376 blue:0.522 alpha:1.000]; [self.contentView addSubview:_textField]; @@ -69,9 +68,6 @@ } -- (void)dealloc { - [super dealloc]; -} @end diff --git a/Classes/Utils/InAppSettingsKit/Views/IASKSlider.h b/Classes/Utils/InAppSettingsKit/Views/IASKSlider.h index 34c5ecbbe..ddaa5c4df 100755 --- a/Classes/Utils/InAppSettingsKit/Views/IASKSlider.h +++ b/Classes/Utils/InAppSettingsKit/Views/IASKSlider.h @@ -21,6 +21,6 @@ NSString *_key; } -@property (nonatomic, retain) NSString *key; +@property(nonatomic, strong) NSString *key; @end diff --git a/Classes/Utils/InAppSettingsKit/Views/IASKSlider.m b/Classes/Utils/InAppSettingsKit/Views/IASKSlider.m index d591ff298..3c4ca4567 100755 --- a/Classes/Utils/InAppSettingsKit/Views/IASKSlider.m +++ b/Classes/Utils/InAppSettingsKit/Views/IASKSlider.m @@ -22,9 +22,7 @@ @synthesize key=_key; - (void)dealloc { - [_key release], _key = nil; - - [super dealloc]; + _key = nil; } @end diff --git a/Classes/Utils/InAppSettingsKit/Views/IASKSwitch.h b/Classes/Utils/InAppSettingsKit/Views/IASKSwitch.h index b1439bd1c..7124c2ec8 100755 --- a/Classes/Utils/InAppSettingsKit/Views/IASKSwitch.h +++ b/Classes/Utils/InAppSettingsKit/Views/IASKSwitch.h @@ -21,6 +21,6 @@ NSString *_key; } -@property (nonatomic, retain) NSString *key; +@property(nonatomic, strong) NSString *key; @end diff --git a/Classes/Utils/InAppSettingsKit/Views/IASKSwitch.m b/Classes/Utils/InAppSettingsKit/Views/IASKSwitch.m index f32aba4d3..2a0ce5f21 100755 --- a/Classes/Utils/InAppSettingsKit/Views/IASKSwitch.m +++ b/Classes/Utils/InAppSettingsKit/Views/IASKSwitch.m @@ -22,9 +22,7 @@ @synthesize key=_key; - (void)dealloc { - [_key release], _key = nil; - - [super dealloc]; + _key = nil; } diff --git a/Classes/Utils/InAppSettingsKit/Views/IASKTextField.h b/Classes/Utils/InAppSettingsKit/Views/IASKTextField.h index 47c9be375..7fb2467d2 100755 --- a/Classes/Utils/InAppSettingsKit/Views/IASKTextField.h +++ b/Classes/Utils/InAppSettingsKit/Views/IASKTextField.h @@ -21,6 +21,6 @@ NSString *_key; } -@property (nonatomic, retain) NSString *key; +@property(nonatomic, strong) NSString *key; @end diff --git a/Classes/Utils/InAppSettingsKit/Views/IASKTextField.m b/Classes/Utils/InAppSettingsKit/Views/IASKTextField.m index 9056896f4..b4792b6b4 100755 --- a/Classes/Utils/InAppSettingsKit/Views/IASKTextField.m +++ b/Classes/Utils/InAppSettingsKit/Views/IASKTextField.m @@ -22,9 +22,7 @@ @synthesize key=_key; - (void)dealloc { - [_key release], _key = nil; - - [super dealloc]; + _key = nil; } @end diff --git a/Classes/Utils/NinePatch/NinePatch.h b/Classes/Utils/NinePatch/NinePatch.h deleted file mode 100755 index 29f638fc1..000000000 --- a/Classes/Utils/NinePatch/NinePatch.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * NinePatch.h - * NinePatch - * - * Copyright 2010 Tortuga 22, Inc. All rights reserved. - * - */ - -#import -#import - -#import "TUNinePatchProtocols.h" -#import "TUNinePatch.h" -#import "TUNinePatchCache.h" -#import "TUDebugLoggingAssistant.h" \ No newline at end of file diff --git a/Classes/Utils/NinePatch/NinePatch.xcodeproj/project.pbxproj b/Classes/Utils/NinePatch/NinePatch.xcodeproj/project.pbxproj deleted file mode 100755 index 6f7e5eca3..000000000 --- a/Classes/Utils/NinePatch/NinePatch.xcodeproj/project.pbxproj +++ /dev/null @@ -1,431 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 324A2926111CC27800CC0BF0 /* TUNinePatchCachingCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = 324A2924111CC27800CC0BF0 /* TUNinePatchCachingCategories.h */; }; - 324A2927111CC27800CC0BF0 /* TUNinePatchCachingCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 324A2925111CC27800CC0BF0 /* TUNinePatchCachingCategories.m */; }; - 324A2930111CC2CB00CC0BF0 /* TUCachingNinePatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 324A292E111CC2CB00CC0BF0 /* TUCachingNinePatch.h */; }; - 324A2931111CC2CB00CC0BF0 /* TUCachingNinePatch.m in Sources */ = {isa = PBXBuildFile; fileRef = 324A292F111CC2CB00CC0BF0 /* TUCachingNinePatch.m */; }; - 324A2940111CE12C00CC0BF0 /* TUNinePatchCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 324A293E111CE12C00CC0BF0 /* TUNinePatchCache.h */; }; - 324A2941111CE12C00CC0BF0 /* TUNinePatchCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 324A293F111CE12C00CC0BF0 /* TUNinePatchCache.m */; }; - 325B80EF11B001C300B86EA1 /* TUDebugLoggingAssistant.h in Headers */ = {isa = PBXBuildFile; fileRef = 325B80ED11B001C300B86EA1 /* TUDebugLoggingAssistant.h */; }; - 325B80F011B001C300B86EA1 /* TUDebugLoggingAssistant.m in Sources */ = {isa = PBXBuildFile; fileRef = 325B80EE11B001C300B86EA1 /* TUDebugLoggingAssistant.m */; }; - 325B80F811B00C9800B86EA1 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 325B80F711B00C9800B86EA1 /* CoreFoundation.framework */; }; - 325B821F11B317E400B86EA1 /* NinePatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 325B821E11B317E400B86EA1 /* NinePatch.h */; }; - 32BBFEFF10E95B5700F57FBC /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32BBFEFE10E95B5700F57FBC /* CoreGraphics.framework */; }; - 32BBFF0610E95B6E00F57FBC /* TUNinePatchProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 32BBFF0510E95B6E00F57FBC /* TUNinePatchProtocols.h */; }; - 32BBFF2710E95BCF00F57FBC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32BBFF2610E95BCF00F57FBC /* UIKit.framework */; }; - 32BBFF2C10E95BF900F57FBC /* TUNinePatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 32BBFF2A10E95BF900F57FBC /* TUNinePatch.h */; }; - 32BBFF2D10E95BF900F57FBC /* TUNinePatch.m in Sources */ = {isa = PBXBuildFile; fileRef = 32BBFF2B10E95BF900F57FBC /* TUNinePatch.m */; }; - 32BBFF3510E95CA700F57FBC /* TUHorizontalNinePatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 32BBFF3310E95CA700F57FBC /* TUHorizontalNinePatch.h */; }; - 32BBFF3610E95CA700F57FBC /* TUHorizontalNinePatch.m in Sources */ = {isa = PBXBuildFile; fileRef = 32BBFF3410E95CA700F57FBC /* TUHorizontalNinePatch.m */; }; - 32BBFF3910E95CD600F57FBC /* TUVerticalNinePatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 32BBFF3710E95CD600F57FBC /* TUVerticalNinePatch.h */; }; - 32BBFF3A10E95CD600F57FBC /* TUVerticalNinePatch.m in Sources */ = {isa = PBXBuildFile; fileRef = 32BBFF3810E95CD600F57FBC /* TUVerticalNinePatch.m */; }; - 32BBFF3D10E95D3800F57FBC /* TUFullNinePatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 32BBFF3B10E95D3800F57FBC /* TUFullNinePatch.h */; }; - 32BBFF3E10E95D3800F57FBC /* TUFullNinePatch.m in Sources */ = {isa = PBXBuildFile; fileRef = 32BBFF3C10E95D3800F57FBC /* TUFullNinePatch.m */; }; - 32BBFF4310E9605300F57FBC /* UIImage-TUNinePatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 32BBFF4110E9605300F57FBC /* UIImage-TUNinePatch.h */; }; - 32BBFF4410E9605300F57FBC /* UIImage-TUNinePatch.m in Sources */ = {isa = PBXBuildFile; fileRef = 32BBFF4210E9605300F57FBC /* UIImage-TUNinePatch.m */; }; - AA747D9F0F9514B9006C5449 /* NinePatch_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* NinePatch_Prefix.pch */; }; - AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 324A2924111CC27800CC0BF0 /* TUNinePatchCachingCategories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUNinePatchCachingCategories.h; sourceTree = ""; }; - 324A2925111CC27800CC0BF0 /* TUNinePatchCachingCategories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TUNinePatchCachingCategories.m; sourceTree = ""; }; - 324A292E111CC2CB00CC0BF0 /* TUCachingNinePatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUCachingNinePatch.h; sourceTree = ""; }; - 324A292F111CC2CB00CC0BF0 /* TUCachingNinePatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TUCachingNinePatch.m; sourceTree = ""; }; - 324A293E111CE12C00CC0BF0 /* TUNinePatchCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUNinePatchCache.h; sourceTree = ""; }; - 324A293F111CE12C00CC0BF0 /* TUNinePatchCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TUNinePatchCache.m; sourceTree = ""; }; - 325B80ED11B001C300B86EA1 /* TUDebugLoggingAssistant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUDebugLoggingAssistant.h; sourceTree = ""; }; - 325B80EE11B001C300B86EA1 /* TUDebugLoggingAssistant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TUDebugLoggingAssistant.m; sourceTree = ""; }; - 325B80F711B00C9800B86EA1 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; - 325B821E11B317E400B86EA1 /* NinePatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NinePatch.h; sourceTree = ""; }; - 32BBFEFE10E95B5700F57FBC /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - 32BBFF0510E95B6E00F57FBC /* TUNinePatchProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUNinePatchProtocols.h; sourceTree = ""; }; - 32BBFF2610E95BCF00F57FBC /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - 32BBFF2A10E95BF900F57FBC /* TUNinePatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUNinePatch.h; sourceTree = ""; }; - 32BBFF2B10E95BF900F57FBC /* TUNinePatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TUNinePatch.m; sourceTree = ""; }; - 32BBFF3310E95CA700F57FBC /* TUHorizontalNinePatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUHorizontalNinePatch.h; sourceTree = ""; }; - 32BBFF3410E95CA700F57FBC /* TUHorizontalNinePatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TUHorizontalNinePatch.m; sourceTree = ""; }; - 32BBFF3710E95CD600F57FBC /* TUVerticalNinePatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUVerticalNinePatch.h; sourceTree = ""; }; - 32BBFF3810E95CD600F57FBC /* TUVerticalNinePatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TUVerticalNinePatch.m; sourceTree = ""; }; - 32BBFF3B10E95D3800F57FBC /* TUFullNinePatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUFullNinePatch.h; sourceTree = ""; }; - 32BBFF3C10E95D3800F57FBC /* TUFullNinePatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TUFullNinePatch.m; sourceTree = ""; }; - 32BBFF4110E9605300F57FBC /* UIImage-TUNinePatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage-TUNinePatch.h"; sourceTree = ""; }; - 32BBFF4210E9605300F57FBC /* UIImage-TUNinePatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage-TUNinePatch.m"; sourceTree = ""; }; - AA747D9E0F9514B9006C5449 /* NinePatch_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NinePatch_Prefix.pch; sourceTree = SOURCE_ROOT; }; - AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - D2AAC07E0554694100DB518D /* libNinePatch.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNinePatch.a; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - D2AAC07C0554694100DB518D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */, - 32BBFEFF10E95B5700F57FBC /* CoreGraphics.framework in Frameworks */, - 32BBFF2710E95BCF00F57FBC /* UIKit.framework in Frameworks */, - 325B80F811B00C9800B86EA1 /* CoreFoundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 034768DFFF38A50411DB9C8B /* Products */ = { - isa = PBXGroup; - children = ( - D2AAC07E0554694100DB518D /* libNinePatch.a */, - ); - name = Products; - sourceTree = ""; - }; - 0867D691FE84028FC02AAC07 /* NinePatch */ = { - isa = PBXGroup; - children = ( - 08FB77AEFE84172EC02AAC07 /* Classes */, - 32C88DFF0371C24200C91783 /* Other Sources */, - 0867D69AFE84028FC02AAC07 /* Frameworks */, - 034768DFFF38A50411DB9C8B /* Products */, - 32BBFF2610E95BCF00F57FBC /* UIKit.framework */, - 325B80F711B00C9800B86EA1 /* CoreFoundation.framework */, - 325B821E11B317E400B86EA1 /* NinePatch.h */, - ); - name = NinePatch; - sourceTree = ""; - }; - 0867D69AFE84028FC02AAC07 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 32BBFEFE10E95B5700F57FBC /* CoreGraphics.framework */, - AACBBE490F95108600F1A2B1 /* Foundation.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 08FB77AEFE84172EC02AAC07 /* Classes */ = { - isa = PBXGroup; - children = ( - 325B80EC11B0019B00B86EA1 /* Debugging Utilities */, - 324A292C111CC2C100CC0BF0 /* Caching */, - 32BBFF4010E9604300F57FBC /* Categories */, - 32BBFF3F10E9603E00F57FBC /* NinePatch */, - ); - name = Classes; - sourceTree = ""; - }; - 324A292C111CC2C100CC0BF0 /* Caching */ = { - isa = PBXGroup; - children = ( - 324A292E111CC2CB00CC0BF0 /* TUCachingNinePatch.h */, - 324A292F111CC2CB00CC0BF0 /* TUCachingNinePatch.m */, - 324A293E111CE12C00CC0BF0 /* TUNinePatchCache.h */, - 324A293F111CE12C00CC0BF0 /* TUNinePatchCache.m */, - ); - name = Caching; - sourceTree = ""; - }; - 325B80EC11B0019B00B86EA1 /* Debugging Utilities */ = { - isa = PBXGroup; - children = ( - 325B80ED11B001C300B86EA1 /* TUDebugLoggingAssistant.h */, - 325B80EE11B001C300B86EA1 /* TUDebugLoggingAssistant.m */, - ); - name = "Debugging Utilities"; - sourceTree = ""; - }; - 32BBFF3F10E9603E00F57FBC /* NinePatch */ = { - isa = PBXGroup; - children = ( - 32BBFF0510E95B6E00F57FBC /* TUNinePatchProtocols.h */, - 32BBFF2A10E95BF900F57FBC /* TUNinePatch.h */, - 32BBFF2B10E95BF900F57FBC /* TUNinePatch.m */, - 32BBFF3310E95CA700F57FBC /* TUHorizontalNinePatch.h */, - 32BBFF3410E95CA700F57FBC /* TUHorizontalNinePatch.m */, - 32BBFF3710E95CD600F57FBC /* TUVerticalNinePatch.h */, - 32BBFF3810E95CD600F57FBC /* TUVerticalNinePatch.m */, - 32BBFF3B10E95D3800F57FBC /* TUFullNinePatch.h */, - 32BBFF3C10E95D3800F57FBC /* TUFullNinePatch.m */, - ); - name = NinePatch; - sourceTree = ""; - }; - 32BBFF4010E9604300F57FBC /* Categories */ = { - isa = PBXGroup; - children = ( - 32BBFF4110E9605300F57FBC /* UIImage-TUNinePatch.h */, - 32BBFF4210E9605300F57FBC /* UIImage-TUNinePatch.m */, - 324A2924111CC27800CC0BF0 /* TUNinePatchCachingCategories.h */, - 324A2925111CC27800CC0BF0 /* TUNinePatchCachingCategories.m */, - ); - name = Categories; - sourceTree = ""; - }; - 32C88DFF0371C24200C91783 /* Other Sources */ = { - isa = PBXGroup; - children = ( - AA747D9E0F9514B9006C5449 /* NinePatch_Prefix.pch */, - ); - name = "Other Sources"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - D2AAC07A0554694100DB518D /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - AA747D9F0F9514B9006C5449 /* NinePatch_Prefix.pch in Headers */, - 32BBFF0610E95B6E00F57FBC /* TUNinePatchProtocols.h in Headers */, - 32BBFF2C10E95BF900F57FBC /* TUNinePatch.h in Headers */, - 32BBFF3510E95CA700F57FBC /* TUHorizontalNinePatch.h in Headers */, - 32BBFF3910E95CD600F57FBC /* TUVerticalNinePatch.h in Headers */, - 32BBFF3D10E95D3800F57FBC /* TUFullNinePatch.h in Headers */, - 32BBFF4310E9605300F57FBC /* UIImage-TUNinePatch.h in Headers */, - 324A2926111CC27800CC0BF0 /* TUNinePatchCachingCategories.h in Headers */, - 324A2930111CC2CB00CC0BF0 /* TUCachingNinePatch.h in Headers */, - 324A2940111CE12C00CC0BF0 /* TUNinePatchCache.h in Headers */, - 325B80EF11B001C300B86EA1 /* TUDebugLoggingAssistant.h in Headers */, - 325B821F11B317E400B86EA1 /* NinePatch.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - D2AAC07D0554694100DB518D /* NinePatch */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "NinePatch" */; - buildPhases = ( - D2AAC07A0554694100DB518D /* Headers */, - D2AAC07B0554694100DB518D /* Sources */, - D2AAC07C0554694100DB518D /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = NinePatch; - productName = NinePatch; - productReference = D2AAC07E0554694100DB518D /* libNinePatch.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 0867D690FE84028FC02AAC07 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0610; - }; - buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "NinePatch" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 0867D691FE84028FC02AAC07 /* NinePatch */; - productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - D2AAC07D0554694100DB518D /* NinePatch */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - D2AAC07B0554694100DB518D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 32BBFF2D10E95BF900F57FBC /* TUNinePatch.m in Sources */, - 32BBFF3610E95CA700F57FBC /* TUHorizontalNinePatch.m in Sources */, - 32BBFF3A10E95CD600F57FBC /* TUVerticalNinePatch.m in Sources */, - 32BBFF3E10E95D3800F57FBC /* TUFullNinePatch.m in Sources */, - 32BBFF4410E9605300F57FBC /* UIImage-TUNinePatch.m in Sources */, - 324A2927111CC27800CC0BF0 /* TUNinePatchCachingCategories.m in Sources */, - 324A2931111CC2CB00CC0BF0 /* TUCachingNinePatch.m in Sources */, - 324A2941111CE12C00CC0BF0 /* TUNinePatchCache.m in Sources */, - 325B80F011B001C300B86EA1 /* TUDebugLoggingAssistant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 1DEB921F08733DC00010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = NinePatch_Prefix.pch; - GCC_THUMB_SUPPORT = NO; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; - ONLY_ACTIVE_ARCH = NO; - PRODUCT_NAME = NinePatch; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 1DEB922008733DC00010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = s; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = NinePatch_Prefix.pch; - GCC_THUMB_SUPPORT = NO; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; - PRODUCT_NAME = NinePatch; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 1DEB922308733DC00010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "Don't Code Sign"; - GCC_C_LANGUAGE_STANDARD = c99; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_THUMB_SUPPORT = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = "-ObjC"; - PROVISIONING_PROFILE = ""; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 1DEB922408733DC00010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "Don't Code Sign"; - GCC_C_LANGUAGE_STANDARD = c99; - GCC_THUMB_SUPPORT = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = NO; - OTHER_LDFLAGS = "-ObjC"; - PROVISIONING_PROFILE = ""; - SDKROOT = iphoneos; - }; - name = Release; - }; - D3D14E7E15A72BD10074A527 /* Distribution */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "Don't Code Sign"; - GCC_C_LANGUAGE_STANDARD = c99; - GCC_THUMB_SUPPORT = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = NO; - OTHER_LDFLAGS = "-ObjC"; - PROVISIONING_PROFILE = ""; - SDKROOT = iphoneos; - }; - name = Distribution; - }; - D3D14E7F15A72BD10074A527 /* Distribution */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = s; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = NinePatch_Prefix.pch; - GCC_THUMB_SUPPORT = NO; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; - PRODUCT_NAME = NinePatch; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Distribution; - }; - D3D14E8015A72BD70074A527 /* DistributionAdhoc */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "Don't Code Sign"; - GCC_C_LANGUAGE_STANDARD = c99; - GCC_THUMB_SUPPORT = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = NO; - OTHER_LDFLAGS = "-ObjC"; - PROVISIONING_PROFILE = ""; - SDKROOT = iphoneos; - }; - name = DistributionAdhoc; - }; - D3D14E8115A72BD70074A527 /* DistributionAdhoc */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = s; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = NinePatch_Prefix.pch; - GCC_THUMB_SUPPORT = NO; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; - PRODUCT_NAME = NinePatch; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = DistributionAdhoc; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "NinePatch" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB921F08733DC00010E9CD /* Debug */, - 1DEB922008733DC00010E9CD /* Release */, - D3D14E7F15A72BD10074A527 /* Distribution */, - D3D14E8115A72BD70074A527 /* DistributionAdhoc */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "NinePatch" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB922308733DC00010E9CD /* Debug */, - 1DEB922408733DC00010E9CD /* Release */, - D3D14E7E15A72BD10074A527 /* Distribution */, - D3D14E8015A72BD70074A527 /* DistributionAdhoc */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 0867D690FE84028FC02AAC07 /* Project object */; -} diff --git a/Classes/Utils/NinePatch/NinePatch_Prefix.pch b/Classes/Utils/NinePatch/NinePatch_Prefix.pch deleted file mode 100755 index 2b1046d32..000000000 --- a/Classes/Utils/NinePatch/NinePatch_Prefix.pch +++ /dev/null @@ -1,157 +0,0 @@ -// -// Prefix header for all source files of the 'CocoaTouchStaticLibrary' target in the 'CocoaTouchStaticLibrary' project. -// - -#ifdef __OBJC__ - #import -#endif -/** - This struct is used for doing pixel-tasting. We get CoreGraphics to create a bitmap context wherein the memory representation looks like this struct, then we cast the pointer to that memory to be of this struct's type. Pretty self-explanatory. - */ -typedef struct _TURGBAPixel { - UInt8 red; - UInt8 green; - UInt8 blue; - UInt8 alpha; -} TURGBAPixel; - -/** - Defined here, used as part of the pixel-tasting code. Helps make sure the memory representation of the bitmap context is made up of stuff that looks just like TURGBAPixel. - */ -#define TURGBABytesPerPixel (4) - -/** - This tests if a pixel is black. Here "black" means alpha isn't at zero (AKA: it's at least partially opaque) and r == g == b == 0. - */ -#define TURGBAPixelIsBlack(PIXEL) (((PIXEL.red == 0) && (PIXEL.green == 0) && (PIXEL.blue == 0) && (PIXEL.alpha != 0))?(YES):(NO)) - -#define TUNotFoundRange (NSMakeRange(NSNotFound,0)) -#define TUIsNotFoundRange(RANGE) (NSEqualRanges(RANGE, TUNotFoundRange)) - -#define TUTruncateBelow(VALUE, FLOOR) ((( VALUE ) < ( FLOOR ))?(( FLOOR )):(( VALUE ))) -#define TUTruncateAbove(VALUE, CEILING) ((( VALUE ) > ( CEILING ))?(( CEILING )):(( VALUE ))) -#define TUTruncateWithin(VALUE, FLOOR, CEILING) ((( VALUE ) < ( FLOOR ))?(( FLOOR )):((( VALUE ) > ( CEILING ))?(( CEILING )):(( VALUE )))) -#define TUTruncateAtZero(VALUE) TUTruncateBelow(VALUE, 0.0f) - -#define TUForceYesOrNo(ABOOL) ((ABOOL)?(YES):(NO)) -#define TUYesOrNoString(ABOOL) ((( ABOOL ))?(@"YES"):(@"NO")) - -#define TUWithinEpsilon(EPSILON, X, Y) TUForceYesOrNo((((X-Y) > (-1.0f * EPSILON)) || ((X-Y) < EPSILON))) - -//#define DEBUG -//#define NP_ASSERTION_CHECKING -//#define IMAGEDEBUG - -// DLog is almost a drop-in replacement for NSLog -// DLog(); -// DLog(@"here"); -// DLog(@"value: %d", x); -// Unfortunately this doesn't work DLog(aStringVariable); you have to do this instead DLog(@"%@", aStringVariable); -#ifdef DEBUG -#define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); -#else -#define DLog(...) -#endif - -// ALog always displays output regardless of the DEBUG setting -#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); - -#define LLog(STR) DLog(@"%@",STR) - -#define NPLogException(E) DLog(@"Caught '%@' < '%@', '%@' >.",[E name],[E reason],[E userInfo]) -#define NPLogError(E) DLog(@"Error: '%@', '%@', '%@'.",[E localizedDescription],[E localizedFailureReason],[E localizedRecoveryOptions]); - -#ifdef NP_ASSERTION_CHECKING -#define NPLogExceptionRethrowIfAssertionFailure(E) { \ -NPLogException(E); \ -if (E && [[E name] isEqualToString:NSInternalInconsistencyException]) { \ - @throw E; \ -}} -#else -#define NPLogExceptionRethrowIfAssertionFailure(E) NPLogException(E) -#endif - -#ifdef NP_OUTPUT_LOGGING -#define NPFOutputLog(AFLOAT) DLog(@"returning %s: '%f'.",#AFLOAT,AFLOAT) -#define NPDOutputLog(ANINT) DLog(@"returning %s: '%d'.",#ANINT,ANINT) -#define NPOOutputLog(ANOBJ) DLog(@"returning %s: '%@'.",#ANOBJ,ANOBJ) -#define NPBOutputLog(ABOOL) DLog(@"returning %s: '%@'.",#ABOOL,TUYesOrNoString(ABOOL)) -#define NPCGROutputLog(ARECT) DLog(@"returning %s: '%@'.",#ARECT,NSStringFromCGRect(ARECT)) -#define NPCGSOutputLog(ASIZE) DLog(@"returning %s: '%@'.",#ASIZE,NSStringFromCGSize(ASIZE)) -#define NPCGPOutputLog(APOINT) DLog(@"returning %s: '%@'.",#APOINT,NSStringFromCGPoint(APOINT)) -#define NPNSROutputLog(ARANGE) DLog(@"returning %s: '%@'.",#ARANGE,NSStringFromRange(ARANGE)) -#else -#define NPFOutputLog(...) -#define NPDOutputLog(...) -#define NPOOutputLog(...) -#define NPBOutputLog(...) -#define NPCGROutputLog(...) -#define NPCGSOutputLog(...) -#define NPCGPOutputLog(...) -#define NPNSROutputLog(...) -#endif - -#ifdef NP_INPUT_LOGGING -#define NPAInputLog(...) DLog(##__VA_ARGS__) -// convenience input loggers for single-argument messages -#define NPAFInputLog(AFLOAT) DLog(@"%s: '%f'",#AFLOAT,AFLOAT) -#define NPADInputLog(ANINT) DLog(@"%s: '%d'",#ANINT,ANINT) -#define NPAOInputLog(ANOBJ) DLog(@"%s: '%@'",#ANOBJ,ANOBJ) -#define NPABInputLog(ABOOL) DLog(@"%s: '%@'",#ABOOL,TUYesOrNoString(ABOOL)) -#else -#define NPAInputLog(...) -#define NPAFInputLog(AFLOAT) -#define NPADInputLog(ANINT) -#define NPAOInputLog(ANOBJ) -#define NPABInputLog(ABOOL) -#endif - - -#ifdef NP_ASSERTION_CHECKING -#define NPParameterAssert(COND) NSParameterAssert(COND) -#define NPCParameterAssert(COND) NSCParameterAssert(COND) -#define NPAssert(COND,DESC) NSAssert(COND,DESC) -#define NPCAssert(COND,DESC) NSCAssert(COND,DESC) -#else -#define NPParameterAssert(...) -#define NPCParameterAssert(...) -#define NPAssert(...) -#define NPCAssert(...) -#endif - -#define STRINGIFY2( x) #x -#define STRINGIFY(x) STRINGIFY2(x) -#define PASTE2( a, b) a##b -#define PASTE( a, b) PASTE2( a, b) -#define PASSTHROUGH(X) X - -#define NPOBJCStringOfToken(TOKEN) PASSTHROUGH(PASTE( PASSTHROUGH(@), PASSTHROUGH(STRINGIFY(TOKEN)))) - -#define NPSelfProperty(PROP) -//#define NPSelfProperty(PROP) (self.PROP) -//#define NPSelfProperty(PROP) ([self PROP]) - -#define NPAssertPropertyNonNil(PROP) NPAssert((NPSelfProperty(PROP) != nil), ([NSString stringWithFormat:@"self.%s should never be nil.",( (#PROP) )])) - -#define NPParameterAssertNotNilConformsToProtocol(OBJ,PROT) NPParameterAssert((OBJ != nil) && ([OBJ conformsToProtocol:@protocol(PROT)])) -#define NPParameterAssertNotNilIsKindOfClass(OBJ,CLASS) NPParameterAssert((OBJ != nil) && ([OBJ isKindOfClass:[CLASS class]])) - -#define NPAssertNilOrConformsToProtocol(OBJ,PROT) NPAssert(((OBJ == nil) || ((OBJ != nil) && [OBJ conformsToProtocol:@protocol(PROT)])),([NSString stringWithFormat:@"Variable %s must either be nil or conform to %s protocol.", ( (#OBJ) ), ( (#PROT) )])) -#define NPAssertNilOrIsKindOfClass(OBJ,CLASS) NPAssert(((OBJ == nil) || ((OBJ != nil) && [OBJ isKindOfClass:[CLASS class]])), ([NSString stringWithFormat:@"Variable %s must either be nil or be kind of %s class.", (#OBJ), (#CLASS)])) - -#define NPAssertWithinEpsilon(EPSILON,X,Y) NPAssert( (((X-Y) > (-1.0f * EPSILON)) || ((X-Y) < EPSILON)),([NSString stringWithFormat:@"Should have (%s,%s) within %f but instead (%f,%f).",#X,#Y,EPSILON,X,Y])) -#define NPAssertWithinOne(X,Y) NPAssertWithinEpsilon(1.0f,X,Y) - -#define NPAssertThreeSubSizesSumCorrectlyOnOneAxis(AXIS,MASTERSIZE,SIZE_ONE,SIZE_TWO,SIZE_THREE) NPAssertWithinOne(MASTERSIZE.AXIS,( SIZE_ONE.AXIS + SIZE_TWO.AXIS + SIZE_THREE.AXIS )) -#define NPAssertCorrectSubsizeWidthDecomposition(MASTER,SIZE_ONE,SIZE_TWO,SIZE_THREE) NPAssertThreeSubSizesSumCorrectlyOnOneAxis(width, MASTER, SIZE_ONE, SIZE_TWO, SIZE_THREE) -#define NPAssertCorrectSubsizeHeightDecomposition(MASTER,SIZE_ONE,SIZE_TWO,SIZE_THREE) NPAssertThreeSubSizesSumCorrectlyOnOneAxis(height, MASTER, SIZE_ONE, SIZE_TWO, SIZE_THREE) - -#define NPAssertCorrectSubimageWidthDecomposition(MASTER,IMAGE_ONE,IMAGE_TWO,IMAGE_THREE) NPAssertCorrectSubsizeWidthDecomposition([MASTER size],[IMAGE_ONE size],[IMAGE_TWO size],[IMAGE_THREE size]) -#define NPAssertCorrectSubimageHeightDecomposition(MASTER,IMAGE_ONE,IMAGE_TWO,IMAGE_THREE) NPAssertCorrectSubsizeWidthDecomposition([MASTER size],[IMAGE_ONE size],[IMAGE_TWO size],[IMAGE_THREE size]) - -#ifdef IMAGEDEBUG -#define IMLog(IMAGE, IMAGENAME) TUImageLog(IMAGE,[[NSString stringWithFormat:@"debugImage.%.0f.%u.",[NSDate timeIntervalSinceReferenceDate],((NSUInteger) rand())] stringByAppendingString:( IMAGENAME )]) -#else -#define IMLog(IMAGE, IMAGENAME) -#endif - diff --git a/Classes/Utils/NinePatch/TUCachingNinePatch.h b/Classes/Utils/NinePatch/TUCachingNinePatch.h deleted file mode 100755 index 6d1a1a99d..000000000 --- a/Classes/Utils/NinePatch/TUCachingNinePatch.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// TUCachingNinePatch.h -// NinePatch -// -// Copyright 2010 Tortuga 22, Inc. All rights reserved. -// - -#import -#import -#import "TUNinePatchProtocols.h" - -@interface TUCachingNinePatch : NSObject < NSCoding, NSCopying > { - id < TUNinePatch > _ninePatch; - NSMutableDictionary *_ninePatchImageCache; -} - -// Synthesized Properties -@property(nonatomic, retain, readonly) id < TUNinePatch > ninePatch; -@property(nonatomic, retain, readonly) NSMutableDictionary *ninePatchImageCache; - -// Init + Dealloc --(id)initWithNinePatchNamed:(NSString *)ninePatchName; --(id)initWithNinePatch:(id < TUNinePatch >)ninePatch; -+(id)ninePatchCacheWithNinePatchNamed:(NSString *)ninePatchName; -+(id)ninePatchCacheWithNinePatch:(id < TUNinePatch >)ninePatch; --(void)dealloc; - -// NSCoding --(id)initWithCoder:(NSCoder *)aDecoder; --(void)encodeWithCoder:(NSCoder *)anEncoder; - -// NSCopying --(id)copyWithZone:(NSZone *)zone; - -// Nib --(void)awakeFromNib; - -// Cache Management --(void)flushCachedImages; - -// Image Access - Utility Accessors --(UIImage *)imageOfSize:(CGSize)size; - -// Cache Access --(void)cacheImage:(UIImage *)image ofSize:(CGSize)size; --(UIImage *)cachedImageOfSize:(CGSize)size; - -// Image Construction --(UIImage *)constructImageOfSize:(CGSize)size; - -@end diff --git a/Classes/Utils/NinePatch/TUCachingNinePatch.m b/Classes/Utils/NinePatch/TUCachingNinePatch.m deleted file mode 100755 index 34c3bef3d..000000000 --- a/Classes/Utils/NinePatch/TUCachingNinePatch.m +++ /dev/null @@ -1,125 +0,0 @@ -// -// TUCachingNinePatch.m -// NinePatch -// -// Copyright 2010 Tortuga 22, Inc. All rights reserved. -// - -#import "TUCachingNinePatch.h" -#import "TUNinePatch.h" -#import "TUNinePatchCachingCategories.h" - -@interface TUCachingNinePatch () - -// Synthesized Properties -@property(nonatomic, retain, readwrite) id < TUNinePatch > ninePatch; -@property(nonatomic, retain, readwrite) NSMutableDictionary *ninePatchImageCache; - -@end - - -@implementation TUCachingNinePatch - -#pragma mark Synthesized Properties -@synthesize ninePatch = _ninePatch; -@synthesize ninePatchImageCache = _ninePatchImageCache; - -#pragma mark Init + Dealloc --(id)initWithNinePatchNamed:(NSString *)ninePatchName { - return [self initWithNinePatch:[TUNinePatch ninePatchNamed:ninePatchName]]; -} - --(id)initWithNinePatch:(id < TUNinePatch >)ninePatch { - if (self = [super init]) { - self.ninePatch = ninePatch; - self.ninePatchImageCache = [NSMutableDictionary dictionaryWithCapacity:5]; - } - return self; -} - -#pragma mark - -+(id)ninePatchCacheWithNinePatchNamed:(NSString *)ninePatchName { - return [[[self alloc] initWithNinePatchNamed:ninePatchName] autorelease]; -} - -+(id)ninePatchCacheWithNinePatch:(id < TUNinePatch >)ninePatch { - return [[[self alloc] initWithNinePatch:ninePatch] autorelease]; -} - -#pragma mark - --(void)dealloc { - self.ninePatch = nil; - self.ninePatchImageCache = nil; - [super dealloc]; -} - -#pragma mark NSCoding --(id)initWithCoder:(NSCoder *)aDecoder { - NSParameterAssert(aDecoder != nil); - if (self = [super init]) { - self.ninePatch = [aDecoder decodeObjectForKey:@"ninePatch"]; - self.ninePatchImageCache = [aDecoder decodeObjectForKey:@"ninePatchImageCache"]; - } - return self; -} - --(void)encodeWithCoder:(NSCoder *)anEncoder { - NSParameterAssert(anEncoder != nil); - [anEncoder encodeObject:self.ninePatch - forKey:@"ninePatch"]; - [anEncoder encodeObject:self.ninePatchImageCache - forKey:@"ninePatchImageCache"]; -} - -#pragma mark NSCopying --(id)copyWithZone:(NSZone *)zone { - return [[[self class] alloc] initWithNinePatch:self.ninePatch]; -} - -#pragma mark Nib --(void)awakeFromNib { - [super awakeFromNib]; - if (!self.ninePatchImageCache) { - self.ninePatchImageCache = [NSMutableDictionary dictionaryWithCapacity:5]; - }; -} - -#pragma mark Cache Management --(void)flushCachedImages { - NPAssertPropertyNonNil(ninePatchImageCache); - [self.ninePatchImageCache removeAllObjects]; -} - -#pragma mark Image Access - Utility Accessors --(UIImage *)imageOfSize:(CGSize)size { - UIImage *imageOfSize = [self cachedImageOfSize:size]; - if (!imageOfSize) { - imageOfSize = [self constructImageOfSize:size]; - if (imageOfSize) { - [self cacheImage:imageOfSize - ofSize:size]; - } - } - return imageOfSize; -} - -#pragma mark Cache Access --(void)cacheImage:(UIImage *)image ofSize:(CGSize)size { - NPParameterAssertNotNilIsKindOfClass(image,UIImage); - NPAssertPropertyNonNil(self.ninePatchImageCache); - return [self.ninePatchImageCache setObject:image - forSize:size]; -} - --(UIImage *)cachedImageOfSize:(CGSize)size { - NPAssertPropertyNonNil(ninePatchImageCache); - return [self.ninePatchImageCache objectForSize:size]; -} - -#pragma mark Image Construction --(UIImage *)constructImageOfSize:(CGSize)size { - NPAssertPropertyNonNil(ninePatch); - return (!self.ninePatch)?(nil):([self.ninePatch imageOfSize:size]); -} - -@end diff --git a/Classes/Utils/NinePatch/TUDebugLoggingAssistant.h b/Classes/Utils/NinePatch/TUDebugLoggingAssistant.h deleted file mode 100755 index 7c6f04f68..000000000 --- a/Classes/Utils/NinePatch/TUDebugLoggingAssistant.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// TUDebugLoggingAssistant.h -// NinePatch -// -// Copyright 2010 Tortuga 22, Inc. All rights reserved. -// - -#import -#import - - -@interface TUDebugLoggingAssistant : NSObject { - NSString *_sessionIdentifier; - NSMutableSet *_activatedLoggingTags; -} - -// Synthesized Properties -@property(nonatomic, retain, readonly) NSString *sessionIdentifier; -@property(nonatomic, retain, readonly) NSMutableSet *activatedLoggingTags; - -// Init + Dealloc --(id)init; --(void)dealloc; - -// Managing Logging --(void)startLoggingTag:(NSString *)loggingTag; --(void)stopLoggingTag:(NSString *)loggingTag; --(void)startLoggingTags:(NSString *)loggingTag,...; --(void)stopLoggingTags:(NSString *)loggingTag,...; --(void)startLoggingTagsFromArray:(NSArray *)loggingTags; --(void)stopLoggingTagsFromArray:(NSArray *)loggingTags; - -// Formatting --(NSString *)formattedImageLogFilenameForTimestamp:(NSTimeInterval)timestamp specifiedFileName:(NSString *)specifiedFileName; - -// Log-Checking --(BOOL)shouldLogLineWithTag:(NSString *)tag; - -// Singleton Access -+(id)shared; - -// Managing Logging -+(void)startLoggingTag:(NSString *)loggingTag; -+(void)stopLoggingTag:(NSString *)loggingTag; -+(void)startLoggingTags:(NSString *)loggingTag,...; -+(void)stopLoggingTags:(NSString *)loggingTag,...; -+(void)startLoggingTagsFromArray:(NSArray *)loggingTags; -+(void)stopLoggingTagsFromArray:(NSArray *)loggingTags; - -// Formatting -+(NSString *)formattedImageLogFilenameForTimestamp:(NSTimeInterval)timestamp specifiedFileName:(NSString *)specifiedFileName; - -// Log-Checking -+(BOOL)shouldLogLineWithTag:(NSString *)tag; - -@end diff --git a/Classes/Utils/NinePatch/TUDebugLoggingAssistant.m b/Classes/Utils/NinePatch/TUDebugLoggingAssistant.m deleted file mode 100755 index 94e12afcc..000000000 --- a/Classes/Utils/NinePatch/TUDebugLoggingAssistant.m +++ /dev/null @@ -1,362 +0,0 @@ -// -// TUDebugLoggingAssistant.m -// NinePatch -// -// Copyright 2010 Tortuga 22, Inc. All rights reserved. -// - -#import "TUDebugLoggingAssistant.h" - -@interface TUDebugLoggingAssistant () - -@property(nonatomic, retain, readwrite) NSString *sessionIdentifier; -@property(nonatomic, retain, readwrite) NSMutableSet *activatedLoggingTags; - -@end - - -@implementation TUDebugLoggingAssistant - -#pragma mark Synthesized Properties -@synthesize sessionIdentifier = _sessionIdentifier; -@synthesize activatedLoggingTags = _activatedLoggingTags; - -#pragma mark Init + Dealloc --(id)init { - if (self = [super init]) { - self.activatedLoggingTags = [NSMutableSet set]; - NSString *uuidString = @"UUID_ERROR_ENCOUNTERED"; - @try { - CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault); - if (uuid) { - @try { - uuidString = ((NSString *) CFUUIDCreateString(kCFAllocatorDefault, uuid)); - } - @catch (NSException * e) { - NPLogException(e); - if (uuidString) { - @try { - CFRelease(uuidString); - } - @catch (NSException * ee) { - NPLogException(ee); - } - @finally { - uuidString = @"UUID_ERROR_ENCOUNTERED"; - } - } - } - @finally { - @try { - CFRelease(uuid); - } - @catch (NSException * e) { - NPLogException(e); - } - } - } - } - @catch (NSException * e) { - NPLogException(e); - } - @finally { - if (uuidString) { - self.sessionIdentifier = uuidString; - [self.sessionIdentifier release]; // drops retain count back to 1 - } - } - } - return self; -} - -#pragma mark - --(void)dealloc { - self.sessionIdentifier = nil; - self.activatedLoggingTags = nil; - [super dealloc]; -} - -#pragma mark Managing Logging --(void)startLoggingTag:(NSString *)loggingTag { - NPAOInputLog(loggingTag); - NPParameterAssertNotNilIsKindOfClass(loggingTag,NSString); - NPAssertPropertyNonNil(activatedLoggingTags); - if (loggingTag) { - @try { - [self.activatedLoggingTags addObject:loggingTag]; - } - @catch (NSException * e) { - NPLogException(e); - } - } -} - --(void)stopLoggingTag:(NSString *)loggingTag { - NPAOInputLog(loggingTag); - NPParameterAssertNotNilIsKindOfClass(loggingTag,NSString); - NPAssertPropertyNonNil(activatedLoggingTags); - if (loggingTag) { - @try { - [self.activatedLoggingTags removeObject:loggingTag]; - } - @catch (NSException * e) { - NPLogException(e); - } - } -} - --(void)startLoggingTags:(NSString *)loggingTag,... { - id eachObject; - va_list argumentList; - if (loggingTag) { - NSMutableArray *workingArray = [NSMutableArray arrayWithObject:loggingTag]; - va_start(argumentList, loggingTag); - @try { - while ((eachObject = va_arg(argumentList, id))) { - @try { - [workingArray addObject:eachObject]; - } - @catch (NSException * e) { - NPLogException(e); - } - } - } - @catch (NSException * e) { - NPLogException(e); - } - @finally { - @try { - va_end(argumentList); - } - @catch (NSException * e) { - NPLogException(e); - } - @finally { - if (workingArray) { - [self startLoggingTagsFromArray:workingArray]; - } - } - } - } -} - --(void)stopLoggingTags:(NSString *)loggingTag,... { - id eachObject; - va_list argumentList; - if (loggingTag) { - NSMutableArray *workingArray = [NSMutableArray arrayWithObject:loggingTag]; - va_start(argumentList, loggingTag); - @try { - while ((eachObject = va_arg(argumentList, id))) { - @try { - [workingArray addObject:eachObject]; - } - @catch (NSException * e) { - NPLogException(e); - } - } - } - @catch (NSException * e) { - NPLogException(e); - } - @finally { - @try { - va_end(argumentList); - } - @catch (NSException * e) { - NPLogException(e); - } - @finally { - if (workingArray) { - [self stopLoggingTagsFromArray:workingArray]; - } - } - } - } -} - --(void)startLoggingTagsFromArray:(NSArray *)loggingTags { - NPAOInputLog(loggingTags); - NPParameterAssertNotNilIsKindOfClass(loggingTags,NSArray); - NPAssertPropertyNonNil(activatedLoggingTags); - if (loggingTags) { - // N.B.: we're not shooting for speed here - // b/c if you're even instantiating an instance of this - // class it means you're in a debug frenzy and have other - // issues. - // - // So here we break out the for loop and insert objects - // individually so that the asserts in the [self startLoggingTag:tag] - // will get noticed if you're smuggling non-string logging tags in - // by passing them in as part of an array. - // - // No point having type-induced errors in your debugging assistant. - for (NSString *loggingTag in loggingTags) { - [self startLoggingTag:loggingTag]; - } - } -} - --(void)stopLoggingTagsFromArray:(NSArray *)loggingTags { - NPAOInputLog(loggingTags); - NPParameterAssertNotNilIsKindOfClass(loggingTags,NSArray); - NPAssertPropertyNonNil(activatedLoggingTags); - if (loggingTags) { - // CF comment in startLoggingTagsFromArray - // for some context here - for (NSString *loggingTag in loggingTags) { - [self stopLoggingTag:loggingTag]; - } - } -} - -#pragma mark Formatting --(NSString *)formattedImageLogFilenameForTimestamp:(NSTimeInterval)timestamp specifiedFileName:(NSString *)specifiedFileName { - NPAInputLog(@"formattedImageLogFilenameForTimestamp:'%f' specifiedFileName:'%@'",timestamp,specifiedFileName); - NPParameterAssertNotNilIsKindOfClass(specifiedFileName,NSString); - NPAssertPropertyNonNil(sessionIdentifier); - NSString *outString = nil; - @try { - if (specifiedFileName) { - outString = [NSString stringWithFormat:@"%@_%@_%.0f.png",self.sessionIdentifier,specifiedFileName,timestamp]; - } else { - outString = [NSString stringWithFormat:@"%@_%.0f.png",self.sessionIdentifier,timestamp]; - } - } - @catch (NSException * e) { - NPLogException(e); - } - NPOOutputLog(outString); - return outString; -} - -#pragma mark Log-Checking --(BOOL)shouldLogLineWithTag:(NSString *)tag { - NPAInputLog(@"shouldLogLineWithTag:'%@'",tag); - NPParameterAssertNotNilIsKindOfClass(tag,NSString); - NPAssertPropertyNonNil(activatedLoggingTags); - BOOL shouldLogLineWithTag = NO; - if (tag) { - @try { - shouldLogLineWithTag = [self.activatedLoggingTags containsObject:tag]; - } - @catch (NSException * e) { - NPLogException(e); - shouldLogLineWithTag = NO; - } - } - NPBOutputLog(shouldLogLineWithTag); - return shouldLogLineWithTag; -} - -#pragma mark Singleton Access -+(id)shared { - static id shared; - if (!shared) { - shared = [[[self class] alloc] init]; - } - NPAssertNilOrIsKindOfClass(shared,TUDebugLoggingAssistant); - return shared; -} - -#pragma mark Managing Logging -+(void)startLoggingTag:(NSString *)loggingTag { - [[self shared] startLoggingTag:loggingTag]; -} - -+(void)stopLoggingTag:(NSString *)loggingTag { - [[self shared] stopLoggingTag:loggingTag]; -} - -#pragma mark - -+(void)startLoggingTags:(NSString *)loggingTag,... { - id eachObject; - va_list argumentList; - if (loggingTag) { - NSMutableArray *workingArray = [NSMutableArray arrayWithObject:loggingTag]; - va_start(argumentList, loggingTag); - @try { - while ((eachObject = va_arg(argumentList, id))) { - @try { - [workingArray addObject:eachObject]; - } - @catch (NSException * e) { - NPLogException(e); - } - } - } - @catch (NSException * e) { - NPLogException(e); - } - @finally { - @try { - va_end(argumentList); - } - @catch (NSException * e) { - NPLogException(e); - } - @finally { - if (workingArray) { - [self startLoggingTagsFromArray:workingArray]; - } - } - } - } -} - -+(void)stopLoggingTags:(NSString *)loggingTag,... { - id eachObject; - va_list argumentList; - if (loggingTag) { - NSMutableArray *workingArray = [NSMutableArray arrayWithObject:loggingTag]; - va_start(argumentList, loggingTag); - @try { - while ((eachObject = va_arg(argumentList, id))) { - @try { - [workingArray addObject:eachObject]; - } - @catch (NSException * e) { - NPLogException(e); - } - } - } - @catch (NSException * e) { - NPLogException(e); - } - @finally { - @try { - va_end(argumentList); - } - @catch (NSException * e) { - NPLogException(e); - } - @finally { - if (workingArray) { - [self stopLoggingTagsFromArray:workingArray]; - } - } - } - } -} - -#pragma mark - -+(void)startLoggingTagsFromArray:(NSArray *)loggingTags { - [[self shared] startLoggingTagsFromArray:loggingTags]; -} - -+(void)stopLoggingTagsFromArray:(NSArray *)loggingTags { - [[self shared] stopLoggingTagsFromArray:loggingTags]; -} - -#pragma mark Formatting -+(NSString *)formattedImageLogFilenameForTimestamp:(NSTimeInterval)timestamp specifiedFileName:(NSString *)specifiedFileName { - return [[self shared] formattedImageLogFilenameForTimestamp:timestamp - specifiedFileName:specifiedFileName]; -} - -#pragma mark Log-Checking -+(BOOL)shouldLogLineWithTag:(NSString *)tag { - return [[self shared] shouldLogLineWithTag:tag]; -} - -@end diff --git a/Classes/Utils/NinePatch/TUFullNinePatch.h b/Classes/Utils/NinePatch/TUFullNinePatch.h deleted file mode 100755 index 261b51ec2..000000000 --- a/Classes/Utils/NinePatch/TUFullNinePatch.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// TUFullNinePatch.h -// NinePatch -// -// Copyright 2009 Tortuga 22, Inc. All rights reserved. -// - -#import -#import - -#import "TUNinePatch.h" -#import "TUNinePatchProtocols.h" - -/** - Concrete TUNinePatch instance. Handles NinePatches that stretch horizontally and vertically. Only instantiate directly if you know what you're doing. - */ -@interface TUFullNinePatch : TUNinePatch < TUNinePatch > { - UIImage *_upperEdge; - UIImage *_lowerEdge; - UIImage *_leftEdge; - UIImage *_rightEdge; - UIImage *_upperLeftCorner; - UIImage *_lowerLeftCorner; - UIImage *_upperRightCorner; - UIImage *_lowerRightCorner; -} - -// Synthesized Properties -@property(nonatomic, retain, readonly) UIImage *upperEdge; -@property(nonatomic, retain, readonly) UIImage *lowerEdge; -@property(nonatomic, retain, readonly) UIImage *leftEdge; -@property(nonatomic, retain, readonly) UIImage *rightEdge; - -@property(nonatomic, retain, readonly) UIImage *upperLeftCorner; -@property(nonatomic, retain, readonly) UIImage *lowerLeftCorner; -@property(nonatomic, retain, readonly) UIImage *upperRightCorner; -@property(nonatomic, retain, readonly) UIImage *lowerRightCorner; - -// Init + Dealloc --(id)initWithCenter:(UIImage *)center contentRegion:(CGRect)contentRegion tileCenterVertically:(BOOL)tileCenterVertically tileCenterHorizontally:(BOOL)tileCenterHorizontally upperLeftCorner:(UIImage *)upperLeftCorner upperRightCorner:(UIImage *)upperRightCorner lowerLeftCorner:(UIImage *)lowerLeftCorner lowerRightCorner:(UIImage *)lowerRightCorner leftEdge:(UIImage *)leftEdge rightEdge:(UIImage *)rightEdge upperEdge:(UIImage *)upperEdge lowerEdge:(UIImage *)lowerEdge; --(void)dealloc; - -// Sanity-Checking Tools --(BOOL)checkSizeSanityAgainstOriginalImage:(UIImage *)originalImage; - -// TUNinePatch Overrides --(void)drawInRect:(CGRect)rect; --(CGFloat)leftEdgeWidth; --(CGFloat)rightEdgeWidth; --(CGFloat)upperEdgeHeight; --(CGFloat)lowerEdgeHeight; - -// Image Logging --(void)logExplodedImage; - -@end \ No newline at end of file diff --git a/Classes/Utils/NinePatch/TUFullNinePatch.m b/Classes/Utils/NinePatch/TUFullNinePatch.m deleted file mode 100755 index 92abc32a6..000000000 --- a/Classes/Utils/NinePatch/TUFullNinePatch.m +++ /dev/null @@ -1,318 +0,0 @@ -// -// TUFullNinePatch.m -// NinePatch -// -// Copyright 2009 Tortuga 22, Inc. All rights reserved. -// - -#import "TUFullNinePatch.h" -#import "TUNinePatchProtocols.h" -#import "UIImage-TUNinePatch.h" - -@interface TUFullNinePatch () - -// Synthesized Properties -@property(nonatomic, retain, readwrite) UIImage *upperEdge; -@property(nonatomic, retain, readwrite) UIImage *lowerEdge; -@property(nonatomic, retain, readwrite) UIImage *leftEdge; -@property(nonatomic, retain, readwrite) UIImage *rightEdge; - -@property(nonatomic, retain, readwrite) UIImage *upperLeftCorner; -@property(nonatomic, retain, readwrite) UIImage *lowerLeftCorner; -@property(nonatomic, retain, readwrite) UIImage *upperRightCorner; -@property(nonatomic, retain, readwrite) UIImage *lowerRightCorner; - -@end - - -@implementation TUFullNinePatch - -#pragma mark Synthesized Properties -@synthesize upperEdge = _upperEdge; -@synthesize lowerEdge = _lowerEdge; -@synthesize leftEdge = _leftEdge; -@synthesize rightEdge = _rightEdge; - -@synthesize upperLeftCorner = _upperLeftCorner; -@synthesize lowerLeftCorner = _lowerLeftCorner; -@synthesize upperRightCorner = _upperRightCorner; -@synthesize lowerRightCorner = _lowerRightCorner; - -#pragma mark NSCoding --(id)initWithCoder:(NSCoder *)coder { - if (self = [super initWithCoder:coder]) { - self.upperEdge = (UIImage *) [coder decodeObjectForKey:@"upperEdge"]; - self.lowerEdge = (UIImage *) [coder decodeObjectForKey:@"lowerEdge"]; - self.leftEdge = (UIImage *) [coder decodeObjectForKey:@"leftEdge"]; - self.rightEdge = (UIImage *) [coder decodeObjectForKey:@"rightEdge"]; - self.upperLeftCorner = (UIImage *) [coder decodeObjectForKey:@"upperLeftCorner"]; - self.lowerLeftCorner = (UIImage *) [coder decodeObjectForKey:@"lowerLeftCorner"]; - self.upperRightCorner = (UIImage *) [coder decodeObjectForKey:@"upperRightCorner"]; - self.lowerRightCorner = (UIImage *) [coder decodeObjectForKey:@"lowerRightCorner"]; - } - return self; -} - --(void)encodeWithCoder:(NSCoder *)coder { - [super encodeWithCoder:coder]; - - [coder encodeObject:self.upperEdge - forKey:@"upperEdge"]; - - [coder encodeObject:self.lowerEdge - forKey:@"lowerEdge"]; - - [coder encodeObject:self.leftEdge - forKey:@"leftEdge"]; - - [coder encodeObject:self.rightEdge - forKey:@"rightEdge"]; - - [coder encodeObject:self.upperLeftCorner - forKey:@"upperLeftCorner"]; - - [coder encodeObject:self.lowerLeftCorner - forKey:@"lowerLeftCorner"]; - - [coder encodeObject:self.upperRightCorner - forKey:@"upperRightCorner"]; - - [coder encodeObject:self.lowerRightCorner - forKey:@"lowerRightCorner"]; -} - -#pragma mark NSCopying --(id)copyWithZone:(NSZone *)zone { - return [[[self class] allocWithZone:zone] initWithCenter:self.center - contentRegion:self.contentRegion - tileCenterVertically:self.tileCenterVertically - tileCenterHorizontally:self.tileCenterHorizontally - upperLeftCorner:self.upperLeftCorner - upperRightCorner:self.upperRightCorner - lowerLeftCorner:self.lowerLeftCorner - lowerRightCorner:self.lowerRightCorner - leftEdge:self.leftEdge - rightEdge:self.rightEdge - upperEdge:self.upperEdge - lowerEdge:self.lowerEdge]; -} - -#pragma mark Init + Dealloc --(id)initWithCenter:(UIImage *)center contentRegion:(CGRect)contentRegion tileCenterVertically:(BOOL)tileCenterVertically tileCenterHorizontally:(BOOL)tileCenterHorizontally upperLeftCorner:(UIImage *)upperLeftCorner upperRightCorner:(UIImage *)upperRightCorner lowerLeftCorner:(UIImage *)lowerLeftCorner lowerRightCorner:(UIImage *)lowerRightCorner leftEdge:(UIImage *)leftEdge rightEdge:(UIImage *)rightEdge upperEdge:(UIImage *)upperEdge lowerEdge:(UIImage *)lowerEdge { - NPParameterAssertNotNilIsKindOfClass(upperLeftCorner,UIImage); - NPParameterAssertNotNilIsKindOfClass(lowerLeftCorner,UIImage); - NPParameterAssertNotNilIsKindOfClass(upperRightCorner,UIImage); - NPParameterAssertNotNilIsKindOfClass(lowerRightCorner,UIImage); - NPParameterAssertNotNilIsKindOfClass(leftEdge,UIImage); - NPParameterAssertNotNilIsKindOfClass(rightEdge,UIImage); - NPParameterAssertNotNilIsKindOfClass(upperEdge,UIImage); - NPParameterAssertNotNilIsKindOfClass(lowerEdge,UIImage); - if (self = [super initWithCenter:center - contentRegion:contentRegion - tileCenterVertically:tileCenterVertically - tileCenterHorizontally:tileCenterHorizontally]) { - self.upperEdge = upperEdge; - self.lowerEdge = lowerEdge; - self.leftEdge = leftEdge; - self.rightEdge = rightEdge; - self.upperLeftCorner = upperLeftCorner; - self.lowerLeftCorner = lowerLeftCorner; - self.upperRightCorner = upperRightCorner; - self.lowerRightCorner = lowerRightCorner; - } - return self; -} - -#pragma mark --(void)dealloc { - self.upperEdge = nil; - self.lowerEdge = nil; - self.leftEdge = nil; - self.rightEdge = nil; - self.upperLeftCorner = nil; - self.lowerLeftCorner = nil; - self.upperRightCorner = nil; - self.lowerRightCorner = nil; - [super dealloc]; -} - -#pragma mark Sanity-Checking Tools --(BOOL)checkSizeSanityAgainstOriginalImage:(UIImage *)originalImage { - CGSize os = [originalImage size]; - CGFloat ow = os.width; - CGFloat oh = os.height; - - CGFloat tr = ([[self upperEdge] size].width + [[self upperLeftCorner] size].width + [[self upperRightCorner] size].width); - CGFloat mr = ([[self center] size].width + [[self leftEdge] size].width + [[self rightEdge] size].width); - CGFloat lr = ([[self lowerEdge] size].width + [[self lowerLeftCorner] size].width + [[self lowerRightCorner] size].width); - - - BOOL topRow = TUWithinEpsilon(1.0f,ow,tr); - BOOL midRow = TUWithinEpsilon(1.0f,ow,mr); - BOOL lowRow = TUWithinEpsilon(1.0f,ow,lr); - - CGFloat lc = ([[self upperLeftCorner] size].height + [[self lowerLeftCorner] size].height + [[self leftEdge] size].height); - CGFloat mc = ([[self center] size].height + [[self upperEdge] size].height + [[self lowerEdge] size].height); - CGFloat rc = ([[self upperRightCorner] size].height + [[self lowerRightCorner] size].height + [[self rightEdge] size].height); - - BOOL lCol = TUWithinEpsilon(1.0f,oh,lc); - BOOL mCol = TUWithinEpsilon(1.0f,oh,mc); - BOOL rCol = TUWithinEpsilon(1.0f,oh,rc); - - BOOL sizesMatch = TUForceYesOrNo(midRow && topRow && lowRow && mCol && lCol && rCol); - DLog(@"SANITY sizesMatch: '%@.'",TUYesOrNoString(sizesMatch)); - DLog(@"SANITY topRow: '%@', midRow:'%@, lowRow:'%@'.", TUYesOrNoString(topRow),TUYesOrNoString(midRow),TUYesOrNoString(lowRow)); - DLog(@"SANITY lCol: '%@', mCol:'%@, rCol:'%@'.", TUYesOrNoString(lCol),TUYesOrNoString(mCol),TUYesOrNoString(rCol)); - DLog(@"SANITY ",ow,tr,mr,lr); - DLog(@"SANITY ",oh,lc,mc,rc); - return sizesMatch; -} - -#pragma mark TUNinePatch Overrides --(void)drawInRect:(CGRect)rect { - NPSelfProperty(center); - NPSelfProperty(leftEdge); - NPSelfProperty(rightEdge); - NPSelfProperty(lowerEdge); - NPSelfProperty(upperEdge); - NPSelfProperty(upperLeftCorner); - NPSelfProperty(upperRightCorner); - NPSelfProperty(lowerLeftCorner); - NPSelfProperty(lowerRightCorner); - - CGFloat leftEdgeWidth = [self leftEdgeWidth]; - CGFloat rightEdgeWidth = [self rightEdgeWidth]; - BOOL hasLeftEdge = (leftEdgeWidth > 0.0f)?(YES):(NO); - BOOL hasRightEdge = (rightEdgeWidth > 0.0f)?(YES):(NO); - - CGFloat upperEdgeHeight = [self upperEdgeHeight]; - CGFloat lowerEdgeHeight = [self lowerEdgeHeight]; - BOOL hasUpperEdge = (upperEdgeHeight > 0.0f)?(YES):(NO); - BOOL hasLowerEdge = (lowerEdgeHeight > 0.0f)?(YES):(NO); - - BOOL hasUpperLeftCorner = (hasLeftEdge && hasUpperEdge)?(YES):(NO); - BOOL hasUpperRightCorner = (hasRightEdge && hasUpperEdge)?(YES):(NO); - BOOL hasLowerLeftCorner = (hasLeftEdge && hasLowerEdge)?(YES):(NO); - BOOL hasLowerRightCorner = (hasRightEdge && hasLowerEdge)?(YES):(NO); - - - - CGFloat contentWidth = TUTruncateAtZero(rect.size.width - (leftEdgeWidth + rightEdgeWidth)); - CGFloat contentHeight = TUTruncateAtZero(rect.size.height - (upperEdgeHeight + lowerEdgeHeight)); - BOOL hasContentWidth = (contentWidth > 0.0f)?(YES):(NO); - BOOL hasContentHeight = (contentWidth > 0.0f)?(YES):(NO); - if (hasContentWidth && hasContentHeight) { - [self.center drawInRect:CGRectMake(CGRectGetMinX(rect) + leftEdgeWidth, CGRectGetMinY(rect) + upperEdgeHeight, contentWidth, contentHeight)]; - } - if (hasContentWidth) { - if (hasUpperEdge) { - [self.upperEdge drawInRect:CGRectMake( - CGRectGetMinX(rect) + leftEdgeWidth, - CGRectGetMinY(rect), - contentWidth, - upperEdgeHeight)]; - } - if (hasLowerEdge) { - [self.lowerEdge drawInRect:CGRectMake( - CGRectGetMinX(rect) + leftEdgeWidth, - CGRectGetMaxY(rect) - lowerEdgeHeight, - contentWidth, - lowerEdgeHeight)]; - } - } - if (hasContentHeight) { - if (hasLeftEdge) { - [self.leftEdge drawInRect:CGRectMake( - CGRectGetMinX(rect), - CGRectGetMinY(rect) + upperEdgeHeight, - leftEdgeWidth, - contentHeight)]; - } - if (hasRightEdge) { - [self.rightEdge drawInRect:CGRectMake( - CGRectGetMaxX(rect) - rightEdgeWidth, - CGRectGetMinY(rect) + upperEdgeHeight, - rightEdgeWidth, - contentHeight)]; - } - } - if (hasUpperLeftCorner && self.upperLeftCorner) { - [self.upperLeftCorner drawAtPoint:CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect))]; - } - if (hasUpperRightCorner && self.upperRightCorner) { - [self.upperRightCorner drawAtPoint:CGPointMake(CGRectGetMaxX(rect) - rightEdgeWidth, CGRectGetMinY(rect))]; - } - if (hasLowerLeftCorner && self.lowerLeftCorner) { - [self.lowerLeftCorner drawAtPoint:CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect) - lowerEdgeHeight)]; - } - if (hasLowerRightCorner && self.lowerRightCorner) { - [self.lowerRightCorner drawAtPoint:CGPointMake(CGRectGetMaxX(rect) - rightEdgeWidth, CGRectGetMaxY(rect) - lowerEdgeHeight)]; - } -} - -#pragma mark - --(CGFloat)leftEdgeWidth { - return ((self.upperLeftCorner)? - ([self.upperLeftCorner size].width): - (((self.lowerLeftCorner)? - ([self.lowerLeftCorner size].width):(0.0f)))); -} - --(CGFloat)rightEdgeWidth { - return ((self.upperRightCorner)? - ([self.upperRightCorner size].width) - :(((self.lowerRightCorner)? - ([self.lowerRightCorner size].width):(0.0f)))); -} - --(CGFloat)upperEdgeHeight { - return ((self.upperLeftCorner)? - ([self.upperLeftCorner size].height) - :(((self.upperRightCorner)? - ([self.upperRightCorner size].height):(0.0f)))); -} - --(CGFloat)lowerEdgeHeight { - return ((self.lowerLeftCorner)? - ([self.lowerLeftCorner size].height) - :(((self.lowerRightCorner)? - ([self.lowerRightCorner size].height):(0.0f)))); -} - -#pragma mark Customized Description Overrides --(NSString *)descriptionPostfix { - return [NSString stringWithFormat:@"%@, self.upperEdge:<'%@'>, self.lowerEdge:<'%@'>, self.leftEdge:<'%@'>, self.rightEdge:<'%@'>, self.upperLeftCorner:<'%@'>, self.lowerLeftCorner:<'%@'>, self.upperRightCorner:<'%@'>, self.lowerRightCorner:<'%@'>", - [super descriptionPostfix], - self.upperEdge, - self.lowerEdge, - self.leftEdge, - self.rightEdge, - self.upperLeftCorner, - self.lowerLeftCorner, - self.upperRightCorner, - self.lowerRightCorner]; -} - -#pragma mark Image Logging --(void)logExplodedImage { - CGFloat centerWidth = ((self.center)?(self.center.size.width):(0.0f)); - CGFloat centerHeight = ((self.center)?(self.center.size.height):(0.0f)); - CGSize mySize = CGSizeMake( - 4.0f + (centerWidth + ([self leftEdgeWidth]) + ([self rightEdgeWidth])), - 4.0f + (centerHeight + ([self upperEdgeHeight]) + ([self lowerEdgeHeight])) - ); - UIGraphicsBeginImageContext(mySize); - [self.center drawAtPoint:CGPointMake(2.0f + [self leftEdgeWidth], 2.0f + [self upperEdgeHeight])]; - [self.upperLeftCorner drawAtPoint:CGPointMake(0.0f, 0.0f)]; - [self.leftEdge drawAtPoint:CGPointMake(0.0f, [self upperEdgeHeight] + 2.0f)]; - [self.lowerLeftCorner drawAtPoint:CGPointMake(0.0f, [self upperEdgeHeight] + 4.0f + centerHeight)]; - [self.upperEdge drawAtPoint:CGPointMake(2.0f + [self leftEdgeWidth], 0.0f)]; - [self.upperRightCorner drawAtPoint:CGPointMake(4.0f + [self leftEdgeWidth] + centerWidth, 0.0f)]; - [self.rightEdge drawAtPoint:CGPointMake(4.0f + [self leftEdgeWidth] + centerWidth, 2.0f + [self upperEdgeHeight])]; - [self.lowerRightCorner drawAtPoint:CGPointMake(4.0f + [self leftEdgeWidth] + centerWidth, 4.0f + [self upperEdgeHeight] + centerHeight)]; - [self.lowerEdge drawAtPoint:CGPointMake(2.0f + [self leftEdgeWidth], 4.0f + [self upperEdgeHeight] + centerHeight)]; - IMLog(UIGraphicsGetImageFromCurrentImageContext(), @"explodedNinePatchImage"); - UIGraphicsEndImageContext(); -} - -@end \ No newline at end of file diff --git a/Classes/Utils/NinePatch/TUHorizontalNinePatch.h b/Classes/Utils/NinePatch/TUHorizontalNinePatch.h deleted file mode 100755 index 10ce83479..000000000 --- a/Classes/Utils/NinePatch/TUHorizontalNinePatch.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// TUHorizontalNinePatch.h -// NinePatch -// -// Copyright 2009 Tortuga 22, Inc. All rights reserved. -// - -#import -#import - -#import "TUNinePatch.h" -#import "TUNinePatchProtocols.h" - -/** - Concrete TUNinePatch instance. Handles NinePatches that stretch horizontally but not vertically. Only instantiate directly if you know what you're doing. - */ -@interface TUHorizontalNinePatch : TUNinePatch < TUNinePatch > { - UIImage *_leftEdge; - UIImage *_rightEdge; -} - -// Synthesized Properties -@property(nonatomic, retain, readonly) UIImage *leftEdge; -@property(nonatomic, retain, readonly) UIImage *rightEdge; - -// Init + Dealloc --(id)initWithCenter:(UIImage *)center contentRegion:(CGRect)contentRegion tileCenterVertically:(BOOL)tileCenterVertically tileCenterHorizontally:(BOOL)tileCenterHorizontally leftEdge:(UIImage *)leftEdge rightEdge:(UIImage *)rightEdge; --(void)dealloc; - -// TUNinePatch Overrides --(void)drawInRect:(CGRect)rect; --(BOOL)stretchesVertically; --(CGSize)sizeForContentOfSize:(CGSize)contentSize; --(CGFloat)leftEdgeWidth; --(CGFloat)rightEdgeWidth; - -@end diff --git a/Classes/Utils/NinePatch/TUHorizontalNinePatch.m b/Classes/Utils/NinePatch/TUHorizontalNinePatch.m deleted file mode 100755 index b570cb2dc..000000000 --- a/Classes/Utils/NinePatch/TUHorizontalNinePatch.m +++ /dev/null @@ -1,124 +0,0 @@ -// -// TUHorizontalNinePatch.m -// NinePatch -// -// Copyright 2009 Tortuga 22, Inc. All rights reserved. -// - -#import "TUHorizontalNinePatch.h" - -@interface TUHorizontalNinePatch () - -// Synthesized Properties -@property(nonatomic, retain, readwrite) UIImage *leftEdge; -@property(nonatomic, retain, readwrite) UIImage *rightEdge; - -@end - - -@implementation TUHorizontalNinePatch - -#pragma mark Synthesized Properties -@synthesize leftEdge = _leftEdge; -@synthesize rightEdge = _rightEdge; - -#pragma mark NSCoding --(id)initWithCoder:(NSCoder *)coder { - if (self = [super initWithCoder:coder]) { - self.leftEdge = (UIImage *)[coder decodeObjectForKey:@"leftEdge"]; - self.rightEdge = (UIImage *)[coder decodeObjectForKey:@"rightEdge"]; - } - return self; -} - --(void)encodeWithCoder:(NSCoder *)coder { - [super encodeWithCoder:coder]; - - [coder encodeObject:self.leftEdge - forKey:@"leftEdge"]; - - [coder encodeObject:self.rightEdge - forKey:@"rightEdge"]; -} - -#pragma mark NSCopying --(id)copyWithZone:(NSZone *)zone { - return [[[self class] allocWithZone:zone] initWithCenter:self.center - contentRegion:self.contentRegion - tileCenterVertically:self.tileCenterVertically - tileCenterHorizontally:self.tileCenterHorizontally - leftEdge:self.leftEdge - rightEdge:self.rightEdge]; -} - -#pragma mark Init + Dealloc --(id)initWithCenter:(UIImage *)center contentRegion:(CGRect)contentRegion tileCenterVertically:(BOOL)tileCenterVertically tileCenterHorizontally:(BOOL)tileCenterHorizontally leftEdge:(UIImage *)leftEdge rightEdge:(UIImage *)rightEdge { - NPParameterAssertNotNilIsKindOfClass(leftEdge,UIImage); - NPParameterAssertNotNilIsKindOfClass(rightEdge,UIImage); - if (self = [super initWithCenter:center - contentRegion:contentRegion - tileCenterVertically:tileCenterVertically - tileCenterHorizontally:tileCenterHorizontally]) { - self.leftEdge = leftEdge; - self.rightEdge = rightEdge; - } - return self; -} - -#pragma mark - --(void)dealloc { - self.leftEdge = nil; - self.rightEdge = nil; - [super dealloc]; -} - -#pragma mark TUNinePatch Overrides --(void)drawInRect:(CGRect)rect { - CGFloat height = [self minimumHeight]; - [self.center drawInRect:CGRectMake(CGRectGetMinX(rect) + [self leftEdgeWidth], CGRectGetMinY(rect), CGRectGetWidth(rect) - ([self leftEdgeWidth] + [self rightEdgeWidth]), height)]; - if (self.leftEdge) { - [self.leftEdge drawAtPoint:CGPointMake(CGRectGetMinX(rect),CGRectGetMinY(rect))]; - } - if (self.rightEdge) { - [self.rightEdge drawAtPoint:CGPointMake(CGRectGetMaxX(rect) - [self rightEdgeWidth], CGRectGetMinY(rect))]; - } -} - -#pragma mark - --(BOOL)stretchesVertically { - return NO; -} - -#pragma mark - --(CGSize)sizeForContentOfSize:(CGSize)contentSize { - CGSize outSize = [super sizeForContentOfSize:contentSize]; - outSize.height = [self minimumHeight]; - return outSize; -} - -#pragma mark - --(CGFloat)leftEdgeWidth { - CGFloat leftEdgeWidth = 0.0f; - if (self.leftEdge) { - leftEdgeWidth = [self.leftEdge size].width; - } - return leftEdgeWidth; -} - --(CGFloat)rightEdgeWidth { - CGFloat rightEdgeWidth = 0.0f; - if (self.leftEdge) { - rightEdgeWidth = [self.rightEdge size].width; - } - return rightEdgeWidth; -} - -#pragma mark Customized Description Overrides --(NSString *)descriptionPostfix { - return [NSString stringWithFormat:@"%@, self.leftEdge:<'%@'>, self.rightEdge:<'%@'>", - [super descriptionPostfix], - self.leftEdge, - self.rightEdge]; -} - -@end \ No newline at end of file diff --git a/Classes/Utils/NinePatch/TUNinePatch.h b/Classes/Utils/NinePatch/TUNinePatch.h deleted file mode 100755 index 175854c37..000000000 --- a/Classes/Utils/NinePatch/TUNinePatch.h +++ /dev/null @@ -1,125 +0,0 @@ -// -// TUNinePatch.h -// NinePatch -// -// Copyright 2009 Tortuga 22, Inc. All rights reserved. -// - -#import -#import -#import -#import "TUNinePatchProtocols.h" - -/** - Abstract base class for concrete NinePatches; this is the public interface into the TUNinePatch class cluster. Note particularly that TUNinePatch itself doesn't actually implement the TUNinePatch protocol, but its convenience methods promise to supply objects that do implement TUNinePatch. You should really only be using the classlevel convenience methods on this class unless you know what you're doing. If a method isn't documented it's probably not really for public use yet. - */ -@interface TUNinePatch : NSObject < NSCoding, NSCopying > { - UIImage *_center; - CGRect _contentRegion; - BOOL _tileCenterVertically; - BOOL _tileCenterHorizontally; -} - -// Synthesized Properties -@property(nonatomic, retain, readonly) UIImage *center; -@property(nonatomic, assign, readonly) CGRect contentRegion; -@property(nonatomic, assign, readonly) BOOL tileCenterVertically; -@property(nonatomic, assign, readonly) BOOL tileCenterHorizontally; - -// NSCoding --(id)initWithCoder:(NSCoder *)coder; --(void)encodeWithCoder:(NSCoder *)coder; - -// NSCopying --(id)copyWithZone:(NSZone *)zone; - -// Init + Dealloc --(id)initWithCenter:(UIImage *)center contentRegion:(CGRect)contentRegion; --(id)initWithCenter:(UIImage *)center contentRegion:(CGRect)contentRegion tileCenterVertically:(BOOL)tileCenterVertically tileCenterHorizontally:(BOOL)tileCenterHorizontally; --(void)dealloc; - -// Convenience Constructors -/** - This parses ninePatchImage and instantiates an instance of the appropriate TUNinePatch subclass. - - @param ninePatchImage A non-nil UIImage object containing the contents of a .9.png file (eg: it still contains the 1px border containing the scaling information). - @returns An autoreleased object implementing the TUNinePatch protocol, loaded with the contents of ninePatchImage. Can be nil if errors encountered. - */ -+(id < TUNinePatch >)ninePatchWithNinePatchImage:(UIImage *)ninePatchImage; - -/** - Calls through to ninePatchWithImage:stretchableRegion:contentRegion:tileCenterVertically:tileCenterHorizontally with contentRegion=CGRectZero and NO on the tiling params. Will probably get made private or protected soon. - */ -+(id < TUNinePatch >)ninePatchWithImage:(UIImage *)image stretchableRegion:(CGRect)stretchableRegion; - -/** - Creates a NinePatch using the passed-in image and the passed-in scaling information. This method may go protected soon, leaving only the ninePatchWithNinePatchImage: as a public convenience (possibly with the addition of ninePatchNamed: method as well). The argument for goign protected or private is that if this library winds up expanding discontinuous stretchable regions (as is done on Android) then there would be a separate interface for passing in 4 stretchable regions, making the public interface cmoplicated and "multiple ways in". - - @param image A non-nil UIImage object that contains the displayable content. This is contents of .9.png file AFTER removing the 1px border. - @param stretchableRegion Rect specifying the bounds of the central stretchable region. In the .9.png this is specified on the left and top margins. - @param contentRegion Rect specifying the bounds of the content region, EG the box into which associated content might fit. In the .9.png this is specified on the bottom and right margins. - @param tileCenterVertically (Currently unsupported) is intended to specify whether or not the center scales by resizing or scales by tiling. Not fully supported at this time, only use if you know what you're doing. - @param tileCenterHorizontally (Currently unsupported) is intended to specify whether or not the center scales by resizing or scales by tiling. Not fully supported at this time, only use if you know what you're doing. - - @returns An object implementing the TUNinePatch protocol. Can be nil if problems were encountered. - */ -+(id < TUNinePatch >)ninePatchWithImage:(UIImage *)image stretchableRegion:(CGRect)stretchableRegion contentRegion:(CGRect)contentRegion tileCenterVertically:(BOOL)tileCenterVertically tileCenterHorizontally:(BOOL)tileCenterHorizontally; - -// Bundle Loading -/** - Creates a ninepatch in two steps: it takes filename, and tries to load @"filename.9.png" from the main bundle. If that loads it then attempts to construct a NinePatch from that image file's contents. Differs from UIImage's analogous method in that no caching is done. - - @param filename A non-nil NSString containing the filename of the source image but NOT including ".9.png". - @returns An object implementing the TUNinePatch protocol. Can be nil if problems encountered. - */ -+(id < TUNinePatch >)ninePatchNamed:(NSString *)filename; - -// Nine Patch Image Manipulation - High Level -+(CGRect)rectFromHorizontalRange:(NSRange)horizontalRange verticalRange:(NSRange)verticalRange; -+(CGRect)stretchableRegionOfNinePatchImage:(UIImage *)ninePatchImage; -+(CGRect)contentRegionOfNinePatchImage:(UIImage *)ninePatchImage; -+(BOOL)shouldTileCenterHorizontallyForNinePatchImage:(UIImage *)ninePatchImage; -+(BOOL)shouldTileCenterVerticallyForNinePatchImage:(UIImage *)ninePatchImage; - -// Drawing Utility --(void)drawInRect:(CGRect)rect; - -// Diagnostic Utilities --(UIImage *)upperEdge; --(UIImage *)lowerEdge; --(UIImage *)leftEdge; --(UIImage *)rightEdge; - --(UIImage *)upperLeftCorner; --(UIImage *)lowerLeftCorner; --(UIImage *)upperRightCorner; --(UIImage *)lowerRightCorner; - -// TUNinePatch Protocol Methods - Drawing --(void)inContext:(CGContextRef)context drawAtPoint:(CGPoint)point forContentOfSize:(CGSize)contentSize; --(void)inContext:(CGContextRef)context drawCenteredInRect:(CGRect)rect forContentOfSize:(CGSize)contentSize; --(void)inContext:(CGContextRef)context drawInRect:(CGRect)rect; - -// TUNinePatch Protocol Methods - Image Construction --(UIImage *)imageOfSize:(CGSize)size; - -// TUNinePatch Protocol Methods - Sizing --(BOOL)stretchesHorizontally; --(BOOL)stretchesVertically; --(CGFloat)minimumWidth; --(CGFloat)minimumHeight; --(CGSize)minimumSize; --(CGSize)sizeForContentOfSize:(CGSize)contentSize; --(CGPoint)upperLeftCornerForContentWhenDrawnAtPoint:(CGPoint)point; - -// TUNinePatch Protocol Methods - Geometry --(CGFloat)leftEdgeWidth; --(CGFloat)rightEdgeWidth; --(CGFloat)upperEdgeHeight; --(CGFloat)lowerEdgeHeight; - -// Customized Description --(NSString *)description; --(NSString *)descriptionPostfix; - -@end \ No newline at end of file diff --git a/Classes/Utils/NinePatch/TUNinePatch.m b/Classes/Utils/NinePatch/TUNinePatch.m deleted file mode 100755 index 8c3303fb0..000000000 --- a/Classes/Utils/NinePatch/TUNinePatch.m +++ /dev/null @@ -1,514 +0,0 @@ -// -// TUNinePatch.m -// NinePatch -// -// Copyright 2009 Tortuga 22, Inc. All rights reserved. -// - -#import "TUNinePatch.h" -#import "TUVerticalNinePatch.h" -#import "TUHorizontalNinePatch.h" -#import "TUFullNinePatch.h" -#import "UIImage-TUNinePatch.h" - -@interface TUNinePatch () - -@property(nonatomic, retain, readwrite) UIImage *center; -@property(nonatomic, assign, readwrite) CGRect contentRegion; -@property(nonatomic, assign, readwrite) BOOL tileCenterVertically; -@property(nonatomic, assign, readwrite) BOOL tileCenterHorizontally; - -@end - - -@implementation TUNinePatch - -#pragma mark Synthesized Properties -@synthesize center = _center; -@synthesize contentRegion = _contentRegion; -@synthesize tileCenterVertically = _tileCenterVertically; -@synthesize tileCenterHorizontally = _tileCenterHorizontally; - -#pragma mark NSCoding --(id)initWithCoder:(NSCoder *)coder { - NPAOInputLog(coder); - if (self = [super init]) { - self.center = (UIImage *)[coder decodeObjectForKey:@"center"]; - self.contentRegion = [coder decodeCGRectForKey:@"contentRegion"]; - self.tileCenterVertically = [coder decodeBoolForKey:@"tileCenterVertically"]; - self.tileCenterHorizontally = [coder decodeBoolForKey:@"tileCenterHorizontally"]; - } - return self; -} - --(void)encodeWithCoder:(NSCoder *)coder { - NPAOInputLog(coder); - [coder encodeObject:self.center - forKey:@"center"]; - - [coder encodeCGRect:self.contentRegion - forKey:@"contentRegion"]; - - [coder encodeBool:self.tileCenterVertically - forKey:@"tileCenterVertically"]; - - [coder encodeBool:self.tileCenterHorizontally - forKey:@"tileCenterHorizontally"]; -} - -#pragma mark NSCopying --(id)copyWithZone:(NSZone *)zone { - return [[[self class] allocWithZone:zone] initWithCenter:self.center - contentRegion:self.contentRegion - tileCenterVertically:self.tileCenterVertically - tileCenterHorizontally:self.tileCenterHorizontally]; -} - -#pragma mark Init + Dealloc --(id)initWithCenter:(UIImage *)center contentRegion:(CGRect)contentRegion { - return [self initWithCenter:center - contentRegion:contentRegion - tileCenterVertically:NO - tileCenterHorizontally:NO]; -} - --(id)initWithCenter:(UIImage *)center contentRegion:(CGRect)contentRegion tileCenterVertically:(BOOL)tileCenterVertically tileCenterHorizontally:(BOOL)tileCenterHorizontally { - NPAInputLog(@"[%@:<0x%x> initWithCenter:%@ contentRegion:%@ tileCenterVertically:%d tileCenterHorizontally:%d]", [self class], ((NSUInteger) self), center, NSStringFromCGRect(contentRegion), tileCenterVertically, tileCenterHorizontally); - NPParameterAssertNotNilIsKindOfClass(center, UIImage); - if (self = [super init]) { - self.center = center; - self.contentRegion = contentRegion; - self.tileCenterVertically = tileCenterVertically; - self.tileCenterHorizontally = tileCenterHorizontally; - } - return self; -} - -#pragma mark - --(void)dealloc { - self.center = nil; - [super dealloc]; -} - -#pragma mark Convenience Constructors -+(id < TUNinePatch >)ninePatchWithNinePatchImage:(UIImage *)ninePatchImage { - NPAInputLog(@"ninePatchWithNinePatchImage:'%@'",ninePatchImage); - id < TUNinePatch > outPatch = nil; - if (ninePatchImage) { - @try { - outPatch = [self ninePatchWithImage:[ninePatchImage imageAsNinePatchImage] - stretchableRegion:[self stretchableRegionOfNinePatchImage:ninePatchImage] - contentRegion:[self contentRegionOfNinePatchImage:ninePatchImage] - tileCenterVertically:[self shouldTileCenterVerticallyForNinePatchImage:ninePatchImage] - tileCenterHorizontally:[self shouldTileCenterHorizontallyForNinePatchImage:ninePatchImage]]; - } - @catch (NSException * e) { - NPLogException(e); - outPatch = nil; - } - } - NPAssertNilOrConformsToProtocol(outPatch,TUNinePatch); - NPOOutputLog(outPatch); - return outPatch; -} - -+(id < TUNinePatch >)ninePatchWithImage:(UIImage *)image stretchableRegion:(CGRect)stretchableRegion { - NPAInputLog(@"ninePatchWithImage:'%@' stretchableRegion:'%@'",image,NSStringFromCGRect(stretchableRegion)); - NPParameterAssertNotNilIsKindOfClass(image,UIImage); - return [self ninePatchWithImage:image - stretchableRegion:stretchableRegion - contentRegion:CGRectZero - tileCenterVertically:NO - tileCenterHorizontally:NO]; -} - -+(id < TUNinePatch >)ninePatchWithImage:(UIImage *)image stretchableRegion:(CGRect)stretchableRegion contentRegion:(CGRect)contentRegion tileCenterVertically:(BOOL)tileCenterVertically tileCenterHorizontally:(BOOL)tileCenterHorizontally { - NPAInputLog(@"ninePatchWithImage:'%@' stretchableRegion:'%@' contentRegion:'%@' tileCenterVertically:'%@' tileCenterHorizontally:'%@'",image,NSStringFromCGRect(stretchableRegion),NSStringFromCGRect(contentRegion),TUYesOrNoString(tileCenterVertically),TUYesOrNoString(tileCenterHorizontally)); - NPParameterAssertNotNilIsKindOfClass(image,UIImage); - NPParameterAssert(stretchableRegion.origin.x >= 0.0f); - NPParameterAssert(stretchableRegion.origin.y >= 0.0f); - NPParameterAssert([image size].width >= stretchableRegion.origin.x + stretchableRegion.size.width); - NPParameterAssert([image size].height >= stretchableRegion.origin.y + stretchableRegion.size.height); - id < TUNinePatch > ninePatch = nil; - if (image) { - CGFloat imageWidth = [image size].width; - CGFloat imageHeight = [image size].height; - CGRect fixedStretchableRegion = stretchableRegion; - CGFloat stretchableRegionMinX = CGRectGetMinX(fixedStretchableRegion); - CGFloat stretchableRegionMinY = CGRectGetMinY(fixedStretchableRegion); - CGFloat stretchableRegionMaxX = CGRectGetMaxX(fixedStretchableRegion); - CGFloat stretchableRegionMaxY = CGRectGetMaxY(fixedStretchableRegion); - BOOL stretchesOnLeft = (stretchableRegionMinX > 0.0f)?(YES):(NO); - BOOL stretchesOnRight = (stretchableRegionMaxX < imageWidth)?(YES):(NO); - BOOL stretchesOnTop = (stretchableRegionMinY > 0.0f)?(YES):(NO); - BOOL stretchesOnBottom = (stretchableRegionMaxY < imageHeight)?(YES):(NO); - BOOL stretchesHorizontally = (stretchesOnLeft || stretchesOnRight)?(YES):(NO); - BOOL stretchesVertically = (stretchesOnTop || stretchesOnBottom)?(YES):(NO); - if (stretchesVertically && stretchesHorizontally) { - LLog(@"...the specified stretchable region stretches horizontally and vertically."); - UIImage *center = [image extractCenterForStretchableRegion:fixedStretchableRegion]; - UIImage *upperLeftCorner = [image extractUpperLeftCornerForStretchableRegion:fixedStretchableRegion]; - UIImage *upperRightCorner = [image extractUpperRightCornerForStretchableRegion:fixedStretchableRegion]; - UIImage *lowerLeftCorner = [image extractLowerLeftCornerForStretchableRegion:fixedStretchableRegion]; - UIImage *lowerRightCorner = [image extractLowerRightCornerForStretchableRegion:fixedStretchableRegion]; - UIImage *leftEdge = [image extractLeftEdgeForStretchableRegion:fixedStretchableRegion]; - UIImage *rightEdge = [image extractRightEdgeForStretchableRegion:fixedStretchableRegion]; - UIImage *lowerEdge = [image extractLowerEdgeForStretchableRegion:fixedStretchableRegion]; - UIImage *upperEdge = [image extractUpperEdgeForStretchableRegion:fixedStretchableRegion]; - - // Mega-Block of size sanity checking - - // Given that the only major bug encountered while developing this library - // proved to be a difficult-to-track-down source of off-by-one errors in - // the sizes of the slices, you can understand the paranoia here. - // - // Just remember to build with the assertion-checking off. - - NPAssertCorrectSubimageWidthDecomposition(image, upperLeftCorner, upperEdge, upperRightCorner); - NPAssertCorrectSubimageWidthDecomposition(image, leftEdge, upperEdge, rightEdge); - NPAssertCorrectSubimageWidthDecomposition(image, lowerLeftCorner, lowerEdge, lowerRightCorner); - - NPAssertCorrectSubimageHeightDecomposition(image, upperLeftCorner, leftEdge, lowerLeftCorner); - NPAssertCorrectSubimageHeightDecomposition(image, upperEdge, center, lowerEdge); - NPAssertCorrectSubimageHeightDecomposition(image, upperRightCorner, rightEdge, lowerRightCorner); - - NPAssertWithinOne(([upperLeftCorner size].height), ([upperRightCorner size].height)); - NPAssertWithinOne(([upperLeftCorner size].height), ([upperEdge size].height)); - NPAssertWithinOne(([upperEdge size].height), ([upperRightCorner size].height)); - - NPAssertWithinOne(([leftEdge size].height), ([center size].height)); - NPAssertWithinOne(([center size].height), ([rightEdge size].height)); - NPAssertWithinOne(([rightEdge size].height), ([leftEdge size].height)); - - NPAssertWithinOne(([lowerLeftCorner size].height), ([lowerRightCorner size].height)); - NPAssertWithinOne(([lowerRightCorner size].height), ([lowerEdge size].height)); - NPAssertWithinOne(([lowerEdge size].height), ([lowerLeftCorner size].height)); - - NPAssertWithinOne(([upperLeftCorner size].width), ([leftEdge size].width)); - NPAssertWithinOne(([leftEdge size].width), ([lowerLeftCorner size].width)); - NPAssertWithinOne(([upperLeftCorner size].width), ([lowerLeftCorner size].width)); - - NPAssertWithinOne(([upperEdge size].width), ([center size].width)); - NPAssertWithinOne(([center size].width), ([lowerEdge size].width)); - NPAssertWithinOne(([upperEdge size].width), ([lowerEdge size].width)); - - NPAssertWithinOne(([upperRightCorner size].width), ([rightEdge size].width)); - NPAssertWithinOne(([rightEdge size].width), ([lowerRightCorner size].width)); - NPAssertWithinOne(([lowerRightCorner size].width), ([upperRightCorner size].width)); - - ninePatch = [[[TUFullNinePatch alloc] initWithCenter:center - contentRegion:contentRegion - tileCenterVertically:tileCenterVertically - tileCenterHorizontally:tileCenterHorizontally - upperLeftCorner:upperLeftCorner - upperRightCorner:upperRightCorner - lowerLeftCorner:lowerLeftCorner - lowerRightCorner:lowerRightCorner - leftEdge:leftEdge - rightEdge:rightEdge - upperEdge:upperEdge - lowerEdge:lowerEdge] autorelease]; - } else if (stretchesVertically) { - UIImage *center = [image extractCenterForStretchableRegion:fixedStretchableRegion]; - UIImage *upperEdge = [image extractUpperEdgeForStretchableRegion:fixedStretchableRegion]; - UIImage *lowerEdge = [image extractLowerEdgeForStretchableRegion:fixedStretchableRegion]; - - NPAssertCorrectSubimageHeightDecomposition(image,center,upperEdge,lowerEdge); - NPAssertWithinOne(([center size].width),([upperEdge size].width)); - NPAssertWithinOne(([lowerEdge size].width),([upperEdge size].width)); - NPAssertWithinOne(([center size].width),([lowerEdge size].width)); - - ninePatch = [[[TUVerticalNinePatch alloc] initWithCenter:center - contentRegion:contentRegion - tileCenterVertically:tileCenterVertically - tileCenterHorizontally:tileCenterHorizontally - upperEdge:upperEdge - lowerEdge:lowerEdge] autorelease]; - } else if (stretchesHorizontally) { - UIImage *center = [image extractCenterForStretchableRegion:fixedStretchableRegion]; - UIImage *leftEdge = [image extractLeftEdgeForStretchableRegion:fixedStretchableRegion]; - UIImage *rightEdge = [image extractRightEdgeForStretchableRegion:fixedStretchableRegion]; - - NPAssertCorrectSubimageWidthDecomposition(image, leftEdge, center, rightEdge); - NPAssertWithinOne(([center size].height),([leftEdge size].height)); - NPAssertWithinOne(([center size].height),([rightEdge size].height)); - NPAssertWithinOne(([leftEdge size].height),([rightEdge size].height)); - - ninePatch = [[[TUHorizontalNinePatch alloc] initWithCenter:center - contentRegion:contentRegion - tileCenterVertically:tileCenterVertically - tileCenterHorizontally:tileCenterHorizontally - leftEdge:leftEdge - rightEdge:rightEdge] autorelease]; - } else { - ninePatch = [[[self alloc] initWithCenter:image - contentRegion:contentRegion - tileCenterVertically:tileCenterVertically - tileCenterHorizontally:tileCenterHorizontally] autorelease]; - } - } - NPAssertNilOrConformsToProtocol(ninePatch,TUNinePatch); - NPOOutputLog(ninePatch); - return ninePatch; -} - -#pragma mark Bundle Loading -+(id < TUNinePatch >)ninePatchNamed:(NSString *)filename { - NPParameterAssertNotNilIsKindOfClass(filename,NSString); - id < TUNinePatch > outPatch = nil; - if (filename) { - NSBundle *mainBundle = [NSBundle mainBundle]; - if (mainBundle) { - NSString *filePath = [mainBundle pathForResource:[NSString stringWithFormat:@"%@.9",filename] - ofType:@"png"]; - if (filePath) { - UIImage *ninepatch = [[UIImage alloc] initWithContentsOfFile:filePath]; - if (ninepatch) { - @try { - outPatch = [self ninePatchWithNinePatchImage:ninepatch]; - } - @catch (NSException * e) { - NPLogException(e); - outPatch = nil; - } - @finally { - [ninepatch release]; - } - } - } - } - } - NPAssertNilOrConformsToProtocol(outPatch,TUNinePatch); - NPOOutputLog(outPatch); - return outPatch; -} - -#pragma mark Nine Patch Image Manipulation - High Level -+(CGRect)rectFromHorizontalRange:(NSRange)horizontalRange verticalRange:(NSRange)verticalRange { - NPAInputLog(@"rectFromHorizontalRange:'%@' verticalRange:'%@'",NSStringFromRange(horizontalRange),NSStringFromRange(verticalRange)); - CGFloat minX = (TUIsNotFoundRange(horizontalRange))?(0.0f):((CGFloat) horizontalRange.location); - CGFloat width = (TUIsNotFoundRange(horizontalRange))?(0.0f):((CGFloat) horizontalRange.length); - CGFloat minY = (TUIsNotFoundRange(verticalRange)?(0.0f):((CGFloat) verticalRange.location)); - CGFloat height = (TUIsNotFoundRange(verticalRange)?(0.0f):((CGFloat) verticalRange.length)); - CGRect outRect = CGRectMake(minX,minY,width,height); - NPCGROutputLog(outRect); - return outRect; -} - -+(CGRect)stretchableRegionOfNinePatchImage:(UIImage *)ninePatchImage { - NPAInputLog(@"stretchableRegionOfNinePatchImage:'%@'",ninePatchImage); - NPParameterAssertNotNilIsKindOfClass(ninePatchImage,UIImage); - CGRect outRect = CGRectZero; - if (ninePatchImage) { - outRect = [self rectFromHorizontalRange:[ninePatchImage blackPixelRangeInUpperStrip] - verticalRange:[ninePatchImage blackPixelRangeInLeftStrip]]; - } - NPCGROutputLog(outRect); - return outRect; -} - -+(CGRect)contentRegionOfNinePatchImage:(UIImage *)ninePatchImage { - NPAInputLog(@"contentRegionOfNinePatchImage:'%@'",ninePatchImage); - NPParameterAssertNotNilIsKindOfClass(ninePatchImage,UIImage); - CGRect outRect = CGRectZero; - if (ninePatchImage) { - outRect = [self rectFromHorizontalRange:[ninePatchImage blackPixelRangeInLowerStrip] - verticalRange:[ninePatchImage blackPixelRangeInRightStrip]]; - } - NPCGROutputLog(outRect); - return outRect; -} - -+(BOOL)shouldTileCenterHorizontallyForNinePatchImage:(UIImage *)ninePatchImage { - NPAInputLog(@"shouldTileCenterHorizontallyForNinePatchImage:'%@'",ninePatchImage); - NPParameterAssertNotNilIsKindOfClass(ninePatchImage,UIImage); - BOOL shouldTileCenterHorizontallyForNinePatchImage = NO; - if (ninePatchImage) { - shouldTileCenterHorizontallyForNinePatchImage = [ninePatchImage upperLeftCornerIsBlackPixel]; - } - NPBOutputLog(shouldTileCenterHorizontallyForNinePatchImage); - return shouldTileCenterHorizontallyForNinePatchImage; -} - -+(BOOL)shouldTileCenterVerticallyForNinePatchImage:(UIImage *)ninePatchImage { - NPAInputLog(@"shouldTileCenterHorizontallyForNinePatchImage:'%@'",ninePatchImage); - NPParameterAssertNotNilIsKindOfClass(ninePatchImage,UIImage); - BOOL shouldTileCenterVerticallyForNinePatchImage = NO; - if (ninePatchImage) { - shouldTileCenterVerticallyForNinePatchImage = [ninePatchImage lowerLeftCornerIsBlackPixel]; - } - NPBOutputLog(shouldTileCenterVerticallyForNinePatchImage); - return shouldTileCenterVerticallyForNinePatchImage; -} - -#pragma mark Drawing Utility --(void)drawInRect:(CGRect)rect { - if (self.center) { - if (self.tileCenterHorizontally && self.tileCenterVertically) { - [self.center drawAsPatternInRect:rect]; - } else { - // NB: this behavior is not 100% accurate - // in that it only works right for tiling on and off - // half-tiling has to wait - [self.center drawInRect:rect]; - } - } -} - -#pragma mark Diagnostic Utilities --(UIImage *)upperEdge { - return nil; -} - --(UIImage *)lowerEdge { - return nil; -} - --(UIImage *)leftEdge { - return nil; -} - --(UIImage *)rightEdge { - return nil; -} - --(UIImage *)upperLeftCorner { - return nil; -} - --(UIImage *)lowerLeftCorner { - return nil; -} - --(UIImage *)upperRightCorner { - return nil; -} - --(UIImage *)lowerRightCorner { - return nil; -} - -#pragma mark TUNinePatch Protocol Methods - Drawing --(void)inContext:(CGContextRef)context drawAtPoint:(CGPoint)point forContentOfSize:(CGSize)contentSize { - NPParameterAssert(context != nil); - NPAInputLog(@"inContext:'%@' drawAtPoint:'%@' forContentOfSize:'%@'",context,NSStringFromCGPoint(point),NSStringFromCGSize(contentSize)); - CGSize size = [self sizeForContentOfSize:contentSize]; - [self inContext:context - drawInRect:CGRectMake(point.x, point.y, size.width, size.height)]; -} - --(void)inContext:(CGContextRef)context drawCenteredInRect:(CGRect)rect forContentOfSize:(CGSize)contentSize { - NPParameterAssert(context != nil); - NPAInputLog(@"inContext:'%@' drawCenteredInRect:'%@' forContentOfSize:'%@'",context,NSStringFromCGRect(rect),NSStringFromCGSize(contentSize)); - CGSize size = [self sizeForContentOfSize:contentSize]; - CGFloat xStart = floorf((CGRectGetWidth(rect) - size.width) * 0.5f); - CGFloat yStart = floorf((CGRectGetHeight(rect) - size.height) * 0.5f); - [self inContext:context - drawInRect:CGRectMake(xStart, yStart, size.width, size.height)]; -} - --(void)inContext:(CGContextRef)context drawInRect:(CGRect)rect { - if (context) { - CGContextSaveGState(context); - CGContextBeginTransparencyLayer(context, nil); - @try { - [self drawInRect:rect]; - } - @catch (NSException * e) { - NPLogException(e); - } - @finally { - CGContextEndTransparencyLayer(context); - CGContextRestoreGState(context); - } - } -} - -#pragma mark TUNinePatch Protocol Methods - Image Construction --(UIImage *)imageOfSize:(CGSize)size { - UIImage *image = nil; - UIGraphicsBeginImageContext(size); - [self drawInRect:CGRectMake(0.0f,0.0f,size.width,size.height)]; - image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return image; -} - -#pragma mark TUNinePatch Protocol Methods - Sizing --(BOOL)stretchesHorizontally { - return YES; -} - --(BOOL)stretchesVertically { - return YES; -} - -#pragma mark - --(CGFloat)minimumWidth { - CGFloat minimumWidth = 0.0f; - if (self.center) { - minimumWidth = [self.center size].width + self.rightEdgeWidth + self.leftEdgeWidth; - } - return minimumWidth; -} - --(CGFloat)minimumHeight { - CGFloat minimumHeight = 0.0f; - if (self.center) { - minimumHeight = [self.center size].height + self.upperEdgeHeight + self.lowerEdgeHeight; - } - return minimumHeight; -} - --(CGSize)minimumSize { - return CGSizeMake([self minimumWidth], [self minimumHeight]); -} - --(CGSize)sizeForContentOfSize:(CGSize)contentSize { - CGSize outSize = [self minimumSize]; - CGFloat contentRegionWidth = CGRectGetWidth(self.contentRegion); - CGFloat contentRegionHeight = CGRectGetHeight(self.contentRegion); - if ((contentRegionWidth > 0.0f) || (contentRegionHeight > 0.0f)) { - // WE HAVE CONTENT REGION - outSize.width += (contentSize.width > contentRegionWidth)?(contentSize.width - contentRegionWidth):(0.0f); - outSize.height += (contentSize.height > contentRegionHeight)?(contentSize.height - contentRegionHeight):(0.0f); - } else { - // WE ONLY NEED A SIMPLE "WHICH IS BIGGER?" CHECK - outSize.width = (contentSize.width > outSize.width)?(contentSize.width):(outSize.width); - outSize.height = (contentSize.height > outSize.height)?(contentSize.height):(outSize.height); - } - return outSize; -} - --(CGPoint)upperLeftCornerForContentWhenDrawnAtPoint:(CGPoint)point { - return CGPointMake(point.x + CGRectGetMinX(self.contentRegion), point.y + CGRectGetMinY(self.contentRegion)); -} - -#pragma mark TUNinePatch Protocol Methods - Geometry --(CGFloat)leftEdgeWidth { - return 0.0f; -} - --(CGFloat)rightEdgeWidth { - return 0.0f; -} - --(CGFloat)upperEdgeHeight { - return 0.0f; -} - --(CGFloat)lowerEdgeHeight { - return 0.0f; -} - -#pragma mark Customized Description --(NSString *)description { - return [NSString stringWithFormat:@"<%@>:( %@ )",[super description],[self descriptionPostfix]]; -} - --(NSString *)descriptionPostfix { - return [NSString stringWithFormat:@"center:<'%@'>, contentRegion:<'%@'>", self.center, NSStringFromCGRect(self.contentRegion)]; -} - - -@end \ No newline at end of file diff --git a/Classes/Utils/NinePatch/TUNinePatchCache.h b/Classes/Utils/NinePatch/TUNinePatchCache.h deleted file mode 100755 index e42d519d3..000000000 --- a/Classes/Utils/NinePatch/TUNinePatchCache.h +++ /dev/null @@ -1,99 +0,0 @@ -// -// TUNinePatchCache.h -// NinePatch -// -// Copyright 2010 Tortuga 22, Inc. All rights reserved. -// - -#import -#import -#import "TUNinePatchProtocols.h" - -@class TUCachingNinePatch; -/** - - This class is included to make it easy to work with NinePatches if (1) all you want are static images (you don't care much about drawing into CGContextRefs) and (2) . Its semantics are probably non-optimal but are very straightforward: it caches every single request you make to it (both NinePatches and the rendered images). If you're only generating a handful of images and/or you're not super memory-constrained you should probably use this class. It has functionality for flushing the cache with various levels of granularity if you need such functionality. - - One thing that's maybe not so obvious is that the methods on this class span two levels of abstraction and caching. Briefly: - - an instance of TUCachingNinePatch has a ninePatch property (that is a TUNinePatch-implementing object) - - TUCachingNinePatch caches all images it generates - - TUNinePatchCache generates and caches instance of TUCachingNinePatch (which in turn cache images) - - Where the danger zone emerges is ninePatchNamed: this constructs a TUCachingNinePatch (which as part of its construction constructs an object implementing TUNinePatch), caches the TUCachingNinePatch instance, and returns that instance's ninePatch property (which is what actually implements the TUNinePatch protocol). This is in fact the behavior we wanted when we made this library, but it is a little subtle. - - */ -@interface TUNinePatchCache : NSObject { - NSMutableDictionary *_ninePatchCache; -} - -// Synthesized Properties -/** - This is where the NinePatches get cached. You should pretty much never look at or manipulate this directly. If I believed in private instance variables this's be private. Maybe I'll make it private soon. - */ -@property(nonatomic, retain, readonly) NSMutableDictionary *ninePatchCache; - --(id)init; -/** - Gets at the application's shared instance, creating it if it doesn't exist. - */ -+(id)shared; - -// Getting Ninepatches Directly -/** - Use this method to get at the actual NinePatch you want to interact with (if eg you're using this cache but need finer-grained control than just generating images). Will load the NinePatch (from the app's main bundle) if it doesn't exist yet. - - @param ninePatchName The name of the NinePatch you're trying to get at. - @returns The NinePatch object you wanted. Can return nil if problems were encountered. - */ --(id < TUNinePatch >)ninePatchNamed:(NSString *)ninePachName; - -// These methods should be private, if I believed in private methods --(TUCachingNinePatch *)cachingNinePatchNamed:(NSString *)ninePatchName; --(void)cacheCachingNinePatch:(TUCachingNinePatch *)cachingNinePatch named:(NSString *)ninePatchName; --(TUCachingNinePatch *)cachedCachingNinePatchNamed:(NSString *)ninePatchName; --(TUCachingNinePatch *)constructCachingNinePatchNamed:(NSString *)ninePatchName; - -// Getting Images Directly -/** - This method renders the image at the requested size using the NinePatch with the passed-in name. Tries to use a cached image and/or NinePatch as possible, otherwise loading from scratch. Any NinePatch or image it loads is subsequently cached. - - @param size The size the output image should be rendered at. - @param ninePatchName the name of the NinePatch you want to use to render the image. Don't include @".9.png" in the name. - @returns An image rendered from the specified ninePatchName at the requested size. Can return nil if difficulties were encountered. Image should be retained if it is important it be held onto by the recipient, but should not be released by the recipient. - */ --(UIImage *)imageOfSize:(CGSize)size forNinePatchNamed:(NSString *)ninePatchName; - -// Getting Ninepatches - Convenience -/** - Semantics same as instance-level method of same name, but calls through to the singleton instance. - */ -+(id < TUNinePatch >)ninePatchNamed:(NSString *)ninePatchName; - -// Getting Images - Convenience -/** - This is a convenience method; calls instance method of the same name on the singleton. Easiest way to use this in your code. - */ -+(UIImage *)imageOfSize:(CGSize)size forNinePatchNamed:(NSString *)ninePatchName; - -// Cache Management - Direct -/** - Flushes all cached content (NinePatches AND their cached rendered images, if any). - */ --(void)flushCache; -/** - Flushes only the content for the NinePatch with the passed-in name. Won't complain if there's no cached NinePatch with the passed-in name. - */ --(void)flushCacheForNinePatchNamed:(NSString *)name; - -// Cache Management - Convenience -/** - Flushes all cached content from the singleton. - */ -+(void)flushCache; - -/** - Flushes the NinePatch with the passed-in name from the singleton (which also flushes any cached images). - */ -+(void)flushCacheForNinePatchNamed:(NSString *)name; - -@end diff --git a/Classes/Utils/NinePatch/TUNinePatchCache.m b/Classes/Utils/NinePatch/TUNinePatchCache.m deleted file mode 100755 index bd6cb9c8b..000000000 --- a/Classes/Utils/NinePatch/TUNinePatchCache.m +++ /dev/null @@ -1,133 +0,0 @@ -// -// TUNinePatchCache.m -// NinePatch -// -// Copyright 2010 Tortuga 22, Inc. All rights reserved. -// - -#import "TUNinePatchCache.h" -#import "TUCachingNinePatch.h" -#import "TUNinePatch.h" - -@interface TUNinePatchCache () - -@property(nonatomic, retain, readwrite) NSMutableDictionary *ninePatchCache; - -@end - - -@implementation TUNinePatchCache - -#pragma mark Synthesized Properties -@synthesize ninePatchCache = _ninePatchCache; - -#pragma mark Init + Dealloc --(id)init { - if (self = [super init]) { - self.ninePatchCache = [NSMutableDictionary dictionary]; - } - return self; -} - -#pragma mark - -+(id)shared { - static TUNinePatchCache *shared; - if (!shared) { - shared = [[self alloc] init]; - } - return shared; -} - -#pragma mark - --(void)dealloc { - self.ninePatchCache = nil; - [super dealloc]; -} - -#pragma mark Getting Ninepatches Directly -// Getting Ninepatches Directly --(id < TUNinePatch >)ninePatchNamed:(NSString *)ninePatchName { - TUCachingNinePatch *cachingNinePatch = [self cachingNinePatchNamed:ninePatchName]; - NPAssertNilOrIsKindOfClass(cachingNinePatch,TUCachingNinePatch); - return (!cachingNinePatch)?(nil):([cachingNinePatch ninePatch]); -} - - --(TUCachingNinePatch *)cachingNinePatchNamed:(NSString *)ninePatchName { - TUCachingNinePatch *cachingNinePatch = [self cachedCachingNinePatchNamed:ninePatchName]; - NPAssertNilOrIsKindOfClass(cachingNinePatch,TUCachingNinePatch); - if (!cachingNinePatch) { - cachingNinePatch = [self constructCachingNinePatchNamed:ninePatchName]; - NPAssertNilOrIsKindOfClass(cachingNinePatch,TUCachingNinePatch); - if (cachingNinePatch) { - [self cacheCachingNinePatch:cachingNinePatch - named:ninePatchName]; - } - } - return cachingNinePatch; -} - --(void)cacheCachingNinePatch:(TUCachingNinePatch *)cachingNinePatch named:(NSString *)ninePatchName { - NPAssertPropertyNonNil(ninePatchCache); - if (cachingNinePatch && ninePatchName) { - [self.ninePatchCache setObject:cachingNinePatch - forKey:ninePatchName]; - } -} - --(TUCachingNinePatch *)cachedCachingNinePatchNamed:(NSString *)ninePatchName { - return (!ninePatchName)?(nil):([self.ninePatchCache objectForKey:ninePatchName]); -} - --(TUCachingNinePatch *)constructCachingNinePatchNamed:(NSString *)ninePatchName { - return (!ninePatchName)?(nil):([TUCachingNinePatch ninePatchCacheWithNinePatchNamed:ninePatchName]); -} - -#pragma mark Getting Images Directly --(UIImage *)imageOfSize:(CGSize)size forNinePatchNamed:(NSString *)ninePatchName { - NPParameterAssertNotNilIsKindOfClass(ninePatchName,NSString); - UIImage *image = nil; - TUCachingNinePatch *cachingNinePatch = [self cachingNinePatchNamed:ninePatchName]; - if (cachingNinePatch) { - image = [cachingNinePatch imageOfSize:size]; - } - return image; -} - -#pragma mark Getting Ninepatches - Convenience -+(TUCachingNinePatch *)cachingNinePatchNamed:(NSString *)ninePatchName { - return [[self shared] ninePatchNamed:ninePatchName]; -} - -+(id < TUNinePatch >)ninePatchNamed:(NSString *)ninePatchName { - TUCachingNinePatch *cachingNinePatch = [[self shared] cachingNinePatchNamed:ninePatchName]; - NPAssertNilOrIsKindOfClass(cachingNinePatch,TUCachingNinePatch); - return (!cachingNinePatch)?(nil):([cachingNinePatch ninePatch]); -} - -#pragma mark Getting Images - Convenience -+(UIImage *)imageOfSize:(CGSize)size forNinePatchNamed:(NSString *)ninePatchName { - return [[self shared] imageOfSize:size - forNinePatchNamed:ninePatchName]; -} - -#pragma mark Cache Management - Direct --(void)flushCache { - [self.ninePatchCache removeAllObjects]; -} --(void)flushCacheForNinePatchNamed:(NSString *)name { - if (name) { - [self.ninePatchCache removeObjectForKey:name]; - } -} - -#pragma mark Cache Management - Convenience -+(void)flushCache { - [[self shared] flushCache]; -} - -+(void)flushCacheForNinePatchNamed:(NSString *)name { - [[self shared] flushCacheForNinePatchNamed:name]; -} - -@end \ No newline at end of file diff --git a/Classes/Utils/NinePatch/TUNinePatchCachingCategories.h b/Classes/Utils/NinePatch/TUNinePatchCachingCategories.h deleted file mode 100755 index 7f897495b..000000000 --- a/Classes/Utils/NinePatch/TUNinePatchCachingCategories.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// TUNinePatchCachingCategories.h -// NinePatch -// -// Copyright 2010 Tortuga 22, Inc. All rights reserved. -// - -#import -#import -#import - -@interface NSString (NinePatchCaching) - -+(NSString *)ninePatchKeyStringForSize:(CGSize)size; - -@end - -@interface NSDictionary (NinePatchCaching) - --(id)objectForSize:(CGSize)size; - -@end - -@interface NSMutableDictionary (NinePatchCaching) - --(void)setObject:(id)object forSize:(CGSize)size; - -@end diff --git a/Classes/Utils/NinePatch/TUNinePatchCachingCategories.m b/Classes/Utils/NinePatch/TUNinePatchCachingCategories.m deleted file mode 100755 index 7ec6d81af..000000000 --- a/Classes/Utils/NinePatch/TUNinePatchCachingCategories.m +++ /dev/null @@ -1,52 +0,0 @@ -// -// TUNinePatchCachingCategories.m -// NinePatch -// -// Copyright 2010 Tortuga 22, Inc. All rights reserved. -// - -#import "TUNinePatchCachingCategories.h" - -@implementation NSString (NinePatchCaching) - -/** - It's not clear we can't just use NSStringFromCGSize. This might get cut in a future revision. - */ -+(NSString *)ninePatchKeyStringForSize:(CGSize)size { - return [NSString stringWithFormat:@"ninePatchKeyString.%#.0f.%#.0f",size.width,size.height]; -} - -@end - -@implementation NSDictionary (NinePatchCaching) - -/** - Convenience method to make it a little less annoying to pull objects out of the caches keyed by their size. - */ --(id)objectForSize:(CGSize)size { - id object = nil; - NSString *key = [NSString ninePatchKeyStringForSize:size]; - if (key) { - object = [self objectForKey:key]; - } - return object; -} - -@end - -@implementation NSMutableDictionary (NinePatchCaching) - -/** - Convenience method to make it a little less annoying to put objects in the caches keyed by their size. - */ --(void)setObject:(id)object forSize:(CGSize)size { - if (object) { - NSString *key = [NSString ninePatchKeyStringForSize:size]; - if (key) { - [self setObject:object - forKey:key]; - } - } -} - -@end diff --git a/Classes/Utils/NinePatch/TUNinePatchProtocols.h b/Classes/Utils/NinePatch/TUNinePatchProtocols.h deleted file mode 100755 index f3889b1ad..000000000 --- a/Classes/Utils/NinePatch/TUNinePatchProtocols.h +++ /dev/null @@ -1,121 +0,0 @@ -// -// TUNinePatch.h -// NinePatch -// -// Copyright 2009 Tortuga 22, Inc. All rights reserved. -// - -#import -#import - -/** - - Defines the methods shared by all concrete NinePatch classes. Expect many of these methods to be removed from the - protocol as the library is improved. - - */ -@protocol TUNinePatch < NSObject, NSCoding, NSCopying > - -// TUNinePatch Protocol Methods - Drawing -/** - This draws the NinePatch with its upper-left corner at a specified location in a specified context, scaled to fit content of the size. This is a good method to use when drawing NinePatches that use the content bounds. This method will probably be improved in the future to return the upper-left corner for the content to be drawn. - - @param context A non-nil CGContextRef into which NinePatch will be drawn. - @param point The upper left corner the NinePatch will be drawn at. - @param size The size of the content the NinePatch will be sized to contain. - */ --(void)inContext:(CGContextRef)context drawAtPoint:(CGPoint)point forContentOfSize:(CGSize)size; - -/** - This draws the NinePatch centered (horizontally and vertically) inside the containmentRect in the specified context, sized to fit content of the passed-in size. This is essentially a convenience method wrapping inContext:drawAtPoint:forContentOfSize:. Like its cousin it'll probably be modified to return information about where the content should be drawn. Will let the NinePatch overflow the containmentRect if the necessary size is sufficiently large; it'll be centered, just too big. - - @param context A non-nil CGContextRef into which NinePatch will be drawn. - @param containmentRect the rect in which the NinePatch will be centered. - @param size The size of the content the NinePatch will be sized to contain. - */ --(void)inContext:(CGContextRef)context drawCenteredInRect:(CGRect)containmentRect forContentOfSize:(CGSize)size; - -/** - This method draws the NinePatch into the passed-in context filling the passed-in rect. In all current implementations of TUNinePatch the other drawing utilities eventually call through this method to do their actual drawing. - - @param context A non-nil CGContextRef into which NinePatch will be drawn. - @param rect The rect into which the NinePatch will be drawn. NinePatch is scaled to fill the rect. - */ --(void)inContext:(CGContextRef)context drawInRect:(CGRect)rect; - -// TUNinePatch Protocol Methods - Image Construction -/** - Renders the NinePatch into an image of the requested size. Implementations vary in their memory management here -- to guarantee the returned image hangs around you should retain it. - - @param size The size the output UIImage should be. - @returns A UIImage rendering of the NinePatch scaled like the passed-in size. - */ --(UIImage *)imageOfSize:(CGSize)size; - -// TUNinePatch Protocol Methods - Sizing -/** - Returns YES if the NinePatch scales horizontally, NO otherwise. May be removed from protocol in future. - */ --(BOOL)stretchesHorizontally; -/** - Returns YES if the NinePatch scales vertically, NO otherwise. May be removed from protocol in future. - */ --(BOOL)stretchesVertically; - -/** - Returns smallest horizontal size you scan scale NinePatch down to. This is usually equal to the leftEdge + the rightEdge (sending central column width -> 0). May be removed from protocol in future. - - @returns minimumWidth the smallest width NinePatch will render at. - */ --(CGFloat)minimumWidth; - -/** - Returns smallest vertical size you scan scale NinePatch down to. This is usually equal to the topEdge + bottomEdge (sending central row height -> 0). May be removed from protocol in future. - - @returns minimumHeight the smallest height NinePatch will render at. - */ --(CGFloat)minimumHeight; - -/** - Returns CGSize created from minimumWidth and minimumHeight in the obvious way. - */ --(CGSize)minimumSize; - -/** - This is used for layout. Recall that NinePatch allows you to specify a "content region" (into which the content must fit) as a way of standardizing the amount of padding you do when using a particular NinePatch. This method returns the size the NinePatch needs to be drawn at to correctly accommodate content of the passed-in size. Note that for NinePatches that don't specify anything wrt content size this is the identity function. - - @param contentSize The size of the content you're using the NinePatch to display. - @returns The size you need to draw the NinePatch at to accommodate the content. - */ --(CGSize)sizeForContentOfSize:(CGSize)contentSize; - -/** - This is used for layout. This is basically a convenience function to calculate the offset for where "content" starts. It's the identity function when the NinePatch doesn't specify anything for the content region. - - @param point The point at which you're planning to place the upper left corner of the NinePatch when you draw it. - @returns The point at which you need to place the upper left corner of the content you're going to draw. - */ --(CGPoint)upperLeftCornerForContentWhenDrawnAtPoint:(CGPoint)point; - -// TUNinePatch Protocol Methods - Geometry -/** - The width of the left column. This geometric property lookup is probably going to get removed from the protocol. - */ --(CGFloat)leftEdgeWidth; - -/** - The width of the right column. This geometric property lookup is probably going to get removed from the protocol. - */ --(CGFloat)rightEdgeWidth; - -/** - The width of the upper row. This geometric property lookup is probably going to get removed from the protocol. - */ --(CGFloat)upperEdgeHeight; - -/** - The width of the lower column. This geometric property lookup is probably going to get removed from the protocol. - */ --(CGFloat)lowerEdgeHeight; - -@end \ No newline at end of file diff --git a/Classes/Utils/NinePatch/TUVerticalNinePatch.h b/Classes/Utils/NinePatch/TUVerticalNinePatch.h deleted file mode 100755 index c9c266f28..000000000 --- a/Classes/Utils/NinePatch/TUVerticalNinePatch.h +++ /dev/null @@ -1,36 +0,0 @@ -// -// TUVerticalNinePatch.h -// NinePatch -// -// Copyright 2009 Tortuga 22, Inc. All rights reserved. -// - -#import -#import -#import "TUNinePatch.h" -#import "TUNinePatchProtocols.h" - -/** - Concrete TUNinePatch instance. Handles NinePatches that only stretch vertically. Only instantiate directly if you know what you're doing. - */ -@interface TUVerticalNinePatch : TUNinePatch < TUNinePatch > { - UIImage *_upperEdge; - UIImage *_lowerEdge; -} - -// Synthesized Properties -@property(nonatomic, retain, readonly) UIImage *upperEdge; -@property(nonatomic, retain, readonly) UIImage *lowerEdge; - -// Init + Dealloc --(id)initWithCenter:(UIImage *)center contentRegion:(CGRect)contentRegion tileCenterVertically:(BOOL)tileCenterVertically tileCenterHorizontally:(BOOL)tileCenterHorizontally upperEdge:(UIImage *)upperEdge lowerEdge:(UIImage *)lowerEdge; --(void)dealloc; - -// TUNinePatch Overrides --(void)drawInRect:(CGRect)rect; --(BOOL)stretchesHorizontally; --(CGSize)sizeForContentOfSize:(CGSize)contentSize; --(CGFloat)upperEdgeHeight; --(CGFloat)lowerEdgeHeight; - -@end \ No newline at end of file diff --git a/Classes/Utils/NinePatch/TUVerticalNinePatch.m b/Classes/Utils/NinePatch/TUVerticalNinePatch.m deleted file mode 100755 index f2363050c..000000000 --- a/Classes/Utils/NinePatch/TUVerticalNinePatch.m +++ /dev/null @@ -1,132 +0,0 @@ -// -// TUVerticalNinePatch.m -// NinePatch -// -// Copyright 2009 Tortuga 22, Inc. All rights reserved. -// - -#import "TUVerticalNinePatch.h" - -@interface TUVerticalNinePatch () - -// Synthesized Properties -@property(nonatomic, retain, readwrite) UIImage *upperEdge; -@property(nonatomic, retain, readwrite) UIImage *lowerEdge; - -@end - - -@implementation TUVerticalNinePatch - -#pragma mark Synthesized Properties -@synthesize upperEdge = _upperEdge; -@synthesize lowerEdge = _lowerEdge; - -#pragma mark NSCoding --(id)initWithCoder:(NSCoder *)coder { - if (self = [super initWithCoder:coder]) { - self.upperEdge = (UIImage *)[coder decodeObjectForKey:@"upperEdge"]; - self.lowerEdge = (UIImage *)[coder decodeObjectForKey:@"lowerEdge"]; - } - return self; -} - --(void)encodeWithCoder:(NSCoder *)coder { - [super encodeWithCoder:coder]; - - [coder encodeObject:self.upperEdge - forKey:@"upperEdge"]; - - [coder encodeObject:self.lowerEdge - forKey:@"lowerEdge"]; -} - -#pragma mark NSCopying --(id)copyWithZone:(NSZone *)zone { - return [[[self class] allocWithZone:zone] initWithCenter:self.center - contentRegion:self.contentRegion - tileCenterVertically:self.tileCenterVertically - tileCenterHorizontally:self.tileCenterHorizontally - upperEdge:self.upperEdge - lowerEdge:self.lowerEdge]; -} - -#pragma mark Init + Dealloc --(id)initWithCenter:(UIImage *)center contentRegion:(CGRect)contentRegion tileCenterVertically:(BOOL)tileCenterVertically tileCenterHorizontally:(BOOL)tileCenterHorizontally upperEdge:(UIImage *)upperEdge lowerEdge:(UIImage *)lowerEdge { - NPParameterAssertNotNilIsKindOfClass(upperEdge,UIImage); - NPParameterAssertNotNilIsKindOfClass(lowerEdge,UIImage); - if (self = [super initWithCenter:center - contentRegion:contentRegion - tileCenterVertically:tileCenterVertically - tileCenterHorizontally:tileCenterHorizontally]) { - self.upperEdge = upperEdge; - self.lowerEdge = lowerEdge; - } - return self; -} - -#pragma mark - --(void)dealloc { - self.upperEdge = nil; - self.lowerEdge = nil; - [super dealloc]; -} - -#pragma mark TUNinePatch Overrides --(void)drawInRect:(CGRect)rect { - NPSelfProperty(center); - NPSelfProperty(upperEdge); - NPSelfProperty(lowerEdge); - CGFloat width = [self minimumWidth]; - [self.center drawInRect:CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect) + [self upperEdgeHeight], width, CGRectGetHeight(rect) - ([self upperEdgeHeight] + [self lowerEdgeHeight]))]; - if (self.upperEdge) { - [self.upperEdge drawAtPoint:CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect))]; - } - if (self.lowerEdge) { - [self.lowerEdge drawAtPoint:CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect) - [self lowerEdgeHeight])]; - } -} - -#pragma mark - --(BOOL)stretchesHorizontally { - return NO; -} - --(CGSize)sizeForContentOfSize:(CGSize)contentSize { - NPAInputLog(@"sizeForContentOfSize:'%@'",NSStringFromCGSize(contentSize)); - CGSize outSize = [super sizeForContentOfSize:contentSize]; - outSize.width = [self minimumWidth]; - NPCGSOutputLog(outSize); - return outSize; -} - -#pragma mark - --(CGFloat)upperEdgeHeight { - NPSelfProperty(upperEdge); - CGFloat upperEdgeHeight = 0.0f; - if (self.upperEdge) { - upperEdgeHeight = [self.upperEdge size].height; - } - NPFOutputLog(upperEdgeHeight); - return upperEdgeHeight; -} - --(CGFloat)lowerEdgeHeight { - NPSelfProperty(lowerEdge); - CGFloat lowerEdgeHeight = 0.0f; - if (self.lowerEdge) { - lowerEdgeHeight = [self.lowerEdge size].height; - } - NPFOutputLog(lowerEdgeHeight); - return lowerEdgeHeight; -} - -#pragma mark Customized Description Overrides --(NSString *)descriptionPostfix { - return [NSString stringWithFormat:@"%@, self.upperEdge:<'%@'>, self.lowerEdge:<'%@'>", - [super descriptionPostfix], - self.upperEdge, - self.lowerEdge]; -} - -@end \ No newline at end of file diff --git a/Classes/Utils/NinePatch/UIImage-TUNinePatch.h b/Classes/Utils/NinePatch/UIImage-TUNinePatch.h deleted file mode 100755 index 78ba6fe67..000000000 --- a/Classes/Utils/NinePatch/UIImage-TUNinePatch.h +++ /dev/null @@ -1,77 +0,0 @@ -// -// UIImage-TUNinePatch.h -// NinePatch -// -// Copyright 2009 Tortuga 22, Inc. All rights reserved. -// - -#import -#import -#import "TUNinePatchProtocols.h" - -void TUImageLog(UIImage *image, NSString *imageName); -/** - This category implements all the image-slicing, pixel-tasting, and similar image-manipulation and image-analysis functions. These are only used in methods that'll probably become private real soon now, so maybe a "not much to see here" sign is called for. - */ -@interface UIImage (TUNinePatch) - -// Black Pixel Searching - Corners --(BOOL)upperLeftCornerIsBlackPixel; --(BOOL)upperRightCornerIsBlackPixel; --(BOOL)lowerLeftCornerIsBlackPixel; --(BOOL)lowerRightCornerIsBlackPixel; - -// Pixel Tasting - Single Pixel --(BOOL)isBlackPixel; - -// Black Pixel Searching - Strips --(NSRange)blackPixelRangeInUpperStrip; --(NSRange)blackPixelRangeInLowerStrip; --(NSRange)blackPixelRangeInLeftStrip; --(NSRange)blackPixelRangeInRightStrip; - -// Pixel Tasting - Strips --(NSRange)blackPixelRangeAsVerticalStrip; --(NSRange)blackPixelRangeAsHorizontalStrip; - -// Corners - Rects --(CGRect)upperLeftCornerRect; --(CGRect)lowerLeftCornerRect; --(CGRect)upperRightCornerRect; --(CGRect)lowerRightCornerRect; - -// Corners - Slicing --(UIImage *)upperLeftCorner; --(UIImage *)lowerLeftCorner; --(UIImage *)upperRightCorner; --(UIImage *)lowerRightCorner; - -// Strips - Sizing --(CGRect)upperStripRect; --(CGRect)lowerStripRect; --(CGRect)leftStripRect; --(CGRect)rightStripRect; - -// Strips - Slicing --(UIImage *)upperStrip; --(UIImage *)lowerStrip; --(UIImage *)leftStrip; --(UIImage *)rightStrip; - -// Subimage Slicing --(UIImage *)subImageInRect:(CGRect)rect; - -// Nine-Patch Content Extraction --(UIImage *)imageAsNinePatchImage; - --(UIImage *)extractUpperLeftCornerForStretchableRegion:(CGRect)stretchableRegion; --(UIImage *)extractUpperRightCornerForStretchableRegion:(CGRect)stretchableRegion; --(UIImage *)extractLowerLeftCornerForStretchableRegion:(CGRect)stretchableRegion; --(UIImage *)extractLowerRightCornerForStretchableRegion:(CGRect)stretchableRegion; --(UIImage *)extractLeftEdgeForStretchableRegion:(CGRect)stretchableRegion; --(UIImage *)extractRightEdgeForStretchableRegion:(CGRect)stretchableRegion; --(UIImage *)extractUpperEdgeForStretchableRegion:(CGRect)stretchableRegion; --(UIImage *)extractLowerEdgeForStretchableRegion:(CGRect)stretchableRegion; --(UIImage *)extractCenterForStretchableRegion:(CGRect)stretchableRegion; - -@end diff --git a/Classes/Utils/NinePatch/UIImage-TUNinePatch.m b/Classes/Utils/NinePatch/UIImage-TUNinePatch.m deleted file mode 100755 index 4f9d16095..000000000 --- a/Classes/Utils/NinePatch/UIImage-TUNinePatch.m +++ /dev/null @@ -1,539 +0,0 @@ -// -// UIImage-TUNinePatch.m -// NinePatch -// -// Copyright 2009 Tortuga 22, Inc. All rights reserved. -// - -#import "UIImage-TUNinePatch.h" -#import "TUNinePatchProtocols.h" - -void TUImageLog(UIImage *image, NSString *imageName) { - if (image && imageName) { - NSString *fullFileName = [imageName stringByAppendingString:@".png"]; - if (fullFileName) { - NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; - if (documentsDirectory) { - NSString *fullFilePath = [documentsDirectory stringByAppendingPathComponent:fullFileName]; - if (fullFilePath) { - NSData *pngData = UIImagePNGRepresentation(image); - if (pngData) { - NSFileManager *fileManager = [NSFileManager defaultManager]; - if (fileManager) { - BOOL succeeded = [fileManager createFileAtPath:fullFilePath contents:pngData attributes:nil]; - if (succeeded) { - DLog(@"Seemingly successfully wrote image to file at: '%@'.",fullFilePath); - } else { - DLog(@"Seemingly failed to write image to file at: '%@'.",fullFilePath); - } - } else { - LLog(@"Couldn't get default fileManager, aborting imagelog."); - } - } else { - LLog(@"Couldn't get PNGRepresentation, aborting imagelog."); - } - } else { - LLog(@"Couldn't get fullFilePath, aborting imagelog."); - } - } else { - LLog(@"Couldn't get fullFilePath, aborting imagelog."); - } - } else { - DLog(@"Could't get fullFileName, aborting imageLog."); - } - } else { - DLog(@"Can't log image: '%@', imageName: '%@', as one or both are nil.",image, imageName); - } -} - -@implementation UIImage (TUNinePatch) - -#pragma mark Black Pixel Searching - Corners --(BOOL)upperLeftCornerIsBlackPixel { - BOOL upperLeftCornerIsBlackPixel = NO; - UIImage *upperLeftCorner = [self upperLeftCorner]; - if (upperLeftCorner) { - upperLeftCornerIsBlackPixel = [upperLeftCorner isBlackPixel]; - } - NPBOutputLog(upperLeftCornerIsBlackPixel); - return upperLeftCornerIsBlackPixel; -} - --(BOOL)upperRightCornerIsBlackPixel { - BOOL upperRightCornerIsBlackPixel = NO; - UIImage *upperRightCorner = [self upperRightCorner]; - if (upperRightCorner) { - upperRightCornerIsBlackPixel = [upperRightCorner isBlackPixel]; - } - NPBOutputLog(upperRightCornerIsBlackPixel); - return upperRightCornerIsBlackPixel; -} - --(BOOL)lowerLeftCornerIsBlackPixel { - BOOL lowerLeftCornerIsBlackPixel = NO; - UIImage *lowerLeftCorner = [self lowerLeftCorner]; - if (lowerLeftCorner) { - lowerLeftCornerIsBlackPixel = [lowerLeftCorner isBlackPixel]; - } - NPBOutputLog(lowerLeftCornerIsBlackPixel); - return lowerLeftCornerIsBlackPixel; -} - --(BOOL)lowerRightCornerIsBlackPixel { - BOOL lowerRightCornerIsBlackPixel = NO; - UIImage *lowerRightCorner = [self lowerRightCorner]; - if (lowerRightCorner) { - lowerRightCornerIsBlackPixel = [lowerRightCorner isBlackPixel]; - } - NPBOutputLog(lowerRightCornerIsBlackPixel); - return lowerRightCornerIsBlackPixel; -} - -#pragma mark Pixel Tasting - Single Pixel --(BOOL)isBlackPixel { - NPAssert(([self size].width > 0.0f), @"Should have width > 0.0f"); - NPAssert(([self size].height > 0.0f), @"Should have height > 0.0f"); - BOOL isBlackPixel = NO; - if (([self size].width > 0.0f) && ([self size].height > 0.0f)) { - CGImageRef cgImage = [self CGImage]; - NSUInteger width = CGImageGetWidth(cgImage); - NSUInteger height = CGImageGetHeight(cgImage); - NSUInteger bytesPerRow = width * TURGBABytesPerPixel; - NSUInteger bitsPerComponent = 8; - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - UInt8 *pixelByteData = malloc(width * height * TURGBABytesPerPixel); - - - CGContextRef context = CGBitmapContextCreate( - (void *)pixelByteData, - width, - height, - bitsPerComponent, - bytesPerRow, - colorSpace, - kCGImageAlphaPremultipliedLast); - - CGContextDrawImage(context, CGRectMake(0.0f,0.0f,1.0f,1.0f), cgImage); - TURGBAPixel *pixelData = (TURGBAPixel *) CGBitmapContextGetData(context); - if (pixelData) { - isBlackPixel = TURGBAPixelIsBlack(pixelData[0]); - } - CGContextRelease(context); - CGColorSpaceRelease(colorSpace); - free(pixelByteData); - } - NPBOutputLog(isBlackPixel); - return isBlackPixel; -} - -#pragma mark Black Pixel Searching - Strips --(NSRange)blackPixelRangeInUpperStrip { - NSRange blackPixelRangeInUpperStrip = TUNotFoundRange; - UIImage *upperStrip = [self upperStrip]; - if (upperStrip) { - blackPixelRangeInUpperStrip = [upperStrip blackPixelRangeAsHorizontalStrip]; - } - NPNSROutputLog(blackPixelRangeInUpperStrip); - return blackPixelRangeInUpperStrip; -} - --(NSRange)blackPixelRangeInLowerStrip { - NSRange blackPixelRangeInLowerStrip = TUNotFoundRange; - UIImage *lowerStrip = [self lowerStrip]; - if (lowerStrip) { - blackPixelRangeInLowerStrip = [lowerStrip blackPixelRangeAsHorizontalStrip]; - } - NPNSROutputLog(blackPixelRangeInLowerStrip); - return blackPixelRangeInLowerStrip; -} - --(NSRange)blackPixelRangeInLeftStrip { - NSRange blackPixelRangeInLeftStrip = TUNotFoundRange; - UIImage *leftStrip = [self leftStrip]; - if (leftStrip) { - blackPixelRangeInLeftStrip = [leftStrip blackPixelRangeAsVerticalStrip]; - } - NPNSROutputLog(blackPixelRangeInLeftStrip); - return blackPixelRangeInLeftStrip; -} - --(NSRange)blackPixelRangeInRightStrip { - NSRange blackPixelRangeInRightStrip = TUNotFoundRange; - UIImage *rightStrip = [self rightStrip]; - if (rightStrip) { - blackPixelRangeInRightStrip = [rightStrip blackPixelRangeAsVerticalStrip]; - } - NPNSROutputLog(blackPixelRangeInRightStrip); - return blackPixelRangeInRightStrip; -} - -#pragma mark Pixel Tasting - Strips --(NSRange)blackPixelRangeAsVerticalStrip { - NPAssert([self size].width == 1.0f, @"This method assumes the image has width == 1.0f"); - NSRange blackPixelRangeAsVerticalStrip = TUNotFoundRange; - NSUInteger firstBlackPixel = NSNotFound; - NSUInteger lastBlackPixel = NSNotFound; - if ([self size].height > 0.0f) { - CGImageRef cgImage = [self CGImage]; - - NSUInteger width = CGImageGetWidth(cgImage); - NSUInteger height = CGImageGetHeight(cgImage); - NSUInteger bytesPerRow = width * TURGBABytesPerPixel; - NSUInteger bitsPerComponent = 8; - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - UInt8 *pixelByteData = malloc(width * height * TURGBABytesPerPixel); - - CGContextRef context = CGBitmapContextCreate( - (void *)pixelByteData, - width, - height, - bitsPerComponent, - bytesPerRow, - colorSpace, - kCGImageAlphaPremultipliedLast); - - // NEW: seeing nondetermnistic errors where sometimes the image is parsed right - // and sometimes not parsed right. The followthing three lines paint the context - // to solid white, then paste the image over it, so this ought to normalize the - // outcome a bit more. - CGRect contextBounds = CGRectMake(0.0f, 0.0f, width, height); - CGContextSetFillColorWithColor(context, [[UIColor whiteColor] CGColor]); - CGContextFillRect(context, contextBounds); - - // Having normalized the context we now paint the image - CGContextDrawImage(context, contextBounds, cgImage); - TURGBAPixel *pixelData = (TURGBAPixel *) CGBitmapContextGetData(context); - if (pixelData) { - // CF note in the AsHorizontal method below - for (NSUInteger i = 0; i < height; i++) { - if (TURGBAPixelIsBlack(pixelData[((height - 1) - i)])) { - firstBlackPixel = ((height - 1) - i); - } - if (TURGBAPixelIsBlack(pixelData[i])) { - lastBlackPixel = i; - } - } - - if ((firstBlackPixel != NSNotFound) && (lastBlackPixel != NSNotFound)) { - NPAssert(lastBlackPixel >= firstBlackPixel, ([NSString stringWithFormat:@"Got firstBlackPixel:'%d' and lastBlackPixel:'%d'.",firstBlackPixel,lastBlackPixel])); - blackPixelRangeAsVerticalStrip.location = TUTruncateWithin(firstBlackPixel, 0, height - 1) / self.scale; - // We can't just use TUTruncateAtZero on lastBlackPixel - firstBlackPixel here. - // The semantics of pixel coordinates are such that a zero difference between lastBlackPixel and firstBlackPixel is ok - // but < 0 is obv. very bad. - // Thus 1 + TUTruncateAtZero(lastBlackPixel - firstBlackPixel) won't work. - // and fixing the expression s.t. it does work is more complicated than - // just breaking it down like so. - NSInteger length = lastBlackPixel - firstBlackPixel; - if (length >= 0) { - length += 1; - } else { - length = 0; - } - blackPixelRangeAsVerticalStrip.length = length/self.scale; - } - } - CGContextRelease(context); - CGColorSpaceRelease(colorSpace); - free(pixelByteData); - } - NPNSROutputLog(blackPixelRangeAsVerticalStrip); - return blackPixelRangeAsVerticalStrip; -} - --(NSRange)blackPixelRangeAsHorizontalStrip { - NPAssert([self size].height == 1.0f, @"This method assumes the image has height == 1.0f"); - NSRange blackPixelRangeAsHorizontalStrip = TUNotFoundRange; - NSUInteger firstBlackPixel = NSNotFound; - NSUInteger lastBlackPixel = NSNotFound; - if ([self size].width > 0.0f) { - CGImageRef cgImage = [self CGImage]; - - NSUInteger width = CGImageGetWidth(cgImage); - NSUInteger height = CGImageGetHeight(cgImage); - NSUInteger bytesPerRow = width * TURGBABytesPerPixel; - NSUInteger bitsPerComponent = 8; - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - UInt8 *pixelByteData = malloc(width * height * TURGBABytesPerPixel); - - CGContextRef context = CGBitmapContextCreate( - (void *)pixelByteData, - width, - height, - bitsPerComponent, - bytesPerRow, - colorSpace, - kCGImageAlphaPremultipliedLast); - - // NEW: seeing nondetermnistic errors where sometimes the image is parsed right - // and sometimes not parsed right. The followthing three lines paint the context - // to solid white, then paste the image over it, so this ought to normalize the - // outcome a bit more. - CGRect contextBounds = CGRectMake(0.0f, 0.0f, width, height); - CGContextSetFillColorWithColor(context, [[UIColor whiteColor] CGColor]); - CGContextFillRect(context, contextBounds); - - // Having normalized the context we now paint the image - CGContextDrawImage(context, contextBounds, cgImage); - TURGBAPixel *pixelData = (TURGBAPixel *) CGBitmapContextGetData(context); - if (pixelData) { - // The for loop below is walking the strip from both ends. - // Basically you could do this check a bunch of ways, with a - // bunch of trade-offs in terms of how fast it is and how robust it - // is and how any "format errors" in your nine patch manifest. - // - // What I have found is that ninepatch is a fussy format, with a - // common failure mode being that you painted a pixel "black" but - // either got the alpha wrong, or it wasn't quite black, or it - // didn't composite to black, etc., and thus get invalid ninepatches. - // - // What I do here is just look for the highest and lowest black pixels, - // and treat anything in between as also black. EG: - // - // - if X == black and O == not-black - // - then these square brackes - [ and ] - enclose the "black" region - // - // - then: OOOOXXXXXOOOOO -> OOOO[XXXXX]OOOOO - // - but also: OOOXXOOXXOOO -> OOO[XXOOXX]OOO - // - and even: OXOOOOOOOXO -> O[XOOOOOOOX]O - // - // This is a judgement call on my part, in that the approach I can take to - // accomplish this is straightforward without any complicated state tracking, - // and the behavior it has in the face of "invalid" nine-patches is generally - // what I meant, anyways. - // - // The actual implementation is straightforward but suboptimal. - // I look through the array once, iterating i from 0->(width -1). - // On each iteration I taste the pixel @ i and at (width - 1) -1, - // and if the pixel @ i is black I set the "lastBlackPixel" == i - // and if the pixel @ (width - 1) - i is black I set the "firstBlackPixel" - // to (width - 1) - i. - // - // Once the loop is done the values in the lastBlackPixel and firstBlackPixel - // contain what they ought to have. - // - // Given the continual risk of hard-to-spot off-by-one errors throughout this - // library I've opted to keep it dumb and suboptimal in places like this one, - // so that I can be more comfortable that what problems there are are elsewhere. - // - // If you subseqently do add an improved loop please wrap it in ifdefs like - // #ifdef CLEVERNESS YOUR-CODE #else DUMB-CODE #endif - // - for (NSUInteger i = 0; i < width; i++) { - if (TURGBAPixelIsBlack(pixelData[((width - 1) - i)])) { - firstBlackPixel = ((width - 1) - i); - } - if (TURGBAPixelIsBlack(pixelData[i])) { - lastBlackPixel = i; - } - } - - if ((firstBlackPixel != NSNotFound) && (lastBlackPixel != NSNotFound)) { - NPAssert(lastBlackPixel >= firstBlackPixel, ([NSString stringWithFormat:@"Got firstBlackPixel:'%d' and lastBlackPixel:'%d'.",firstBlackPixel,lastBlackPixel])); - blackPixelRangeAsHorizontalStrip.location = TUTruncateWithin(firstBlackPixel, 0, width - 1) / self.scale; - // We can't just use TUTruncateAtZero on lastBlackPixel - firstBlackPixel here. - // The semantics of pixel coordinates are such that a zero difference between lastBlackPixel and firstBlackPixel is ok - // but < 0 is obv. very bad. - // Thus 1 + TUTruncateAtZero(lastBlackPixel - firstBlackPixel) won't work. - // and fixing the expression s.t. it does work is more complicated than - // just breaking it down like so. - NSInteger length = lastBlackPixel - firstBlackPixel; - if (length >= 0) { - length += 1; - } else { - length = 0; - } - blackPixelRangeAsHorizontalStrip.length = length / self.scale; - } - } - CGContextRelease(context); - CGColorSpaceRelease(colorSpace); - free(pixelByteData); - } - NPNSROutputLog(blackPixelRangeAsHorizontalStrip); - return blackPixelRangeAsHorizontalStrip; -} - -#pragma mark Corners - Rects --(CGRect)upperLeftCornerRect { - return CGRectMake(0.0f, 0.0f, 1.0f/self.scale, 1.0f/self.scale); -} - --(CGRect)lowerLeftCornerRect { - return CGRectMake(0.0f, [self size].height - (1.0f/self.scale), 1.0f/self.scale, 1.0f/self.scale); -} - --(CGRect)upperRightCornerRect { - return CGRectMake([self size].width - (1.0f/self.scale), 0.0f, 1.0f/self.scale, 1.0f/self.scale); -} - --(CGRect)lowerRightCornerRect { - return CGRectMake([self size].width - 1.0f, [self size].height - (1.0f/self.scale), 1.0f/self.scale, 1.0f/self.scale); -} - -#pragma mark Corners - Slicing --(UIImage *)upperLeftCorner { - return [self subImageInRect:[self upperLeftCornerRect]]; -} - --(UIImage *)lowerLeftCorner { - return [self subImageInRect:[self lowerLeftCornerRect]]; -} - --(UIImage *)upperRightCorner { - return [self subImageInRect:[self upperRightCornerRect]]; -} - --(UIImage *)lowerRightCorner { - return [self subImageInRect:[self lowerRightCornerRect]]; -} - -#pragma mark Strips - Sizing --(CGRect)upperStripRect { - CGSize selfSize = [self size]; - CGFloat stripWidth = TUTruncateAtZero(selfSize.width - (2.0f/self.scale)); - return CGRectMake((1.0f/self.scale), 0.0f, stripWidth, 1.0f/self.scale); -} - --(CGRect)lowerStripRect { - CGSize selfSize = [self size]; - CGFloat stripWidth = TUTruncateAtZero(selfSize.width - (2.0f/self.scale)); - return CGRectMake(1.0f/self.scale, selfSize.height - (1.0f/self.scale), stripWidth, 1.0f/self.scale); -} - --(CGRect)leftStripRect { - CGSize selfSize = [self size]; - CGFloat stripHeight = TUTruncateAtZero(selfSize.height - (2.0f/self.scale)); - return CGRectMake(0.0f, 1.0f/self.scale, 1.0f/self.scale, stripHeight); -} - --(CGRect)rightStripRect { - CGSize selfSize = [self size]; - CGFloat stripHeight = TUTruncateAtZero(selfSize.height - (2.0f/self.scale)); - return CGRectMake(selfSize.width - (1.0f/self.scale), 1.0f/self.scale, 1.0f/self.scale, stripHeight); -} - -#pragma mark Strips - Slicing --(UIImage *)upperStrip { - return [self subImageInRect:[self upperStripRect]]; -} - --(UIImage *)lowerStrip { - return [self subImageInRect:[self lowerStripRect]]; -} - --(UIImage *)leftStrip { - return [self subImageInRect:[self leftStripRect]]; -} - --(UIImage *)rightStrip { - return [self subImageInRect:[self rightStripRect]]; -} - --(UIImage *)subImageInRect:(CGRect)rect { - NPAInputLog(@"subImageInRect:'%@'",NSStringFromCGRect(rect)); - UIImage *subImage = nil; - CGImageRef cir = [self CGImage]; - if (cir) { - rect.origin.x *= self.scale; - rect.origin.y *= self.scale; - rect.size.width *= self.scale; - rect.size.height *= self.scale; - CGImageRef subCGImage = CGImageCreateWithImageInRect(cir, rect); - if (subCGImage) { - subImage = [UIImage imageWithCGImage:subCGImage scale:self.scale orientation:self.imageOrientation]; - CGImageRelease(subCGImage); - NPAssertNilOrIsKindOfClass(subImage,UIImage); - NPAssert((CGSizeEqualToSize([subImage size], rect.size)), @"Shouldn't get unequal subimage and requested sizes."); - } else { - DLog(@"Couldn't create subImage in rect: '%@'.", NSStringFromCGRect(rect)); - } - } else { - LLog(@"self.CGImage is somehow nil."); - } - //DLog(@"[%@:<0x%x> subImageInRect:%@] yielded subImage: '%@' of size: '%@'", [self class], ((NSUInteger) self), NSStringFromCGRect(rect), subImage, NSStringFromCGSize([subImage size])); - //IMLog(self, @"subImageInRectSourceImage"); - //IMLog(subImage, @"subImageInRect"); - NPOOutputLog(subImage); - return subImage; -} - -#pragma mark Nine-Patch Content Extraction --(UIImage *)imageAsNinePatchImage { - UIImage *imageOfNinePatchImage = nil; - CGFloat width = [self size].width - (2.0f/self.scale); - CGFloat height = [self size].height - (2.0f/self.scale); - if (width > 0.0f && height > 0.0f) { - imageOfNinePatchImage = [self subImageInRect:CGRectMake((1.0f/self.scale), (1.0f/self.scale), width, height)]; - } - NPOOutputLog(imageOfNinePatchImage); - return imageOfNinePatchImage; -} - -#pragma mark - --(UIImage *)extractUpperLeftCornerForStretchableRegion:(CGRect)stretchableRegion { - NPAInputLog(@"extractUpperLeftCornerForStretchableRegion:'%@'",NSStringFromCGRect(stretchableRegion)); - UIImage *upperLeftCorner = [self subImageInRect:CGRectMake(0.0f, 0.0f, CGRectGetMinX(stretchableRegion), CGRectGetMinY(stretchableRegion))]; - NPOOutputLog(upperLeftCorner); - return upperLeftCorner; -} - --(UIImage *)extractUpperRightCornerForStretchableRegion:(CGRect)stretchableRegion { - NPAInputLog(@"extractUpperRightCornerForStretchableRegion:'%@'",NSStringFromCGRect(stretchableRegion)); - UIImage *upperRightCorner = [self subImageInRect:CGRectMake(CGRectGetMaxX(stretchableRegion), 0.0f, [self size].width - CGRectGetMaxX(stretchableRegion), CGRectGetMinY(stretchableRegion))]; - NPOOutputLog(upperRightCorner); - return upperRightCorner; -} - --(UIImage *)extractLowerLeftCornerForStretchableRegion:(CGRect)stretchableRegion { - NPAInputLog(@"extractUpperRightCornerForStretchableRegion:'%@'",NSStringFromCGRect(stretchableRegion)); - UIImage *lowerLeftCorner = [self subImageInRect:CGRectMake(0.0f, CGRectGetMaxY(stretchableRegion), CGRectGetMinX(stretchableRegion), [self size].height - CGRectGetMaxY(stretchableRegion))]; - NPOOutputLog(lowerLeftCorner); - return lowerLeftCorner; -} - --(UIImage *)extractLowerRightCornerForStretchableRegion:(CGRect)stretchableRegion { - NPAInputLog(@"extractLowerRightCornerForStretchableRegion:'%@'",NSStringFromCGRect(stretchableRegion)); - UIImage *lowerRightCorner = [self subImageInRect:CGRectMake(CGRectGetMaxX(stretchableRegion), CGRectGetMaxY(stretchableRegion), [self size].width - CGRectGetMaxX(stretchableRegion), [self size].height - CGRectGetMaxY(stretchableRegion))]; - NPOOutputLog(lowerRightCorner); - return lowerRightCorner; -} - -#pragma mark - --(UIImage *)extractLeftEdgeForStretchableRegion:(CGRect)stretchableRegion { - NPAInputLog(@"extractLeftEdgeForStretchableRegion:'%@'",NSStringFromCGRect(stretchableRegion)); - UIImage *leftEdge = [self subImageInRect:CGRectMake(0.0f, CGRectGetMinY(stretchableRegion), CGRectGetMinX(stretchableRegion), CGRectGetHeight(stretchableRegion))]; - NPOOutputLog(leftEdge); - return leftEdge; -} - --(UIImage *)extractRightEdgeForStretchableRegion:(CGRect)stretchableRegion { - NPAInputLog(@"extractRightEdgeForStretchableRegion:'%@'",NSStringFromCGRect(stretchableRegion)); - UIImage *rightEdge = [self subImageInRect:CGRectMake(CGRectGetMaxX(stretchableRegion), CGRectGetMinY(stretchableRegion), [self size].width - CGRectGetMaxX(stretchableRegion), CGRectGetHeight(stretchableRegion))]; - NPOOutputLog(rightEdge); - return rightEdge; -} - --(UIImage *)extractUpperEdgeForStretchableRegion:(CGRect)stretchableRegion { - NPAInputLog(@"extractUpperEdgeForStretchableRegion:'%@'",NSStringFromCGRect(stretchableRegion)); - UIImage *upperEdge = [self subImageInRect:CGRectMake(CGRectGetMinX(stretchableRegion), 0.0f, CGRectGetWidth(stretchableRegion), CGRectGetMinY(stretchableRegion))]; - NPOOutputLog(upperEdge); - return upperEdge; -} - --(UIImage *)extractLowerEdgeForStretchableRegion:(CGRect)stretchableRegion { - NPAInputLog(@"extractLowerEdgeForStretchableRegion:'%@'",NSStringFromCGRect(stretchableRegion)); - UIImage *lowerEdge = [self subImageInRect:CGRectMake(CGRectGetMinX(stretchableRegion), CGRectGetMaxY(stretchableRegion), CGRectGetWidth(stretchableRegion), [self size].height - CGRectGetMaxY(stretchableRegion))]; - NPOOutputLog(center); - return lowerEdge; -} - -#pragma mark - --(UIImage *)extractCenterForStretchableRegion:(CGRect)stretchableRegion { - NPAInputLog(@"extractCenterForStretchableRegion:'%@'",NSStringFromCGRect(stretchableRegion)); - UIImage *center = [self subImageInRect:stretchableRegion]; - NPOOutputLog(center); - return center; -} - - -@end diff --git a/Classes/Utils/OrderedDictionary.m b/Classes/Utils/OrderedDictionary.m index 0d6683e8a..d644d0001 100644 --- a/Classes/Utils/OrderedDictionary.m +++ b/Classes/Utils/OrderedDictionary.m @@ -23,23 +23,15 @@ #import "OrderedDictionary.h" -NSString *DescriptionForObject(NSObject *object, id locale, NSUInteger indent) -{ +NSString *DescriptionForObject(NSObject *object, id locale, NSUInteger indent) { NSString *objectString; - if ([object isKindOfClass:[NSString class]]) - { - objectString = (NSString *)[[object retain] autorelease]; - } - else if ([object respondsToSelector:@selector(descriptionWithLocale:indent:)]) - { + if ([object isKindOfClass:[NSString class]]) { + objectString = (NSString *)object; + } else if ([object respondsToSelector:@selector(descriptionWithLocale:indent:)]) { objectString = [(NSDictionary *)object descriptionWithLocale:locale indent:indent]; - } - else if ([object respondsToSelector:@selector(descriptionWithLocale:)]) - { + } else if ([object respondsToSelector:@selector(descriptionWithLocale:)]) { objectString = [(NSSet *)object descriptionWithLocale:locale]; - } - else - { + } else { objectString = [object description]; } return objectString; @@ -47,128 +39,101 @@ NSString *DescriptionForObject(NSObject *object, id locale, NSUInteger indent) @implementation OrderedDictionary -- (void) initObjectsWithCapacity:(NSUInteger)capacity -{ - if (self != nil) - { +- (void)initObjectsWithCapacity:(NSUInteger)capacity { + if (self != nil) { dictionary = [[NSMutableDictionary alloc] initWithCapacity:capacity]; array = [[NSMutableArray alloc] initWithCapacity:capacity]; } } -- (id)init -{ +- (id)init { self = [super init]; [self initObjectsWithCapacity:0]; return self; } -- (id)initWithCapacity:(NSUInteger)capacity -{ +- (id)initWithCapacity:(NSUInteger)capacity { self = [super init]; [self initObjectsWithCapacity:0]; return self; } -- (void)dealloc -{ - [dictionary release]; - [array release]; - [super dealloc]; -} - -- (id)copy -{ +- (id)copy { return [self mutableCopy]; } -- (void)setObject:(id)anObject forKey:(id)aKey -{ - if (![dictionary objectForKey:aKey]) - { +- (void)setObject:(id)anObject forKey:(id)aKey { + if (![dictionary objectForKey:aKey]) { [array addObject:aKey]; } [dictionary setObject:anObject forKey:aKey]; } -- (void)removeObjectForKey:(id)aKey -{ +- (void)removeObjectForKey:(id)aKey { [dictionary removeObjectForKey:aKey]; [array removeObject:aKey]; } -- (NSUInteger)count -{ +- (NSUInteger)count { return [dictionary count]; } -- (id)objectForKey:(id)aKey -{ +- (id)objectForKey:(id)aKey { return [dictionary objectForKey:aKey]; } -- (NSEnumerator *)keyEnumerator -{ +- (NSEnumerator *)keyEnumerator { return [array objectEnumerator]; } -- (NSEnumerator *)reverseKeyEnumerator -{ +- (NSEnumerator *)reverseKeyEnumerator { return [array reverseObjectEnumerator]; } - // Added by Diorcet Yann -- (void)insertObject:(id)anObject forKey:(id)aKey selector:(SEL)comparator -{ - if ([dictionary objectForKey:aKey]) - { +- (void)insertObject:(id)anObject forKey:(id)aKey selector:(SEL)comparator { + if ([dictionary objectForKey:aKey]) { [self removeObjectForKey:aKey]; } - NSUInteger anIndex; - for(anIndex = 0; anIndex < [array count]; ++anIndex) { - NSComparisonResult result = (NSComparisonResult) [aKey performSelector:comparator withObject:[array objectAtIndex: anIndex]]; - if(result <= 0) { - break; - } - } + NSUInteger anIndex; + IMP imp = [aKey methodForSelector:comparator]; + NSComparisonResult (*func)(id, SEL, id) = (void *)imp; + + for (anIndex = 0; anIndex < [array count]; ++anIndex) { + NSComparisonResult result = (NSComparisonResult)func(aKey, comparator, [array objectAtIndex:anIndex]); + if (result <= 0) { + break; + } + } [array insertObject:aKey atIndex:anIndex]; [dictionary setObject:anObject forKey:aKey]; } // -- (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex -{ - if ([dictionary objectForKey:aKey]) - { +- (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex { + if ([dictionary objectForKey:aKey]) { [self removeObjectForKey:aKey]; } [array insertObject:aKey atIndex:anIndex]; [dictionary setObject:anObject forKey:aKey]; } -- (id)keyAtIndex:(NSUInteger)anIndex -{ +- (id)keyAtIndex:(NSUInteger)anIndex { return [array objectAtIndex:anIndex]; } -- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level -{ +- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level { NSMutableString *indentString = [NSMutableString string]; NSUInteger i, count = level; - for (i = 0; i < count; i++) - { + for (i = 0; i < count; i++) { [indentString appendFormat:@" "]; } - + NSMutableString *description = [NSMutableString string]; [description appendFormat:@"%@{\n", indentString]; - for (NSObject *key in self) - { - [description appendFormat:@"%@ %@ = %@;\n", - indentString, - DescriptionForObject(key, locale, level), - DescriptionForObject([self objectForKey:key], locale, level)]; + for (NSObject *key in self) { + [description appendFormat:@"%@ %@ = %@;\n", indentString, DescriptionForObject(key, locale, level), + DescriptionForObject([self objectForKey:key], locale, level)]; } [description appendFormat:@"%@}\n", indentString]; return description; diff --git a/Classes/Utils/TPKeyboardAvoiding/LICENSE.txt b/Classes/Utils/TPKeyboardAvoiding/LICENSE.txt new file mode 100755 index 000000000..b2071e3e3 --- /dev/null +++ b/Classes/Utils/TPKeyboardAvoiding/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2013 Michael Tyson + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. \ No newline at end of file diff --git a/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h b/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h new file mode 100755 index 000000000..b870e97fd --- /dev/null +++ b/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h @@ -0,0 +1,14 @@ +// +// TPKeyboardAvoidingCollectionView.h +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2013 A Tasty Pixel & The CocoaBots. All rights reserved. +// + +#import +#import "UIScrollView+TPKeyboardAvoidingAdditions.h" + +@interface TPKeyboardAvoidingCollectionView : UICollectionView +- (BOOL)focusNextTextField; +- (void)scrollToActiveTextField; +@end diff --git a/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.m b/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.m new file mode 100755 index 000000000..1625a461b --- /dev/null +++ b/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.m @@ -0,0 +1,108 @@ +// +// TPKeyboardAvoidingCollectionView.m +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2013 A Tasty Pixel & The CocoaBots. All rights reserved. +// + +#import "TPKeyboardAvoidingCollectionView.h" + +@interface TPKeyboardAvoidingCollectionView () +@end + +@implementation TPKeyboardAvoidingCollectionView + +#pragma mark - Setup/Teardown + +- (void)setup { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(TPKeyboardAvoiding_keyboardWillShow:) + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) + name:UIKeyboardWillHideNotification + object:nil]; +} + +- (id)initWithFrame:(CGRect)frame { + if (!(self = [super initWithFrame:frame])) + return nil; + [self setup]; + return self; +} + +- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout { + if (!(self = [super initWithFrame:frame collectionViewLayout:layout])) + return nil; + [self setup]; + return self; +} + +- (void)awakeFromNib { + [self setup]; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +#if !__has_feature(objc_arc) + [super dealloc]; +#endif +} + +- (void)setFrame:(CGRect)frame { + [super setFrame:frame]; + [self TPKeyboardAvoiding_updateContentInset]; +} + +- (void)setContentSize:(CGSize)contentSize { + if (CGSizeEqualToSize(contentSize, self.contentSize)) { + // Prevent triggering contentSize when it's already the same that + // cause weird infinte scrolling and locking bug + return; + } + [super setContentSize:contentSize]; + [self TPKeyboardAvoiding_updateContentInset]; +} + +- (BOOL)focusNextTextField { + return [self TPKeyboardAvoiding_focusNextTextField]; +} +- (void)scrollToActiveTextField { + return [self TPKeyboardAvoiding_scrollToActiveTextField]; +} + +#pragma mark - Responders, events + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + [[self TPKeyboardAvoiding_findFirstResponderBeneathView:self] resignFirstResponder]; + [super touchesEnded:touches withEvent:event]; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + if (![self focusNextTextField]) { + [textField resignFirstResponder]; + } + return YES; +} + +- (void)textFieldDidBeginEditing:(UITextField *)textField { + [self scrollToActiveTextField]; +} + +- (void)textViewDidBeginEditing:(UITextView *)textView { + [self scrollToActiveTextField]; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + [NSObject + cancelPreviousPerformRequestsWithTarget:self + selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) + object:self]; + [self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) + withObject:self + afterDelay:0.1]; +} + +@end diff --git a/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h b/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h new file mode 100755 index 000000000..4d38de93c --- /dev/null +++ b/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h @@ -0,0 +1,15 @@ +// +// TPKeyboardAvoidingScrollView.h +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2013 A Tasty Pixel. All rights reserved. +// + +#import +#import "UIScrollView+TPKeyboardAvoidingAdditions.h" + +@interface TPKeyboardAvoidingScrollView : UIScrollView +- (void)contentSizeToFit; +- (BOOL)focusNextTextField; +- (void)scrollToActiveTextField; +@end diff --git a/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m b/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m new file mode 100755 index 000000000..f7042d605 --- /dev/null +++ b/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m @@ -0,0 +1,100 @@ +// +// TPKeyboardAvoidingScrollView.m +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2013 A Tasty Pixel. All rights reserved. +// + +#import "TPKeyboardAvoidingScrollView.h" + +@interface TPKeyboardAvoidingScrollView () +@end + +@implementation TPKeyboardAvoidingScrollView + +#pragma mark - Setup/Teardown + +- (void)setup { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(TPKeyboardAvoiding_keyboardWillShow:) + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) + name:UIKeyboardWillHideNotification + object:nil]; +} + +- (id)initWithFrame:(CGRect)frame { + if (!(self = [super initWithFrame:frame])) + return nil; + [self setup]; + return self; +} + +- (void)awakeFromNib { + [self setup]; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +#if !__has_feature(objc_arc) + [super dealloc]; +#endif +} + +- (void)setFrame:(CGRect)frame { + [super setFrame:frame]; + [self TPKeyboardAvoiding_updateContentInset]; +} + +- (void)setContentSize:(CGSize)contentSize { + [super setContentSize:contentSize]; + [self TPKeyboardAvoiding_updateFromContentSizeChange]; +} + +- (void)contentSizeToFit { + self.contentSize = [self TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames]; +} + +- (BOOL)focusNextTextField { + return [self TPKeyboardAvoiding_focusNextTextField]; +} +- (void)scrollToActiveTextField { + return [self TPKeyboardAvoiding_scrollToActiveTextField]; +} + +#pragma mark - Responders, events + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + [[self TPKeyboardAvoiding_findFirstResponderBeneathView:self] resignFirstResponder]; + [super touchesEnded:touches withEvent:event]; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + if (![self focusNextTextField]) { + [textField resignFirstResponder]; + } + return YES; +} + +- (void)textFieldDidBeginEditing:(UITextField *)textField { + [self scrollToActiveTextField]; +} + +- (void)textViewDidBeginEditing:(UITextView *)textView { + [self scrollToActiveTextField]; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + [NSObject + cancelPreviousPerformRequestsWithTarget:self + selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) + object:self]; + [self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) + withObject:self + afterDelay:0.1]; +} + +@end diff --git a/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h b/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h new file mode 100755 index 000000000..83cde3204 --- /dev/null +++ b/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h @@ -0,0 +1,14 @@ +// +// TPKeyboardAvoidingTableView.h +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2013 A Tasty Pixel. All rights reserved. +// + +#import +#import "UIScrollView+TPKeyboardAvoidingAdditions.h" + +@interface TPKeyboardAvoidingTableView : UITableView +- (BOOL)focusNextTextField; +- (void)scrollToActiveTextField; +@end diff --git a/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.m b/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.m new file mode 100755 index 000000000..b1624a2b1 --- /dev/null +++ b/Classes/Utils/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.m @@ -0,0 +1,103 @@ +// +// TPKeyboardAvoidingTableView.m +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2013 A Tasty Pixel. All rights reserved. +// + +#import "TPKeyboardAvoidingTableView.h" + +@interface TPKeyboardAvoidingTableView () +@end + +@implementation TPKeyboardAvoidingTableView + +#pragma mark - Setup/Teardown + +- (void)setup { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(TPKeyboardAvoiding_keyboardWillShow:) + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) + name:UIKeyboardWillHideNotification + object:nil]; +} + +- (id)initWithFrame:(CGRect)frame { + if (!(self = [super initWithFrame:frame])) + return nil; + [self setup]; + return self; +} + +- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)withStyle { + if (!(self = [super initWithFrame:frame style:withStyle])) + return nil; + [self setup]; + return self; +} + +- (void)awakeFromNib { + [self setup]; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +#if !__has_feature(objc_arc) + [super dealloc]; +#endif +} + +- (void)setFrame:(CGRect)frame { + [super setFrame:frame]; + [self TPKeyboardAvoiding_updateContentInset]; +} + +- (void)setContentSize:(CGSize)contentSize { + [super setContentSize:contentSize]; + [self TPKeyboardAvoiding_updateContentInset]; +} + +- (BOOL)focusNextTextField { + return [self TPKeyboardAvoiding_focusNextTextField]; +} +- (void)scrollToActiveTextField { + return [self TPKeyboardAvoiding_scrollToActiveTextField]; +} + +#pragma mark - Responders, events + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + [[self TPKeyboardAvoiding_findFirstResponderBeneathView:self] resignFirstResponder]; + [super touchesEnded:touches withEvent:event]; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + if (![self focusNextTextField]) { + [textField resignFirstResponder]; + } + return YES; +} + +- (void)textFieldDidBeginEditing:(UITextField *)textField { + [self scrollToActiveTextField]; +} + +- (void)textViewDidBeginEditing:(UITextView *)textView { + [self scrollToActiveTextField]; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + [NSObject + cancelPreviousPerformRequestsWithTarget:self + selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) + object:self]; + [self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) + withObject:self + afterDelay:0.1]; +} + +@end diff --git a/Classes/Utils/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h b/Classes/Utils/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h new file mode 100755 index 000000000..103b5cb25 --- /dev/null +++ b/Classes/Utils/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h @@ -0,0 +1,22 @@ +// +// UIScrollView+TPKeyboardAvoidingAdditions.h +// TPKeyboardAvoidingSample +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2013 A Tasty Pixel. All rights reserved. +// + +#import + +@interface UIScrollView (TPKeyboardAvoidingAdditions) +- (BOOL)TPKeyboardAvoiding_focusNextTextField; +- (void)TPKeyboardAvoiding_scrollToActiveTextField; + +- (void)TPKeyboardAvoiding_keyboardWillShow:(NSNotification *)notification; +- (void)TPKeyboardAvoiding_keyboardWillHide:(NSNotification *)notification; +- (void)TPKeyboardAvoiding_updateContentInset; +- (void)TPKeyboardAvoiding_updateFromContentSizeChange; +- (void)TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:(UIView *)view; +- (UIView *)TPKeyboardAvoiding_findFirstResponderBeneathView:(UIView *)view; +- (CGSize)TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames; +@end diff --git a/Classes/Utils/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.m b/Classes/Utils/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.m new file mode 100755 index 000000000..de9279d55 --- /dev/null +++ b/Classes/Utils/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.m @@ -0,0 +1,301 @@ +// +// UIScrollView+TPKeyboardAvoidingAdditions.m +// TPKeyboardAvoidingSample +// +// Created by Michael Tyson on 30/09/2013. +// Copyright 2013 A Tasty Pixel. All rights reserved. +// + +#import "UIScrollView+TPKeyboardAvoidingAdditions.h" +#import "TPKeyboardAvoidingScrollView.h" +#import + +static const CGFloat kCalculatedContentPadding = 10; +static const CGFloat kMinimumScrollOffsetPadding = 20; + +static const int kStateKey; + +#define _UIKeyboardFrameEndUserInfoKey \ + (&UIKeyboardFrameEndUserInfoKey != NULL ? UIKeyboardFrameEndUserInfoKey : @"UIKeyboardBoundsUserInfoKey") + +@interface TPKeyboardAvoidingState : NSObject +@property(nonatomic, assign) UIEdgeInsets priorInset; +@property(nonatomic, assign) UIEdgeInsets priorScrollIndicatorInsets; +@property(nonatomic, assign) BOOL keyboardVisible; +@property(nonatomic, assign) CGRect keyboardRect; +@property(nonatomic, assign) CGSize priorContentSize; +@end + +@implementation UIScrollView (TPKeyboardAvoidingAdditions) + +- (TPKeyboardAvoidingState *)keyboardAvoidingState { + TPKeyboardAvoidingState *state = objc_getAssociatedObject(self, &kStateKey); + if (!state) { + state = [[TPKeyboardAvoidingState alloc] init]; + objc_setAssociatedObject(self, &kStateKey, state, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +#if !__has_feature(objc_arc) + [state release]; +#endif + } + return state; +} + +- (void)TPKeyboardAvoiding_keyboardWillShow:(NSNotification *)notification { + TPKeyboardAvoidingState *state = self.keyboardAvoidingState; + + if (state.keyboardVisible) { + return; + } + + UIView *firstResponder = [self TPKeyboardAvoiding_findFirstResponderBeneathView:self]; + + state.keyboardRect = + [self convertRect:[[[notification userInfo] objectForKey:_UIKeyboardFrameEndUserInfoKey] CGRectValue] + fromView:nil]; + state.keyboardVisible = YES; + state.priorInset = self.contentInset; + state.priorScrollIndicatorInsets = self.scrollIndicatorInsets; + + if ([self isKindOfClass:[TPKeyboardAvoidingScrollView class]]) { + state.priorContentSize = self.contentSize; + + if (CGSizeEqualToSize(self.contentSize, CGSizeZero)) { + // Set the content size, if it's not set. Do not set content size explicitly if auto-layout + // is being used to manage subviews + self.contentSize = [self TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames]; + } + } + + // Shrink view's inset by the keyboard's height, and scroll to show the text field/view being edited + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; + [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] + floatValue]]; + + self.contentInset = [self TPKeyboardAvoiding_contentInsetForKeyboard]; + + if (firstResponder) { + CGFloat viewableHeight = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom; + [self setContentOffset:CGPointMake(self.contentOffset.x, + [self TPKeyboardAvoiding_idealOffsetForView:firstResponder + withViewingAreaHeight:viewableHeight]) + animated:NO]; + } + + self.scrollIndicatorInsets = self.contentInset; + + [UIView commitAnimations]; +} + +- (void)TPKeyboardAvoiding_keyboardWillHide:(NSNotification *)notification { + TPKeyboardAvoidingState *state = self.keyboardAvoidingState; + + if (!state.keyboardVisible) { + return; + } + + state.keyboardRect = CGRectZero; + state.keyboardVisible = NO; + + // Restore dimensions to prior size + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; + [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] + floatValue]]; + + if ([self isKindOfClass:[TPKeyboardAvoidingScrollView class]]) { + self.contentSize = state.priorContentSize; + } + + self.contentInset = state.priorInset; + self.scrollIndicatorInsets = state.priorScrollIndicatorInsets; + [UIView commitAnimations]; +} + +- (void)TPKeyboardAvoiding_updateContentInset { + TPKeyboardAvoidingState *state = self.keyboardAvoidingState; + if (state.keyboardVisible) { + self.contentInset = [self TPKeyboardAvoiding_contentInsetForKeyboard]; + } +} + +- (void)TPKeyboardAvoiding_updateFromContentSizeChange { + TPKeyboardAvoidingState *state = self.keyboardAvoidingState; + if (state.keyboardVisible) { + state.priorContentSize = self.contentSize; + self.contentInset = [self TPKeyboardAvoiding_contentInsetForKeyboard]; + } +} + +#pragma mark - Utilities + +- (BOOL)TPKeyboardAvoiding_focusNextTextField { + UIView *firstResponder = [self TPKeyboardAvoiding_findFirstResponderBeneathView:self]; + if (!firstResponder) { + return NO; + } + + CGFloat minY = CGFLOAT_MAX; + UIView *view = nil; + [self TPKeyboardAvoiding_findTextFieldAfterTextField:firstResponder beneathView:self minY:&minY foundView:&view]; + + if (view) { + [view performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.0]; + return YES; + } + + return NO; +} + +- (void)TPKeyboardAvoiding_scrollToActiveTextField { + TPKeyboardAvoidingState *state = self.keyboardAvoidingState; + + if (!state.keyboardVisible) + return; + + CGFloat visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom; + + CGPoint idealOffset = CGPointMake( + 0, [self TPKeyboardAvoiding_idealOffsetForView:[self TPKeyboardAvoiding_findFirstResponderBeneathView:self] + withViewingAreaHeight:visibleSpace]); + + // Ordinarily we'd use -setContentOffset:animated:YES here, but it does not appear to + // scroll to the desired content offset. So we wrap in our own animation block. + [UIView animateWithDuration:0.25 + animations:^{ + [self setContentOffset:idealOffset animated:NO]; + }]; +} + +#pragma mark - Helpers + +- (UIView *)TPKeyboardAvoiding_findFirstResponderBeneathView:(UIView *)view { + // Search recursively for first responder + for (UIView *childView in view.subviews) { + if ([childView respondsToSelector:@selector(isFirstResponder)] && [childView isFirstResponder]) + return childView; + UIView *result = [self TPKeyboardAvoiding_findFirstResponderBeneathView:childView]; + if (result) + return result; + } + return nil; +} + +- (void)TPKeyboardAvoiding_findTextFieldAfterTextField:(UIView *)priorTextField + beneathView:(UIView *)view + minY:(CGFloat *)minY + foundView:(UIView **)foundView { + // Search recursively for text field or text view below priorTextField + CGFloat priorFieldOffset = CGRectGetMinY([self convertRect:priorTextField.frame fromView:priorTextField.superview]); + for (UIView *childView in view.subviews) { + if (childView.hidden) + continue; + if (([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) && + childView.isUserInteractionEnabled) { + CGRect frame = [self convertRect:childView.frame fromView:view]; + if (childView != priorTextField && CGRectGetMinY(frame) >= priorFieldOffset && + CGRectGetMinY(frame) < *minY && + !(frame.origin.y == priorTextField.frame.origin.y && frame.origin.x < priorTextField.frame.origin.x)) { + *minY = CGRectGetMinY(frame); + *foundView = childView; + } + } else { + [self TPKeyboardAvoiding_findTextFieldAfterTextField:priorTextField + beneathView:childView + minY:minY + foundView:foundView]; + } + } +} + +- (void)TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:(UIView *)view { + for (UIView *childView in view.subviews) { + if (([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]])) { + [self TPKeyboardAvoiding_initializeView:childView]; + } else { + [self TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:childView]; + } + } +} + +- (CGSize)TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames { + + BOOL wasShowingVerticalScrollIndicator = self.showsVerticalScrollIndicator; + BOOL wasShowingHorizontalScrollIndicator = self.showsHorizontalScrollIndicator; + + self.showsVerticalScrollIndicator = NO; + self.showsHorizontalScrollIndicator = NO; + + CGRect rect = CGRectZero; + for (UIView *view in self.subviews) { + rect = CGRectUnion(rect, view.frame); + } + rect.size.height += kCalculatedContentPadding; + + self.showsVerticalScrollIndicator = wasShowingVerticalScrollIndicator; + self.showsHorizontalScrollIndicator = wasShowingHorizontalScrollIndicator; + + return rect.size; +} + +- (UIEdgeInsets)TPKeyboardAvoiding_contentInsetForKeyboard { + TPKeyboardAvoidingState *state = self.keyboardAvoidingState; + UIEdgeInsets newInset = self.contentInset; + CGRect keyboardRect = state.keyboardRect; + newInset.bottom = keyboardRect.size.height - (CGRectGetMaxY(keyboardRect) - CGRectGetMaxY(self.bounds)); + return newInset; +} + +- (CGFloat)TPKeyboardAvoiding_idealOffsetForView:(UIView *)view withViewingAreaHeight:(CGFloat)viewAreaHeight { + CGSize contentSize = self.contentSize; + CGFloat offset = 0.0; + + CGRect subviewRect = [view convertRect:view.bounds toView:self]; + + // Attempt to center the subview in the visible space, but if that means there will be less than + // kMinimumScrollOffsetPadding + // pixels above the view, then substitute kMinimumScrollOffsetPadding + CGFloat padding = (viewAreaHeight - subviewRect.size.height) / 2; + if (padding < kMinimumScrollOffsetPadding) { + padding = kMinimumScrollOffsetPadding; + } + + // Ideal offset places the subview rectangle origin "padding" points from the top of the scrollview. + // If there is a top contentInset, also compensate for this so that subviewRect will not be placed under + // things like navigation bars. + offset = subviewRect.origin.y - padding - self.contentInset.top; + + // Constrain the new contentOffset so we can't scroll past the bottom. Note that we don't take the bottom + // inset into account, as this is manipulated to make space for the keyboard. + if (offset > (contentSize.height - viewAreaHeight)) { + offset = contentSize.height - viewAreaHeight; + } + + // Constrain the new contentOffset so we can't scroll past the top, taking contentInsets into account + if (offset < -self.contentInset.top) { + offset = -self.contentInset.top; + } + + return offset; +} + +- (void)TPKeyboardAvoiding_initializeView:(UIView *)view { + if ([view isKindOfClass:[UITextField class]] && ((UITextField *)view).returnKeyType == UIReturnKeyDefault && + (![(id)view delegate] || [(UIScrollView *)view delegate] == (id)self)) { + [(UIScrollView *)view setDelegate:(id)self]; + UIView *otherView = nil; + CGFloat minY = CGFLOAT_MAX; + [self TPKeyboardAvoiding_findTextFieldAfterTextField:view beneathView:self minY:&minY foundView:&otherView]; + + if (otherView) { + ((UITextField *)view).returnKeyType = UIReturnKeyNext; + } else { + ((UITextField *)view).returnKeyType = UIReturnKeyDone; + } + } +} + +@end + +@implementation TPKeyboardAvoidingState +@end diff --git a/Classes/Utils/TPMultiLayoutViewController/TPMultiLayoutViewController.h b/Classes/Utils/TPMultiLayoutViewController/TPMultiLayoutViewController.h index 460480c33..acce76b5a 100755 --- a/Classes/Utils/TPMultiLayoutViewController/TPMultiLayoutViewController.h +++ b/Classes/Utils/TPMultiLayoutViewController/TPMultiLayoutViewController.h @@ -20,8 +20,8 @@ // Call directly to use with custom animation (override willRotateToInterfaceOrientation to disable the switch there) - (void)applyLayoutForInterfaceOrientation:(UIInterfaceOrientation)newOrientation; -@property (nonatomic, retain) IBOutlet UIView *landscapeView; -@property (nonatomic, retain) IBOutlet UIView *portraitView; +@property(nonatomic, strong) IBOutlet UIView *landscapeView; +@property(nonatomic, strong) IBOutlet UIView *portraitView; @property (assign) BOOL viewIsCurrentlyPortrait; @end diff --git a/Classes/Utils/TPMultiLayoutViewController/TPMultiLayoutViewController.m b/Classes/Utils/TPMultiLayoutViewController/TPMultiLayoutViewController.m index 668e0d747..0e7c0f579 100755 --- a/Classes/Utils/TPMultiLayoutViewController/TPMultiLayoutViewController.m +++ b/Classes/Utils/TPMultiLayoutViewController/TPMultiLayoutViewController.m @@ -28,31 +28,26 @@ [super viewDidLoad]; // Construct attribute tables - portraitAttributes = [[self attributeTableForViewHierarchy:portraitView associateWithViewHierarchy:self.view] retain]; - landscapeAttributes = [[self attributeTableForViewHierarchy:landscapeView associateWithViewHierarchy:self.view] retain]; - viewIsCurrentlyPortrait = (self.view == portraitView); - - // Don't need to retain the original template view hierarchies any more - self.portraitView = nil; + portraitAttributes = [self attributeTableForViewHierarchy:portraitView associateWithViewHierarchy:self.view]; + landscapeAttributes = [self attributeTableForViewHierarchy:landscapeView associateWithViewHierarchy:self.view]; + viewIsCurrentlyPortrait = (self.view == portraitView); + + // Don't need to retain the original template view hierarchies any more + self.portraitView = nil; self.landscapeView = nil; } - (void)viewDidUnload { [super viewDidUnload]; - [portraitAttributes release]; portraitAttributes = nil; - [landscapeAttributes release]; landscapeAttributes = nil; } - (void)dealloc { - [portraitAttributes release]; portraitAttributes = nil; - [landscapeAttributes release]; landscapeAttributes = nil; - [super dealloc]; } - (void)viewWillAppear:(BOOL)animated { @@ -89,12 +84,14 @@ } - (void)addAttributesForSubviewHierarchy:(UIView*)view associatedWithSubviewHierarchy:(UIView*)associatedView toTable:(NSMutableDictionary*)table { - [table setObject:[self attributesForView:view] forKey:[NSValue valueWithPointer:associatedView]]; - - if ( ![self shouldDescendIntoSubviewsOfView:view] ) return; - - for ( UIView *subview in view.subviews ) { - UIView *associatedSubView = (view == associatedView ? subview : [self findAssociatedViewForView:subview amongViews:associatedView.subviews]); + [table setObject:[self attributesForView:view] + forKey:[NSValue valueWithPointer:(__bridge const void *)(associatedView)]]; + + if (![self shouldDescendIntoSubviewsOfView:view]) + return; + + for (UIView *subview in view.subviews) { + UIView *associatedSubView = (view == associatedView ? subview : [self findAssociatedViewForView:subview amongViews:associatedView.subviews]); if ( associatedSubView ) { [self addAttributesForSubviewHierarchy:subview associatedWithSubviewHierarchy:associatedSubView toTable:table]; } @@ -189,10 +186,10 @@ } - (void)applyAttributeTable:(NSDictionary*)table toViewHierarchy:(UIView*)view { - NSDictionary *attributes = [table objectForKey:[NSValue valueWithPointer:view]]; - if ( attributes ) { - [self applyAttributes:attributes toView:view]; - } + NSDictionary *attributes = [table objectForKey:[NSValue valueWithPointer:(__bridge const void *)(view)]]; + if (attributes) { + [self applyAttributes:attributes toView:view]; + } //if ( view.hidden ) return; diff --git a/Classes/Utils/UACellBackgroundView/UACellBackgroundView.h b/Classes/Utils/UACellBackgroundView/UACellBackgroundView.h deleted file mode 100644 index ad0298870..000000000 --- a/Classes/Utils/UACellBackgroundView/UACellBackgroundView.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// UACellBackgroundView.h -// Ambiance -// -// Created by Matt Coneybeare on 1/31/10. -// Copyright 2010 Urban Apps LLC. All rights reserved. -// -// Modified by Diorcet Yann on 07/12/12 - -#import - -#import - -typedef enum { - UACellBackgroundViewPositionSingle = 0, - UACellBackgroundViewPositionTop, - UACellBackgroundViewPositionBottom, - UACellBackgroundViewPositionMiddle -} UACellBackgroundViewPosition; - -@interface UACellBackgroundView : UIView { -} - -@property(nonatomic) UACellBackgroundViewPosition position; -@property(nonatomic, copy) UIColor *backgroundColor; -@property(nonatomic, copy) UIColor *borderColor; -@property(assign) BOOL automaticPositioning; - -@end diff --git a/Classes/Utils/UACellBackgroundView/UACellBackgroundView.m b/Classes/Utils/UACellBackgroundView/UACellBackgroundView.m deleted file mode 100644 index 82a9671ed..000000000 --- a/Classes/Utils/UACellBackgroundView/UACellBackgroundView.m +++ /dev/null @@ -1,287 +0,0 @@ -// -// UACellBackgroundView.m -// Ambiance -// -// Created by Matt Coneybeare on 1/31/10. -// Copyright 2010 Urban Apps LLC. All rights reserved. -// -// Modified by Diorcet Yann on 07/12/12 - -#define kDefaultMargin 10 - -#import "UACellBackgroundView.h" - -static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth,float ovalHeight); - -@implementation UACellBackgroundView - -@synthesize position; -@synthesize backgroundColor; -@synthesize borderColor; -@synthesize automaticPositioning; - -- (void)initUACellBackgroundView { - backgroundColor = nil; - [self setBackgroundColor:[UIColor colorWithRed:0.02 green:0.549 blue:0.961 alpha:1.0]]; - borderColor = nil; - [self setBorderColor:[UIColor grayColor]]; - automaticPositioning = TRUE; -} - -- (id)init { - self = [super init]; - if(self != nil) { - [self initUACellBackgroundView]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if(self != nil) { - [self initUACellBackgroundView]; - } - return self; -} - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if(self != nil) { - [self initUACellBackgroundView]; - } - return self; -} - -- (BOOL)isOpaque { - return NO; -} - -- (void)setBackgroundColor:(UIColor *)abackgroundColor { - if(backgroundColor != nil) { - [backgroundColor release]; - } - backgroundColor = [[UIColor alloc] initWithCGColor:abackgroundColor.CGColor]; - [self setNeedsDisplay]; -} - -- (void)setBorderColor:(UIColor *)aborderColor { - if(borderColor != nil) { - [borderColor release]; - } - - borderColor = [[UIColor alloc] initWithCGColor:aborderColor.CGColor]; - [self setNeedsDisplay]; -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - if(!automaticPositioning) - return; - - // - // Auto found position - // - - // Find TableViewCell - UIView *view = [self superview]; - while( view != nil && ![view isKindOfClass:[UITableView class]] ) view = [view superview]; - - // Find TableViewCell - UIView *cellView = [self superview]; - while( cellView != nil && ![cellView isKindOfClass:[UITableViewCell class]] ) cellView = [cellView superview]; - - if(view != nil && cellView != nil) { - UITableViewCell *cell = (UITableViewCell*)cellView; - UITableView *tableView = (UITableView*)view; - - if([tableView style] == UITableViewStyleGrouped) { - NSIndexPath *path = [tableView indexPathForCell:cell]; - if(path) { - NSInteger count = [tableView numberOfRowsInSection:[path section]]; - // Set Position for background view - if([path row] == 0) { - if([path row] == (count - 1)) { - [self setPosition:UACellBackgroundViewPositionSingle]; - } else { - [self setPosition:UACellBackgroundViewPositionTop]; - } - } else if([path row] == (count - 1)) { - [self setPosition:UACellBackgroundViewPositionBottom]; - } else { - [self setPosition:UACellBackgroundViewPositionMiddle]; - } - } - } else { - [self setPosition:UACellBackgroundViewPositionMiddle]; - } - } - [self setNeedsDisplay]; -} - -- (void)drawRect:(CGRect)aRect { - // Drawing code - - CGContextRef c = UIGraphicsGetCurrentContext(); - // don't use arcs on iOS >= 7 - BOOL use_arcs = [[[UIDevice currentDevice] systemVersion] floatValue] < 7; - - int lineWidth = 1; - - CGRect rect = [self bounds]; - CGFloat minx = CGRectGetMinX(rect), midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect); - CGFloat miny = CGRectGetMinY(rect), midy = CGRectGetMidY(rect), maxy = CGRectGetMaxY(rect); - miny -= 1; - - CGFloat locations[2] = { 0.0, 1.0 }; - CGColorSpaceRef myColorspace = CGColorGetColorSpace([[self backgroundColor] CGColor]); - CGGradientRef myGradient = nil; - const CGFloat *default_components = CGColorGetComponents([[self backgroundColor] CGColor]); - CGFloat components[8] = {default_components[0], default_components[1], default_components[2], default_components[3], default_components[0] * 0.766f, default_components[1] * 0.766f, default_components[2] * 0.766f, default_components[3]}; - CGContextSetStrokeColorWithColor(c, [borderColor CGColor]); - CGContextSetLineWidth(c, lineWidth); - CGContextSetAllowsAntialiasing(c, YES); - CGContextSetShouldAntialias(c, YES); - - if (position == UACellBackgroundViewPositionTop && use_arcs) { - - miny += 1; - - CGMutablePathRef path = CGPathCreateMutable(); - CGPathMoveToPoint(path, NULL, minx, maxy); - CGPathAddArcToPoint(path, NULL, minx, miny, midx, miny, kDefaultMargin); - CGPathAddArcToPoint(path, NULL, maxx, miny, maxx, maxy, kDefaultMargin); - CGPathAddLineToPoint(path, NULL, maxx, maxy); - CGPathAddLineToPoint(path, NULL, minx, maxy); - CGPathCloseSubpath(path); - - // Fill and stroke the path - CGContextSaveGState(c); - CGContextAddPath(c, path); - CGContextClip(c); - - myGradient = CGGradientCreateWithColorComponents(myColorspace, components, locations, 2); - CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0); - - CGContextAddPath(c, path); - CGPathRelease(path); - CGContextStrokePath(c); - CGContextRestoreGState(c); - - } else if (position == UACellBackgroundViewPositionBottom && use_arcs) { - - CGMutablePathRef path = CGPathCreateMutable(); - CGPathMoveToPoint(path, NULL, minx, miny); - CGPathAddArcToPoint(path, NULL, minx, maxy, midx, maxy, kDefaultMargin); - CGPathAddArcToPoint(path, NULL, maxx, maxy, maxx, miny, kDefaultMargin); - CGPathAddLineToPoint(path, NULL, maxx, miny); - CGPathAddLineToPoint(path, NULL, minx, miny); - CGPathCloseSubpath(path); - - // Fill and stroke the path - CGContextSaveGState(c); - CGContextAddPath(c, path); - CGContextClip(c); - - myGradient = CGGradientCreateWithColorComponents(myColorspace, components, locations, 2); - CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0); - - CGContextAddPath(c, path); - CGPathRelease(path); - CGContextStrokePath(c); - CGContextRestoreGState(c); - - - } else if (position == UACellBackgroundViewPositionMiddle || !use_arcs) { - // in iOS7, this will be the default handling - CGMutablePathRef path = CGPathCreateMutable(); - CGPathMoveToPoint(path, NULL, minx, miny); - CGPathAddLineToPoint(path, NULL, maxx, miny); - CGPathAddLineToPoint(path, NULL, maxx, maxy); - CGPathAddLineToPoint(path, NULL, minx, maxy); - CGPathAddLineToPoint(path, NULL, minx, miny); - CGPathCloseSubpath(path); - - // Fill and stroke the path - CGContextSaveGState(c); - CGContextAddPath(c, path); - CGContextClip(c); - - myGradient = CGGradientCreateWithColorComponents(myColorspace, components, locations, 2); - CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0); - - CGContextAddPath(c, path); - CGPathRelease(path); - CGContextStrokePath(c); - CGContextRestoreGState(c); - - } else if (position == UACellBackgroundViewPositionSingle) { - miny += 1; - - CGMutablePathRef path = CGPathCreateMutable(); - CGPathMoveToPoint(path, NULL, minx, midy); - CGPathAddArcToPoint(path, NULL, minx, miny, midx, miny, kDefaultMargin); - CGPathAddArcToPoint(path, NULL, maxx, miny, maxx, midy, kDefaultMargin); - CGPathAddArcToPoint(path, NULL, maxx, maxy, midx, maxy, kDefaultMargin); - CGPathAddArcToPoint(path, NULL, minx, maxy, minx, midy, kDefaultMargin); - CGPathCloseSubpath(path); - - - // Fill and stroke the path - CGContextSaveGState(c); - CGContextAddPath(c, path); - CGContextClip(c); - - - myGradient = CGGradientCreateWithColorComponents(myColorspace, components, locations, 2); - CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0); - - CGContextAddPath(c, path); - CGPathRelease(path); - CGContextStrokePath(c); - CGContextRestoreGState(c); - } - - CGGradientRelease(myGradient); - return; -} - -- (void)dealloc { - [backgroundColor release]; - [super dealloc]; -} - -- (void)setPosition:(UACellBackgroundViewPosition)newPosition { - if (position != newPosition) { - position = newPosition; - [self setNeedsDisplay]; - } -} - -@end - -static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth,float ovalHeight) { - float fw, fh; - - if (ovalWidth == 0 || ovalHeight == 0) {// 1 - CGContextAddRect(context, rect); - return; - } - - CGContextSaveGState(context);// 2 - - CGContextTranslateCTM (context, CGRectGetMinX(rect),// 3 - CGRectGetMinY(rect)); - CGContextScaleCTM (context, ovalWidth, ovalHeight);// 4 - fw = CGRectGetWidth (rect) / ovalWidth;// 5 - fh = CGRectGetHeight (rect) / ovalHeight;// 6 - - CGContextMoveToPoint(context, fw, fh/2); // 7 - CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);// 8 - CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);// 9 - CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);// 10 - CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); // 11 - CGContextClosePath(context);// 12 - - CGContextRestoreGState(context);// 13 -} diff --git a/Classes/Utils/UIAlertView+Blocks/UIAlertView+Blocks.h b/Classes/Utils/UIAlertView+Blocks/UIAlertView+Blocks.h new file mode 100644 index 000000000..63f5d0e45 --- /dev/null +++ b/Classes/Utils/UIAlertView+Blocks/UIAlertView+Blocks.h @@ -0,0 +1,59 @@ +// +// UIAlertView+Blocks.h +// UIAlertViewBlocks +// +// Created by Ryan Maxwell on 29/08/13. +// +// The MIT License (MIT) +// +// Copyright (c) 2013 Ryan Maxwell +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +#import + +typedef void (^UIAlertViewBlock)(UIAlertView *alertView); +typedef void (^UIAlertViewCompletionBlock)(UIAlertView *alertView, NSInteger buttonIndex); + +@interface UIAlertView (Blocks) + ++ (instancetype)showWithTitle:(NSString *)title + message:(NSString *)message + style:(UIAlertViewStyle)style + cancelButtonTitle:(NSString *)cancelButtonTitle + otherButtonTitles:(NSArray *)otherButtonTitles + tapBlock:(UIAlertViewCompletionBlock)tapBlock; + ++ (instancetype)showWithTitle:(NSString *)title + message:(NSString *)message + cancelButtonTitle:(NSString *)cancelButtonTitle + otherButtonTitles:(NSArray *)otherButtonTitles + tapBlock:(UIAlertViewCompletionBlock)tapBlock; + +@property(copy, nonatomic) UIAlertViewCompletionBlock tapBlock; +@property(copy, nonatomic) UIAlertViewCompletionBlock willDismissBlock; +@property(copy, nonatomic) UIAlertViewCompletionBlock didDismissBlock; + +@property(copy, nonatomic) UIAlertViewBlock willPresentBlock; +@property(copy, nonatomic) UIAlertViewBlock didPresentBlock; +@property(copy, nonatomic) UIAlertViewBlock cancelBlock; + +@property(copy, nonatomic) BOOL (^shouldEnableFirstOtherButtonBlock)(UIAlertView *alertView); + +@end diff --git a/Classes/Utils/UIAlertView+Blocks/UIAlertView+Blocks.m b/Classes/Utils/UIAlertView+Blocks/UIAlertView+Blocks.m new file mode 100644 index 000000000..1a0041b83 --- /dev/null +++ b/Classes/Utils/UIAlertView+Blocks/UIAlertView+Blocks.m @@ -0,0 +1,264 @@ +// +// UIAlertView+Blocks.m +// UIAlertViewBlocks +// +// Created by Ryan Maxwell on 29/08/13. +// +// The MIT License (MIT) +// +// Copyright (c) 2013 Ryan Maxwell +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +#import "UIAlertView+Blocks.h" + +#import + +static const void *UIAlertViewOriginalDelegateKey = &UIAlertViewOriginalDelegateKey; + +static const void *UIAlertViewTapBlockKey = &UIAlertViewTapBlockKey; +static const void *UIAlertViewWillPresentBlockKey = &UIAlertViewWillPresentBlockKey; +static const void *UIAlertViewDidPresentBlockKey = &UIAlertViewDidPresentBlockKey; +static const void *UIAlertViewWillDismissBlockKey = &UIAlertViewWillDismissBlockKey; +static const void *UIAlertViewDidDismissBlockKey = &UIAlertViewDidDismissBlockKey; +static const void *UIAlertViewCancelBlockKey = &UIAlertViewCancelBlockKey; +static const void *UIAlertViewShouldEnableFirstOtherButtonBlockKey = &UIAlertViewShouldEnableFirstOtherButtonBlockKey; + +@implementation UIAlertView (Blocks) + ++ (instancetype)showWithTitle:(NSString *)title + message:(NSString *)message + style:(UIAlertViewStyle)style + cancelButtonTitle:(NSString *)cancelButtonTitle + otherButtonTitles:(NSArray *)otherButtonTitles + tapBlock:(UIAlertViewCompletionBlock)tapBlock { + + NSString *firstObject = otherButtonTitles.count ? otherButtonTitles[0] : nil; + + UIAlertView *alertView = [[self alloc] initWithTitle:title + message:message + delegate:nil + cancelButtonTitle:cancelButtonTitle + otherButtonTitles:firstObject, nil]; + + alertView.alertViewStyle = style; + + if (otherButtonTitles.count > 1) { + for (NSString *buttonTitle in + [otherButtonTitles subarrayWithRange:NSMakeRange(1, otherButtonTitles.count - 1)]) { + [alertView addButtonWithTitle:buttonTitle]; + } + } + + if (tapBlock) { + alertView.tapBlock = tapBlock; + } + + [alertView show]; + +#if !__has_feature(objc_arc) + return [alertView autorelease]; +#else + return alertView; +#endif +} + ++ (instancetype)showWithTitle:(NSString *)title + message:(NSString *)message + cancelButtonTitle:(NSString *)cancelButtonTitle + otherButtonTitles:(NSArray *)otherButtonTitles + tapBlock:(UIAlertViewCompletionBlock)tapBlock { + + return [self showWithTitle:title + message:message + style:UIAlertViewStyleDefault + cancelButtonTitle:cancelButtonTitle + otherButtonTitles:otherButtonTitles + tapBlock:tapBlock]; +} + +#pragma mark - + +- (void)_checkAlertViewDelegate { + if (self.delegate != (id)self) { + objc_setAssociatedObject(self, UIAlertViewOriginalDelegateKey, self.delegate, OBJC_ASSOCIATION_ASSIGN); + self.delegate = (id)self; + } +} + +- (UIAlertViewCompletionBlock)tapBlock { + return objc_getAssociatedObject(self, UIAlertViewTapBlockKey); +} + +- (void)setTapBlock:(UIAlertViewCompletionBlock)tapBlock { + [self _checkAlertViewDelegate]; + objc_setAssociatedObject(self, UIAlertViewTapBlockKey, tapBlock, OBJC_ASSOCIATION_COPY); +} + +- (UIAlertViewCompletionBlock)willDismissBlock { + return objc_getAssociatedObject(self, UIAlertViewWillDismissBlockKey); +} + +- (void)setWillDismissBlock:(UIAlertViewCompletionBlock)willDismissBlock { + [self _checkAlertViewDelegate]; + objc_setAssociatedObject(self, UIAlertViewWillDismissBlockKey, willDismissBlock, OBJC_ASSOCIATION_COPY); +} + +- (UIAlertViewCompletionBlock)didDismissBlock { + return objc_getAssociatedObject(self, UIAlertViewDidDismissBlockKey); +} + +- (void)setDidDismissBlock:(UIAlertViewCompletionBlock)didDismissBlock { + [self _checkAlertViewDelegate]; + objc_setAssociatedObject(self, UIAlertViewDidDismissBlockKey, didDismissBlock, OBJC_ASSOCIATION_COPY); +} + +- (UIAlertViewBlock)willPresentBlock { + return objc_getAssociatedObject(self, UIAlertViewWillPresentBlockKey); +} + +- (void)setWillPresentBlock:(UIAlertViewBlock)willPresentBlock { + [self _checkAlertViewDelegate]; + objc_setAssociatedObject(self, UIAlertViewWillPresentBlockKey, willPresentBlock, OBJC_ASSOCIATION_COPY); +} + +- (UIAlertViewBlock)didPresentBlock { + return objc_getAssociatedObject(self, UIAlertViewDidPresentBlockKey); +} + +- (void)setDidPresentBlock:(UIAlertViewBlock)didPresentBlock { + [self _checkAlertViewDelegate]; + objc_setAssociatedObject(self, UIAlertViewDidPresentBlockKey, didPresentBlock, OBJC_ASSOCIATION_COPY); +} + +- (UIAlertViewBlock)cancelBlock { + return objc_getAssociatedObject(self, UIAlertViewCancelBlockKey); +} + +- (void)setCancelBlock:(UIAlertViewBlock)cancelBlock { + [self _checkAlertViewDelegate]; + objc_setAssociatedObject(self, UIAlertViewCancelBlockKey, cancelBlock, OBJC_ASSOCIATION_COPY); +} + +- (void)setShouldEnableFirstOtherButtonBlock:(BOOL (^)(UIAlertView *alertView))shouldEnableFirstOtherButtonBlock { + [self _checkAlertViewDelegate]; + objc_setAssociatedObject(self, UIAlertViewShouldEnableFirstOtherButtonBlockKey, shouldEnableFirstOtherButtonBlock, + OBJC_ASSOCIATION_COPY); +} + +- (BOOL (^)(UIAlertView *alertView))shouldEnableFirstOtherButtonBlock { + return objc_getAssociatedObject(self, UIAlertViewShouldEnableFirstOtherButtonBlockKey); +} + +#pragma mark - UIAlertViewDelegate + +- (void)willPresentAlertView:(UIAlertView *)alertView { + UIAlertViewBlock block = alertView.willPresentBlock; + + if (block) { + block(alertView); + } + + id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey); + if (originalDelegate && [originalDelegate respondsToSelector:@selector(willPresentAlertView:)]) { + [originalDelegate willPresentAlertView:alertView]; + } +} + +- (void)didPresentAlertView:(UIAlertView *)alertView { + UIAlertViewBlock block = alertView.didPresentBlock; + + if (block) { + block(alertView); + } + + id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey); + if (originalDelegate && [originalDelegate respondsToSelector:@selector(didPresentAlertView:)]) { + [originalDelegate didPresentAlertView:alertView]; + } +} + +- (void)alertViewCancel:(UIAlertView *)alertView { + UIAlertViewBlock block = alertView.cancelBlock; + + if (block) { + block(alertView); + } + + id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey); + if (originalDelegate && [originalDelegate respondsToSelector:@selector(alertViewCancel:)]) { + [originalDelegate alertViewCancel:alertView]; + } +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { + UIAlertViewCompletionBlock completion = alertView.tapBlock; + + if (completion) { + completion(alertView, buttonIndex); + } + + id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey); + if (originalDelegate && [originalDelegate respondsToSelector:@selector(alertView:clickedButtonAtIndex:)]) { + [originalDelegate alertView:alertView clickedButtonAtIndex:buttonIndex]; + } +} + +- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex { + UIAlertViewCompletionBlock completion = alertView.willDismissBlock; + + if (completion) { + completion(alertView, buttonIndex); + } + + id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey); + if (originalDelegate && [originalDelegate respondsToSelector:@selector(alertView:willDismissWithButtonIndex:)]) { + [originalDelegate alertView:alertView willDismissWithButtonIndex:buttonIndex]; + } +} + +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { + UIAlertViewCompletionBlock completion = alertView.didDismissBlock; + + if (completion) { + completion(alertView, buttonIndex); + } + + id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey); + if (originalDelegate && [originalDelegate respondsToSelector:@selector(alertView:didDismissWithButtonIndex:)]) { + [originalDelegate alertView:alertView didDismissWithButtonIndex:buttonIndex]; + } +} + +- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView { + BOOL (^shouldEnableFirstOtherButtonBlock)(UIAlertView *alertView) = alertView.shouldEnableFirstOtherButtonBlock; + + if (shouldEnableFirstOtherButtonBlock) { + return shouldEnableFirstOtherButtonBlock(alertView); + } + + id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey); + if (originalDelegate && [originalDelegate respondsToSelector:@selector(alertViewShouldEnableFirstOtherButton:)]) { + return [originalDelegate alertViewShouldEnableFirstOtherButton:alertView]; + } + + return YES; +} + +@end diff --git a/Classes/Utils/Utils.h b/Classes/Utils/Utils.h index 28b950d5d..0ae4df985 100644 --- a/Classes/Utils/Utils.h +++ b/Classes/Utils/Utils.h @@ -4,55 +4,60 @@ * * 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. - */ + */ -#ifndef LINPHONE_UTILS_H -#define LINPHONE_UTILS_H +#import "LinphoneManager.h" -#define DYNAMIC_CAST(x, cls) \ - ({ \ - cls *inst_ = (cls *)(x); \ - [inst_ isKindOfClass:[cls class]]? inst_ : nil; \ - }) - -typedef enum _LinphoneLoggerSeverity { - LinphoneLoggerDebug = 0, - LinphoneLoggerLog, - LinphoneLoggerWarning, - LinphoneLoggerError, - LinphoneLoggerFatal -} LinphoneLoggerSeverity; +#define LOGV(level, ...) [LinphoneLogger log:level file:__FILE__ line:__LINE__ format:__VA_ARGS__] +#define LOGD(...) LOGV(ORTP_DEBUG, __VA_ARGS__) +#define LOGI(...) LOGV(ORTP_MESSAGE, __VA_ARGS__) +#define LOGW(...) LOGV(ORTP_WARNING, __VA_ARGS__) +#define LOGE(...) LOGV(ORTP_ERROR, __VA_ARGS__) +#define LOGF(...) LOGV(ORTP_FATAL, __VA_ARGS__) +#define IPAD (LinphoneManager.runningOnIpad) @interface LinphoneLogger : NSObject { } -+ (void)log:(LinphoneLoggerSeverity) severity format:(NSString *)format,...; -+ (void)logc:(LinphoneLoggerSeverity) severity format:(const char *)format,...; ++ (void)log:(OrtpLogLevel)severity file:(const char *)file line:(int)line format:(NSString *)format, ...; +void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); @end -@interface LinphoneUtils : NSObject { - -} +@interface LinphoneUtils : NSObject + (BOOL)findAndResignFirstResponder:(UIView*)view; + (void)adjustFontSize:(UIView*)view mult:(float)mult; + (void)buttonFixStates:(UIButton*)button; -+ (void)buttonFixStatesForTabs:(UIButton*)button; + (void)buttonMultiViewAddAttributes:(NSMutableDictionary*)attributes button:(UIButton*)button; + (void)buttonMultiViewApplyAttributes:(NSDictionary*)attributes button:(UIButton*)button; ++ (NSString *)deviceName; + +typedef enum { + LinphoneDateHistoryList, + LinphoneDateHistoryDetails, + LinphoneDateChatList, + LinphoneDateChatBubble, +} LinphoneDateFormat; + ++ (NSString *)timeToString:(time_t)time withFormat:(LinphoneDateFormat)format; + ++ (BOOL)hasSelfAvatar; ++ (UIImage *)selfAvatar; + ++ (NSString *)durationToString:(int)duration; @end @@ -62,12 +67,64 @@ typedef enum _LinphoneLoggerSeverity { @end -void Linphone_log(NSString* format, ...) NS_FORMAT_FUNCTION(1,2); -void Linphone_dbg(NSString* format, ...) NS_FORMAT_FUNCTION(1,2); -void Linphone_warn(NSString* format, ...) NS_FORMAT_FUNCTION(1,2); -void Linphone_err(NSString* format, ...) NS_FORMAT_FUNCTION(1,2); -void Linphone_fatal(NSString* format, ...) NS_FORMAT_FUNCTION(1,2); +@interface NSString (md5) +- (NSString *)md5; +@end -#endif +@interface UIImage (squareCrop) + +- (UIImage *)squareCrop; +- (UIImage *)scaleToSize:(CGSize)size squared:(BOOL)squared; + +@end + +@interface ContactDisplay : NSObject ++ (void)setDisplayNameLabel:(UILabel *)label forContact:(ABRecordRef)contact; ++ (void)setDisplayNameLabel:(UILabel *)label forAddress:(const LinphoneAddress *)addr; +@end + +#import +#import + +#define LINPHONE_MAIN_COLOR [UIColor colorWithRed:207.0f / 255.0f green:76.0f / 255.0f blue:41.0f / 255.0f alpha:1.0f] +#define LINPHONE_SETTINGS_BG_IOS7 [UIColor colorWithRed:164 / 255. green:175 / 255. blue:183 / 255. alpha:1.0] + +@interface UIColor (LightAndDark) + +- (UIColor *)adjustHue:(float)hm saturation:(float)sm brightness:(float)bm alpha:(float)am; + +- (UIColor *)lumColor:(float)mult; + +- (UIColor *)lighterColor; + +- (UIColor *)darkerColor; + +@end + +@interface UIImage (ForceDecode) + ++ (UIImage *)decodedImageWithImage:(UIImage *)image; + +@end + +/* Use that macro when you want to invoke a custom initialisation method on your class, + whatever is using it (xib, source code, etc., tableview cell) */ +#define INIT_WITH_COMMON \ + -(instancetype)init { \ + self = [super init]; \ + [self commonInit]; \ + return self; \ + } \ + -(instancetype)initWithCoder : (NSCoder *)aDecoder { \ + self = [super initWithCoder:aDecoder]; \ + [self commonInit]; \ + return self; \ + } \ + -(instancetype)initWithFrame : (CGRect)frame { \ + self = [super initWithFrame:frame]; \ + [self commonInit]; \ + return self; \ + } \ + -(instancetype)commonInit diff --git a/Classes/Utils/Utils.m b/Classes/Utils/Utils.m index 31581e8cf..923ad4130 100644 --- a/Classes/Utils/Utils.m +++ b/Classes/Utils/Utils.m @@ -4,271 +4,611 @@ * * 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 +#import +#import +#import #import "Utils.h" -#include "linphone/linphonecore.h" +#import "linphone/linphonecore.h" +#import "UILabel+Boldify.h" +#import "FastAddressBook.h" +#import "ColorSpaceUtilities.h" @implementation LinphoneLogger - -+ (void)logv:(LinphoneLoggerSeverity)severity format:(NSString*)format args:(va_list)args{ - NSString *str = [[NSString alloc] initWithFormat: format arguments:args]; - if(severity <= LinphoneLoggerDebug) { - ms_debug("%s", [str UTF8String]); - } else if(severity <= LinphoneLoggerLog) { - ms_message("%s", [str UTF8String]); - } else if(severity <= LinphoneLoggerWarning) { - ms_warning("%s", [str UTF8String]); - } else if(severity <= LinphoneLoggerError) { - ms_error("%s", [str UTF8String]); - } else if(severity <= LinphoneLoggerFatal) { - ms_fatal("%s", [str UTF8String]); - } - [str release]; ++ (void)log:(OrtpLogLevel)severity file:(const char *)file line:(int)line format:(NSString *)format, ... { + va_list args; + va_start(args, format); + NSString *str = [[NSString alloc] initWithFormat:format arguments:args]; + const char *utf8str = [str cStringUsingEncoding:NSString.defaultCStringEncoding]; + int filesize = 20; + const char *filename = strchr(file, '/') ? strrchr(file, '/') + 1 : file; + if (severity <= ORTP_DEBUG) { + // lol: ortp_debug(XXX) can be disabled at compile time, but ortp_log(ORTP_DEBUG, xxx) will always be valid even + // not in debug build... + ortp_debug("%*s:%3d - %s", filesize, filename + MAX((int)strlen(filename) - filesize, 0), line, utf8str); + } else { + ortp_log(severity, "%*s:%3d - %s", filesize, filename + MAX((int)strlen(filename) - filesize, 0), line, + utf8str); + } + va_end(args); } -+ (void)log:(LinphoneLoggerSeverity) severity format:(NSString *)format,... { - va_list args; - va_start (args, format); - [LinphoneLogger logv:severity format:format args:args]; - va_end (args); -} +#pragma mark - Logs Functions callbacks -+ (void)logc:(LinphoneLoggerSeverity) severity format:(const char *)format,... { - va_list args; - va_start (args, format); - if(severity <= LinphoneLoggerDebug) { - ortp_logv(ORTP_DEBUG, format, args); - } else if(severity <= LinphoneLoggerLog) { - ortp_logv(ORTP_MESSAGE, format, args); - } else if(severity <= LinphoneLoggerWarning) { - ortp_logv(ORTP_WARNING, format, args); - } else if(severity <= LinphoneLoggerError) { - ortp_logv(ORTP_ERROR, format, args); - } else if(severity <= LinphoneLoggerFatal) { - ortp_logv(ORTP_FATAL, format, args); - } - va_end (args); +void linphone_iphone_log_handler(int lev, const char *fmt, va_list args) { + NSString *format = [[NSString alloc] initWithUTF8String:fmt]; + NSString *formatedString = [[NSString alloc] initWithFormat:format arguments:args]; + char levelC = 'I'; + switch ((OrtpLogLevel)lev) { + case ORTP_FATAL: + levelC = 'F'; + break; + case ORTP_ERROR: + levelC = 'E'; + break; + case ORTP_WARNING: + levelC = 'W'; + break; + case ORTP_MESSAGE: + levelC = 'I'; + break; + case ORTP_TRACE: + case ORTP_DEBUG: + levelC = 'D'; + break; + case ORTP_LOGLEV_END: + return; + } + // since \r are interpreted like \n, avoid double new lines when logging packets + NSLog(@"%c %@", levelC, [formatedString stringByReplacingOccurrencesOfString:@"\r\n" withString:@"\n"]); } @end @implementation LinphoneUtils -+ (BOOL)findAndResignFirstResponder:(UIView*)view { - if (view.isFirstResponder) { - [view resignFirstResponder]; - return YES; - } - for (UIView *subView in view.subviews) { - if ([LinphoneUtils findAndResignFirstResponder:subView]) - return YES; - } - return NO; ++ (BOOL)hasSelfAvatar { + return [NSURL URLWithString:[LinphoneManager.instance lpConfigStringForKey:@"avatar"]] != nil; +} ++ (UIImage *)selfAvatar { + NSURL *url = [NSURL URLWithString:[LinphoneManager.instance lpConfigStringForKey:@"avatar"]]; + __block UIImage *ret = nil; + if (url) { + __block NSConditionLock *photoLock = [[NSConditionLock alloc] initWithCondition:1]; + // load avatar synchronously so that we can return UIIMage* directly - since we are + // only using thumbnail, it must be pretty fast to fetch even without cache. + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [LinphoneManager.instance.photoLibrary assetForURL:url + resultBlock:^(ALAsset *asset) { + ret = [[UIImage alloc] initWithCGImage:[asset thumbnail]]; + [photoLock lock]; + [photoLock unlockWithCondition:0]; + } + failureBlock:^(NSError *error) { + LOGE(@"Can't read avatar"); + [photoLock lock]; + [photoLock unlockWithCondition:0]; + }]; + }); + [photoLock lockWhenCondition:0]; + [photoLock unlock]; + } + + if (!ret) { + ret = [UIImage imageNamed:@"avatar.png"]; + } + return ret; } -+ (void)adjustFontSize:(UIView*)view mult:(float)mult{ - if([view isKindOfClass:[UILabel class]]) { - UILabel *label = (UILabel*)view; - UIFont *font = [label font]; - [label setFont:[UIFont fontWithName:font.fontName size:font.pointSize * mult]]; - } else if([view isKindOfClass:[UITextField class]]) { - UITextField *label = (UITextField*)view; - UIFont *font = [label font]; - [label setFont:[UIFont fontWithName:font.fontName size:font.pointSize * mult]]; - } else if([view isKindOfClass:[UIButton class]]) { - UIButton* button = (UIButton*)view; - UIFont* font = button.titleLabel.font; - [button.titleLabel setFont:[UIFont fontWithName:font.fontName size:font.pointSize*mult]]; - } else { - for(UIView *subView in [view subviews]) { - [LinphoneUtils adjustFontSize:subView mult:mult]; - } - } ++ (NSString *)durationToString:(int)duration { + NSMutableString *result = [[NSMutableString alloc] init]; + if (duration / 3600 > 0) { + [result appendString:[NSString stringWithFormat:@"%02i:", duration / 3600]]; + duration = duration % 3600; + } + return [result stringByAppendingString:[NSString stringWithFormat:@"%02i:%02i", (duration / 60), (duration % 60)]]; } -+ (void)buttonFixStates:(UIButton*)button { - // Set selected+over title: IB lack ! - [button setTitle:[button titleForState:UIControlStateSelected] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - // Set selected+over titleColor: IB lack ! - [button setTitleColor:[button titleColorForState:UIControlStateHighlighted] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - // Set selected+disabled title: IB lack ! - [button setTitle:[button titleForState:UIControlStateSelected] - forState:(UIControlStateDisabled | UIControlStateSelected)]; - - // Set selected+disabled titleColor: IB lack ! - [button setTitleColor:[button titleColorForState:UIControlStateDisabled] - forState:(UIControlStateDisabled | UIControlStateSelected)]; ++ (NSString *)timeToString:(time_t)time withFormat:(LinphoneDateFormat)format { + NSString *formatstr; + NSDate *todayDate = [[NSDate alloc] init]; + NSDate *messageDate = (time == 0) ? todayDate : [NSDate dateWithTimeIntervalSince1970:time]; + NSDateComponents *todayComponents = + [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear + fromDate:todayDate]; + NSDateComponents *dateComponents = + [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear + fromDate:messageDate]; + BOOL sameYear = (todayComponents.year == dateComponents.year); + BOOL sameMonth = (sameYear && (todayComponents.month == dateComponents.month)); + BOOL sameDay = (sameMonth && (todayComponents.day == dateComponents.day)); + + switch (format) { + case LinphoneDateHistoryList: + if (sameYear) { + formatstr = NSLocalizedString(@"EEE dd MMMM", + @"Date formatting in History List, for current year (also see " + @"http://cybersam.com/ios-dev/quick-guide-to-ios-dateformatting)"); + } else { + formatstr = NSLocalizedString(@"EEE dd MMMM yyyy", + @"Date formatting in History List, for previous years (also see " + @"http://cybersam.com/ios-dev/quick-guide-to-ios-dateformatting)"); + } + break; + case LinphoneDateHistoryDetails: + formatstr = NSLocalizedString(@"EEE dd MMM 'at' HH'h'mm", @"Date formatting in History Details (also see " + @"http://cybersam.com/ios-dev/" + @"quick-guide-to-ios-dateformatting)"); + break; + case LinphoneDateChatList: + if (sameDay) { + formatstr = NSLocalizedString( + @"HH:mm", @"Date formatting in Chat List and Conversation bubbles, for current day (also see " + @"http://cybersam.com/ios-dev/quick-guide-to-ios-dateformatting)"); + } else { + formatstr = + NSLocalizedString(@"MM/dd", @"Date formatting in Chat List, for all but current day (also see " + @"http://cybersam.com/ios-dev/quick-guide-to-ios-dateformatting)"); + } + break; + case LinphoneDateChatBubble: + if (sameDay) { + formatstr = NSLocalizedString( + @"HH:mm", @"Date formatting in Chat List and Conversation bubbles, for current day (also see " + @"http://cybersam.com/ios-dev/quick-guide-to-ios-dateformatting)"); + } else { + formatstr = NSLocalizedString(@"MM/dd - HH:mm", + @"Date formatting in Conversation bubbles, for all but current day (also " + @"see http://cybersam.com/ios-dev/quick-guide-to-ios-dateformatting)"); + } + break; + } + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateFormat:formatstr]; + return [dateFormatter stringFromDate:messageDate]; } -+ (void)buttonFixStatesForTabs:(UIButton*)button { - // Set selected+over title: IB lack ! - [button setTitle:[button titleForState:UIControlStateSelected] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - // Set selected+over titleColor: IB lack ! - [button setTitleColor:[button titleColorForState:UIControlStateSelected] - forState:(UIControlStateHighlighted | UIControlStateSelected)]; - - // Set selected+disabled title: IB lack ! - [button setTitle:[button titleForState:UIControlStateSelected] - forState:(UIControlStateDisabled | UIControlStateSelected)]; - - // Set selected+disabled titleColor: IB lack ! - [button setTitleColor:[button titleColorForState:UIControlStateDisabled] - forState:(UIControlStateDisabled | UIControlStateSelected)]; ++ (BOOL)findAndResignFirstResponder:(UIView *)view { + if (view.isFirstResponder) { + [view resignFirstResponder]; + return YES; + } + for (UIView *subView in view.subviews) { + if ([LinphoneUtils findAndResignFirstResponder:subView]) + return YES; + } + return NO; } -+ (void)buttonMultiViewAddAttributes:(NSMutableDictionary*)attributes button:(UIButton*)button { - [LinphoneUtils addDictEntry:attributes item:[button titleForState:UIControlStateNormal] key:@"title-normal"]; - [LinphoneUtils addDictEntry:attributes item:[button titleForState:UIControlStateHighlighted] key:@"title-highlighted"]; - [LinphoneUtils addDictEntry:attributes item:[button titleForState:UIControlStateDisabled] key:@"title-disabled"]; - [LinphoneUtils addDictEntry:attributes item:[button titleForState:UIControlStateSelected] key:@"title-selected"]; - [LinphoneUtils addDictEntry:attributes item:[button titleForState:UIControlStateDisabled | UIControlStateHighlighted] key:@"title-disabled-highlighted"]; - [LinphoneUtils addDictEntry:attributes item:[button titleForState:UIControlStateSelected | UIControlStateHighlighted] key:@"title-selected-highlighted"]; - [LinphoneUtils addDictEntry:attributes item:[button titleForState:UIControlStateSelected | UIControlStateDisabled] key:@"title-selected-disabled"]; - - [LinphoneUtils addDictEntry:attributes item:[button titleColorForState:UIControlStateNormal] key:@"title-color-normal"]; - [LinphoneUtils addDictEntry:attributes item:[button titleColorForState:UIControlStateHighlighted] key:@"title-color-highlighted"]; - [LinphoneUtils addDictEntry:attributes item:[button titleColorForState:UIControlStateDisabled] key:@"title-color-disabled"]; - [LinphoneUtils addDictEntry:attributes item:[button titleColorForState:UIControlStateSelected] key:@"title-color-selected"]; - [LinphoneUtils addDictEntry:attributes item:[button titleColorForState:UIControlStateDisabled | UIControlStateHighlighted] key:@"title-color-disabled-highlighted"]; - [LinphoneUtils addDictEntry:attributes item:[button titleColorForState:UIControlStateSelected | UIControlStateHighlighted] key:@"title-color-selected-highlighted"]; - [LinphoneUtils addDictEntry:attributes item:[button titleColorForState:UIControlStateSelected | UIControlStateDisabled] key:@"title-color-selected-disabled"]; - ++ (void)adjustFontSize:(UIView *)view mult:(float)mult { + if ([view isKindOfClass:[UILabel class]]) { + UILabel *label = (UILabel *)view; + UIFont *font = [label font]; + [label setFont:[UIFont fontWithName:font.fontName size:font.pointSize * mult]]; + } else if ([view isKindOfClass:[UITextField class]]) { + UITextField *label = (UITextField *)view; + UIFont *font = [label font]; + [label setFont:[UIFont fontWithName:font.fontName size:font.pointSize * mult]]; + } else if ([view isKindOfClass:[UIButton class]]) { + UIButton *button = (UIButton *)view; + UIFont *font = button.titleLabel.font; + [button.titleLabel setFont:[UIFont fontWithName:font.fontName size:font.pointSize * mult]]; + } else { + for (UIView *subView in [view subviews]) { + [LinphoneUtils adjustFontSize:subView mult:mult]; + } + } +} + ++ (void)buttonFixStates:(UIButton *)button { + // Interface builder lack fixes + [button setTitle:[button titleForState:UIControlStateSelected] + forState:(UIControlStateHighlighted | UIControlStateSelected)]; + [button setTitleColor:[button titleColorForState:UIControlStateHighlighted] + forState:(UIControlStateHighlighted | UIControlStateSelected)]; + [button setTitle:[button titleForState:UIControlStateSelected] + forState:(UIControlStateDisabled | UIControlStateSelected)]; + [button setTitleColor:[button titleColorForState:UIControlStateDisabled] + forState:(UIControlStateDisabled | UIControlStateSelected)]; +} + ++ (void)buttonMultiViewAddAttributes:(NSMutableDictionary *)attributes button:(UIButton *)button { + [LinphoneUtils addDictEntry:attributes item:[button titleForState:UIControlStateNormal] key:@"title-normal"]; + [LinphoneUtils addDictEntry:attributes + item:[button titleForState:UIControlStateHighlighted] + key:@"title-highlighted"]; + [LinphoneUtils addDictEntry:attributes item:[button titleForState:UIControlStateDisabled] key:@"title-disabled"]; + [LinphoneUtils addDictEntry:attributes item:[button titleForState:UIControlStateSelected] key:@"title-selected"]; + [LinphoneUtils addDictEntry:attributes + item:[button titleForState:UIControlStateDisabled | UIControlStateHighlighted] + key:@"title-disabled-highlighted"]; + [LinphoneUtils addDictEntry:attributes + item:[button titleForState:UIControlStateSelected | UIControlStateHighlighted] + key:@"title-selected-highlighted"]; + [LinphoneUtils addDictEntry:attributes + item:[button titleForState:UIControlStateSelected | UIControlStateDisabled] + key:@"title-selected-disabled"]; + + [LinphoneUtils addDictEntry:attributes + item:[button titleColorForState:UIControlStateNormal] + key:@"title-color-normal"]; + [LinphoneUtils addDictEntry:attributes + item:[button titleColorForState:UIControlStateHighlighted] + key:@"title-color-highlighted"]; + [LinphoneUtils addDictEntry:attributes + item:[button titleColorForState:UIControlStateDisabled] + key:@"title-color-disabled"]; + [LinphoneUtils addDictEntry:attributes + item:[button titleColorForState:UIControlStateSelected] + key:@"title-color-selected"]; + [LinphoneUtils addDictEntry:attributes + item:[button titleColorForState:UIControlStateDisabled | UIControlStateHighlighted] + key:@"title-color-disabled-highlighted"]; + [LinphoneUtils addDictEntry:attributes + item:[button titleColorForState:UIControlStateSelected | UIControlStateHighlighted] + key:@"title-color-selected-highlighted"]; + [LinphoneUtils addDictEntry:attributes + item:[button titleColorForState:UIControlStateSelected | UIControlStateDisabled] + key:@"title-color-selected-disabled"]; + [LinphoneUtils addDictEntry:attributes item:NSStringFromUIEdgeInsets([button titleEdgeInsets]) key:@"title-edge"]; - [LinphoneUtils addDictEntry:attributes item:NSStringFromUIEdgeInsets([button contentEdgeInsets]) key:@"content-edge"]; + [LinphoneUtils addDictEntry:attributes + item:NSStringFromUIEdgeInsets([button contentEdgeInsets]) + key:@"content-edge"]; [LinphoneUtils addDictEntry:attributes item:NSStringFromUIEdgeInsets([button imageEdgeInsets]) key:@"image-edge"]; - - [LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateNormal] key:@"image-normal"]; - [LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateHighlighted] key:@"image-highlighted"]; - [LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateDisabled] key:@"image-disabled"]; - [LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateSelected] key:@"image-selected"]; - [LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateDisabled | UIControlStateHighlighted] key:@"image-disabled-highlighted"]; - [LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateSelected | UIControlStateHighlighted] key:@"image-selected-highlighted"]; - [LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateSelected | UIControlStateDisabled] key:@"image-selected-disabled"]; - - [LinphoneUtils addDictEntry:attributes item:[button backgroundImageForState:UIControlStateNormal] key:@"background-normal"]; - [LinphoneUtils addDictEntry:attributes item:[button backgroundImageForState:UIControlStateHighlighted] key:@"background-highlighted"]; - [LinphoneUtils addDictEntry:attributes item:[button backgroundImageForState:UIControlStateDisabled] key:@"background-disabled"]; - [LinphoneUtils addDictEntry:attributes item:[button backgroundImageForState:UIControlStateSelected] key:@"background-selected"]; - [LinphoneUtils addDictEntry:attributes item:[button backgroundImageForState:UIControlStateDisabled | UIControlStateHighlighted] key:@"background-disabled-highlighted"]; - [LinphoneUtils addDictEntry:attributes item:[button backgroundImageForState:UIControlStateSelected | UIControlStateHighlighted] key:@"background-selected-highlighted"]; - [LinphoneUtils addDictEntry:attributes item:[button backgroundImageForState:UIControlStateSelected | UIControlStateDisabled] key:@"background-selected-disabled"]; + + [LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateNormal] key:@"image-normal"]; + [LinphoneUtils addDictEntry:attributes + item:[button imageForState:UIControlStateHighlighted] + key:@"image-highlighted"]; + [LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateDisabled] key:@"image-disabled"]; + [LinphoneUtils addDictEntry:attributes item:[button imageForState:UIControlStateSelected] key:@"image-selected"]; + [LinphoneUtils addDictEntry:attributes + item:[button imageForState:UIControlStateDisabled | UIControlStateHighlighted] + key:@"image-disabled-highlighted"]; + [LinphoneUtils addDictEntry:attributes + item:[button imageForState:UIControlStateSelected | UIControlStateHighlighted] + key:@"image-selected-highlighted"]; + [LinphoneUtils addDictEntry:attributes + item:[button imageForState:UIControlStateSelected | UIControlStateDisabled] + key:@"image-selected-disabled"]; + + [LinphoneUtils addDictEntry:attributes + item:[button backgroundImageForState:UIControlStateNormal] + key:@"background-normal"]; + [LinphoneUtils addDictEntry:attributes + item:[button backgroundImageForState:UIControlStateHighlighted] + key:@"background-highlighted"]; + [LinphoneUtils addDictEntry:attributes + item:[button backgroundImageForState:UIControlStateDisabled] + key:@"background-disabled"]; + [LinphoneUtils addDictEntry:attributes + item:[button backgroundImageForState:UIControlStateSelected] + key:@"background-selected"]; + [LinphoneUtils addDictEntry:attributes + item:[button backgroundImageForState:UIControlStateDisabled | UIControlStateHighlighted] + key:@"background-disabled-highlighted"]; + [LinphoneUtils addDictEntry:attributes + item:[button backgroundImageForState:UIControlStateSelected | UIControlStateHighlighted] + key:@"background-selected-highlighted"]; + [LinphoneUtils addDictEntry:attributes + item:[button backgroundImageForState:UIControlStateSelected | UIControlStateDisabled] + key:@"background-selected-disabled"]; } -+ (void)buttonMultiViewApplyAttributes:(NSDictionary*)attributes button:(UIButton*)button { - [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-normal"] forState:UIControlStateNormal]; - [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-highlighted"] forState:UIControlStateHighlighted]; - [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-disabled"] forState:UIControlStateDisabled]; - [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-selected"] forState:UIControlStateSelected]; - [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-disabled-highlighted"] forState:UIControlStateDisabled | UIControlStateHighlighted]; - [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-selected-highlighted"] forState:UIControlStateSelected | UIControlStateHighlighted]; - [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-selected-disabled"] forState:UIControlStateSelected | UIControlStateDisabled]; - - [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-normal"] forState:UIControlStateNormal]; - [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-highlighted"] forState:UIControlStateHighlighted]; - [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-disabled"] forState:UIControlStateDisabled]; - [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-selected"] forState:UIControlStateSelected]; - [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-disabled-highlighted"] forState:UIControlStateDisabled | UIControlStateHighlighted]; - [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-selected-highlighted"] forState:UIControlStateSelected | UIControlStateHighlighted]; - [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-selected-disabled"] forState:UIControlStateSelected | UIControlStateDisabled]; - ++ (void)buttonMultiViewApplyAttributes:(NSDictionary *)attributes button:(UIButton *)button { + [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-normal"] forState:UIControlStateNormal]; + [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-highlighted"] + forState:UIControlStateHighlighted]; + [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-disabled"] forState:UIControlStateDisabled]; + [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-selected"] forState:UIControlStateSelected]; + [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-disabled-highlighted"] + forState:UIControlStateDisabled | UIControlStateHighlighted]; + [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-selected-highlighted"] + forState:UIControlStateSelected | UIControlStateHighlighted]; + [button setTitle:[LinphoneUtils getDictEntry:attributes key:@"title-selected-disabled"] + forState:UIControlStateSelected | UIControlStateDisabled]; + + [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-normal"] + forState:UIControlStateNormal]; + [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-highlighted"] + forState:UIControlStateHighlighted]; + [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-disabled"] + forState:UIControlStateDisabled]; + [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-selected"] + forState:UIControlStateSelected]; + [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-disabled-highlighted"] + forState:UIControlStateDisabled | UIControlStateHighlighted]; + [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-selected-highlighted"] + forState:UIControlStateSelected | UIControlStateHighlighted]; + [button setTitleColor:[LinphoneUtils getDictEntry:attributes key:@"title-color-selected-disabled"] + forState:UIControlStateSelected | UIControlStateDisabled]; + [button setTitleEdgeInsets:UIEdgeInsetsFromString([LinphoneUtils getDictEntry:attributes key:@"title-edge"])]; [button setContentEdgeInsets:UIEdgeInsetsFromString([LinphoneUtils getDictEntry:attributes key:@"content-edge"])]; [button setImageEdgeInsets:UIEdgeInsetsFromString([LinphoneUtils getDictEntry:attributes key:@"image-edge"])]; - [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-normal"] forState:UIControlStateNormal]; - [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-highlighted"] forState:UIControlStateHighlighted]; - [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-disabled"] forState:UIControlStateDisabled]; - [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-selected"] forState:UIControlStateSelected]; - [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-disabled-highlighted"] forState:UIControlStateDisabled | UIControlStateHighlighted]; - [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-selected-highlighted"] forState:UIControlStateSelected | UIControlStateHighlighted]; - [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-selected-disabled"] forState:UIControlStateSelected | UIControlStateDisabled]; - - [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-normal"] forState:UIControlStateNormal]; - [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-highlighted"] forState:UIControlStateHighlighted]; - [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-disabled"] forState:UIControlStateDisabled]; - [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-selected"] forState:UIControlStateSelected]; - [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-disabled-highlighted"] forState:UIControlStateDisabled | UIControlStateHighlighted]; - [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-selected-highlighted"] forState:UIControlStateSelected | UIControlStateHighlighted]; - [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-selected-disabled"] forState:UIControlStateSelected | UIControlStateDisabled]; + [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-normal"] forState:UIControlStateNormal]; + [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-highlighted"] + forState:UIControlStateHighlighted]; + [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-disabled"] forState:UIControlStateDisabled]; + [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-selected"] forState:UIControlStateSelected]; + [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-disabled-highlighted"] + forState:UIControlStateDisabled | UIControlStateHighlighted]; + [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-selected-highlighted"] + forState:UIControlStateSelected | UIControlStateHighlighted]; + [button setImage:[LinphoneUtils getDictEntry:attributes key:@"image-selected-disabled"] + forState:UIControlStateSelected | UIControlStateDisabled]; + + [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-normal"] + forState:UIControlStateNormal]; + [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-highlighted"] + forState:UIControlStateHighlighted]; + [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-disabled"] + forState:UIControlStateDisabled]; + [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-selected"] + forState:UIControlStateSelected]; + [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-disabled-highlighted"] + forState:UIControlStateDisabled | UIControlStateHighlighted]; + [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-selected-highlighted"] + forState:UIControlStateSelected | UIControlStateHighlighted]; + [button setBackgroundImage:[LinphoneUtils getDictEntry:attributes key:@"background-selected-disabled"] + forState:UIControlStateSelected | UIControlStateDisabled]; } - -+ (void)addDictEntry:(NSMutableDictionary*)dict item:(id)item key:(id)key { - if(item != nil && key != nil) { - [dict setObject:item forKey:key]; - } ++ (void)addDictEntry:(NSMutableDictionary *)dict item:(id)item key:(id)key { + if (item != nil && key != nil) { + [dict setObject:item forKey:key]; + } } -+ (id)getDictEntry:(NSDictionary*)dict key:(id)key { - if(key != nil) { - return [dict objectForKey:key]; - } - return nil; ++ (id)getDictEntry:(NSDictionary *)dict key:(id)key { + if (key != nil) { + return [dict objectForKey:key]; + } + return nil; +} + ++ (NSString *)deviceName { + struct utsname systemInfo; + uname(&systemInfo); + + return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; } @end @implementation NSNumber (HumanReadableSize) -- (NSString*)toHumanReadableSize { - float floatSize = [self floatValue]; +- (NSString *)toHumanReadableSize { + float floatSize = [self floatValue]; if (floatSize < 1023) - return([NSString stringWithFormat:@"%1.0f bytes",floatSize]); + return ([NSString stringWithFormat:@"%1.0f bytes", floatSize]); floatSize = floatSize / 1024; if (floatSize < 1023) - return([NSString stringWithFormat:@"%1.1f KB",floatSize]); + return ([NSString stringWithFormat:@"%1.1f KB", floatSize]); floatSize = floatSize / 1024; if (floatSize < 1023) - return([NSString stringWithFormat:@"%1.1f MB",floatSize]); + return ([NSString stringWithFormat:@"%1.1f MB", floatSize]); floatSize = floatSize / 1024; - - return([NSString stringWithFormat:@"%1.1f GB",floatSize]); + + return ([NSString stringWithFormat:@"%1.1f GB", floatSize]); } @end -#define LOGV(level, argstart) \ - va_list args; \ - va_start(args, argstart); \ - [LinphoneLogger logv:level format:argstart args:args]; \ - va_end(args); +@implementation NSString (md5) -void Linphone_log(NSString* format, ...){ - LOGV(LinphoneLoggerLog, format); +- (NSString *)md5 { + const char *ptr = [self UTF8String]; + unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH]; + CC_MD5(ptr, (unsigned int)strlen(ptr), md5Buffer); + NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; + for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { + [output appendFormat:@"%02x", md5Buffer[i]]; + } + + return output; } -void Linphone_dbg(NSString* format, ...){ - LOGV(LinphoneLoggerDebug, format); +@end + +@implementation ContactDisplay + ++ (void)setDisplayNameLabel:(UILabel *)label forContact:(ABRecordRef)contact { + label.text = [FastAddressBook displayNameForContact:contact]; +#if 0 + NSString *lLastName = CFBridgingRelease(ABRecordCopyValue(contact, kABPersonLastNameProperty)); + NSString *lLocalizedLastName = [FastAddressBook localizedLabel:lLastName]; + if (lLocalizedLastName) { + [label boldSubstring:lLocalizedLastName]; + } +#endif } -void Linphone_warn(NSString* format, ...){ - LOGV(LinphoneLoggerWarning, format); ++ (void)setDisplayNameLabel:(UILabel *)label forAddress:(const LinphoneAddress *)addr { + const LinphoneFriend *contact = [FastAddressBook getContactWithAddress:addr]; + if (contact) { + [ContactDisplay setDisplayNameLabel:label forContact:contact]; + } else { + label.text = [FastAddressBook displayNameForAddress:addr]; + } } -void Linphone_err(NSString* format, ...){ - LOGV(LinphoneLoggerError, format); +@end + +@implementation UIImage (squareCrop) + +- (UIImage *)squareCrop { + // This calculates the crop area. + + size_t originalWidth = CGImageGetWidth(self.CGImage); + size_t originalHeight = CGImageGetHeight(self.CGImage); + + size_t edge = MIN(originalWidth, originalHeight); + + float posX = (originalWidth - edge) / 2.0f; + float posY = (originalHeight - edge) / 2.0f; + + CGRect rect = CGRectMake(posX, posY, edge, edge); + + // Create bitmap image from original image data, + // using rectangle to specify desired crop area + CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect); + UIImage *img = [UIImage imageWithCGImage:imageRef]; + CGImageRelease(imageRef); + + return img; /* + UIImage *ret = nil; + + + + CGRect cropSquare = CGRectMake(posX, posY, edge, edge); + + // CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], cropSquare); + // ret = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation]; + // + // CGImageRelease(imageRef); + + CGImageRef imageRef = CGImageCreateWithImageInRect(self.CGImage, cropSquare); + ret = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation]; + CGImageRelease(imageRef); + + + return ret;*/ } -void Linphone_fatal(NSString* format, ...){ - LOGV(LinphoneLoggerFatal, format); +- (UIImage *)scaleToSize:(CGSize)size squared:(BOOL)squared { + UIImage *scaledImage = self; + if (squared) { + // scaledImage = [self squareCrop]; + size.width = size.height = MAX(size.width, size.height); + } + + UIGraphicsBeginImageContext(size); + + [scaledImage drawInRect:CGRectMake(0, 0, size.width, size.height)]; + scaledImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return scaledImage; } + +@end + +@implementation UIColor (LightAndDark) + +- (UIColor *)lumColor:(float)mult { + float hsbH, hsbS, hsbB; + float rgbaR, rgbaG, rgbaB, rgbaA; + + // Get RGB + CGColorRef cgColor = [self CGColor]; + CGColorSpaceRef cgColorSpace = CGColorGetColorSpace(cgColor); + if (CGColorSpaceGetModel(cgColorSpace) != kCGColorSpaceModelRGB) { + LOGW(@"Can't convert not RGB color"); + return self; + } else { + const CGFloat *colors = CGColorGetComponents(cgColor); + rgbaR = colors[0]; + rgbaG = colors[1]; + rgbaB = colors[2]; + rgbaA = CGColorGetAlpha(cgColor); + } + + RGB2HSL(rgbaR, rgbaG, rgbaB, &hsbH, &hsbS, &hsbB); + + hsbB = MIN(MAX(hsbB * mult, 0.0), 1.0); + + HSL2RGB(hsbH, hsbS, hsbB, &rgbaR, &rgbaG, &rgbaB); + + return [UIColor colorWithRed:rgbaR green:rgbaG blue:rgbaB alpha:rgbaA]; +} + +- (UIColor *)adjustHue:(float)hm saturation:(float)sm brightness:(float)bm alpha:(float)am { + float hsbH, hsbS, hsbB; + float rgbaR, rgbaG, rgbaB, rgbaA; + + // Get RGB + CGColorRef cgColor = [self CGColor]; + CGColorSpaceRef cgColorSpace = CGColorGetColorSpace(cgColor); + if (CGColorSpaceGetModel(cgColorSpace) != kCGColorSpaceModelRGB) { + LOGW(@"Can't convert not RGB color"); + return self; + } else { + const CGFloat *colors = CGColorGetComponents(cgColor); + rgbaR = colors[0]; + rgbaG = colors[1]; + rgbaB = colors[2]; + rgbaA = CGColorGetAlpha(cgColor); + } + + RGB2HSL(rgbaR, rgbaG, rgbaB, &hsbH, &hsbS, &hsbB); + + hsbH = MIN(MAX(hsbH + hm, 0.0), 1.0); + hsbS = MIN(MAX(hsbS + sm, 0.0), 1.0); + hsbB = MIN(MAX(hsbB + bm, 0.0), 1.0); + rgbaA = MIN(MAX(rgbaA + am, 0.0), 1.0); + + HSL2RGB(hsbH, hsbS, hsbB, &rgbaR, &rgbaG, &rgbaB); + + return [UIColor colorWithRed:rgbaR green:rgbaG blue:rgbaB alpha:rgbaA]; +} + +- (UIColor *)lighterColor { + return [self lumColor:1.3]; +} + +- (UIColor *)darkerColor { + return [self lumColor:0.75]; +} + +@end + +@implementation UIImage (ForceDecode) + ++ (UIImage *)decodedImageWithImage:(UIImage *)image { + CGImageRef imageRef = image.CGImage; + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = CGBitmapContextCreate( + NULL, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef), 8, + // Just always return width * 4 will be enough + CGImageGetWidth(imageRef) * 4, + // System only supports RGB, set explicitly + colorSpace, + // Makes system don't need to do extra conversion when displayed. + // NOTE: here we remove the alpha channel for performance. Most of the time, images loaded + // from the network are jpeg with no alpha channel. As a TODO, finding a way to detect + // if alpha channel is necessary would be nice. + kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Little); + CGColorSpaceRelease(colorSpace); + if (!context) + return nil; + + CGRect rect = (CGRect){CGPointZero, {CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)}}; + CGContextDrawImage(context, rect, imageRef); + CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context); + CGContextRelease(context); + + UIImage *decompressedImage = + [[UIImage alloc] initWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation]; + CGImageRelease(decompressedImageRef); + return decompressedImage; +} + +@end diff --git a/Classes/Utils/XMLRPC/XMLRPC.xcodeproj/project.pbxproj b/Classes/Utils/XMLRPC/XMLRPC.xcodeproj/project.pbxproj index 30f032b2f..56618966f 100755 --- a/Classes/Utils/XMLRPC/XMLRPC.xcodeproj/project.pbxproj +++ b/Classes/Utils/XMLRPC/XMLRPC.xcodeproj/project.pbxproj @@ -43,7 +43,6 @@ 07452BE20E469C9000A57686 /* XMLRPCConnectionDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCConnectionDelegate.h; sourceTree = ""; }; 075137F90E429E560019E4F6 /* XMLRPCConnectionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCConnectionManager.h; sourceTree = ""; }; 075137FA0E429E560019E4F6 /* XMLRPCConnectionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLRPCConnectionManager.m; sourceTree = ""; }; - 0759A6F21143495E000DFE98 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = Languages/English.lproj/InfoPlist.strings; sourceTree = ""; }; 0799AF040F6721FF00B71B22 /* XMLRPCUnitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "XMLRPCUnitTests-Info.plist"; path = "Resources/Property Lists/XMLRPCUnitTests-Info.plist"; sourceTree = ""; }; 0799AF0A0F67227F00B71B22 /* XMLRPCUnitTests.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = XMLRPCUnitTests.xcconfig; path = Configurations/XMLRPCUnitTests.xcconfig; sourceTree = ""; }; 0799AF0B0F67227F00B71B22 /* XMLRPCUnitTestsDevelopment.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = XMLRPCUnitTestsDevelopment.xcconfig; path = Configurations/XMLRPCUnitTestsDevelopment.xcconfig; sourceTree = ""; }; @@ -132,7 +131,6 @@ 074E8A200F6D8D6E00BE0B22 /* Localized Strings */ = { isa = PBXGroup; children = ( - 0759A6F11143495E000DFE98 /* InfoPlist.strings */, ); name = "Localized Strings"; sourceTree = ""; @@ -317,7 +315,7 @@ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0610; + LastUpgradeCheck = 0700; }; buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "XMLRPC" */; compatibilityVersion = "Xcode 3.2"; @@ -358,17 +356,6 @@ }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXVariantGroup section */ - 0759A6F11143495E000DFE98 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 0759A6F21143495E000DFE98 /* English */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - /* Begin XCBuildConfiguration section */ 1DEB91B308733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; @@ -403,6 +390,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 07127C590F4266F4009C7476 /* CommonDevelopment.xcconfig */; buildSettings = { + ENABLE_TESTABILITY = YES; GCC_THUMB_SUPPORT = NO; IPHONEOS_DEPLOYMENT_TARGET = 4.0; ONLY_ACTIVE_ARCH = YES; @@ -422,7 +410,6 @@ GCC_THUMB_SUPPORT = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; - ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = XMLRPC; PUBLIC_HEADERS_FOLDER_PATH = /headers/; SKIP_INSTALL = YES; diff --git a/Classes/Utils/XMLRPCHelper.h b/Classes/Utils/XMLRPCHelper.h new file mode 100644 index 000000000..b0dc0a269 --- /dev/null +++ b/Classes/Utils/XMLRPCHelper.h @@ -0,0 +1,46 @@ +// +// UrmetXMLRPC.h +// IperVoice +// +// Created by guillaume on 27/05/2015. +// Copyright (c) 2015 Urmet. All rights reserved. +// + +#import +#import +#import +#import +#import + +@interface XMLRPCHelper : NSObject +/* This class is only here to handle XMLRPC responses. + * + * The implementation for didReceiveResponse: (XMLRPCResponse *)response will check if the XMLRPC + * responded 'OK', in which case the view will return to idle, or if there is an error, an + * Alert will be displayed with the error message. + * + * All the rest is implemented to do nothing, which is what we want for Urmet + */ + +/** + * Will send the XML request to the 'xmlrpc_url' server that is defined in the 'assistant' section + * of the linphonerc file. + * You must implement the - didReceiveResponse method if you are using this. + */ +- (void)sendXMLRequestMethod:(NSString *)method withParams:(NSArray *)params; +- (void)sendXMLRequestMethod:(NSString *)method + withParams:(NSArray *)params + onSuccess:(BOOL (^)(XMLRPCResponse *response))block; +- (void)sendXMLRequestMethod:(NSString *)method + withParams:(NSArray *)params + onSuccess:(BOOL (^)(XMLRPCResponse *response))successBlock + onError:(BOOL (^)(XMLRPCRequest *response))errorBlock; + +// CUSTOM API + ++ (void)GetProvisioningURL:(NSString *)username + password:(NSString *)password + domain:(NSString *)domain + OnSuccess:(void (^)(NSString *url))onSucess; + +@end diff --git a/Classes/Utils/XMLRPCHelper.m b/Classes/Utils/XMLRPCHelper.m new file mode 100644 index 000000000..d24185ea7 --- /dev/null +++ b/Classes/Utils/XMLRPCHelper.m @@ -0,0 +1,165 @@ +// +// UrmetXMLRPC.m +// IperVoice +// +// Created by guillaume on 01/06/2015. +// Copyright (c) 2015 Urmet. All rights reserved. +// + +#import + +#import "LinphoneManager.h" +#import "DTAlertView.h" +#import "XMLRPCHelper.h" +#import "Utils.h" + +/* This subclass allows use to store the block to execute on success */ +@interface BlockXMLRPCRequest : XMLRPCRequest +@property(copy, nonatomic) BOOL (^successBlock)(XMLRPCResponse *response); +@property(copy, nonatomic) BOOL (^xmlErrorBlock)(XMLRPCRequest *request); +@end + +@implementation BlockXMLRPCRequest +@end + +@implementation XMLRPCHelper + +#pragma mark - API + +static XMLRPCHelper *xmlManager = nil; + ++ (XMLRPCHelper *)xml { + @synchronized(self) { + if (xmlManager == nil) { + xmlManager = [[XMLRPCHelper alloc] init]; + } + } + return xmlManager; +} + +- (void)sendXMLRequestMethod:(NSString *)method withParams:(NSArray *)params { + [self sendXMLRequestMethod:method withParams:params onSuccess:nil onError:nil]; +} + +- (void)sendXMLRequestMethod:(NSString *)method + withParams:(NSArray *)params + onSuccess:(BOOL (^)(XMLRPCResponse *))successBlock { + [self sendXMLRequestMethod:method withParams:params onSuccess:successBlock onError:nil]; +} + +- (void)sendXMLRequestMethod:(NSString *)method + withParams:(NSArray *)params + onSuccess:(BOOL (^)(XMLRPCResponse *))successBlock + onError:(BOOL (^)(XMLRPCRequest *req))errorBlock { + LOGI(@"XMLRPC %@ - %@", method, params); + NSURL *URL = + [NSURL URLWithString:[LinphoneManager.instance lpConfigStringForKey:@"xmlrpc_url" inSection:@"assistant"]]; + BlockXMLRPCRequest *request = [[BlockXMLRPCRequest alloc] initWithURL:URL]; + [request setMethod:method withParameters:params]; + if (successBlock) { + request.successBlock = successBlock; + } + if (errorBlock) { + request.xmlErrorBlock = errorBlock; + } + + XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager]; + [manager spawnConnectionWithXMLRPCRequest:request delegate:self]; +} + +#pragma mark - XMLRPCConnectionHandler delegate + +- (void)request:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response { + + BlockXMLRPCRequest *req = (BlockXMLRPCRequest *)request; + NSString *error = nil; + BOOL handleHere = YES; + + LOGI(@"XMLRPC %@ - %@", [request method], [response body]); + + if (req.successBlock) { + handleHere = req.successBlock(response); + } + if (!handleHere) + return; + + if ([response isFault]) { + error = response.faultString; + } else if (response.object != nil && ![response.object isEqualToString:@"OK"]) { + error = NSLocalizedString(@"Unknown error", nil); + } else if ([response.object isEqualToString:@"OK"]) { + // do nothing, if the client is interested in the response he will have handled it + } else { + LOGE(@"Empty object for XMLRPC response: HTTP error"); + error = NSLocalizedString(@"(no description)", nil); + } + + if (error != nil) { + [self displayErrorPopup:error]; + } +} + +- (void)request:(XMLRPCRequest *)request didFailWithError:(NSError *)error { + BlockXMLRPCRequest *req = (BlockXMLRPCRequest *)request; + BOOL handleHere = YES; + if (req.xmlErrorBlock) { + handleHere = req.xmlErrorBlock(request); + } + if (!handleHere) + return; + // do not display technical message to the user.. + [self displayErrorPopup:NSLocalizedString(@"Server error", nil)]; // error.localizedDescription]; + LOGE(@"requestDidFailWithError: %@", error.localizedDescription); +} + +- (BOOL)request:(XMLRPCRequest *)request canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { + return NO; +} + +- (void)request:(XMLRPCRequest *)request didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { + /* Do nothing, not needed */ +} + +- (void)request:(XMLRPCRequest *)request didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { + /* Do nothing, not needed */ +} + +#pragma mark - Error alerts + +- (void)displayErrorPopup:(NSString *)error { + DTAlertView *av = [[DTAlertView alloc] initWithTitle:NSLocalizedString(@"Server request error", nil) message:error]; + [av addCancelButtonWithTitle:NSLocalizedString(@"OK", nil) block:nil]; + [av show]; +} + ++ (void)GetProvisioningURL:(NSString *)username + password:(NSString *)password + domain:(NSString *)domain + OnSuccess:(void (^)(NSString *response))onSuccess { + if (!username || !password || !domain) { + onSuccess(nil); + return; + } + + [self.class.xml sendXMLRequestMethod:@"get_remote_provisioning_filename" + withParams:@[ username, password, domain ] + onSuccess:^BOOL(XMLRPCResponse *response) { + if (!response.isFault && response.object) { + NSString *url = + [NSString stringWithFormat:@"%@/%@.xml", + [LinphoneManager.instance lpConfigStringForKey:@"remote_prosivioning_root" + inSection:@"assistant"], + response.object]; + onSuccess(url); + } else { + onSuccess(nil); + } + return FALSE; + + } + onError:^BOOL(XMLRPCRequest *request) { + onSuccess(nil); + return FALSE; + }]; +} +@end diff --git a/Classes/WizardViewController.h b/Classes/WizardViewController.h deleted file mode 100644 index 2b89363b6..000000000 --- a/Classes/WizardViewController.h +++ /dev/null @@ -1,84 +0,0 @@ -/* WizardViewController.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#import -#import "UICompositeViewController.h" - -@interface WizardViewController : TPMultiLayoutViewController - -{ - @private - UITextField *activeTextField; - UIView *currentView; - UIView *nextView; - NSMutableArray *historyViews; -} - -@property (nonatomic, retain) IBOutlet UIScrollView *contentView; - -@property (nonatomic, retain) IBOutlet UIView *welcomeView; -@property (nonatomic, retain) IBOutlet UIView *choiceView; -@property (nonatomic, retain) IBOutlet UIView *createAccountView; -@property (nonatomic, retain) IBOutlet UIView *connectAccountView; -@property (nonatomic, retain) IBOutlet UIView *externalAccountView; -@property (nonatomic, retain) IBOutlet UIView *validateAccountView; -@property (retain, nonatomic) IBOutlet UIView *provisionedAccountView; - -@property (nonatomic, retain) IBOutlet UIView *waitView; - -@property (nonatomic, retain) IBOutlet UIButton *backButton; -@property (nonatomic, retain) IBOutlet UIButton *startButton; -@property (nonatomic, retain) IBOutlet UIButton *createAccountButton; -@property (nonatomic, retain) IBOutlet UIButton *connectAccountButton; -@property (nonatomic, retain) IBOutlet UIButton *externalAccountButton; -@property (retain, nonatomic) IBOutlet UIButton *remoteProvisioningButton; - -@property (retain, nonatomic) IBOutlet UITextField *provisionedUsername; -@property (retain, nonatomic) IBOutlet UITextField *provisionedPassword; -@property (retain, nonatomic) IBOutlet UITextField *provisionedDomain; - -@property (nonatomic, retain) IBOutlet UIImageView *choiceViewLogoImageView; -@property (retain, nonatomic) IBOutlet UISegmentedControl *transportChooser; - -@property (nonatomic, retain) IBOutlet UITapGestureRecognizer *viewTapGestureRecognizer; - -- (void)reset; -- (void)fillDefaultValues; - -- (IBAction)onStartClick:(id)sender; -- (IBAction)onBackClick:(id)sender; -- (IBAction)onCancelClick:(id)sender; - -- (IBAction)onCreateAccountClick:(id)sender; -- (IBAction)onConnectLinphoneAccountClick:(id)sender; -- (IBAction)onExternalAccountClick:(id)sender; -- (IBAction)onCheckValidationClick:(id)sender; -- (IBAction)onRemoteProvisioningClick:(id)sender; - -- (IBAction)onSignInClick:(id)sender; -- (IBAction)onSignInExternalClick:(id)sender; -- (IBAction)onRegisterClick:(id)sender; -- (IBAction)onProvisionedLoginClick:(id)sender; - -@end diff --git a/Classes/WizardViewController.m b/Classes/WizardViewController.m deleted file mode 100644 index 69110d042..000000000 --- a/Classes/WizardViewController.m +++ /dev/null @@ -1,1106 +0,0 @@ -/* WizardViewController.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "WizardViewController.h" -#import "LinphoneManager.h" -#import "PhoneMainView.h" - -#import -#import -#import -#import - -#import "DTAlertView.h" - -typedef enum _ViewElement { - ViewElement_Username = 100, - ViewElement_Password = 101, - ViewElement_Password2 = 102, - ViewElement_Email = 103, - ViewElement_Domain = 104, - ViewElement_Label = 200, - ViewElement_Error = 201, - ViewElement_Username_Error = 404 -} ViewElement; - -@implementation WizardViewController - -@synthesize contentView; - -@synthesize welcomeView; -@synthesize choiceView; -@synthesize createAccountView; -@synthesize connectAccountView; -@synthesize externalAccountView; -@synthesize validateAccountView; -@synthesize provisionedAccountView; -@synthesize waitView; - -@synthesize backButton; -@synthesize startButton; -@synthesize createAccountButton; -@synthesize connectAccountButton; -@synthesize externalAccountButton; -@synthesize remoteProvisioningButton; - -@synthesize provisionedDomain, provisionedPassword, provisionedUsername; - -@synthesize choiceViewLogoImageView; - -@synthesize viewTapGestureRecognizer; - - -#pragma mark - Lifecycle Functions - -- (id)init { - self = [super initWithNibName:@"WizardViewController" bundle:[NSBundle mainBundle]]; - if (self != nil) { - [[NSBundle mainBundle] loadNibNamed:@"WizardViews" - owner:self - options:nil]; - self->historyViews = [[NSMutableArray alloc] init]; - self->currentView = nil; - self->viewTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onViewTap:)]; - } - return self; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - [contentView release]; - - [welcomeView release]; - [choiceView release]; - [createAccountView release]; - [connectAccountView release]; - [externalAccountView release]; - [validateAccountView release]; - - [waitView release]; - - [backButton release]; - [startButton release]; - [createAccountButton release]; - [connectAccountButton release]; - [externalAccountButton release]; - - [choiceViewLogoImageView release]; - - [historyViews release]; - - [viewTapGestureRecognizer release]; - - [remoteProvisioningButton release]; - [provisionedAccountView release]; - [provisionedUsername release]; - [provisionedPassword release]; - [provisionedDomain release]; - [_transportChooser release]; - [super dealloc]; -} - - -#pragma mark - UICompositeViewDelegate Functions - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if(compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:@"Wizard" - content:@"WizardViewController" - stateBar:nil - stateBarEnabled:false - tabBar:nil - tabBarEnabled:false - fullscreen:false - landscapeMode:[LinphoneManager runningOnIpad] - portraitMode:true]; - compositeDescription.darkBackground = true; - } - return compositeDescription; -} - - -#pragma mark - ViewController Functions - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(registrationUpdateEvent:) - name:kLinphoneRegistrationUpdate - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(configuringUpdate:) - name:kLinphoneConfiguringStateUpdate - object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(keyboardWillShow:) - name:UIKeyboardWillShowNotification - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(keyboardWillHide:) - name:UIKeyboardWillHideNotification - object:nil]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneRegistrationUpdate - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:kLinphoneConfiguringStateUpdate - object:nil]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIKeyboardWillShowNotification - object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIKeyboardWillHideNotification - object:nil]; - -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - [viewTapGestureRecognizer setCancelsTouchesInView:FALSE]; - [viewTapGestureRecognizer setDelegate:self]; - [contentView addGestureRecognizer:viewTapGestureRecognizer]; - - if([LinphoneManager runningOnIpad]) { - [LinphoneUtils adjustFontSize:welcomeView mult:2.22f]; - [LinphoneUtils adjustFontSize:choiceView mult:2.22f]; - [LinphoneUtils adjustFontSize:createAccountView mult:2.22f]; - [LinphoneUtils adjustFontSize:connectAccountView mult:2.22f]; - [LinphoneUtils adjustFontSize:externalAccountView mult:2.22f]; - [LinphoneUtils adjustFontSize:validateAccountView mult:2.22f]; - [LinphoneUtils adjustFontSize:provisionedAccountView mult:2.22f]; - } -} - - -#pragma mark - - -+ (void)cleanTextField:(UIView*)view { - if([view isKindOfClass:[UITextField class]]) { - [(UITextField*)view setText:@""]; - } else { - for(UIView *subview in view.subviews) { - [WizardViewController cleanTextField:subview]; - } - } -} - -- (void)fillDefaultValues { - - LinphoneCore* lc = [LinphoneManager getLc]; - [self resetTextFields]; - - LinphoneProxyConfig* current_conf = NULL; - linphone_core_get_default_proxy([LinphoneManager getLc], ¤t_conf); - if( current_conf != NULL ){ - const char* proxy_addr = linphone_proxy_config_get_identity(current_conf); - if( proxy_addr ){ - LinphoneAddress *addr = linphone_address_new( proxy_addr ); - if( addr ){ - const LinphoneAuthInfo *auth = linphone_core_find_auth_info(lc, NULL, linphone_address_get_username(addr), linphone_proxy_config_get_domain(current_conf)); - linphone_address_destroy(addr); - if( auth ){ - [LinphoneLogger log:LinphoneLoggerLog format:@"A proxy config was set up with the remote provisioning, skip wizard"]; - [self onCancelClick:nil]; - } - } - } - } - - LinphoneProxyConfig* default_conf = linphone_core_create_proxy_config([LinphoneManager getLc]); - const char* identity = linphone_proxy_config_get_identity(default_conf); - if( identity ){ - LinphoneAddress* default_addr = linphone_address_new(identity); - if( default_addr ){ - const char* domain = linphone_address_get_domain(default_addr); - const char* username = linphone_address_get_username(default_addr); - if( domain && strlen(domain) > 0){ - //UITextField* domainfield = [WizardViewController findTextField:ViewElement_Domain view:externalAccountView]; - [provisionedDomain setText:[NSString stringWithUTF8String:domain]]; - } - - if( username && strlen(username) > 0 && username[0] != '?' ){ - //UITextField* userField = [WizardViewController findTextField:ViewElement_Username view:externalAccountView]; - [provisionedUsername setText:[NSString stringWithUTF8String:username]]; - } - } - } - - [self changeView:provisionedAccountView back:FALSE animation:TRUE]; - - linphone_proxy_config_destroy(default_conf); - -} - -- (void)resetTextFields { - [WizardViewController cleanTextField:welcomeView]; - [WizardViewController cleanTextField:choiceView]; - [WizardViewController cleanTextField:createAccountView]; - [WizardViewController cleanTextField:connectAccountView]; - [WizardViewController cleanTextField:externalAccountView]; - [WizardViewController cleanTextField:validateAccountView]; - [WizardViewController cleanTextField:provisionedAccountView]; -} - -- (void)reset { - [self clearProxyConfig]; - [[LinphoneManager instance] lpConfigSetBool:FALSE forKey:@"pushnotification_preference"]; - - LinphoneCore *lc = [LinphoneManager getLc]; - LCSipTransports transportValue={5060,5060,-1,-1}; - - if (linphone_core_set_sip_transports(lc, &transportValue)) { - [LinphoneLogger logc:LinphoneLoggerError format:"cannot set transport"]; - } - - [[LinphoneManager instance] lpConfigSetString:@"" forKey:@"sharing_server_preference"]; - [[LinphoneManager instance] lpConfigSetBool:FALSE forKey:@"ice_preference"]; - [[LinphoneManager instance] lpConfigSetString:@"" forKey:@"stun_preference"]; - linphone_core_set_stun_server(lc, NULL); - linphone_core_set_firewall_policy(lc, LinphonePolicyNoFirewall); - [self resetTextFields]; - if ([[LinphoneManager instance] lpConfigBoolForKey:@"hide_wizard_welcome_view_preference"] == true) { - [self changeView:choiceView back:FALSE animation:FALSE]; - } else { - [self changeView:welcomeView back:FALSE animation:FALSE]; - } - [waitView setHidden:TRUE]; -} - -+ (UIView*)findView:(ViewElement)tag view:(UIView*)view { - for(UIView *child in [view subviews]) { - if([child tag] == tag){ - return (UITextField*)child; - } else { - UIView *o = [WizardViewController findView:tag view:child]; - if(o) - return o; - } - } - return nil; -} - -+ (UITextField*)findTextField:(ViewElement)tag view:(UIView*)view { - UIView *aview = [WizardViewController findView:tag view:view]; - if([aview isKindOfClass:[UITextField class]]) - return (UITextField*)aview; - return nil; -} - -+ (UILabel*)findLabel:(ViewElement)tag view:(UIView*)view { - UIView *aview = [WizardViewController findView:tag view:view]; - if([aview isKindOfClass:[UILabel class]]) - return (UILabel*)aview; - return nil; -} - -- (void)clearHistory { - [historyViews removeAllObjects]; -} - -- (void)changeView:(UIView *)view back:(BOOL)back animation:(BOOL)animation { - - static BOOL placement_done = NO; // indicates if the button placement has been done in the wizard choice view - - // Change toolbar buttons following view - if (view == welcomeView) { - [startButton setHidden:false]; - [backButton setHidden:true]; - } else { - [startButton setHidden:true]; - [backButton setHidden:false]; - } - - if (view == validateAccountView) { - [backButton setEnabled:FALSE]; - } else if (view == choiceView) { - if ([[LinphoneManager instance] lpConfigBoolForKey:@"hide_wizard_welcome_view_preference"] == true) { - [backButton setEnabled:FALSE]; - } else { - [backButton setEnabled:TRUE]; - } - } else { - [backButton setEnabled:TRUE]; - } - - if (view == choiceView) { - // layout is this: - // [ Logo ] - // [ Create Btn ] - // [ Connect Btn ] - // [ External Btn ] - // [ Remote Prov ] - - BOOL show_logo = [[LinphoneManager instance] lpConfigBoolForKey:@"show_wizard_logo_in_choice_view_preference"]; - BOOL show_extern = ![[LinphoneManager instance] lpConfigBoolForKey:@"hide_wizard_custom_account"]; - BOOL show_new = ![[LinphoneManager instance] lpConfigBoolForKey:@"hide_wizard_create_account"]; - - if( !placement_done ) { - // visibility - choiceViewLogoImageView.hidden = !show_logo; - externalAccountButton.hidden = !show_extern; - createAccountButton.hidden = !show_new; - - // placement - if (show_logo && show_new && !show_extern) { - // lower both remaining buttons - [createAccountButton setCenter:[connectAccountButton center]]; - [connectAccountButton setCenter:[externalAccountButton center]]; - - } else if (!show_logo && !show_new && show_extern ) { - // move up the extern button - [externalAccountButton setCenter:[createAccountButton center]]; - } - placement_done = YES; - } - if (!show_extern && !show_logo) { - // no option to create or specify a custom account: go to connect view directly - view = connectAccountView; - } - } - - // Animation - if(animation && [[LinphoneManager instance] lpConfigBoolForKey:@"animations_preference"] == true) { - CATransition* trans = [CATransition animation]; - [trans setType:kCATransitionPush]; - [trans setDuration:0.35]; - [trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; - if(back) { - [trans setSubtype:kCATransitionFromLeft]; - }else { - [trans setSubtype:kCATransitionFromRight]; - } - [contentView.layer addAnimation:trans forKey:@"Transition"]; - } - - // Stack current view - if(currentView != nil) { - if(!back) - [historyViews addObject:currentView]; - [currentView removeFromSuperview]; - } - - // Set current view - currentView = view; - [contentView insertSubview:view atIndex:0]; - [view setFrame:[contentView bounds]]; - [contentView setContentSize:[view bounds].size]; -} - -- (void)clearProxyConfig { - linphone_core_clear_proxy_config([LinphoneManager getLc]); - linphone_core_clear_all_auth_info([LinphoneManager getLc]); -} - -- (void)setDefaultSettings:(LinphoneProxyConfig*)proxyCfg { - LinphoneManager* lm = [LinphoneManager instance]; - - [lm configurePushTokenForProxyConfig:proxyCfg]; - -} - -- (BOOL)addProxyConfig:(NSString*)username password:(NSString*)password domain:(NSString*)domain withTransport:(NSString*)transport { - LinphoneCore* lc = [LinphoneManager getLc]; - LinphoneProxyConfig* proxyCfg = linphone_core_create_proxy_config(lc); - NSString* server_address = domain; - - char normalizedUserName[256]; - linphone_proxy_config_normalize_number(proxyCfg, [username cStringUsingEncoding:[NSString defaultCStringEncoding]], normalizedUserName, sizeof(normalizedUserName)); - - const char* identity = linphone_proxy_config_get_identity(proxyCfg); - if( !identity || !*identity ) identity = "sip:user@example.com"; - - LinphoneAddress* linphoneAddress = linphone_address_new(identity); - linphone_address_set_username(linphoneAddress, normalizedUserName); - - if( domain && [domain length] != 0) { - if( transport != nil ){ - server_address = [NSString stringWithFormat:@"%@;transport=%@", server_address, [transport lowercaseString]]; - } - // when the domain is specified (for external login), take it as the server address - linphone_proxy_config_set_server_addr(proxyCfg, [server_address UTF8String]); - linphone_address_set_domain(linphoneAddress, [domain UTF8String]); - } - - char* extractedAddres = linphone_address_as_string_uri_only(linphoneAddress); - - LinphoneAddress* parsedAddress = linphone_address_new(extractedAddres); - ms_free(extractedAddres); - - if( parsedAddress == NULL || !linphone_address_is_sip(parsedAddress) ){ - if( parsedAddress ) linphone_address_destroy(parsedAddress); - UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Check error(s)",nil) - message:NSLocalizedString(@"Please enter a valid username", nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil,nil]; - [errorView show]; - [errorView release]; - return FALSE; - } - - char *c_parsedAddress = linphone_address_as_string_uri_only(parsedAddress); - - linphone_proxy_config_set_identity(proxyCfg, c_parsedAddress); - - linphone_address_destroy(parsedAddress); - ms_free(c_parsedAddress); - - LinphoneAuthInfo* info = linphone_auth_info_new([username UTF8String] - , NULL, [password UTF8String] - , NULL - , NULL - ,linphone_proxy_config_get_domain(proxyCfg)); - - [self setDefaultSettings:proxyCfg]; - - [self clearProxyConfig]; - - linphone_proxy_config_enable_register(proxyCfg, true); - linphone_core_add_auth_info(lc, info); - linphone_core_add_proxy_config(lc, proxyCfg); - linphone_core_set_default_proxy_config(lc, proxyCfg); - return TRUE; -} - -- (void)addProvisionedProxy:(NSString*)username withPassword:(NSString*)password withDomain:(NSString*)domain { - [self clearProxyConfig]; - - LinphoneProxyConfig* proxyCfg = linphone_core_create_proxy_config([LinphoneManager getLc]); - - const char *addr= linphone_proxy_config_get_domain(proxyCfg); - char normalizedUsername[256]; - LinphoneAddress* linphoneAddress = linphone_address_new(addr); - - linphone_proxy_config_normalize_number(proxyCfg, - [username cStringUsingEncoding:[NSString defaultCStringEncoding]], - normalizedUsername, - sizeof(normalizedUsername)); - - linphone_address_set_username(linphoneAddress, normalizedUsername); - linphone_address_set_domain(linphoneAddress, [domain UTF8String]); - - const char* identity = linphone_address_as_string_uri_only(linphoneAddress); - linphone_proxy_config_set_identity(proxyCfg, identity); - - LinphoneAuthInfo* info = linphone_auth_info_new([username UTF8String], NULL, [password UTF8String], NULL, NULL, [domain UTF8String]); - - linphone_proxy_config_enable_register(proxyCfg, true); - linphone_core_add_auth_info([LinphoneManager getLc], info); - linphone_core_add_proxy_config([LinphoneManager getLc], proxyCfg); - linphone_core_set_default_proxy_config([LinphoneManager getLc], proxyCfg); -} - -- (NSString*)identityFromUsername:(NSString*)username { - char normalizedUserName[256]; - LinphoneAddress* linphoneAddress = linphone_address_new("sip:user@domain.com"); - linphone_proxy_config_normalize_number(NULL, [username cStringUsingEncoding:[NSString defaultCStringEncoding]], normalizedUserName, sizeof(normalizedUserName)); - linphone_address_set_username(linphoneAddress, normalizedUserName); - linphone_address_set_domain(linphoneAddress, [[[LinphoneManager instance] lpConfigStringForKey:@"domain" forSection:@"wizard"] UTF8String]); - NSString* uri = [NSString stringWithUTF8String:linphone_address_as_string_uri_only(linphoneAddress)]; - NSString* scheme = [NSString stringWithUTF8String:linphone_address_get_scheme(linphoneAddress)]; - return [uri substringFromIndex:[scheme length] + 1]; -} - -#pragma mark - Linphone XMLRPC - -- (void)checkUserExist:(NSString*)username { - [LinphoneLogger log:LinphoneLoggerLog format:@"XMLRPC check_account %@", username]; - - NSURL *URL = [NSURL URLWithString:[[LinphoneManager instance] lpConfigStringForKey:@"service_url" forSection:@"wizard"]]; - XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithURL: URL]; - [request setMethod: @"check_account" withParameters:[NSArray arrayWithObjects:username, nil]]; - - XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager]; - [manager spawnConnectionWithXMLRPCRequest: request delegate: self]; - - [request release]; - [waitView setHidden:false]; -} - -- (void)createAccount:(NSString*)identity password:(NSString*)password email:(NSString*)email { - NSString *useragent = [LinphoneManager getUserAgent]; - [LinphoneLogger log:LinphoneLoggerLog format:@"XMLRPC create_account_with_useragent %@ %@ %@ %@", identity, password, email, useragent]; - - NSURL *URL = [NSURL URLWithString: [[LinphoneManager instance] lpConfigStringForKey:@"service_url" forSection:@"wizard"]]; - XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithURL: URL]; - [request setMethod: @"create_account_with_useragent" withParameters:[NSArray arrayWithObjects:identity, password, email, useragent, nil]]; - - XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager]; - [manager spawnConnectionWithXMLRPCRequest: request delegate: self]; - - [request release]; - [waitView setHidden:false]; -} - -- (void)checkAccountValidation:(NSString*)identity { - [LinphoneLogger log:LinphoneLoggerLog format:@"XMLRPC check_account_validated %@", identity]; - - NSURL *URL = [NSURL URLWithString: [[LinphoneManager instance] lpConfigStringForKey:@"service_url" forSection:@"wizard"]]; - XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithURL: URL]; - [request setMethod: @"check_account_validated" withParameters:[NSArray arrayWithObjects:identity, nil]]; - - XMLRPCConnectionManager *manager = [XMLRPCConnectionManager sharedManager]; - [manager spawnConnectionWithXMLRPCRequest: request delegate: self]; - - [request release]; - [waitView setHidden:false]; -} - -#pragma mark - - -- (void)registrationUpdate:(LinphoneRegistrationState)state message:(NSString*)message{ - switch (state) { - case LinphoneRegistrationOk: { - [waitView setHidden:true]; - [[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]]; - break; - } - case LinphoneRegistrationNone: - case LinphoneRegistrationCleared: { - [waitView setHidden:true]; - break; - } - case LinphoneRegistrationFailed: { - [waitView setHidden:true]; - UIAlertView* alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Registration failure", nil) - message:message - delegate:nil - cancelButtonTitle:@"OK" - otherButtonTitles:nil]; - [alert show]; - [alert release]; - break; - } - case LinphoneRegistrationProgress: { - [waitView setHidden:false]; - break; - } - default: - break; - } -} - -- (void)loadWizardConfig:(NSString*)rcFilename { - NSString* fullPath = [@"file://" stringByAppendingString:[LinphoneManager bundleFile:rcFilename]]; - linphone_core_set_provisioning_uri([LinphoneManager getLc], [fullPath cStringUsingEncoding:[NSString defaultCStringEncoding]]); - [[LinphoneManager instance] lpConfigSetInt:1 forKey:@"transient_provisioning" forSection:@"misc"]; - [[LinphoneManager instance] resetLinphoneCore]; -} - -#pragma mark - UITextFieldDelegate Functions - -- (BOOL)textFieldShouldReturn:(UITextField *)textField { - [textField resignFirstResponder]; - return YES; -} - -- (void)textFieldDidBeginEditing:(UITextField *)textField { - activeTextField = textField; -} - -- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string -{ - // only validate the username when creating a new account - if( (textField.tag == ViewElement_Username) && (currentView == createAccountView) ){ - NSRegularExpression *regex = [NSRegularExpression - regularExpressionWithPattern:@"^[a-z0-9-_\\.]*$" - options:NSRegularExpressionCaseInsensitive - error:nil]; - NSArray* matches = [regex matchesInString:string options:0 range:NSMakeRange(0, [string length])]; - if ([matches count] == 0) { - UILabel* error = [WizardViewController findLabel:ViewElement_Username_Error view:contentView]; - - // show error with fade animation - [error setText:[NSString stringWithFormat:NSLocalizedString(@"Illegal character in username: %@", nil), string]]; - error.alpha = 0; - error.hidden = NO; - [UIView animateWithDuration:0.3 animations:^{ - error.alpha = 1; - }]; - - // hide again in 2s - [NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(hideError:) userInfo:nil repeats:NO]; - - - return NO; - } - } - return YES; -} -- (void)hideError:(NSTimer*)timer { - UILabel* error_label =[WizardViewController findLabel:ViewElement_Username_Error view:contentView]; - if( error_label ) { - [UIView animateWithDuration:0.3 - animations:^{ - error_label.alpha = 0; - } - completion: ^(BOOL finished) { - error_label.hidden = YES; - } - ]; - } -} - -#pragma mark - Action Functions - -- (IBAction)onStartClick:(id)sender { - [self changeView:choiceView back:FALSE animation:TRUE]; -} - -- (IBAction)onBackClick:(id)sender { - if ([historyViews count] > 0) { - UIView * view = [historyViews lastObject]; - [historyViews removeLastObject]; - [self changeView:view back:TRUE animation:TRUE]; - } -} - -- (IBAction)onCancelClick:(id)sender { - [[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]]; -} - -- (IBAction)onCreateAccountClick:(id)sender { - nextView = createAccountView; - [self loadWizardConfig:@"wizard_linphone_create.rc"]; -} - -- (IBAction)onConnectLinphoneAccountClick:(id)sender { - nextView = connectAccountView; - [self loadWizardConfig:@"wizard_linphone_existing.rc"]; -} - -- (IBAction)onExternalAccountClick:(id)sender { - nextView = externalAccountView; - [self loadWizardConfig:@"wizard_external_sip.rc"]; -} - -- (IBAction)onCheckValidationClick:(id)sender { - NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text; - NSString *identity = [self identityFromUsername:username]; - [self checkAccountValidation:identity]; -} - -- (IBAction)onRemoteProvisioningClick:(id)sender { - UIAlertView* remoteInput = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Enter provisioning URL", @"") - message:@"" - delegate:self - cancelButtonTitle:NSLocalizedString(@"Cancel", @"") - otherButtonTitles:NSLocalizedString(@"Fetch", @""), nil]; - remoteInput.alertViewStyle = UIAlertViewStylePlainTextInput; - - UITextField* prov_url = [remoteInput textFieldAtIndex:0]; - prov_url.keyboardType = UIKeyboardTypeURL; - prov_url.text = [[LinphoneManager instance] lpConfigStringForKey:@"config-uri" forSection:@"misc"]; - prov_url.placeholder = @"URL"; - - [remoteInput show]; - [remoteInput release]; -} - -- (void) verificationSignInWithUsername:(NSString*)username password:(NSString*)password domain:(NSString*)domain withTransport:(NSString*)transport { - NSMutableString *errors = [NSMutableString string]; - if ([username length] == 0) { - [errors appendString:[NSString stringWithFormat:NSLocalizedString(@"Please enter a valid username.\n", nil)]]; - } - - if (domain != nil && [domain length] == 0) { - [errors appendString:[NSString stringWithFormat:NSLocalizedString(@"Please enter a valid domain.\n", nil)]]; - } - - if([errors length]) { - UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Check error(s)",nil) - message:[errors substringWithRange:NSMakeRange(0, [errors length] - 1)] - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil,nil]; - [errorView show]; - [errorView release]; - } else { - [waitView setHidden:false]; - if ([LinphoneManager instance].connectivity == none) { - DTAlertView *alert = [[DTAlertView alloc] initWithTitle:NSLocalizedString(@"No connectivity", nil) - message:NSLocalizedString(@"You can either skip verification or connect to the Internet first.", nil)]; - [alert addCancelButtonWithTitle:NSLocalizedString(@"Stay here", nil) block:^{ - [waitView setHidden:true]; - }]; - [alert addButtonWithTitle:NSLocalizedString(@"Continue", nil) block:^{ - [waitView setHidden:true]; - [self addProxyConfig:username password:password domain:domain withTransport:transport]; - [[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]]; - }]; - [alert show]; - } else { - BOOL success = [self addProxyConfig:username password:password domain:domain withTransport:transport]; - if( !success ){ - waitView.hidden = true; - } - } - } -} - -- (IBAction)onSignInExternalClick:(id)sender { - NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text; - NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text; - NSString *domain = [WizardViewController findTextField:ViewElement_Domain view:contentView].text; - NSString *transport = [self.transportChooser titleForSegmentAtIndex:self.transportChooser.selectedSegmentIndex]; - - [self verificationSignInWithUsername:username password:password domain:domain withTransport:transport]; -} - -- (IBAction)onSignInClick:(id)sender { - NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text; - NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text; - - // domain and server will be configured from the default proxy values - [self verificationSignInWithUsername:username password:password domain:nil withTransport:nil]; -} - -- (IBAction)onRegisterClick:(id)sender { - UITextField* username_tf = [WizardViewController findTextField:ViewElement_Username view:contentView]; - NSString *username = username_tf.text; - NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text; - NSString *password2 = [WizardViewController findTextField:ViewElement_Password2 view:contentView].text; - NSString *email = [WizardViewController findTextField:ViewElement_Email view:contentView].text; - NSMutableString *errors = [NSMutableString string]; - - NSInteger username_length = [[LinphoneManager instance] lpConfigIntForKey:@"username_length" forSection:@"wizard"]; - NSInteger password_length = [[LinphoneManager instance] lpConfigIntForKey:@"password_length" forSection:@"wizard"]; - - if ([username length] < username_length) { - [errors appendString:[NSString stringWithFormat:NSLocalizedString(@"The username is too short (minimum %d characters).\n", nil), username_length]]; - } - - if ([password length] < password_length) { - [errors appendString:[NSString stringWithFormat:NSLocalizedString(@"The password is too short (minimum %d characters).\n", nil), password_length]]; - } - - if (![password2 isEqualToString:password]) { - [errors appendString:NSLocalizedString(@"The passwords are different.\n", nil)]; - } - - NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @".+@.+\\.[A-Za-z]{2}[A-Za-z]*"]; - if(![emailTest evaluateWithObject:email]) { - [errors appendString:NSLocalizedString(@"The email is invalid.\n", nil)]; - } - - if([errors length]) { - UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Check error(s)",nil) - message:[errors substringWithRange:NSMakeRange(0, [errors length] - 1)] - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil,nil]; - [errorView show]; - [errorView release]; - - } else { - username = [username lowercaseString]; - [username_tf setText:username]; - NSString *identity = [self identityFromUsername:username]; - [self checkUserExist:identity]; - } -} - -- (IBAction)onProvisionedLoginClick:(id)sender { - NSString *username = provisionedUsername.text; - NSString *password = provisionedPassword.text; - - NSMutableString *errors = [NSMutableString string]; - if ([username length] == 0) { - - [errors appendString:[NSString stringWithFormat:NSLocalizedString(@"Please enter a valid username.\n", nil)]]; - } - - if([errors length]) { - UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Check error(s)",nil) - message:[errors substringWithRange:NSMakeRange(0, [errors length] - 1)] - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil,nil]; - [errorView show]; - [errorView release]; - } else { - [self.waitView setHidden:false]; - [self addProvisionedProxy:username withPassword:password withDomain:provisionedDomain.text]; - } -} - -- (IBAction)onViewTap:(id)sender { - [LinphoneUtils findAndResignFirstResponder:currentView]; -} - -#pragma mark - UIAlertViewDelegate - --(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { - if (buttonIndex == 1) { /* fetch */ - NSString* url = [alertView textFieldAtIndex:0].text; - if( [url length] > 0 ){ - // missing prefix will result in http:// being used - if( [url rangeOfString:@"://"].location == NSNotFound ) - url = [NSString stringWithFormat:@"http://%@", url]; - - [LinphoneLogger log:LinphoneLoggerLog format:@"Should use remote provisioning URL %@", url]; - linphone_core_set_provisioning_uri([LinphoneManager getLc], [url UTF8String]); - - [waitView setHidden:false]; - [[LinphoneManager instance] resetLinphoneCore]; - } - } else { - [LinphoneLogger log:LinphoneLoggerLog format:@"Canceled remote provisioning"]; - } -} - -- (void)configuringUpdate:(NSNotification *)notif { - LinphoneConfiguringState status = (LinphoneConfiguringState)[[notif.userInfo valueForKey:@"state"] integerValue]; - - [waitView setHidden:true]; - - switch (status) { - case LinphoneConfiguringSuccessful: - if( nextView == nil ){ - [self fillDefaultValues]; - } else { - [self changeView:nextView back:false animation:TRUE]; - nextView = nil; - } - break; - case LinphoneConfiguringFailed: - { - NSString* error_message = [notif.userInfo valueForKey:@"message"]; - UIAlertView* alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Provisioning Load error", nil) - message:error_message - delegate:nil - cancelButtonTitle:NSLocalizedString(@"OK", nil) - otherButtonTitles: nil]; - [alert show]; - [alert release]; - break; - } - - case LinphoneConfiguringSkipped: - default: - break; - } -} - - -#pragma mark - Event Functions - -- (void)registrationUpdateEvent:(NSNotification*)notif { - NSString* message = [notif.userInfo objectForKey:@"message"]; - [self registrationUpdate:[[notif.userInfo objectForKey: @"state"] intValue] message:message]; -} - - -#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]; - - // Move view - UIEdgeInsets inset = {0, 0, 0, 0}; - [contentView setContentInset:inset]; - [contentView setScrollIndicatorInsets:inset]; - [contentView setShowsVerticalScrollIndicator:FALSE]; - - [UIView commitAnimations]; -} - -- (void)keyboardWillShow:(NSNotification *)notif { - //CGRect beginFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; - CGRect endFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; - UIViewAnimationCurve curve = [[[notif userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]; - NSTimeInterval duration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; - [UIView beginAnimations:@"resize" context:nil]; - [UIView setAnimationDuration:duration]; - [UIView setAnimationCurve:curve]; - [UIView setAnimationBeginsFromCurrentState:TRUE]; - - if(([[UIDevice currentDevice].systemVersion floatValue] < 8) && - UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) { - int width = endFrame.size.height; - endFrame.size.height = endFrame.size.width; - endFrame.size.width = width; - } - - // Change inset - { - UIEdgeInsets inset = {0,0,0,0}; - CGRect frame = [contentView frame]; - CGRect rect = [PhoneMainView instance].view.bounds; - CGPoint pos = {frame.size.width, frame.size.height}; - CGPoint gPos = [contentView convertPoint:pos toView:[UIApplication sharedApplication].keyWindow.rootViewController.view]; // Bypass IOS bug on landscape mode - inset.bottom = -(rect.size.height - gPos.y - endFrame.size.height); - if(inset.bottom < 0) inset.bottom = 0; - - [contentView setContentInset:inset]; - [contentView setScrollIndicatorInsets:inset]; - CGRect fieldFrame = activeTextField.frame; - fieldFrame.origin.y += fieldFrame.size.height; - [contentView scrollRectToVisible:fieldFrame animated:TRUE]; - [contentView setShowsVerticalScrollIndicator:TRUE]; - } - [UIView commitAnimations]; -} - - -#pragma mark - XMLRPCConnectionDelegate Functions - -- (void)request:(XMLRPCRequest *)request didReceiveResponse:(XMLRPCResponse *)response { - [LinphoneLogger log:LinphoneLoggerLog format:@"XMLRPC %@: %@", [request method], [response body]]; - [waitView setHidden:true]; - if ([response isFault]) { - NSString *errorString = [NSString stringWithFormat:NSLocalizedString(@"Communication issue (%@)", nil), [response faultString]]; - UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Communication issue",nil) - message:errorString - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil,nil]; - [errorView show]; - [errorView release]; - } else if([response object] != nil) { //Don't handle if not object: HTTP/Communication Error - if([[request method] isEqualToString:@"check_account"]) { - if([response object] == [NSNumber numberWithInt:1]) { - UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Check issue",nil) - message:NSLocalizedString(@"Username already exists", nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil,nil]; - [errorView show]; - [errorView release]; - } else { - NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text; - NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text; - NSString *email = [WizardViewController findTextField:ViewElement_Email view:contentView].text; - NSString* identity = [self identityFromUsername:username]; - [self createAccount:identity password:password email:email]; - } - } else if([[request method] isEqualToString:@"create_account_with_useragent"]) { - if([response object] == [NSNumber numberWithInt:0]) { - NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text; - NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text; - [self changeView:validateAccountView back:FALSE animation:TRUE]; - [WizardViewController findTextField:ViewElement_Username view:contentView].text = username; - [WizardViewController findTextField:ViewElement_Password view:contentView].text = password; - } else { - UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Account creation issue",nil) - message:NSLocalizedString(@"Can't create the account. Please try again.", nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil,nil]; - [errorView show]; - [errorView release]; - } - } else if([[request method] isEqualToString:@"check_account_validated"]) { - if([response object] == [NSNumber numberWithInt:1]) { - NSString *username = [WizardViewController findTextField:ViewElement_Username view:contentView].text; - NSString *password = [WizardViewController findTextField:ViewElement_Password view:contentView].text; - [self addProxyConfig:username password:password domain:nil withTransport:nil]; - } else { - UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Account validation issue",nil) - message:NSLocalizedString(@"Your account is not validate yet.", nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:nil,nil]; - [errorView show]; - [errorView release]; - } - } - } -} - -- (void)request:(XMLRPCRequest *)request didFailWithError:(NSError *)error { - NSString *errorString = [NSString stringWithFormat:NSLocalizedString(@"Communication issue (%@)", nil), [error localizedDescription]]; - UIAlertView* errorView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Communication issue", nil) - message:errorString - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Continue", nil) - otherButtonTitles:nil,nil]; - [errorView show]; - [errorView release]; - [waitView setHidden:true]; -} - -- (BOOL)request:(XMLRPCRequest *)request canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { - return FALSE; -} - -- (void)request:(XMLRPCRequest *)request didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { - -} - -- (void)request:(XMLRPCRequest *)request didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { - -} - -#pragma mark - TPMultiLayoutViewController Functions - -- (NSDictionary*)attributesForView:(UIView*)view { - NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; - [attributes setObject:[NSValue valueWithCGRect:view.frame] forKey:@"frame"]; - [attributes setObject:[NSValue valueWithCGRect:view.bounds] forKey:@"bounds"]; - if([view isKindOfClass:[UIButton class]]) { - UIButton *button = (UIButton *)view; - [LinphoneUtils buttonMultiViewAddAttributes:attributes button:button]; - } - [attributes setObject:[NSNumber numberWithInteger:view.autoresizingMask] forKey:@"autoresizingMask"]; - return attributes; -} - -- (void)applyAttributes:(NSDictionary*)attributes toView:(UIView*)view { - view.frame = [[attributes objectForKey:@"frame"] CGRectValue]; - view.bounds = [[attributes objectForKey:@"bounds"] CGRectValue]; - if([view isKindOfClass:[UIButton class]]) { - UIButton *button = (UIButton *)view; - [LinphoneUtils buttonMultiViewApplyAttributes:attributes button:button]; - } - view.autoresizingMask = [[attributes objectForKey:@"autoresizingMask"] integerValue]; -} - - -#pragma mark - UIGestureRecognizerDelegate Functions - -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { - if ([touch.view isKindOfClass:[UIButton class]]) { - /* we resign any keyboard that's displayed when a button is touched */ - if([LinphoneUtils findAndResignFirstResponder:currentView]) { - return NO; - } - } - return YES; -} - -@end diff --git a/Classes/ar.lproj/AboutView.strings b/Classes/ar.lproj/AboutView.strings new file mode 100644 index 000000000..e3dd9e8fc Binary files /dev/null and b/Classes/ar.lproj/AboutView.strings differ diff --git a/Classes/ar.lproj/AboutViewController.strings b/Classes/ar.lproj/AboutViewController.strings deleted file mode 100644 index 510ef409d..000000000 Binary files a/Classes/ar.lproj/AboutViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/AssistantView.strings b/Classes/ar.lproj/AssistantView.strings new file mode 100644 index 000000000..e80376d62 Binary files /dev/null and b/Classes/ar.lproj/AssistantView.strings differ diff --git a/Classes/ar.lproj/AssistantViewScreens.strings b/Classes/ar.lproj/AssistantViewScreens.strings new file mode 100644 index 000000000..745b7beea Binary files /dev/null and b/Classes/ar.lproj/AssistantViewScreens.strings differ diff --git a/Classes/ar.lproj/CallIncomingView.strings b/Classes/ar.lproj/CallIncomingView.strings new file mode 100644 index 000000000..5deec511b Binary files /dev/null and b/Classes/ar.lproj/CallIncomingView.strings differ diff --git a/Classes/ar.lproj/CallOutgoingView.strings b/Classes/ar.lproj/CallOutgoingView.strings new file mode 100644 index 000000000..c6671b923 Binary files /dev/null and b/Classes/ar.lproj/CallOutgoingView.strings differ diff --git a/Classes/ar.lproj/CallView.strings b/Classes/ar.lproj/CallView.strings new file mode 100644 index 000000000..ed0fd2359 Binary files /dev/null and b/Classes/ar.lproj/CallView.strings differ diff --git a/Classes/ar.lproj/CallView~ipad.strings b/Classes/ar.lproj/CallView~ipad.strings new file mode 100644 index 000000000..ed0fd2359 Binary files /dev/null and b/Classes/ar.lproj/CallView~ipad.strings differ diff --git a/Classes/ar.lproj/ChatConversationCreateView.strings b/Classes/ar.lproj/ChatConversationCreateView.strings new file mode 100644 index 000000000..6c11df3dd Binary files /dev/null and b/Classes/ar.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/ar.lproj/ChatConversationView.strings b/Classes/ar.lproj/ChatConversationView.strings new file mode 100644 index 000000000..bb4dc3456 Binary files /dev/null and b/Classes/ar.lproj/ChatConversationView.strings differ diff --git a/Classes/ar.lproj/ChatRoomViewController.strings b/Classes/ar.lproj/ChatRoomViewController.strings deleted file mode 100644 index c54b6c10d..000000000 Binary files a/Classes/ar.lproj/ChatRoomViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/ChatViewController.strings b/Classes/ar.lproj/ChatViewController.strings deleted file mode 100644 index 473ed23ef..000000000 Binary files a/Classes/ar.lproj/ChatViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/ChatsListView.strings b/Classes/ar.lproj/ChatsListView.strings new file mode 100644 index 000000000..d2440e587 Binary files /dev/null and b/Classes/ar.lproj/ChatsListView.strings differ diff --git a/Classes/ar.lproj/ContactDetailsLabelViewController.strings b/Classes/ar.lproj/ContactDetailsLabelViewController.strings deleted file mode 100644 index b6da920eb..000000000 Binary files a/Classes/ar.lproj/ContactDetailsLabelViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/ContactDetailsView.strings b/Classes/ar.lproj/ContactDetailsView.strings new file mode 100644 index 000000000..553a50110 Binary files /dev/null and b/Classes/ar.lproj/ContactDetailsView.strings differ diff --git a/Classes/ar.lproj/ContactDetailsViewController.strings b/Classes/ar.lproj/ContactDetailsViewController.strings deleted file mode 100644 index e9b9d5865..000000000 Binary files a/Classes/ar.lproj/ContactDetailsViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/ContactsListView.strings b/Classes/ar.lproj/ContactsListView.strings new file mode 100644 index 000000000..0bcb7a8e1 Binary files /dev/null and b/Classes/ar.lproj/ContactsListView.strings differ diff --git a/Classes/ar.lproj/ContactsViewController.strings b/Classes/ar.lproj/ContactsViewController.strings deleted file mode 100644 index 4cd7602f7..000000000 Binary files a/Classes/ar.lproj/ContactsViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/DialerView.strings b/Classes/ar.lproj/DialerView.strings new file mode 100644 index 000000000..43e5ff837 Binary files /dev/null and b/Classes/ar.lproj/DialerView.strings differ diff --git a/Classes/ar.lproj/DialerViewController.strings b/Classes/ar.lproj/DialerViewController.strings deleted file mode 100644 index 2e732010a..000000000 Binary files a/Classes/ar.lproj/DialerViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/DialerViewController~ipad.strings b/Classes/ar.lproj/DialerViewController~ipad.strings deleted file mode 100644 index e64c987f8..000000000 Binary files a/Classes/ar.lproj/DialerViewController~ipad.strings and /dev/null differ diff --git a/Classes/ar.lproj/DialerView~ipad.strings b/Classes/ar.lproj/DialerView~ipad.strings new file mode 100644 index 000000000..5265f5042 Binary files /dev/null and b/Classes/ar.lproj/DialerView~ipad.strings differ diff --git a/Classes/ar.lproj/FirstLoginView.strings b/Classes/ar.lproj/FirstLoginView.strings new file mode 100644 index 000000000..210df7ef4 Binary files /dev/null and b/Classes/ar.lproj/FirstLoginView.strings differ diff --git a/Classes/ar.lproj/FirstLoginViewController.strings b/Classes/ar.lproj/FirstLoginViewController.strings deleted file mode 100644 index a8d08b6fd..000000000 Binary files a/Classes/ar.lproj/FirstLoginViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/HistoryDetailsView.strings b/Classes/ar.lproj/HistoryDetailsView.strings new file mode 100644 index 000000000..1c4bd041b Binary files /dev/null and b/Classes/ar.lproj/HistoryDetailsView.strings differ diff --git a/Classes/ar.lproj/HistoryDetailsViewController.strings b/Classes/ar.lproj/HistoryDetailsViewController.strings deleted file mode 100644 index 1398242f7..000000000 Binary files a/Classes/ar.lproj/HistoryDetailsViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/HistoryDetailsViewController.xib b/Classes/ar.lproj/HistoryDetailsViewController.xib deleted file mode 100644 index 11e9f2bb0..000000000 --- a/Classes/ar.lproj/HistoryDetailsViewController.xib +++ /dev/null @@ -1,266 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Classes/ar.lproj/HistoryListView.strings b/Classes/ar.lproj/HistoryListView.strings new file mode 100644 index 000000000..b2d88ad19 Binary files /dev/null and b/Classes/ar.lproj/HistoryListView.strings differ diff --git a/Classes/ar.lproj/HistoryViewController.strings b/Classes/ar.lproj/HistoryViewController.strings deleted file mode 100644 index a7af86955..000000000 Binary files a/Classes/ar.lproj/HistoryViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/ImageView.strings b/Classes/ar.lproj/ImageView.strings new file mode 100644 index 000000000..fb1a6a864 Binary files /dev/null and b/Classes/ar.lproj/ImageView.strings differ diff --git a/Classes/ar.lproj/ImageViewController.strings b/Classes/ar.lproj/ImageViewController.strings deleted file mode 100644 index c497f29e5..000000000 Binary files a/Classes/ar.lproj/ImageViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/InCallViewController.strings b/Classes/ar.lproj/InCallViewController.strings deleted file mode 100644 index ce0df097d..000000000 Binary files a/Classes/ar.lproj/InCallViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/IncomingCallViewController.strings b/Classes/ar.lproj/IncomingCallViewController.strings deleted file mode 100644 index d90c464f6..000000000 Binary files a/Classes/ar.lproj/IncomingCallViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/IncomingCallViewController~ipad.strings b/Classes/ar.lproj/IncomingCallViewController~ipad.strings deleted file mode 100644 index 123065a5d..000000000 Binary files a/Classes/ar.lproj/IncomingCallViewController~ipad.strings and /dev/null differ diff --git a/Classes/ar.lproj/PhoneMainView.strings b/Classes/ar.lproj/PhoneMainView.strings deleted file mode 100644 index e69de29bb..000000000 diff --git a/Classes/ar.lproj/SettingsView.strings b/Classes/ar.lproj/SettingsView.strings new file mode 100644 index 000000000..bc4c98f15 Binary files /dev/null and b/Classes/ar.lproj/SettingsView.strings differ diff --git a/Classes/ar.lproj/SettingsViewController.strings b/Classes/ar.lproj/SettingsViewController.strings deleted file mode 100644 index e69de29bb..000000000 diff --git a/Classes/ar.lproj/WizardViewController.strings b/Classes/ar.lproj/WizardViewController.strings deleted file mode 100644 index ad5705a37..000000000 Binary files a/Classes/ar.lproj/WizardViewController.strings and /dev/null differ diff --git a/Classes/ar.lproj/WizardViewController~ipad.strings b/Classes/ar.lproj/WizardViewController~ipad.strings deleted file mode 100644 index fe8d8e48e..000000000 Binary files a/Classes/ar.lproj/WizardViewController~ipad.strings and /dev/null differ diff --git a/Classes/ar.lproj/WizardViews.strings b/Classes/ar.lproj/WizardViews.strings deleted file mode 100644 index 743a14dfd..000000000 Binary files a/Classes/ar.lproj/WizardViews.strings and /dev/null differ diff --git a/Classes/de.lproj/AboutView.strings b/Classes/de.lproj/AboutView.strings new file mode 100644 index 000000000..2876bf526 Binary files /dev/null and b/Classes/de.lproj/AboutView.strings differ diff --git a/Classes/de.lproj/AboutViewController.strings b/Classes/de.lproj/AboutViewController.strings deleted file mode 100644 index 2f4d991a1..000000000 Binary files a/Classes/de.lproj/AboutViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/AssistantView.strings b/Classes/de.lproj/AssistantView.strings new file mode 100644 index 000000000..9d344e6c2 Binary files /dev/null and b/Classes/de.lproj/AssistantView.strings differ diff --git a/Classes/de.lproj/AssistantViewScreens.strings b/Classes/de.lproj/AssistantViewScreens.strings new file mode 100644 index 000000000..0b6c95dba Binary files /dev/null and b/Classes/de.lproj/AssistantViewScreens.strings differ diff --git a/Classes/de.lproj/AssistantViews.strings b/Classes/de.lproj/AssistantViews.strings new file mode 100644 index 000000000..135adbe94 Binary files /dev/null and b/Classes/de.lproj/AssistantViews.strings differ diff --git a/Classes/de.lproj/AssistantView~ipad.strings b/Classes/de.lproj/AssistantView~ipad.strings new file mode 100644 index 000000000..a7bd70f9d Binary files /dev/null and b/Classes/de.lproj/AssistantView~ipad.strings differ diff --git a/Classes/de.lproj/CallIncomingView.strings b/Classes/de.lproj/CallIncomingView.strings new file mode 100644 index 000000000..b23a32e7b Binary files /dev/null and b/Classes/de.lproj/CallIncomingView.strings differ diff --git a/Classes/de.lproj/CallOutgoingView.strings b/Classes/de.lproj/CallOutgoingView.strings new file mode 100644 index 000000000..29a3487f1 Binary files /dev/null and b/Classes/de.lproj/CallOutgoingView.strings differ diff --git a/Classes/de.lproj/CallView.strings b/Classes/de.lproj/CallView.strings new file mode 100644 index 000000000..b57c18a33 Binary files /dev/null and b/Classes/de.lproj/CallView.strings differ diff --git a/Classes/de.lproj/CallView~ipad.strings b/Classes/de.lproj/CallView~ipad.strings new file mode 100644 index 000000000..b57c18a33 Binary files /dev/null and b/Classes/de.lproj/CallView~ipad.strings differ diff --git a/Classes/de.lproj/ChatConversationCreateView.strings b/Classes/de.lproj/ChatConversationCreateView.strings new file mode 100644 index 000000000..40d2261e4 Binary files /dev/null and b/Classes/de.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/de.lproj/ChatConversationView.strings b/Classes/de.lproj/ChatConversationView.strings new file mode 100644 index 000000000..2407ae2ec Binary files /dev/null and b/Classes/de.lproj/ChatConversationView.strings differ diff --git a/Classes/de.lproj/ChatRoomView.strings b/Classes/de.lproj/ChatRoomView.strings new file mode 100644 index 000000000..52f33c128 Binary files /dev/null and b/Classes/de.lproj/ChatRoomView.strings differ diff --git a/Classes/de.lproj/ChatRoomViewController.strings b/Classes/de.lproj/ChatRoomViewController.strings deleted file mode 100644 index b116222de..000000000 Binary files a/Classes/de.lproj/ChatRoomViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/ChatView.strings b/Classes/de.lproj/ChatView.strings new file mode 100644 index 000000000..f40dfd2ae Binary files /dev/null and b/Classes/de.lproj/ChatView.strings differ diff --git a/Classes/de.lproj/ChatViewController.strings b/Classes/de.lproj/ChatViewController.strings deleted file mode 100644 index 8e23ff5b2..000000000 Binary files a/Classes/de.lproj/ChatViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/ChatsListView.strings b/Classes/de.lproj/ChatsListView.strings new file mode 100644 index 000000000..bb9ac30c8 Binary files /dev/null and b/Classes/de.lproj/ChatsListView.strings differ diff --git a/Classes/de.lproj/ContactDetailsLabelViewController.strings b/Classes/de.lproj/ContactDetailsLabelViewController.strings deleted file mode 100644 index 0fb0d48df..000000000 Binary files a/Classes/de.lproj/ContactDetailsLabelViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/ContactDetailsView.strings b/Classes/de.lproj/ContactDetailsView.strings new file mode 100644 index 000000000..63fbe10e1 Binary files /dev/null and b/Classes/de.lproj/ContactDetailsView.strings differ diff --git a/Classes/de.lproj/ContactDetailsViewController.strings b/Classes/de.lproj/ContactDetailsViewController.strings deleted file mode 100644 index 13191fe3e..000000000 Binary files a/Classes/de.lproj/ContactDetailsViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/ContactsListView.strings b/Classes/de.lproj/ContactsListView.strings new file mode 100644 index 000000000..75826e6f3 Binary files /dev/null and b/Classes/de.lproj/ContactsListView.strings differ diff --git a/Classes/de.lproj/ContactsView.strings b/Classes/de.lproj/ContactsView.strings new file mode 100644 index 000000000..fdd063fb9 Binary files /dev/null and b/Classes/de.lproj/ContactsView.strings differ diff --git a/Classes/de.lproj/ContactsViewController.strings b/Classes/de.lproj/ContactsViewController.strings deleted file mode 100644 index 51439e412..000000000 Binary files a/Classes/de.lproj/ContactsViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/DialerView.strings b/Classes/de.lproj/DialerView.strings new file mode 100644 index 000000000..3d668596c Binary files /dev/null and b/Classes/de.lproj/DialerView.strings differ diff --git a/Classes/de.lproj/DialerViewController.strings b/Classes/de.lproj/DialerViewController.strings deleted file mode 100644 index 7d5c3d8c0..000000000 Binary files a/Classes/de.lproj/DialerViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/DialerViewController~ipad.strings b/Classes/de.lproj/DialerViewController~ipad.strings deleted file mode 100644 index 20d9f60d1..000000000 Binary files a/Classes/de.lproj/DialerViewController~ipad.strings and /dev/null differ diff --git a/Classes/de.lproj/DialerView~ipad.strings b/Classes/de.lproj/DialerView~ipad.strings new file mode 100644 index 000000000..ed1812926 Binary files /dev/null and b/Classes/de.lproj/DialerView~ipad.strings differ diff --git a/Classes/de.lproj/FirstLoginView.strings b/Classes/de.lproj/FirstLoginView.strings new file mode 100644 index 000000000..486d00d21 Binary files /dev/null and b/Classes/de.lproj/FirstLoginView.strings differ diff --git a/Classes/de.lproj/FirstLoginViewController.strings b/Classes/de.lproj/FirstLoginViewController.strings deleted file mode 100644 index 534ef05a9..000000000 Binary files a/Classes/de.lproj/FirstLoginViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/HistoryDetailsView.strings b/Classes/de.lproj/HistoryDetailsView.strings new file mode 100644 index 000000000..bd71d9218 Binary files /dev/null and b/Classes/de.lproj/HistoryDetailsView.strings differ diff --git a/Classes/de.lproj/HistoryDetailsViewController.strings b/Classes/de.lproj/HistoryDetailsViewController.strings deleted file mode 100644 index fe90e3995..000000000 Binary files a/Classes/de.lproj/HistoryDetailsViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/HistoryListView.strings b/Classes/de.lproj/HistoryListView.strings new file mode 100644 index 000000000..d27b23da5 Binary files /dev/null and b/Classes/de.lproj/HistoryListView.strings differ diff --git a/Classes/de.lproj/HistoryView.strings b/Classes/de.lproj/HistoryView.strings new file mode 100644 index 000000000..b1ce4a4ea Binary files /dev/null and b/Classes/de.lproj/HistoryView.strings differ diff --git a/Classes/de.lproj/HistoryViewController.strings b/Classes/de.lproj/HistoryViewController.strings deleted file mode 100644 index 62d4a82a6..000000000 Binary files a/Classes/de.lproj/HistoryViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/ImageView.strings b/Classes/de.lproj/ImageView.strings new file mode 100644 index 000000000..65e8970e8 Binary files /dev/null and b/Classes/de.lproj/ImageView.strings differ diff --git a/Classes/de.lproj/ImageViewController.strings b/Classes/de.lproj/ImageViewController.strings deleted file mode 100644 index 75b534c54..000000000 Binary files a/Classes/de.lproj/ImageViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/InCallView.strings b/Classes/de.lproj/InCallView.strings new file mode 100644 index 000000000..ecce22323 Binary files /dev/null and b/Classes/de.lproj/InCallView.strings differ diff --git a/Classes/de.lproj/InCallViewController.strings b/Classes/de.lproj/InCallViewController.strings deleted file mode 100644 index 49702cd98..000000000 Binary files a/Classes/de.lproj/InCallViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/IncomingCallView.strings b/Classes/de.lproj/IncomingCallView.strings new file mode 100644 index 000000000..53c9c18ae Binary files /dev/null and b/Classes/de.lproj/IncomingCallView.strings differ diff --git a/Classes/de.lproj/IncomingCallViewController.strings b/Classes/de.lproj/IncomingCallViewController.strings deleted file mode 100644 index 6d9f4da81..000000000 Binary files a/Classes/de.lproj/IncomingCallViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/IncomingCallViewController~ipad.strings b/Classes/de.lproj/IncomingCallViewController~ipad.strings deleted file mode 100644 index 951ad9721..000000000 Binary files a/Classes/de.lproj/IncomingCallViewController~ipad.strings and /dev/null differ diff --git a/Classes/de.lproj/IncomingCallView~ipad.strings b/Classes/de.lproj/IncomingCallView~ipad.strings new file mode 100644 index 000000000..b50cb2cce Binary files /dev/null and b/Classes/de.lproj/IncomingCallView~ipad.strings differ diff --git a/Classes/de.lproj/SettingsView.strings b/Classes/de.lproj/SettingsView.strings new file mode 100644 index 000000000..8ca908a3d Binary files /dev/null and b/Classes/de.lproj/SettingsView.strings differ diff --git a/Classes/de.lproj/WizardViewController.strings b/Classes/de.lproj/WizardViewController.strings deleted file mode 100644 index d5193ce6b..000000000 Binary files a/Classes/de.lproj/WizardViewController.strings and /dev/null differ diff --git a/Classes/de.lproj/WizardViewController~ipad.strings b/Classes/de.lproj/WizardViewController~ipad.strings deleted file mode 100644 index dc4625386..000000000 Binary files a/Classes/de.lproj/WizardViewController~ipad.strings and /dev/null differ diff --git a/Classes/de.lproj/WizardViews.strings b/Classes/de.lproj/WizardViews.strings deleted file mode 100644 index 4ff99898a..000000000 Binary files a/Classes/de.lproj/WizardViews.strings and /dev/null differ diff --git a/Classes/fr.lproj/AboutView.strings b/Classes/fr.lproj/AboutView.strings new file mode 100644 index 000000000..e86f56f6f Binary files /dev/null and b/Classes/fr.lproj/AboutView.strings differ diff --git a/Classes/fr.lproj/AboutViewController.strings b/Classes/fr.lproj/AboutViewController.strings deleted file mode 100644 index 2f4d991a1..000000000 Binary files a/Classes/fr.lproj/AboutViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/AssistantView.strings b/Classes/fr.lproj/AssistantView.strings new file mode 100644 index 000000000..2caf45e7e Binary files /dev/null and b/Classes/fr.lproj/AssistantView.strings differ diff --git a/Classes/fr.lproj/AssistantViewScreens.strings b/Classes/fr.lproj/AssistantViewScreens.strings new file mode 100644 index 000000000..4a4cb8ac5 Binary files /dev/null and b/Classes/fr.lproj/AssistantViewScreens.strings differ diff --git a/Classes/fr.lproj/CallIncomingView.strings b/Classes/fr.lproj/CallIncomingView.strings new file mode 100644 index 000000000..b59db541e Binary files /dev/null and b/Classes/fr.lproj/CallIncomingView.strings differ diff --git a/Classes/fr.lproj/CallOutgoingView.strings b/Classes/fr.lproj/CallOutgoingView.strings new file mode 100644 index 000000000..3d0ae8fab Binary files /dev/null and b/Classes/fr.lproj/CallOutgoingView.strings differ diff --git a/Classes/fr.lproj/CallView.strings b/Classes/fr.lproj/CallView.strings new file mode 100644 index 000000000..a16d4dc96 Binary files /dev/null and b/Classes/fr.lproj/CallView.strings differ diff --git a/Classes/fr.lproj/CallView~ipad.strings b/Classes/fr.lproj/CallView~ipad.strings new file mode 100644 index 000000000..3d9d45aed Binary files /dev/null and b/Classes/fr.lproj/CallView~ipad.strings differ diff --git a/Classes/fr.lproj/ChatConversationCreateView.strings b/Classes/fr.lproj/ChatConversationCreateView.strings new file mode 100644 index 000000000..eb7329b49 Binary files /dev/null and b/Classes/fr.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/fr.lproj/ChatConversationView.strings b/Classes/fr.lproj/ChatConversationView.strings new file mode 100644 index 000000000..14493cb80 Binary files /dev/null and b/Classes/fr.lproj/ChatConversationView.strings differ diff --git a/Classes/fr.lproj/ChatRoomViewController.strings b/Classes/fr.lproj/ChatRoomViewController.strings deleted file mode 100644 index 852063d13..000000000 Binary files a/Classes/fr.lproj/ChatRoomViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/ChatViewController.strings b/Classes/fr.lproj/ChatViewController.strings deleted file mode 100644 index 80a3b9297..000000000 Binary files a/Classes/fr.lproj/ChatViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/ChatsListView.strings b/Classes/fr.lproj/ChatsListView.strings new file mode 100644 index 000000000..b8dc7d434 Binary files /dev/null and b/Classes/fr.lproj/ChatsListView.strings differ diff --git a/Classes/fr.lproj/ContactDetailsLabelViewController.strings b/Classes/fr.lproj/ContactDetailsLabelViewController.strings deleted file mode 100644 index eadd535f4..000000000 Binary files a/Classes/fr.lproj/ContactDetailsLabelViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/ContactDetailsView.strings b/Classes/fr.lproj/ContactDetailsView.strings new file mode 100644 index 000000000..771a06fae Binary files /dev/null and b/Classes/fr.lproj/ContactDetailsView.strings differ diff --git a/Classes/fr.lproj/ContactDetailsViewController.strings b/Classes/fr.lproj/ContactDetailsViewController.strings deleted file mode 100644 index 8a0903b5f..000000000 Binary files a/Classes/fr.lproj/ContactDetailsViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/ContactsListView.strings b/Classes/fr.lproj/ContactsListView.strings new file mode 100644 index 000000000..bf8611f48 Binary files /dev/null and b/Classes/fr.lproj/ContactsListView.strings differ diff --git a/Classes/fr.lproj/ContactsViewController.strings b/Classes/fr.lproj/ContactsViewController.strings deleted file mode 100644 index 7c4b06275..000000000 Binary files a/Classes/fr.lproj/ContactsViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/DialerView.strings b/Classes/fr.lproj/DialerView.strings new file mode 100644 index 000000000..eb45f7837 Binary files /dev/null and b/Classes/fr.lproj/DialerView.strings differ diff --git a/Classes/fr.lproj/DialerViewController.strings b/Classes/fr.lproj/DialerViewController.strings deleted file mode 100644 index bee8fd0d8..000000000 Binary files a/Classes/fr.lproj/DialerViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/DialerViewController~ipad.strings b/Classes/fr.lproj/DialerViewController~ipad.strings deleted file mode 100644 index 6a1e03d3e..000000000 Binary files a/Classes/fr.lproj/DialerViewController~ipad.strings and /dev/null differ diff --git a/Classes/fr.lproj/DialerView~ipad.strings b/Classes/fr.lproj/DialerView~ipad.strings new file mode 100644 index 000000000..35d6d16d3 Binary files /dev/null and b/Classes/fr.lproj/DialerView~ipad.strings differ diff --git a/Classes/fr.lproj/FirstLoginView.strings b/Classes/fr.lproj/FirstLoginView.strings new file mode 100644 index 000000000..db6e7e185 Binary files /dev/null and b/Classes/fr.lproj/FirstLoginView.strings differ diff --git a/Classes/fr.lproj/FirstLoginViewController.strings b/Classes/fr.lproj/FirstLoginViewController.strings deleted file mode 100644 index 7345ceb04..000000000 Binary files a/Classes/fr.lproj/FirstLoginViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/HistoryDetailsView.strings b/Classes/fr.lproj/HistoryDetailsView.strings new file mode 100644 index 000000000..11b0cfe7e Binary files /dev/null and b/Classes/fr.lproj/HistoryDetailsView.strings differ diff --git a/Classes/fr.lproj/HistoryDetailsViewController.strings b/Classes/fr.lproj/HistoryDetailsViewController.strings deleted file mode 100644 index d1a6c5589..000000000 Binary files a/Classes/fr.lproj/HistoryDetailsViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/HistoryListView.strings b/Classes/fr.lproj/HistoryListView.strings new file mode 100644 index 000000000..4de227043 Binary files /dev/null and b/Classes/fr.lproj/HistoryListView.strings differ diff --git a/Classes/fr.lproj/HistoryViewController.strings b/Classes/fr.lproj/HistoryViewController.strings deleted file mode 100644 index 51b409eff..000000000 Binary files a/Classes/fr.lproj/HistoryViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/ImageView.strings b/Classes/fr.lproj/ImageView.strings new file mode 100644 index 000000000..abd98de6a Binary files /dev/null and b/Classes/fr.lproj/ImageView.strings differ diff --git a/Classes/fr.lproj/ImageViewController.strings b/Classes/fr.lproj/ImageViewController.strings deleted file mode 100644 index 4547f70ff..000000000 Binary files a/Classes/fr.lproj/ImageViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/InCallViewController.strings b/Classes/fr.lproj/InCallViewController.strings deleted file mode 100644 index 1fe9948cb..000000000 Binary files a/Classes/fr.lproj/InCallViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/IncomingCallViewController.strings b/Classes/fr.lproj/IncomingCallViewController.strings deleted file mode 100644 index fd68b1fc5..000000000 Binary files a/Classes/fr.lproj/IncomingCallViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/IncomingCallViewController~ipad.strings b/Classes/fr.lproj/IncomingCallViewController~ipad.strings deleted file mode 100644 index bdb7ff117..000000000 Binary files a/Classes/fr.lproj/IncomingCallViewController~ipad.strings and /dev/null differ diff --git a/Classes/fr.lproj/LaunchScreen.strings b/Classes/fr.lproj/LaunchScreen.strings new file mode 100644 index 000000000..d20f77ce5 Binary files /dev/null and b/Classes/fr.lproj/LaunchScreen.strings differ diff --git a/Classes/fr.lproj/SettingsView.strings b/Classes/fr.lproj/SettingsView.strings new file mode 100644 index 000000000..d9b341fb8 Binary files /dev/null and b/Classes/fr.lproj/SettingsView.strings differ diff --git a/Classes/fr.lproj/SideMenuView.strings b/Classes/fr.lproj/SideMenuView.strings new file mode 100644 index 000000000..98c49fa04 Binary files /dev/null and b/Classes/fr.lproj/SideMenuView.strings differ diff --git a/Classes/fr.lproj/SideMenuView~ipad.strings b/Classes/fr.lproj/SideMenuView~ipad.strings new file mode 100644 index 000000000..98c49fa04 Binary files /dev/null and b/Classes/fr.lproj/SideMenuView~ipad.strings differ diff --git a/Classes/fr.lproj/WizardViewController.strings b/Classes/fr.lproj/WizardViewController.strings deleted file mode 100644 index 9631d814a..000000000 Binary files a/Classes/fr.lproj/WizardViewController.strings and /dev/null differ diff --git a/Classes/fr.lproj/WizardViewController~ipad.strings b/Classes/fr.lproj/WizardViewController~ipad.strings deleted file mode 100644 index 60fd9a247..000000000 Binary files a/Classes/fr.lproj/WizardViewController~ipad.strings and /dev/null differ diff --git a/Classes/fr.lproj/WizardViews.strings b/Classes/fr.lproj/WizardViews.strings deleted file mode 100644 index a8665594e..000000000 Binary files a/Classes/fr.lproj/WizardViews.strings and /dev/null differ diff --git a/Classes/ja.lproj/AboutView.strings b/Classes/ja.lproj/AboutView.strings new file mode 100644 index 000000000..8749d7ac7 Binary files /dev/null and b/Classes/ja.lproj/AboutView.strings differ diff --git a/Classes/ja.lproj/AboutViewController.strings b/Classes/ja.lproj/AboutViewController.strings deleted file mode 100644 index 2f4d991a1..000000000 Binary files a/Classes/ja.lproj/AboutViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/AssistantView.strings b/Classes/ja.lproj/AssistantView.strings new file mode 100644 index 000000000..6c6c17a52 Binary files /dev/null and b/Classes/ja.lproj/AssistantView.strings differ diff --git a/Classes/ja.lproj/AssistantViewScreens.strings b/Classes/ja.lproj/AssistantViewScreens.strings new file mode 100644 index 000000000..a1e90dc95 Binary files /dev/null and b/Classes/ja.lproj/AssistantViewScreens.strings differ diff --git a/Classes/ja.lproj/AssistantViews.strings b/Classes/ja.lproj/AssistantViews.strings new file mode 100644 index 000000000..75bbd975a Binary files /dev/null and b/Classes/ja.lproj/AssistantViews.strings differ diff --git a/Classes/ja.lproj/AssistantView~ipad.strings b/Classes/ja.lproj/AssistantView~ipad.strings new file mode 100644 index 000000000..3987f0dd1 Binary files /dev/null and b/Classes/ja.lproj/AssistantView~ipad.strings differ diff --git a/Classes/ja.lproj/CallIncomingView.strings b/Classes/ja.lproj/CallIncomingView.strings new file mode 100644 index 000000000..bf343d60d Binary files /dev/null and b/Classes/ja.lproj/CallIncomingView.strings differ diff --git a/Classes/ja.lproj/CallOutgoingView.strings b/Classes/ja.lproj/CallOutgoingView.strings new file mode 100644 index 000000000..66924391d Binary files /dev/null and b/Classes/ja.lproj/CallOutgoingView.strings differ diff --git a/Classes/ja.lproj/CallView.strings b/Classes/ja.lproj/CallView.strings new file mode 100644 index 000000000..2d76ff897 Binary files /dev/null and b/Classes/ja.lproj/CallView.strings differ diff --git a/Classes/ja.lproj/CallView~ipad.strings b/Classes/ja.lproj/CallView~ipad.strings new file mode 100644 index 000000000..2d76ff897 Binary files /dev/null and b/Classes/ja.lproj/CallView~ipad.strings differ diff --git a/Classes/ja.lproj/ChatConversationCreateView.strings b/Classes/ja.lproj/ChatConversationCreateView.strings new file mode 100644 index 000000000..9271574dd Binary files /dev/null and b/Classes/ja.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/ja.lproj/ChatConversationView.strings b/Classes/ja.lproj/ChatConversationView.strings new file mode 100644 index 000000000..3d83b4fa0 Binary files /dev/null and b/Classes/ja.lproj/ChatConversationView.strings differ diff --git a/Classes/ja.lproj/ChatRoomView.strings b/Classes/ja.lproj/ChatRoomView.strings new file mode 100644 index 000000000..9e0ce9df2 Binary files /dev/null and b/Classes/ja.lproj/ChatRoomView.strings differ diff --git a/Classes/ja.lproj/ChatRoomViewController.strings b/Classes/ja.lproj/ChatRoomViewController.strings deleted file mode 100644 index 221a03340..000000000 Binary files a/Classes/ja.lproj/ChatRoomViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/ChatView.strings b/Classes/ja.lproj/ChatView.strings new file mode 100644 index 000000000..bed49f963 Binary files /dev/null and b/Classes/ja.lproj/ChatView.strings differ diff --git a/Classes/ja.lproj/ChatViewController.strings b/Classes/ja.lproj/ChatViewController.strings deleted file mode 100644 index c343056cb..000000000 Binary files a/Classes/ja.lproj/ChatViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/ChatsListView.strings b/Classes/ja.lproj/ChatsListView.strings new file mode 100644 index 000000000..69ead29aa Binary files /dev/null and b/Classes/ja.lproj/ChatsListView.strings differ diff --git a/Classes/ja.lproj/ContactDetailsLabelViewController.strings b/Classes/ja.lproj/ContactDetailsLabelViewController.strings deleted file mode 100644 index 3760c2439..000000000 Binary files a/Classes/ja.lproj/ContactDetailsLabelViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/ContactDetailsView.strings b/Classes/ja.lproj/ContactDetailsView.strings new file mode 100644 index 000000000..cfd8c6277 Binary files /dev/null and b/Classes/ja.lproj/ContactDetailsView.strings differ diff --git a/Classes/ja.lproj/ContactDetailsViewController.strings b/Classes/ja.lproj/ContactDetailsViewController.strings deleted file mode 100644 index 2ec0735cf..000000000 Binary files a/Classes/ja.lproj/ContactDetailsViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/ContactsListView.strings b/Classes/ja.lproj/ContactsListView.strings new file mode 100644 index 000000000..15d4745f1 Binary files /dev/null and b/Classes/ja.lproj/ContactsListView.strings differ diff --git a/Classes/ja.lproj/ContactsView.strings b/Classes/ja.lproj/ContactsView.strings new file mode 100644 index 000000000..3c82f0b50 Binary files /dev/null and b/Classes/ja.lproj/ContactsView.strings differ diff --git a/Classes/ja.lproj/ContactsViewController.strings b/Classes/ja.lproj/ContactsViewController.strings deleted file mode 100644 index 1704caf57..000000000 Binary files a/Classes/ja.lproj/ContactsViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/DialerView.strings b/Classes/ja.lproj/DialerView.strings new file mode 100644 index 000000000..0cb29f80b Binary files /dev/null and b/Classes/ja.lproj/DialerView.strings differ diff --git a/Classes/ja.lproj/DialerViewController.strings b/Classes/ja.lproj/DialerViewController.strings deleted file mode 100644 index cacc96c3a..000000000 Binary files a/Classes/ja.lproj/DialerViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/DialerViewController~ipad.strings b/Classes/ja.lproj/DialerViewController~ipad.strings deleted file mode 100644 index 328978b7c..000000000 Binary files a/Classes/ja.lproj/DialerViewController~ipad.strings and /dev/null differ diff --git a/Classes/ja.lproj/DialerView~ipad.strings b/Classes/ja.lproj/DialerView~ipad.strings new file mode 100644 index 000000000..84191909a Binary files /dev/null and b/Classes/ja.lproj/DialerView~ipad.strings differ diff --git a/Classes/ja.lproj/FirstLoginView.strings b/Classes/ja.lproj/FirstLoginView.strings new file mode 100644 index 000000000..3c7434854 Binary files /dev/null and b/Classes/ja.lproj/FirstLoginView.strings differ diff --git a/Classes/ja.lproj/FirstLoginViewController.strings b/Classes/ja.lproj/FirstLoginViewController.strings deleted file mode 100644 index fa2bfdad8..000000000 Binary files a/Classes/ja.lproj/FirstLoginViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/HistoryDetailsView.strings b/Classes/ja.lproj/HistoryDetailsView.strings new file mode 100644 index 000000000..cd8b641bc Binary files /dev/null and b/Classes/ja.lproj/HistoryDetailsView.strings differ diff --git a/Classes/ja.lproj/HistoryDetailsViewController.strings b/Classes/ja.lproj/HistoryDetailsViewController.strings deleted file mode 100644 index f56503b10..000000000 Binary files a/Classes/ja.lproj/HistoryDetailsViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/HistoryListView.strings b/Classes/ja.lproj/HistoryListView.strings new file mode 100644 index 000000000..352403060 Binary files /dev/null and b/Classes/ja.lproj/HistoryListView.strings differ diff --git a/Classes/ja.lproj/HistoryView.strings b/Classes/ja.lproj/HistoryView.strings new file mode 100644 index 000000000..7f3010a36 Binary files /dev/null and b/Classes/ja.lproj/HistoryView.strings differ diff --git a/Classes/ja.lproj/HistoryViewController.strings b/Classes/ja.lproj/HistoryViewController.strings deleted file mode 100644 index 28e11d8f0..000000000 Binary files a/Classes/ja.lproj/HistoryViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/ImageView.strings b/Classes/ja.lproj/ImageView.strings new file mode 100644 index 000000000..f412a5c8c Binary files /dev/null and b/Classes/ja.lproj/ImageView.strings differ diff --git a/Classes/ja.lproj/ImageViewController.strings b/Classes/ja.lproj/ImageViewController.strings deleted file mode 100644 index b61fa2966..000000000 Binary files a/Classes/ja.lproj/ImageViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/InCallView.strings b/Classes/ja.lproj/InCallView.strings new file mode 100644 index 000000000..1957fd91f Binary files /dev/null and b/Classes/ja.lproj/InCallView.strings differ diff --git a/Classes/ja.lproj/InCallViewController.strings b/Classes/ja.lproj/InCallViewController.strings deleted file mode 100644 index 7a9a963f2..000000000 Binary files a/Classes/ja.lproj/InCallViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/IncomingCallView.strings b/Classes/ja.lproj/IncomingCallView.strings new file mode 100644 index 000000000..0f451c30a Binary files /dev/null and b/Classes/ja.lproj/IncomingCallView.strings differ diff --git a/Classes/ja.lproj/IncomingCallViewController.strings b/Classes/ja.lproj/IncomingCallViewController.strings deleted file mode 100644 index ff9f3ee3c..000000000 Binary files a/Classes/ja.lproj/IncomingCallViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/IncomingCallViewController~ipad.strings b/Classes/ja.lproj/IncomingCallViewController~ipad.strings deleted file mode 100644 index 0f32ebaae..000000000 Binary files a/Classes/ja.lproj/IncomingCallViewController~ipad.strings and /dev/null differ diff --git a/Classes/ja.lproj/IncomingCallView~ipad.strings b/Classes/ja.lproj/IncomingCallView~ipad.strings new file mode 100644 index 000000000..a1b6009a4 Binary files /dev/null and b/Classes/ja.lproj/IncomingCallView~ipad.strings differ diff --git a/Classes/ja.lproj/SettingsView.strings b/Classes/ja.lproj/SettingsView.strings new file mode 100644 index 000000000..0a3c9f0eb Binary files /dev/null and b/Classes/ja.lproj/SettingsView.strings differ diff --git a/Classes/ja.lproj/WizardViewController.strings b/Classes/ja.lproj/WizardViewController.strings deleted file mode 100644 index 8dc9b8338..000000000 Binary files a/Classes/ja.lproj/WizardViewController.strings and /dev/null differ diff --git a/Classes/ja.lproj/WizardViewController~ipad.strings b/Classes/ja.lproj/WizardViewController~ipad.strings deleted file mode 100644 index 468bd39d7..000000000 Binary files a/Classes/ja.lproj/WizardViewController~ipad.strings and /dev/null differ diff --git a/Classes/ja.lproj/WizardViews.strings b/Classes/ja.lproj/WizardViews.strings deleted file mode 100644 index eb781b5ef..000000000 Binary files a/Classes/ja.lproj/WizardViews.strings and /dev/null differ diff --git a/Classes/nl.lproj/AboutView.strings b/Classes/nl.lproj/AboutView.strings new file mode 100644 index 000000000..ac06a575c Binary files /dev/null and b/Classes/nl.lproj/AboutView.strings differ diff --git a/Classes/nl.lproj/AssistantView.strings b/Classes/nl.lproj/AssistantView.strings new file mode 100644 index 000000000..243eacb86 Binary files /dev/null and b/Classes/nl.lproj/AssistantView.strings differ diff --git a/Classes/nl.lproj/AssistantViewScreens.strings b/Classes/nl.lproj/AssistantViewScreens.strings new file mode 100644 index 000000000..e2384f6fe Binary files /dev/null and b/Classes/nl.lproj/AssistantViewScreens.strings differ diff --git a/Classes/nl.lproj/AssistantViews.strings b/Classes/nl.lproj/AssistantViews.strings new file mode 100644 index 000000000..1ce464cfe Binary files /dev/null and b/Classes/nl.lproj/AssistantViews.strings differ diff --git a/Classes/nl.lproj/AssistantView~ipad.strings b/Classes/nl.lproj/AssistantView~ipad.strings new file mode 100644 index 000000000..b27cb9834 Binary files /dev/null and b/Classes/nl.lproj/AssistantView~ipad.strings differ diff --git a/Classes/nl.lproj/CallIncomingView.strings b/Classes/nl.lproj/CallIncomingView.strings new file mode 100644 index 000000000..70e3a5539 Binary files /dev/null and b/Classes/nl.lproj/CallIncomingView.strings differ diff --git a/Classes/nl.lproj/CallOutgoingView.strings b/Classes/nl.lproj/CallOutgoingView.strings new file mode 100644 index 000000000..e8d84f507 Binary files /dev/null and b/Classes/nl.lproj/CallOutgoingView.strings differ diff --git a/Classes/nl.lproj/CallView.strings b/Classes/nl.lproj/CallView.strings new file mode 100644 index 000000000..31c93b287 Binary files /dev/null and b/Classes/nl.lproj/CallView.strings differ diff --git a/Classes/nl.lproj/CallView~ipad.strings b/Classes/nl.lproj/CallView~ipad.strings new file mode 100644 index 000000000..31c93b287 Binary files /dev/null and b/Classes/nl.lproj/CallView~ipad.strings differ diff --git a/Classes/nl.lproj/ChatConversationCreateView.strings b/Classes/nl.lproj/ChatConversationCreateView.strings new file mode 100644 index 000000000..a31b4228d Binary files /dev/null and b/Classes/nl.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/nl.lproj/ChatConversationView.strings b/Classes/nl.lproj/ChatConversationView.strings new file mode 100644 index 000000000..0709d1b09 Binary files /dev/null and b/Classes/nl.lproj/ChatConversationView.strings differ diff --git a/Classes/nl.lproj/ChatRoomView.strings b/Classes/nl.lproj/ChatRoomView.strings new file mode 100644 index 000000000..72c87d738 Binary files /dev/null and b/Classes/nl.lproj/ChatRoomView.strings differ diff --git a/Classes/nl.lproj/ChatView.strings b/Classes/nl.lproj/ChatView.strings new file mode 100644 index 000000000..067368519 Binary files /dev/null and b/Classes/nl.lproj/ChatView.strings differ diff --git a/Classes/nl.lproj/ChatsListView.strings b/Classes/nl.lproj/ChatsListView.strings new file mode 100644 index 000000000..1c12e43fd Binary files /dev/null and b/Classes/nl.lproj/ChatsListView.strings differ diff --git a/Classes/nl.lproj/ContactDetailsView.strings b/Classes/nl.lproj/ContactDetailsView.strings new file mode 100644 index 000000000..cdb8c45a7 Binary files /dev/null and b/Classes/nl.lproj/ContactDetailsView.strings differ diff --git a/Classes/nl.lproj/ContactsListView.strings b/Classes/nl.lproj/ContactsListView.strings new file mode 100644 index 000000000..11db8e801 Binary files /dev/null and b/Classes/nl.lproj/ContactsListView.strings differ diff --git a/Classes/nl.lproj/ContactsView.strings b/Classes/nl.lproj/ContactsView.strings new file mode 100644 index 000000000..33a5ec66a Binary files /dev/null and b/Classes/nl.lproj/ContactsView.strings differ diff --git a/Classes/nl.lproj/DialerView.strings b/Classes/nl.lproj/DialerView.strings new file mode 100644 index 000000000..566152e68 Binary files /dev/null and b/Classes/nl.lproj/DialerView.strings differ diff --git a/Classes/nl.lproj/DialerView~ipad.strings b/Classes/nl.lproj/DialerView~ipad.strings new file mode 100644 index 000000000..c313f5606 Binary files /dev/null and b/Classes/nl.lproj/DialerView~ipad.strings differ diff --git a/Classes/nl.lproj/FirstLoginView.strings b/Classes/nl.lproj/FirstLoginView.strings new file mode 100644 index 000000000..8fd48bfc7 Binary files /dev/null and b/Classes/nl.lproj/FirstLoginView.strings differ diff --git a/Classes/nl.lproj/HistoryDetailsView.strings b/Classes/nl.lproj/HistoryDetailsView.strings new file mode 100644 index 000000000..17d6e5616 Binary files /dev/null and b/Classes/nl.lproj/HistoryDetailsView.strings differ diff --git a/Classes/nl.lproj/HistoryListView.strings b/Classes/nl.lproj/HistoryListView.strings new file mode 100644 index 000000000..c250982b1 Binary files /dev/null and b/Classes/nl.lproj/HistoryListView.strings differ diff --git a/Classes/nl.lproj/HistoryView.strings b/Classes/nl.lproj/HistoryView.strings new file mode 100644 index 000000000..cacf8ee1b Binary files /dev/null and b/Classes/nl.lproj/HistoryView.strings differ diff --git a/Classes/nl.lproj/ImageView.strings b/Classes/nl.lproj/ImageView.strings new file mode 100644 index 000000000..f89f0207e Binary files /dev/null and b/Classes/nl.lproj/ImageView.strings differ diff --git a/Classes/nl.lproj/InCallView.strings b/Classes/nl.lproj/InCallView.strings new file mode 100644 index 000000000..2af985384 Binary files /dev/null and b/Classes/nl.lproj/InCallView.strings differ diff --git a/Classes/nl.lproj/IncomingCallView.strings b/Classes/nl.lproj/IncomingCallView.strings new file mode 100644 index 000000000..d9397e11a Binary files /dev/null and b/Classes/nl.lproj/IncomingCallView.strings differ diff --git a/Classes/nl.lproj/IncomingCallView~ipad.strings b/Classes/nl.lproj/IncomingCallView~ipad.strings new file mode 100644 index 000000000..735a91234 Binary files /dev/null and b/Classes/nl.lproj/IncomingCallView~ipad.strings differ diff --git a/Classes/nl.lproj/SettingsView.strings b/Classes/nl.lproj/SettingsView.strings new file mode 100644 index 000000000..09bbf0dfb Binary files /dev/null and b/Classes/nl.lproj/SettingsView.strings differ diff --git a/Classes/ru.lproj/AboutView.strings b/Classes/ru.lproj/AboutView.strings new file mode 100644 index 000000000..4a82b772c Binary files /dev/null and b/Classes/ru.lproj/AboutView.strings differ diff --git a/Classes/ru.lproj/AboutViewController.strings b/Classes/ru.lproj/AboutViewController.strings deleted file mode 100644 index 2f4d991a1..000000000 Binary files a/Classes/ru.lproj/AboutViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/AssistantView.strings b/Classes/ru.lproj/AssistantView.strings new file mode 100644 index 000000000..9262b3e4e Binary files /dev/null and b/Classes/ru.lproj/AssistantView.strings differ diff --git a/Classes/ru.lproj/AssistantViewScreens.strings b/Classes/ru.lproj/AssistantViewScreens.strings new file mode 100644 index 000000000..394787525 Binary files /dev/null and b/Classes/ru.lproj/AssistantViewScreens.strings differ diff --git a/Classes/ru.lproj/CallIncomingView.strings b/Classes/ru.lproj/CallIncomingView.strings new file mode 100644 index 000000000..94c94d672 Binary files /dev/null and b/Classes/ru.lproj/CallIncomingView.strings differ diff --git a/Classes/ru.lproj/CallOutgoingView.strings b/Classes/ru.lproj/CallOutgoingView.strings new file mode 100644 index 000000000..a7036d527 Binary files /dev/null and b/Classes/ru.lproj/CallOutgoingView.strings differ diff --git a/Classes/ru.lproj/CallView.strings b/Classes/ru.lproj/CallView.strings new file mode 100644 index 000000000..b6e6d54c0 Binary files /dev/null and b/Classes/ru.lproj/CallView.strings differ diff --git a/Classes/ru.lproj/CallView~ipad.strings b/Classes/ru.lproj/CallView~ipad.strings new file mode 100644 index 000000000..b6e6d54c0 Binary files /dev/null and b/Classes/ru.lproj/CallView~ipad.strings differ diff --git a/Classes/ru.lproj/ChatConversationCreateView.strings b/Classes/ru.lproj/ChatConversationCreateView.strings new file mode 100644 index 000000000..0419d1ba0 Binary files /dev/null and b/Classes/ru.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/ru.lproj/ChatConversationView.strings b/Classes/ru.lproj/ChatConversationView.strings new file mode 100644 index 000000000..68b3e94fc Binary files /dev/null and b/Classes/ru.lproj/ChatConversationView.strings differ diff --git a/Classes/ru.lproj/ChatRoomViewController.strings b/Classes/ru.lproj/ChatRoomViewController.strings deleted file mode 100644 index 48cf472e0..000000000 Binary files a/Classes/ru.lproj/ChatRoomViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/ChatViewController.strings b/Classes/ru.lproj/ChatViewController.strings deleted file mode 100644 index d88302f8e..000000000 Binary files a/Classes/ru.lproj/ChatViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/ChatsListView.strings b/Classes/ru.lproj/ChatsListView.strings new file mode 100644 index 000000000..ef61d7b28 Binary files /dev/null and b/Classes/ru.lproj/ChatsListView.strings differ diff --git a/Classes/ru.lproj/ContactDetailsLabelViewController.strings b/Classes/ru.lproj/ContactDetailsLabelViewController.strings deleted file mode 100644 index ea3b4910b..000000000 Binary files a/Classes/ru.lproj/ContactDetailsLabelViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/ContactDetailsView.strings b/Classes/ru.lproj/ContactDetailsView.strings new file mode 100644 index 000000000..ebbfa2437 Binary files /dev/null and b/Classes/ru.lproj/ContactDetailsView.strings differ diff --git a/Classes/ru.lproj/ContactDetailsViewController.strings b/Classes/ru.lproj/ContactDetailsViewController.strings deleted file mode 100644 index 929df87c5..000000000 Binary files a/Classes/ru.lproj/ContactDetailsViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/ContactsListView.strings b/Classes/ru.lproj/ContactsListView.strings new file mode 100644 index 000000000..3818c755e Binary files /dev/null and b/Classes/ru.lproj/ContactsListView.strings differ diff --git a/Classes/ru.lproj/ContactsViewController.strings b/Classes/ru.lproj/ContactsViewController.strings deleted file mode 100644 index 95b6e2f9c..000000000 Binary files a/Classes/ru.lproj/ContactsViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/DialerView.strings b/Classes/ru.lproj/DialerView.strings new file mode 100644 index 000000000..1400d8e8e Binary files /dev/null and b/Classes/ru.lproj/DialerView.strings differ diff --git a/Classes/ru.lproj/DialerViewController.strings b/Classes/ru.lproj/DialerViewController.strings deleted file mode 100644 index 2bae2e604..000000000 Binary files a/Classes/ru.lproj/DialerViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/DialerViewController~ipad.strings b/Classes/ru.lproj/DialerViewController~ipad.strings deleted file mode 100644 index 153663d76..000000000 Binary files a/Classes/ru.lproj/DialerViewController~ipad.strings and /dev/null differ diff --git a/Classes/ru.lproj/DialerView~ipad.strings b/Classes/ru.lproj/DialerView~ipad.strings new file mode 100644 index 000000000..e0bb1ebb3 Binary files /dev/null and b/Classes/ru.lproj/DialerView~ipad.strings differ diff --git a/Classes/ru.lproj/FirstLoginView.strings b/Classes/ru.lproj/FirstLoginView.strings new file mode 100644 index 000000000..19ce609e0 Binary files /dev/null and b/Classes/ru.lproj/FirstLoginView.strings differ diff --git a/Classes/ru.lproj/FirstLoginViewController.strings b/Classes/ru.lproj/FirstLoginViewController.strings deleted file mode 100644 index b261b2ae4..000000000 Binary files a/Classes/ru.lproj/FirstLoginViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/HistoryDetailsView.strings b/Classes/ru.lproj/HistoryDetailsView.strings new file mode 100644 index 000000000..2244a3324 Binary files /dev/null and b/Classes/ru.lproj/HistoryDetailsView.strings differ diff --git a/Classes/ru.lproj/HistoryDetailsViewController.strings b/Classes/ru.lproj/HistoryDetailsViewController.strings deleted file mode 100644 index fcd2c47c6..000000000 Binary files a/Classes/ru.lproj/HistoryDetailsViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/HistoryListView.strings b/Classes/ru.lproj/HistoryListView.strings new file mode 100644 index 000000000..cce605716 Binary files /dev/null and b/Classes/ru.lproj/HistoryListView.strings differ diff --git a/Classes/ru.lproj/HistoryViewController.strings b/Classes/ru.lproj/HistoryViewController.strings deleted file mode 100644 index 2d1bf025b..000000000 Binary files a/Classes/ru.lproj/HistoryViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/ImageView.strings b/Classes/ru.lproj/ImageView.strings new file mode 100644 index 000000000..b47a96808 Binary files /dev/null and b/Classes/ru.lproj/ImageView.strings differ diff --git a/Classes/ru.lproj/ImageViewController.strings b/Classes/ru.lproj/ImageViewController.strings deleted file mode 100644 index f1b6a5caf..000000000 Binary files a/Classes/ru.lproj/ImageViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/InCallViewController.strings b/Classes/ru.lproj/InCallViewController.strings deleted file mode 100644 index d91c5716e..000000000 Binary files a/Classes/ru.lproj/InCallViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/IncomingCallViewController.strings b/Classes/ru.lproj/IncomingCallViewController.strings deleted file mode 100644 index c13b84710..000000000 Binary files a/Classes/ru.lproj/IncomingCallViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/IncomingCallViewController~ipad.strings b/Classes/ru.lproj/IncomingCallViewController~ipad.strings deleted file mode 100644 index 8aaca9606..000000000 Binary files a/Classes/ru.lproj/IncomingCallViewController~ipad.strings and /dev/null differ diff --git a/Classes/ru.lproj/SettingsView.strings b/Classes/ru.lproj/SettingsView.strings new file mode 100644 index 000000000..825bfd1e1 Binary files /dev/null and b/Classes/ru.lproj/SettingsView.strings differ diff --git a/Classes/ru.lproj/WizardViewController.strings b/Classes/ru.lproj/WizardViewController.strings deleted file mode 100644 index 215fe395f..000000000 Binary files a/Classes/ru.lproj/WizardViewController.strings and /dev/null differ diff --git a/Classes/ru.lproj/WizardViewController~ipad.strings b/Classes/ru.lproj/WizardViewController~ipad.strings deleted file mode 100644 index 7ddb9e698..000000000 Binary files a/Classes/ru.lproj/WizardViewController~ipad.strings and /dev/null differ diff --git a/Classes/ru.lproj/WizardViews.strings b/Classes/ru.lproj/WizardViews.strings deleted file mode 100644 index 8d2de1a47..000000000 Binary files a/Classes/ru.lproj/WizardViews.strings and /dev/null differ diff --git a/Classes/sv.lproj/AboutView.strings b/Classes/sv.lproj/AboutView.strings new file mode 100644 index 000000000..4319c3447 Binary files /dev/null and b/Classes/sv.lproj/AboutView.strings differ diff --git a/Classes/sv.lproj/AssistantView.strings b/Classes/sv.lproj/AssistantView.strings new file mode 100644 index 000000000..b4ff158bb Binary files /dev/null and b/Classes/sv.lproj/AssistantView.strings differ diff --git a/Classes/sv.lproj/AssistantViewScreens.strings b/Classes/sv.lproj/AssistantViewScreens.strings new file mode 100644 index 000000000..6678a164b Binary files /dev/null and b/Classes/sv.lproj/AssistantViewScreens.strings differ diff --git a/Classes/sv.lproj/CallIncomingView.strings b/Classes/sv.lproj/CallIncomingView.strings new file mode 100644 index 000000000..8e18174d7 Binary files /dev/null and b/Classes/sv.lproj/CallIncomingView.strings differ diff --git a/Classes/sv.lproj/CallOutgoingView.strings b/Classes/sv.lproj/CallOutgoingView.strings new file mode 100644 index 000000000..eca868869 Binary files /dev/null and b/Classes/sv.lproj/CallOutgoingView.strings differ diff --git a/Classes/sv.lproj/CallView.strings b/Classes/sv.lproj/CallView.strings new file mode 100644 index 000000000..bff7f06f5 Binary files /dev/null and b/Classes/sv.lproj/CallView.strings differ diff --git a/Classes/sv.lproj/CallView~ipad.strings b/Classes/sv.lproj/CallView~ipad.strings new file mode 100644 index 000000000..bff7f06f5 Binary files /dev/null and b/Classes/sv.lproj/CallView~ipad.strings differ diff --git a/Classes/sv.lproj/ChatConversationCreateView.strings b/Classes/sv.lproj/ChatConversationCreateView.strings new file mode 100644 index 000000000..1808d5502 Binary files /dev/null and b/Classes/sv.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/sv.lproj/ChatConversationView.strings b/Classes/sv.lproj/ChatConversationView.strings new file mode 100644 index 000000000..83d122e9b Binary files /dev/null and b/Classes/sv.lproj/ChatConversationView.strings differ diff --git a/Classes/sv.lproj/ChatsListView.strings b/Classes/sv.lproj/ChatsListView.strings new file mode 100644 index 000000000..7620d76c1 Binary files /dev/null and b/Classes/sv.lproj/ChatsListView.strings differ diff --git a/Classes/sv.lproj/ContactDetailsView.strings b/Classes/sv.lproj/ContactDetailsView.strings new file mode 100644 index 000000000..95c62e2f3 Binary files /dev/null and b/Classes/sv.lproj/ContactDetailsView.strings differ diff --git a/Classes/sv.lproj/ContactsListView.strings b/Classes/sv.lproj/ContactsListView.strings new file mode 100644 index 000000000..ac8f6bb76 Binary files /dev/null and b/Classes/sv.lproj/ContactsListView.strings differ diff --git a/Classes/sv.lproj/DialerView.strings b/Classes/sv.lproj/DialerView.strings new file mode 100644 index 000000000..b28f02395 Binary files /dev/null and b/Classes/sv.lproj/DialerView.strings differ diff --git a/Classes/sv.lproj/DialerView~ipad.strings b/Classes/sv.lproj/DialerView~ipad.strings new file mode 100644 index 000000000..c469fd3ea Binary files /dev/null and b/Classes/sv.lproj/DialerView~ipad.strings differ diff --git a/Classes/sv.lproj/FirstLoginView.strings b/Classes/sv.lproj/FirstLoginView.strings new file mode 100644 index 000000000..f0ab8281c Binary files /dev/null and b/Classes/sv.lproj/FirstLoginView.strings differ diff --git a/Classes/sv.lproj/HistoryDetailsView.strings b/Classes/sv.lproj/HistoryDetailsView.strings new file mode 100644 index 000000000..931bbb0bf Binary files /dev/null and b/Classes/sv.lproj/HistoryDetailsView.strings differ diff --git a/Classes/sv.lproj/HistoryListView.strings b/Classes/sv.lproj/HistoryListView.strings new file mode 100644 index 000000000..18544db61 Binary files /dev/null and b/Classes/sv.lproj/HistoryListView.strings differ diff --git a/Classes/sv.lproj/ImageView.strings b/Classes/sv.lproj/ImageView.strings new file mode 100644 index 000000000..bfc519a95 Binary files /dev/null and b/Classes/sv.lproj/ImageView.strings differ diff --git a/Classes/sv.lproj/LaunchScreen.strings b/Classes/sv.lproj/LaunchScreen.strings new file mode 100644 index 000000000..d20f77ce5 Binary files /dev/null and b/Classes/sv.lproj/LaunchScreen.strings differ diff --git a/Classes/sv.lproj/SettingsView.strings b/Classes/sv.lproj/SettingsView.strings new file mode 100644 index 000000000..ea85eff65 Binary files /dev/null and b/Classes/sv.lproj/SettingsView.strings differ diff --git a/Classes/sv.lproj/SideMenuView.strings b/Classes/sv.lproj/SideMenuView.strings new file mode 100644 index 000000000..98c49fa04 Binary files /dev/null and b/Classes/sv.lproj/SideMenuView.strings differ diff --git a/Classes/sv.lproj/SideMenuView~ipad.strings b/Classes/sv.lproj/SideMenuView~ipad.strings new file mode 100644 index 000000000..98c49fa04 Binary files /dev/null and b/Classes/sv.lproj/SideMenuView~ipad.strings differ diff --git a/Classes/zh_TW.lproj/AboutView.strings b/Classes/zh_TW.lproj/AboutView.strings new file mode 100644 index 000000000..b3e841a49 Binary files /dev/null and b/Classes/zh_TW.lproj/AboutView.strings differ diff --git a/Classes/zh_TW.lproj/AboutViewController.strings b/Classes/zh_TW.lproj/AboutViewController.strings deleted file mode 100644 index cacfb5460..000000000 Binary files a/Classes/zh_TW.lproj/AboutViewController.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/AssistantView.strings b/Classes/zh_TW.lproj/AssistantView.strings new file mode 100644 index 000000000..4b52686f3 Binary files /dev/null and b/Classes/zh_TW.lproj/AssistantView.strings differ diff --git a/Classes/zh_TW.lproj/AssistantViewScreens.strings b/Classes/zh_TW.lproj/AssistantViewScreens.strings new file mode 100644 index 000000000..b5a9ee819 Binary files /dev/null and b/Classes/zh_TW.lproj/AssistantViewScreens.strings differ diff --git a/Classes/zh_TW.lproj/AssistantViews.strings b/Classes/zh_TW.lproj/AssistantViews.strings new file mode 100644 index 000000000..a71b3edde Binary files /dev/null and b/Classes/zh_TW.lproj/AssistantViews.strings differ diff --git a/Classes/zh_TW.lproj/AssistantView~ipad.strings b/Classes/zh_TW.lproj/AssistantView~ipad.strings new file mode 100644 index 000000000..4f6645238 Binary files /dev/null and b/Classes/zh_TW.lproj/AssistantView~ipad.strings differ diff --git a/Classes/zh_TW.lproj/CallIncomingView.strings b/Classes/zh_TW.lproj/CallIncomingView.strings new file mode 100644 index 000000000..79661c7fe Binary files /dev/null and b/Classes/zh_TW.lproj/CallIncomingView.strings differ diff --git a/Classes/zh_TW.lproj/CallOutgoingView.strings b/Classes/zh_TW.lproj/CallOutgoingView.strings new file mode 100644 index 000000000..be2fed212 Binary files /dev/null and b/Classes/zh_TW.lproj/CallOutgoingView.strings differ diff --git a/Classes/zh_TW.lproj/CallView.strings b/Classes/zh_TW.lproj/CallView.strings new file mode 100644 index 000000000..76f223644 Binary files /dev/null and b/Classes/zh_TW.lproj/CallView.strings differ diff --git a/Classes/zh_TW.lproj/CallView~ipad.strings b/Classes/zh_TW.lproj/CallView~ipad.strings new file mode 100644 index 000000000..76f223644 Binary files /dev/null and b/Classes/zh_TW.lproj/CallView~ipad.strings differ diff --git a/Classes/zh_TW.lproj/ChatConversationCreateView.strings b/Classes/zh_TW.lproj/ChatConversationCreateView.strings new file mode 100644 index 000000000..dff95f384 Binary files /dev/null and b/Classes/zh_TW.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/zh_TW.lproj/ChatConversationView.strings b/Classes/zh_TW.lproj/ChatConversationView.strings new file mode 100644 index 000000000..43f050cf2 Binary files /dev/null and b/Classes/zh_TW.lproj/ChatConversationView.strings differ diff --git a/Classes/zh_TW.lproj/ChatRoomView.strings b/Classes/zh_TW.lproj/ChatRoomView.strings new file mode 100644 index 000000000..0daf7d801 Binary files /dev/null and b/Classes/zh_TW.lproj/ChatRoomView.strings differ diff --git a/Classes/zh_TW.lproj/ChatRoomViewController.strings b/Classes/zh_TW.lproj/ChatRoomViewController.strings deleted file mode 100644 index 23f2ad76d..000000000 Binary files a/Classes/zh_TW.lproj/ChatRoomViewController.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/ChatView.strings b/Classes/zh_TW.lproj/ChatView.strings new file mode 100644 index 000000000..4b91117ad Binary files /dev/null and b/Classes/zh_TW.lproj/ChatView.strings differ diff --git a/Classes/zh_TW.lproj/ChatViewController.strings b/Classes/zh_TW.lproj/ChatViewController.strings deleted file mode 100644 index 9e74e9187..000000000 Binary files a/Classes/zh_TW.lproj/ChatViewController.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/ChatsListView.strings b/Classes/zh_TW.lproj/ChatsListView.strings new file mode 100644 index 000000000..df470d1aa Binary files /dev/null and b/Classes/zh_TW.lproj/ChatsListView.strings differ diff --git a/Classes/zh_TW.lproj/ContactDetailsLabelViewController.strings b/Classes/zh_TW.lproj/ContactDetailsLabelViewController.strings deleted file mode 100644 index cd678ed1e..000000000 Binary files a/Classes/zh_TW.lproj/ContactDetailsLabelViewController.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/ContactDetailsView.strings b/Classes/zh_TW.lproj/ContactDetailsView.strings new file mode 100644 index 000000000..0c697dea3 Binary files /dev/null and b/Classes/zh_TW.lproj/ContactDetailsView.strings differ diff --git a/Classes/zh_TW.lproj/ContactDetailsViewController.strings b/Classes/zh_TW.lproj/ContactDetailsViewController.strings deleted file mode 100644 index 5b94a6f7f..000000000 Binary files a/Classes/zh_TW.lproj/ContactDetailsViewController.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/ContactsListView.strings b/Classes/zh_TW.lproj/ContactsListView.strings new file mode 100644 index 000000000..223cca5c9 Binary files /dev/null and b/Classes/zh_TW.lproj/ContactsListView.strings differ diff --git a/Classes/zh_TW.lproj/ContactsView.strings b/Classes/zh_TW.lproj/ContactsView.strings new file mode 100644 index 000000000..b28da865b Binary files /dev/null and b/Classes/zh_TW.lproj/ContactsView.strings differ diff --git a/Classes/zh_TW.lproj/ContactsViewController.strings b/Classes/zh_TW.lproj/ContactsViewController.strings deleted file mode 100644 index 633b2eb51..000000000 Binary files a/Classes/zh_TW.lproj/ContactsViewController.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/DialerView.strings b/Classes/zh_TW.lproj/DialerView.strings new file mode 100644 index 000000000..0db238a66 Binary files /dev/null and b/Classes/zh_TW.lproj/DialerView.strings differ diff --git a/Classes/zh_TW.lproj/DialerViewController.strings b/Classes/zh_TW.lproj/DialerViewController.strings deleted file mode 100644 index 6af0b616c..000000000 Binary files a/Classes/zh_TW.lproj/DialerViewController.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/DialerViewController~ipad.strings b/Classes/zh_TW.lproj/DialerViewController~ipad.strings deleted file mode 100644 index f47328c1d..000000000 Binary files a/Classes/zh_TW.lproj/DialerViewController~ipad.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/DialerView~ipad.strings b/Classes/zh_TW.lproj/DialerView~ipad.strings new file mode 100644 index 000000000..152969c47 Binary files /dev/null and b/Classes/zh_TW.lproj/DialerView~ipad.strings differ diff --git a/Classes/zh_TW.lproj/FirstLoginView.strings b/Classes/zh_TW.lproj/FirstLoginView.strings new file mode 100644 index 000000000..79d9cfea7 Binary files /dev/null and b/Classes/zh_TW.lproj/FirstLoginView.strings differ diff --git a/Classes/zh_TW.lproj/HistoryDetailsView.strings b/Classes/zh_TW.lproj/HistoryDetailsView.strings new file mode 100644 index 000000000..0487493d4 Binary files /dev/null and b/Classes/zh_TW.lproj/HistoryDetailsView.strings differ diff --git a/Classes/zh_TW.lproj/HistoryDetailsViewController.strings b/Classes/zh_TW.lproj/HistoryDetailsViewController.strings deleted file mode 100644 index d29ff8f24..000000000 Binary files a/Classes/zh_TW.lproj/HistoryDetailsViewController.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/HistoryListView.strings b/Classes/zh_TW.lproj/HistoryListView.strings new file mode 100644 index 000000000..bd9b22032 Binary files /dev/null and b/Classes/zh_TW.lproj/HistoryListView.strings differ diff --git a/Classes/zh_TW.lproj/HistoryView.strings b/Classes/zh_TW.lproj/HistoryView.strings new file mode 100644 index 000000000..dfe003109 Binary files /dev/null and b/Classes/zh_TW.lproj/HistoryView.strings differ diff --git a/Classes/zh_TW.lproj/HistoryViewController.strings b/Classes/zh_TW.lproj/HistoryViewController.strings deleted file mode 100644 index 0367a06c1..000000000 Binary files a/Classes/zh_TW.lproj/HistoryViewController.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/ImageView.strings b/Classes/zh_TW.lproj/ImageView.strings new file mode 100644 index 000000000..bd0c17add Binary files /dev/null and b/Classes/zh_TW.lproj/ImageView.strings differ diff --git a/Classes/zh_TW.lproj/ImageViewController.strings b/Classes/zh_TW.lproj/ImageViewController.strings deleted file mode 100644 index 907b630ae..000000000 Binary files a/Classes/zh_TW.lproj/ImageViewController.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/InCallView.strings b/Classes/zh_TW.lproj/InCallView.strings new file mode 100644 index 000000000..229e293de Binary files /dev/null and b/Classes/zh_TW.lproj/InCallView.strings differ diff --git a/Classes/zh_TW.lproj/IncomingCallView.strings b/Classes/zh_TW.lproj/IncomingCallView.strings new file mode 100644 index 000000000..43263a7bb Binary files /dev/null and b/Classes/zh_TW.lproj/IncomingCallView.strings differ diff --git a/Classes/zh_TW.lproj/IncomingCallViewController.strings b/Classes/zh_TW.lproj/IncomingCallViewController.strings deleted file mode 100644 index 4771c71db..000000000 Binary files a/Classes/zh_TW.lproj/IncomingCallViewController.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/IncomingCallViewController~ipad.strings b/Classes/zh_TW.lproj/IncomingCallViewController~ipad.strings deleted file mode 100644 index af166daa8..000000000 Binary files a/Classes/zh_TW.lproj/IncomingCallViewController~ipad.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/IncomingCallView~ipad.strings b/Classes/zh_TW.lproj/IncomingCallView~ipad.strings new file mode 100644 index 000000000..3ef43bd2a Binary files /dev/null and b/Classes/zh_TW.lproj/IncomingCallView~ipad.strings differ diff --git a/Classes/zh_TW.lproj/SettingsView.strings b/Classes/zh_TW.lproj/SettingsView.strings new file mode 100644 index 000000000..1fb19ed42 Binary files /dev/null and b/Classes/zh_TW.lproj/SettingsView.strings differ diff --git a/Classes/zh_TW.lproj/WizardViewController.strings b/Classes/zh_TW.lproj/WizardViewController.strings deleted file mode 100644 index c7cebc6d0..000000000 Binary files a/Classes/zh_TW.lproj/WizardViewController.strings and /dev/null differ diff --git a/Classes/zh_TW.lproj/WizardViewController~ipad.strings b/Classes/zh_TW.lproj/WizardViewController~ipad.strings deleted file mode 100644 index 9e0f0eb25..000000000 Binary files a/Classes/zh_TW.lproj/WizardViewController~ipad.strings and /dev/null differ diff --git a/ImageOptim.sh b/ImageOptim.sh deleted file mode 100755 index 28a58884d..000000000 --- a/ImageOptim.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/sh - -# ImageOptim.sh -# linphone -# -# Created by guillaume on 14/10/13. -# - -if [ "$CONFIGURATION" == "Debug" ]; then - exit 0 -fi - -CONVERT=$(which convert) -CONVERTFILTER="-sharpen 1x0.0 -filter Catrom" -OPTIPNG=$(which optipng) -CMDS="${CONVERT} ${OPTIPNG}" -for i in $CMDS; do - command -v $i > /dev/null && continue || { echo "$i command not found"; exit 1; } -done - -DIR=${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH} -PNGS=$(find $DIR -type f -name *.png) - -echo "Running PNG optimization in $DIR" - -if [[ -f $DIR/optimized ]]; then - echo "Resources already optimized, exit" - exit 0 -fi - -for PNG in $PNGS; do - - BASENAME=$(basename $PNG ".png") - SUFFIX= - PROCESS=true - - # detect images for iPad, in which case basename has to be stripped - case $BASENAME in - *~ipad) - SUFFIX="~ipad" - BASENAME=$(echo ${BASENAME} |cut -f1 -d~) - ;; - # don't ever resize 9Patch assets, otherwise it can't handle the resizing - *9) - PROCESS=false - ;; - esac - - STANDARDFILE=${BASENAME}${SUFFIX}.png - RETINAFILE=${BASENAME}@2x${SUFFIX}.png - - - # skip resize if the retina version already exist, which means the asset was optimized manually - if [ -f $DIR/$BASENAME"@2x"$SUFFIX".png" ]; then - echo "Don't process $BASENAME"; - PROCESS=false - fi - - case $BASENAME in - *@2x$SUFFIX) - continue - ;; - esac - - # for all resources that don't have retina versions, consider the normal version as retina and resize to 50% - if $PROCESS ; then - - echo -n "Processing ${STANDARDFILE} (${CONVERTFILTER})..." - - mv ${DIR}/$STANDARDFILE ${DIR}/$RETINAFILE - $CONVERT ${DIR}/$RETINAFILE $CONVERTFILTER -resize "50%" -strip ${DIR}/$STANDARDFILE > /dev/null - fi - - echo "Optimizing ${BASENAME} and ${BASENAME}@2x ..." - $OPTIPNG $DIR/$RETINAFILE > /dev/null - $OPTIPNG -quiet $DIR/$STANDARDFILE > /dev/null - -done - -# make sure we dont over-optimize -touch $DIR/optimized diff --git a/KifTests/ChatTester.m b/KifTests/ChatTester.m deleted file mode 100644 index 615f095bc..000000000 --- a/KifTests/ChatTester.m +++ /dev/null @@ -1,140 +0,0 @@ -// -// ChatTester.m -// linphone -// -// Created by Guillaume on 17/01/2015. -// -// - -#import "ChatTester.h" -#include "LinphoneManager.h" - -@implementation ChatTester - - -#pragma mark - setup - -- (void)beforeAll { - [super beforeAll]; - [self switchToValidAccountIfNeeded]; - - [tester tapViewWithAccessibilityLabel:LOCALIZED(@"Chat")]; -} - -#pragma mark - tools - -- (void)goBackFromChat { - [tester tapViewWithAccessibilityLabel:LOCALIZED(@"Back")]; -} - -- (void)startChatWith:(NSString*)user { - [tester enterText:user intoViewWithAccessibilityLabel:LOCALIZED(@"Enter a address")]; - [tester tapViewWithAccessibilityLabel:LOCALIZED(@"New Discussion")]; -} - -- (void)sendMessage:(NSString*)message { - [tester enterText:message intoViewWithAccessibilityLabel:LOCALIZED(@"Message field")]; - [tester tapViewWithAccessibilityLabel:LOCALIZED(@"Send")]; -} - - -#pragma mark - tests - -- (void)testSendMessageToMyself { - [self startChatWith:[self accountUsername]]; - - [self sendMessage:@"Hello"]; - - [tester waitForViewWithAccessibilityLabel:LOCALIZED(@"Outgoing message") value:@"Hello" traits:UIAccessibilityTraitStaticText]; - [tester waitForViewWithAccessibilityLabel:LOCALIZED(@"Incoming message") value:@"Hello" traits:UIAccessibilityTraitStaticText]; - - [tester waitForViewWithAccessibilityLabel:LOCALIZED(@"Message status") value:@"delivered" traits:UIAccessibilityTraitImage]; - - [self goBackFromChat]; -} - -- (void)testInvalidSPAddress { - - [self startChatWith:@"sip://toto"]; - - [tester waitForViewWithAccessibilityLabel:LOCALIZED(@"Invalid address") traits:UIAccessibilityTraitStaticText]; - [tester tapViewWithAccessibilityLabel:LOCALIZED(@"Cancel")]; -} - --(void)testSendToSIPAddress{ - NSString* sipAddr = [NSString stringWithFormat:@"sip:%@@%@", [self accountUsername], [self accountDomain]]; - - [self startChatWith:sipAddr]; - - [tester waitForViewWithAccessibilityLabel:LOCALIZED(@"Contact name") value:@"testios" traits:0]; - - [self goBackFromChat]; -} - -- (void)testChatMessageRemoval { - - NSString* user = [self getUUID]; - - [self startChatWith:user]; - [self sendMessage:@"Hello Bro"]; - - [tester tapViewWithAccessibilityLabel:LOCALIZED(@"Edit") traits:UIAccessibilityTraitButton]; - - [tester tapViewWithAccessibilityLabel:LOCALIZED(@"Delete message")]; - - [tester tapViewWithAccessibilityLabel:LOCALIZED(@"Edit") traits:UIAccessibilityTraitButton]; - - - - // check that the tableview is empty - UITableView* tv = nil; - NSError* err = nil; - if( [tester tryFindingAccessibilityElement:nil view:&tv withIdentifier:@"Chat list" tappable:false error:&err] ){ - XCTAssert(tv != nil); - XCTAssert([tv numberOfRowsInSection:0] == 0); // no more messages - } else { - NSLog(@"Error: %@",err); - } - - [self goBackFromChat]; -} - -- (void)testRemoveAllChats { - NSArray* uuids = [self getUUIDArrayOfSize:5]; - - for( NSString* uuid in uuids ){ - [self startChatWith:uuid]; - [self sendMessage:@"Test"]; - [self goBackFromChat]; - } - - [tester tapViewWithAccessibilityLabel:@"Edit" traits:UIAccessibilityTraitButton]; - - // we expect to be able to delete at least the amount of chatrooms we created - for( int i =0; i< uuids.count; i++){ - [tester tapViewWithAccessibilityLabel:@"Delete" traits:UIAccessibilityTraitButton]; - } - - // then we try to delete all the rest of chatrooms - while ( [tester tryFindingTappableViewWithAccessibilityLabel:@"Delete" traits:UIAccessibilityTraitButton error:nil] ) - { - [tester tapViewWithAccessibilityLabel:@"Delete" traits:UIAccessibilityTraitButton]; - NSLog(@"Deleting an extra chat"); - } - - // check that the tableview is empty - UITableView* tv = nil; - NSError* err = nil; - if( [tester tryFindingAccessibilityElement:nil view:&tv withIdentifier:@"ChatRoom list" tappable:false error:&err] ){ - XCTAssert(tv != nil); - XCTAssert([tv numberOfRowsInSection:0] == 0); // no more chat rooms - } else { - NSLog(@"Error: %@",err); - } - - // test that there's no more chatrooms in the core - XCTAssert(linphone_core_get_chat_rooms([LinphoneManager getLc]) == nil); -} - - -@end diff --git a/KifTests/ContactsTester.m b/KifTests/ContactsTester.m deleted file mode 100644 index a0a9a7838..000000000 --- a/KifTests/ContactsTester.m +++ /dev/null @@ -1,78 +0,0 @@ -// -// ContactsTester.m -// linphone -// -// Created by Guillaume BIENKOWSKI on 17/02/2015. -// -// - -#import "ContactsTester.h" - -#import "ContactDetailsTableViewController.h" - -@implementation ContactsTester - -#pragma mark - Setup - -- (void)beforeAll { - [tester tapViewWithAccessibilityLabel:@"Contacts"]; -} - -#pragma mark - Utils - -- (void)setText:(NSString*)text forContactHeaderIndex:(NSInteger)idx { - [tester tapRowAtIndexPath:[NSIndexPath indexPathForRow:idx inSection:0] inTableViewWithAccessibilityIdentifier:@"Contact Name Table"]; - [tester enterTextIntoCurrentFirstResponder:text]; -} - -- (void)setText:(NSString*)text forContactNumbersIndex:(NSInteger)idx inSection:(NSInteger)section { - [tester tapRowAtIndexPath:[NSIndexPath indexPathForRow:idx inSection:section] inTableViewWithAccessibilityIdentifier:@"Contact numbers table"]; - [tester enterTextIntoCurrentFirstResponder:text]; -} - -- (void)createContact:(NSString*)firstName lastName:(NSString*)lastName phoneNumber:(NSString*)phone SIPAddress:(NSString*)sip { - - XCTAssert(firstName != nil); - [tester tapViewWithAccessibilityLabel:@"Add contact"]; - - // check that the OK button is disabled - [tester waitForViewWithAccessibilityLabel:@"Edit" traits:UIAccessibilityTraitButton|UIAccessibilityTraitNotEnabled|UIAccessibilityTraitSelected]; - - [self setText:firstName forContactHeaderIndex:0]; - - // entering text should enable the "edit" button - [tester waitForViewWithAccessibilityLabel:@"Edit" traits:UIAccessibilityTraitButton|UIAccessibilityTraitSelected]; - - if( lastName ) - [self setText:lastName forContactHeaderIndex:1]; - - if ( phone ) - [self setText:phone forContactNumbersIndex:0 inSection:ContactSections_Number]; - - if (sip) - [self setText:sip forContactNumbersIndex:0 inSection:ContactSections_Sip]; - - [tester tapViewWithAccessibilityLabel:@"Edit"]; - [tester tapViewWithAccessibilityLabel:@"Back"]; - -} - -#pragma mark - Tests - -- (void)testDeleteContact { - NSString* contactName = [self getUUID]; - [self createContact:contactName lastName:@"dummy" phoneNumber:@"0102030405" SIPAddress:@"testios"]; - - NSString* fullName = [contactName stringByAppendingString:@" dummy"]; - - [tester tapViewWithAccessibilityLabel:@"Firstname, Lastname" value:fullName traits:UIAccessibilityTraitStaticText]; - - [tester tapViewWithAccessibilityLabel:@"Edit"]; - [tester scrollViewWithAccessibilityIdentifier:@"Contact numbers table" byFractionOfSizeHorizontal:0 vertical:-0.9]; - - [tester tapViewWithAccessibilityLabel:@"Remove"]; - - [tester waitForAbsenceOfViewWithAccessibilityLabel:@"Firstname, Lastname" value:fullName traits:UIAccessibilityTraitStaticText]; -} - -@end diff --git a/KifTests/LinphoneTestCase.h b/KifTests/LinphoneTestCase.h deleted file mode 100644 index 452135db3..000000000 --- a/KifTests/LinphoneTestCase.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// LinphoneTestCase.h -// linphone -// -// Created by Guillaume BIENKOWSKI on 19/01/2015. -// -// - -#import - -#define LOCALIZED(X) NSLocalizedString(X, nil) - -@interface LinphoneTestCase : KIFTestCase -@property BOOL invalidAccountSet; - -- (void)switchToValidAccountIfNeeded; -- (NSString*)accountUsername; -- (NSString*)accountDomain; - -- (NSString*)getUUID; -- (NSArray*)getUUIDArrayOfSize:(size_t)size; - -@end diff --git a/KifTests/LinphoneTestCase.m b/KifTests/LinphoneTestCase.m deleted file mode 100644 index 542cdb12d..000000000 --- a/KifTests/LinphoneTestCase.m +++ /dev/null @@ -1,117 +0,0 @@ -// -// LinphoneTestCase.m -// linphone -// -// Created by Guillaume BIENKOWSKI on 19/01/2015. -// -// - -#import "LinphoneTestCase.h" - -#import "LinphoneManager.h" - -#import "KIF/KIFTypist.h" - -@implementation LinphoneTestCase - -+ (void)initialize { - // default is 0.01, which sometimes confuses the simulator to the point that - // it will miss some keys - [KIFTypist setKeystrokeDelay:0.05]; -} - -- (NSString *)accountUsername { - return @"testios"; -} - -- (NSString *)accountDomain { - return @"sip.linphone.org"; -} - -- (NSString*)getUUID { - return [[NSUUID UUID] UUIDString]; -} - -- (NSArray *)getUUIDArrayOfSize:(size_t)size { - NSMutableArray* array = [NSMutableArray arrayWithCapacity:size]; - for (NSInteger i=0; idata; - const char* domain = linphone_proxy_config_get_domain(cfg); - const char* identity = linphone_proxy_config_get_identity(cfg); - LinphoneAddress* addr = linphone_core_interpret_url(lc, identity); - const char* username = linphone_address_get_username(addr); - - if( addr - && ( username && strcmp(username, [[self accountUsername] UTF8String]) == 0) - && ( domain && strcmp(domain, [[self accountDomain] UTF8String]) == 0 ) - && linphone_proxy_config_get_state(cfg) == LinphoneRegistrationOk ) - { - isOK = true; - linphone_address_destroy(addr); - break; - } else if( addr ) { - linphone_address_destroy(addr); - } - - proxies=proxies->next; - } - return isOK; -} - -- (void)switchToValidAccountIfNeeded { - [UIView setAnimationsEnabled:false]; - - if( invalidAccount && ! [self hasValidProxyConfig] ){ - - [tester tapViewWithAccessibilityLabel:LOCALIZED(@"Settings")]; - [tester tapViewWithAccessibilityLabel:@"Run assistant"]; - [tester waitForTimeInterval:0.5]; - if( [tester tryFindingViewWithAccessibilityLabel:LOCALIZED(@"Launch Wizard") error:nil]){ - [tester tapViewWithAccessibilityLabel:LOCALIZED(@"Launch Wizard")]; - [tester waitForTimeInterval:0.5]; - } - - NSLog(@"Switching to a valid account"); - - [tester tapViewWithAccessibilityLabel:LOCALIZED(@"Start")]; - [tester tapViewWithAccessibilityLabel:LOCALIZED(@"Sign in linphone.org account")]; - - [tester enterText:@"testios" intoViewWithAccessibilityLabel:LOCALIZED(@"Username")]; - [tester enterText:@"testtest" intoViewWithAccessibilityLabel:LOCALIZED(@"Password")]; - - [tester tapViewWithAccessibilityLabel:LOCALIZED(@"Sign in")]; - - invalidAccount = false; - } -} - - -@end diff --git a/KifTests/WizardTester.m b/KifTests/WizardTester.m deleted file mode 100644 index 4ac3c337c..000000000 --- a/KifTests/WizardTester.m +++ /dev/null @@ -1,116 +0,0 @@ -// -// WizardTester.m -// linphone -// -// Created by Guillaume on 17/01/2015. -// -// - - -#import "WizardTester.h" -#import - -@implementation WizardTester - -- (void)beforeEach { - [UIView setAnimationsEnabled:false]; - - [tester tapViewWithAccessibilityLabel:@"Settings"]; - [tester tapViewWithAccessibilityLabel:@"Run assistant"]; - [tester waitForTimeInterval:0.5]; - if( [tester tryFindingViewWithAccessibilityLabel:@"Launch Wizard" error:nil]){ - [tester tapViewWithAccessibilityLabel:@"Launch Wizard"]; - [tester waitForTimeInterval:0.5]; - } -} - -- (void)afterEach{ - [tester tapViewWithAccessibilityLabel:@"Dialer"]; -} - -#pragma mark - State - -+ (void)switchToValidAccountWithTester:(KIFTestCase*)testCase { -} - -#pragma mark - Utilities - -- (void)_linphoneLogin:(NSString*)username withPW:(NSString*)pw { - [tester tapViewWithAccessibilityLabel:@"Start"]; - [tester tapViewWithAccessibilityLabel:@"Sign in linphone.org account"]; - - [tester enterText:username intoViewWithAccessibilityLabel:@"Username"]; - [tester enterText:pw intoViewWithAccessibilityLabel:@"Password"]; - - [tester tapViewWithAccessibilityLabel:@"Sign in"]; -} - - - -- (void)_externalLoginWithProtocol:(NSString*)protocol { - - [self setInvalidAccountSet:true]; - [tester tapViewWithAccessibilityLabel:@"Start"]; - [tester tapViewWithAccessibilityLabel:@"Sign in SIP account"]; - - [tester enterText:@"testios" intoViewWithAccessibilityLabel:@"Username"]; - [tester enterText:@"testtest" intoViewWithAccessibilityLabel:@"Password"]; - [tester enterText:@"sip.linphone.org" intoViewWithAccessibilityLabel:@"Domain"]; - [tester tapViewWithAccessibilityLabel:protocol]; - - [tester tapViewWithAccessibilityLabel:@"Sign in"]; - - // check the registration state - UIView* regState = [tester waitForViewWithAccessibilityLabel:@"Registration state"]; - [tester waitForTimeInterval:1]; - [tester expectView:regState toContainText:@"Registered"]; -} - -#pragma mark - Tests - -- (void)testLinphoneLogin { - - [self _linphoneLogin:@"testios" withPW:@"testtest"]; - - // check the registration state - UIView* regState = [tester waitForViewWithAccessibilityLabel:@"Registration state"]; - [tester waitForTimeInterval:1]; - [tester expectView:regState toContainText:@"Registered"]; - -} - -- (void)testLinphoneLoginWithBadPassword { - [self _linphoneLogin:@"testios" withPW:@"badPass"]; - - [self setInvalidAccountSet:true]; - - UIView* alertViewText = [tester waitForViewWithAccessibilityLabel:@"Registration failure" traits:UIAccessibilityTraitStaticText]; - if( alertViewText ){ - UIView *reason = [tester waitForViewWithAccessibilityLabel:@"Forbidden" traits:UIAccessibilityTraitStaticText]; - if( reason == nil ){ [tester fail]; - } else { - [tester tapViewWithAccessibilityLabel:@"OK"]; // alertview - [tester tapViewWithAccessibilityLabel:@"Cancel"]; // cancel wizard - } - } else { - [tester fail]; - } -} - -- (void)testExternalLoginWithUDP { - [self _externalLoginWithProtocol:@"UDP"]; -} - -- (void)testExternalLoginWithTCP { - [self _externalLoginWithProtocol:@"TCP"]; -} - -- (void)testExternalLoginWithTLS { - [self _externalLoginWithProtocol:@"TLS"]; -} - - - - - -@end diff --git a/COPYING b/LICENCE similarity index 100% rename from COPYING rename to LICENCE diff --git a/LinphoneTester/AppDelegate.h b/LiblinphoneTester/AppDelegate.h similarity index 79% rename from LinphoneTester/AppDelegate.h rename to LiblinphoneTester/AppDelegate.h index a1e3548d5..514c4fb8a 100644 --- a/LinphoneTester/AppDelegate.h +++ b/LiblinphoneTester/AppDelegate.h @@ -10,6 +10,6 @@ @interface AppDelegate : UIResponder -@property (strong, nonatomic) UIWindow *window; +@property(strong, nonatomic) UIWindow *window; @end diff --git a/LiblinphoneTester/AppDelegate.m b/LiblinphoneTester/AppDelegate.m new file mode 100644 index 000000000..c2f8ee863 --- /dev/null +++ b/LiblinphoneTester/AppDelegate.m @@ -0,0 +1,53 @@ +// +// AppDelegate.m +// LinphoneTester +// +// Created by guillaume on 28/05/2014. +// +// + +#import "AppDelegate.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { + UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController; + UINavigationController *navigationController = [splitViewController.viewControllers lastObject]; + splitViewController.delegate = (id)navigationController.topViewController; + } + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of + // temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application + // and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use + // this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application + // state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: + // when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes + // made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application + // was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also + // applicationDidEnterBackground:. +} + +@end diff --git a/LinphoneTester/Base.lproj/Main_iPad.storyboard b/LiblinphoneTester/Base.lproj/Main_iPad.storyboard similarity index 93% rename from LinphoneTester/Base.lproj/Main_iPad.storyboard rename to LiblinphoneTester/Base.lproj/Main_iPad.storyboard index 17746dea5..a8dad803a 100644 --- a/LinphoneTester/Base.lproj/Main_iPad.storyboard +++ b/LiblinphoneTester/Base.lproj/Main_iPad.storyboard @@ -1,8 +1,7 @@ - + - - + @@ -20,15 +19,14 @@ - + - + - @@ -71,15 +69,14 @@ - + - + - diff --git a/LinphoneTester/Base.lproj/Main_iPhone.storyboard b/LiblinphoneTester/Base.lproj/Main_iPhone.storyboard similarity index 96% rename from LinphoneTester/Base.lproj/Main_iPhone.storyboard rename to LiblinphoneTester/Base.lproj/Main_iPhone.storyboard index d2b7677dd..c9b353c45 100644 --- a/LinphoneTester/Base.lproj/Main_iPhone.storyboard +++ b/LiblinphoneTester/Base.lproj/Main_iPhone.storyboard @@ -1,8 +1,7 @@ - + - - + @@ -23,7 +22,7 @@ - + @@ -66,7 +65,7 @@ - + diff --git a/LiblinphoneTester/DetailView.h b/LiblinphoneTester/DetailView.h new file mode 100644 index 000000000..945535107 --- /dev/null +++ b/LiblinphoneTester/DetailView.h @@ -0,0 +1,28 @@ +// +// DetailViewController.h +// LinphoneTester +// +// Created by guillaume on 28/05/2014. +// +// + +#import + +typedef NS_ENUM(int, TestState) { TestStateIdle, TestStatePassed, TestStateInProgress, TestStateFailed }; + +@interface TestItem : NSObject + +@property(strong, nonatomic) NSString *suite; +@property(strong, nonatomic) NSString *name; +@property(nonatomic) TestState state; + +- (id)initWithName:(NSString *)name fromSuite:(NSString *)suite; ++ (TestItem *)testWithName:(NSString *)name fromSuite:(NSString *)suite; + +@end + +@interface DetailView : UITableViewController + +@property(strong, nonatomic) NSString *detailItem; + +@end diff --git a/LiblinphoneTester/DetailView.m b/LiblinphoneTester/DetailView.m new file mode 100644 index 000000000..f8da69f6f --- /dev/null +++ b/LiblinphoneTester/DetailView.m @@ -0,0 +1,230 @@ +// +// DetailViewController.m +// LinphoneTester +// +// Created by guillaume on 28/05/2014. +// +// + +#import "DetailView.h" +#import "MasterView.h" +#import "LogsView.h" +#include "linphone/liblinphone_tester.h" +#import "Utils.h" + +static NSString *const kAllTestsName = @"Run All tests"; + +@implementation TestItem + +- (id)initWithName:(NSString *)name fromSuite:(NSString *)suite { + self = [super init]; + if (self) { + self.name = name; + self.suite = suite; + self.state = TestStateIdle; + } + return self; +} + ++ (TestItem *)testWithName:(NSString *)name fromSuite:(NSString *)suite { + return [[TestItem alloc] initWithName:name fromSuite:suite]; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"{suite:'%@', test:'%@', state:%d}", _suite, _name, _state]; +} + +@end + +@interface DetailView () { + NSMutableArray *_tests; + BOOL in_progress; +} +@property(strong, nonatomic) UIPopoverController *masterPopoverController; +- (void)configureView; +@end + +@implementation DetailView + +#pragma mark - Managing the detail item + +- (void)setDetailItem:(id)newDetailItem { + if (_detailItem != newDetailItem) { + _detailItem = newDetailItem; + + // Update the view. + [self configureView]; + [self.tableView reloadData]; + } + + if (self.masterPopoverController != nil) { + [self.masterPopoverController dismissPopoverAnimated:YES]; + } +} + +- (void)addTestsFromSuite:(NSString *)suite { + int count = bc_tester_nb_tests([suite UTF8String]); + + for (int i = 0; i < count; i++) { + const char *test_name = bc_tester_test_name([suite UTF8String], i); + NSString *testName = [NSString stringWithUTF8String:test_name]; + TestItem *item = [[TestItem alloc] initWithName:testName fromSuite:suite]; + [_tests addObject:item]; + } +} + +- (void)configureView { + _tests = [[NSMutableArray alloc] initWithCapacity:0]; + if (self.detailItem == nil) { + return; + } + + [_tests + addObject:[TestItem testWithName:kAllTestsName fromSuite:self.detailItem]]; // suite name not used for this one + + if ([self.detailItem isEqualToString:@"All"]) { + for (int i = 0; i < bc_tester_nb_suites(); i++) { + [self addTestsFromSuite:[NSString stringWithUTF8String:bc_tester_suite_name(i)]]; + } + } else { + [self addTestsFromSuite:self.detailItem]; + } +} + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view, typically from a nib. + [self configureView]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +#pragma mark - Tableview + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return _tests.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"testCellIdentifier" forIndexPath:indexPath]; + + TestItem *test = _tests[indexPath.row]; + cell.textLabel.text = [NSString stringWithFormat:@"%@/%@", test.suite, test.name]; + NSString *image = nil; + switch (test.state) { + case TestStateIdle: + image = nil; + break; + case TestStatePassed: + image = @"test_passed"; + break; + case TestStateInProgress: + image = @"test_inprogress"; + break; + case TestStateFailed: + image = @"test_failed"; + break; + } + if (image) { + image = [[NSBundle mainBundle] pathForResource:image ofType:@"png"]; + cell.imageView.image = [UIImage imageWithContentsOfFile:image]; + } else { + [cell.imageView setImage:nil]; + } + return cell; +} + +- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { + return NO; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [tableView deselectRowAtIndexPath:indexPath animated:FALSE]; + if (indexPath.row == 0) { + // we should run all tests + NSMutableArray *paths = [[NSMutableArray alloc] init]; + for (int i = 1; i < _tests.count; i++) { + [paths addObject:[NSIndexPath indexPathForRow:i inSection:0]]; + } + [self launchTest:paths]; + } else { + [self launchTest:@[ indexPath ]]; + } +} + +- (void)updateItem:(NSArray *)paths withAnimation:(BOOL)animate { + [self.tableView reloadRowsAtIndexPaths:paths + withRowAnimation:animate ? UITableViewRowAnimationFade : UITableViewRowAnimationNone]; +} + +- (void)launchTest:(NSArray *)paths { + if (in_progress) { + LOGE(@"Test already in progress"); + return; + } + + in_progress = TRUE; + for (NSIndexPath *index in paths) { + TestItem *test = _tests[index.row]; + test.state = TestStateInProgress; + } + [self updateItem:paths withAnimation:FALSE]; + + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + + dispatch_async(queue, ^{ + for (NSIndexPath *index in paths) { + TestItem *test = _tests[index.row]; + LOGI(@"Should launch test %@", test); + NSString *testSuite = test.suite; + if ([test.suite isEqualToString:@"All"]) { + testSuite = nil; + } + NSString *testName = test.name; + if ([test.name isEqualToString:kAllTestsName]) { + testName = nil; + } + BOOL fail = bc_tester_run_tests([testSuite UTF8String], [testName UTF8String]); + if (fail) { + LOGW(@"Test Failed!"); + test.state = TestStateFailed; + } else { + LOGI(@"Test Passed!"); + test.state = TestStatePassed; + } + [self.tableView scrollToRowAtIndexPath:index atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self updateItem:paths withAnimation:TRUE]; + }); + } + in_progress = FALSE; + }); +} + +#pragma mark - Split view + +- (void)splitViewController:(UISplitViewController *)splitController + willHideViewController:(UIViewController *)viewController + withBarButtonItem:(UIBarButtonItem *)barButtonItem + forPopoverController:(UIPopoverController *)popoverController { + barButtonItem.title = NSLocalizedString(@"Master", @"Master"); + [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES]; + self.masterPopoverController = popoverController; +} + +- (void)splitViewController:(UISplitViewController *)splitController + willShowViewController:(UIViewController *)viewController + invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem { + // Called when the view is shown again in the split view, invalidating the button and popover controller. + [self.navigationItem setLeftBarButtonItem:nil animated:YES]; + self.masterPopoverController = nil; +} + +@end diff --git a/LinphoneTester/LinphoneTester-Info.plist b/LiblinphoneTester/LinphoneTester-Info.plist similarity index 95% rename from LinphoneTester/LinphoneTester-Info.plist rename to LiblinphoneTester/LinphoneTester-Info.plist index 80088103a..e6e68329c 100644 --- a/LinphoneTester/LinphoneTester-Info.plist +++ b/LiblinphoneTester/LinphoneTester-Info.plist @@ -13,7 +13,7 @@ CFBundleIcons~ipad CFBundleIdentifier - com.belledonne-communications.tester.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/LinphoneTester/LinphoneTester-Prefix.pch b/LiblinphoneTester/LinphoneTester-Prefix.pch similarity index 100% rename from LinphoneTester/LinphoneTester-Prefix.pch rename to LiblinphoneTester/LinphoneTester-Prefix.pch diff --git a/LinphoneTester/LogsViewController.h b/LiblinphoneTester/LogsView.h similarity index 61% rename from LinphoneTester/LogsViewController.h rename to LiblinphoneTester/LogsView.h index f18bfbc47..f4c6e163b 100644 --- a/LinphoneTester/LogsViewController.h +++ b/LiblinphoneTester/LogsView.h @@ -8,9 +8,8 @@ #import - -@interface LogsViewController : UIViewController -@property (weak, nonatomic) IBOutlet UITextView *tview; +@interface LogsView : UIViewController +@property(weak, nonatomic) IBOutlet UITextView *tview; - (IBAction)clearLogs:(id)sender; diff --git a/LiblinphoneTester/LogsView.m b/LiblinphoneTester/LogsView.m new file mode 100644 index 000000000..38a5995d2 --- /dev/null +++ b/LiblinphoneTester/LogsView.m @@ -0,0 +1,49 @@ +// +// LogsViewController.m +// linphone +// +// Created by Guillaume BIENKOWSKI on 01/06/2014. +// +// + +#import "LogsView.h" +#import "MasterView.h" + +@interface LogsView () { + NSString *txt; +} + +@end + +@implementation LogsView + +- (void)viewDidLoad { + [super viewDidLoad]; +} + +- (void)viewDidAppear:(BOOL)animated { + self.tview.textContainer.lineBreakMode = NSLineBreakByClipping; + self.tview.text = [lastLogs componentsJoinedByString:@"\n"]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(updateLogs:) + name:kLogsUpdateNotification + object:nil]; +} + +- (void)viewDidDisappear:(BOOL)animated { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (IBAction)clearLogs:(id)sender { + + self.tview.text = nil; +} + +- (void)updateLogs:(NSNotification *)notif { + NSArray *newLogs = [notif.userInfo objectForKey:@"newlogs"]; + dispatch_async(dispatch_get_main_queue(), ^{ + self.tview.text = [self.tview.text stringByAppendingString:[newLogs componentsJoinedByString:@"\n"]]; + }); +} + +@end diff --git a/LiblinphoneTester/MasterView.h b/LiblinphoneTester/MasterView.h new file mode 100644 index 000000000..ca609dc2d --- /dev/null +++ b/LiblinphoneTester/MasterView.h @@ -0,0 +1,20 @@ +// +// MasterViewController.h +// LinphoneTester +// +// Created by guillaume on 28/05/2014. +// +// + +#import + +extern NSMutableArray *lastLogs; +extern NSString *const kLogsUpdateNotification; + +@class DetailView; + +@interface MasterView : UITableViewController + +@property(strong, nonatomic) DetailView *detailViewController; + +@end diff --git a/LiblinphoneTester/MasterView.m b/LiblinphoneTester/MasterView.m new file mode 100644 index 000000000..58df6d562 --- /dev/null +++ b/LiblinphoneTester/MasterView.m @@ -0,0 +1,154 @@ +// +// MasterViewController.m +// LinphoneTester +// +// Created by guillaume on 28/05/2014. +// +// + +#import "MasterView.h" +#import "LogsView.h" +#import "DetailView.h" + +#include "linphone/liblinphone_tester.h" +#include "mediastreamer2/msutils.h" +#import "Utils.h" + +@interface MasterView () { + NSMutableArray *_objects; + NSString *bundlePath; + NSString *documentPath; +} +@end + +@implementation MasterView + +- (void)awakeFromNib { + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { + self.clearsSelectionOnViewWillAppear = NO; + self.preferredContentSize = CGSizeMake(320.0, 600.0); + } + [super awakeFromNib]; +} + +NSMutableArray *lastLogs = nil; +NSMutableArray *logsBuffer = nil; +static int const kLastLogsCapacity = 5000; +static int const kLogsBufferCapacity = 10; +NSString *const kLogsUpdateNotification = @"kLogsUpdateNotification"; + +- (void)setupLogging { + lastLogs = [[NSMutableArray alloc] initWithCapacity:kLastLogsCapacity]; + logsBuffer = [NSMutableArray arrayWithCapacity:kLogsBufferCapacity]; + + linphone_core_set_log_level(ORTP_MESSAGE); + linphone_core_set_log_handler((OrtpLogFunc)linphone_iphone_log_handler); +} + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view, typically from a nib. + self.detailViewController = (DetailView *)[[self.splitViewController.viewControllers lastObject] topViewController]; + + [self setupLogging]; + + bundlePath = [[NSBundle mainBundle] bundlePath]; + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + documentPath = [paths objectAtIndex:0]; + + bc_tester_init((void (*)(int, const char *fm, va_list))linphone_iphone_log_handler, ORTP_MESSAGE, ORTP_ERROR); + liblinphone_tester_add_suites(); + + bc_tester_set_resource_dir_prefix([bundlePath UTF8String]); + bc_tester_set_writable_dir_prefix([documentPath UTF8String]); + + LOGI(@"Bundle path: %@", bundlePath); + LOGI(@"Document path: %@", documentPath); + + int count = bc_tester_nb_suites(); + _objects = [[NSMutableArray alloc] initWithCapacity:count + 1]; + [_objects addObject:@"All"]; + for (int i = 0; i < count; i++) { + const char *suite = bc_tester_suite_name(i); + [_objects addObject:[NSString stringWithUTF8String:suite]]; + } +} + +- (void)displayLogs { + LOGI(@"Should display logs"); + [self.navigationController performSegueWithIdentifier:@"viewLogs" sender:self]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +#pragma mark - Table View + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return _objects.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; + + NSString *suite = _objects[indexPath.row]; + cell.textLabel.text = suite; + return cell; +} + +- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the specified item to be editable. + return NO; +} + +- (void)tableView:(UITableView *)tableView + commitEditingStyle:(UITableViewCellEditingStyle)editingStyle + forRowAtIndexPath:(NSIndexPath *)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + [_objects removeObjectAtIndex:indexPath.row]; + [tableView deleteRowsAtIndexPaths:@[ indexPath ] withRowAnimation:UITableViewRowAnimationFade]; + } else if (editingStyle == UITableViewCellEditingStyleInsert) { + // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table + // view. + } +} + +/* +// Override to support rearranging the table view. +- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath +*)toIndexPath +{ +} +*/ + +/* +// Override to support conditional rearranging of the table view. +- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath +{ + // Return NO if you do not want the item to be re-orderable. + return YES; +} +*/ + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { + NSString *object = _objects[indexPath.row]; + self.detailViewController.detailItem = object; + } +} + +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + if ([[segue identifier] isEqualToString:@"showDetail"]) { + NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; + NSString *object = _objects[indexPath.row]; + [[segue destinationViewController] setDetailItem:object]; + } +} + +@end diff --git a/LiblinphoneTester/TesterImages.xcassets/TestAppIcon.appiconset/Contents.json b/LiblinphoneTester/TesterImages.xcassets/TestAppIcon.appiconset/Contents.json new file mode 100644 index 000000000..ebdf0618a --- /dev/null +++ b/LiblinphoneTester/TesterImages.xcassets/TestAppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "57x57", + "scale" : "1x" + }, + { + "idiom" : "iphone", + "size" : "57x57", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "50x50", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "50x50", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "72x72", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "72x72", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/LinphoneTester/TesterImages.xcassets/LaunchImage.launchimage/Contents.json b/LiblinphoneTester/TesterImages.xcassets/TestLaunchImage.launchimage/Contents.json similarity index 100% rename from LinphoneTester/TesterImages.xcassets/LaunchImage.launchimage/Contents.json rename to LiblinphoneTester/TesterImages.xcassets/TestLaunchImage.launchimage/Contents.json diff --git a/LinphoneTester Tests/ar.lproj/InfoPlist.strings b/LiblinphoneTester/ar.lproj/InfoPlist.strings similarity index 100% rename from LinphoneTester Tests/ar.lproj/InfoPlist.strings rename to LiblinphoneTester/ar.lproj/InfoPlist.strings diff --git a/LinphoneTester/ar.lproj/Main_iPad.strings b/LiblinphoneTester/ar.lproj/Main_iPad.strings similarity index 100% rename from LinphoneTester/ar.lproj/Main_iPad.strings rename to LiblinphoneTester/ar.lproj/Main_iPad.strings diff --git a/LinphoneTester/ar.lproj/Main_iPhone.strings b/LiblinphoneTester/ar.lproj/Main_iPhone.strings similarity index 100% rename from LinphoneTester/ar.lproj/Main_iPhone.strings rename to LiblinphoneTester/ar.lproj/Main_iPhone.strings diff --git a/LinphoneTester Tests/en.lproj/InfoPlist.strings b/LiblinphoneTester/en.lproj/InfoPlist.strings similarity index 100% rename from LinphoneTester Tests/en.lproj/InfoPlist.strings rename to LiblinphoneTester/en.lproj/InfoPlist.strings diff --git a/LiblinphoneTester/main.m b/LiblinphoneTester/main.m new file mode 100644 index 000000000..33760acb6 --- /dev/null +++ b/LiblinphoneTester/main.m @@ -0,0 +1,100 @@ +// +// main.m +// LinphoneTester +// +// Created by guillaume on 28/05/2014. +// +// + +#import + +#import "AppDelegate.h" +#include +#include + +static NSString *const kKEY_CRASH_REPORT = @"CRASH_REPORT"; +static NSString *const kKEY_ExceptionName = @"UnhandledExceptionName"; +static NSString *const kKEY_ExceptionReason = @"UnhandledExceptionReason"; +static NSString *const kKEY_ExceptionUserInfo = @"UnhandledExceptionUserInfo"; +static NSString *const kKEY_ExceptionCallStack = @"UnhandledExceptionCallStack"; +static NSString *const kKEY_ExceptionScreenshot = @"UnhandledExceptionScreenshot"; +static NSString *const kKEY_ExceptionTimestamp = @"UnhandledExceptionTimestamp"; + +static void unhandledExceptionHandler(NSException *exception) { + NSMutableDictionary *crashReport = [NSMutableDictionary dictionary]; + crashReport[kKEY_ExceptionName] = exception.name; + crashReport[kKEY_ExceptionReason] = exception.reason; + crashReport[kKEY_ExceptionUserInfo] = exception.userInfo ?: [NSNull null].debugDescription; + crashReport[kKEY_ExceptionCallStack] = exception.callStackSymbols.debugDescription; + + NSLog(@"CRASH: %@ - %@", exception.name, exception.callStackSymbols.debugDescription); + + [[NSUserDefaults standardUserDefaults] setObject:[NSDictionary dictionaryWithDictionary:crashReport] + forKey:kKEY_CRASH_REPORT]; + [[NSUserDefaults standardUserDefaults] synchronize]; + exit(1); +} + +/* SignalHandler + * + * Handle uncaught signals + */ + +void SignalHandler(int sig, siginfo_t *info, void *context) { + void *frames[128]; + int i, len = backtrace(frames, 128); + char **symbols = backtrace_symbols(frames, len); + + /* + * Now format into a message for sending to the user + */ + + NSMutableString *buffer = [[NSMutableString alloc] initWithCapacity:4096]; + + NSBundle *bundle = [NSBundle mainBundle]; + [buffer appendFormat:@"PComp version %@ build %@\n\n", [bundle objectForInfoDictionaryKey:@"CFBundleVersion"], + [bundle objectForInfoDictionaryKey:@"CIMBuildNumber"]]; + [buffer appendString:@"Uncaught Signal\n"]; + [buffer appendFormat:@"si_signo %d\n", info->si_signo]; + [buffer appendFormat:@"si_code %d\n", info->si_code]; + [buffer appendFormat:@"si_value %d\n", info->si_value.sival_int]; + [buffer appendFormat:@"si_errno %d\n", info->si_errno]; + [buffer appendFormat:@"si_addr %p\n", info->si_addr]; + [buffer appendFormat:@"si_status %d\n", info->si_status]; + [buffer appendString:@"Stack trace:\n\n"]; + for (i = 0; i < len; ++i) { + [buffer appendFormat:@"%4d - %s\n", i, symbols[i]]; + } + + /* + * Get the error file to write this to + */ + + NSLog(@"Error %@", buffer); + exit(1); +} + +void InstallUncaughtExceptionHandler() { + NSSetUncaughtExceptionHandler(&unhandledExceptionHandler); + struct sigaction mySigAction; + mySigAction.sa_sigaction = SignalHandler; + mySigAction.sa_flags = SA_SIGINFO; + + sigemptyset(&mySigAction.sa_mask); + sigaction(SIGQUIT, &mySigAction, NULL); + sigaction(SIGILL, &mySigAction, NULL); + sigaction(SIGTRAP, &mySigAction, NULL); + sigaction(SIGABRT, &mySigAction, NULL); + sigaction(SIGEMT, &mySigAction, NULL); + sigaction(SIGFPE, &mySigAction, NULL); + sigaction(SIGBUS, &mySigAction, NULL); + sigaction(SIGSEGV, &mySigAction, NULL); + sigaction(SIGSYS, &mySigAction, NULL); +} + +int main(int argc, char *argv[]) { + InstallUncaughtExceptionHandler(); + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/Linphone.clr b/Linphone.clr deleted file mode 100644 index 4efb6decf..000000000 Binary files a/Linphone.clr and /dev/null differ diff --git a/LinphoneTester Tests/DTObjectBlockExecutor.m b/LinphoneTester Tests/DTObjectBlockExecutor.m deleted file mode 100644 index 4e9dfd0fd..000000000 --- a/LinphoneTester Tests/DTObjectBlockExecutor.m +++ /dev/null @@ -1,30 +0,0 @@ -// -// DTObjectBlockExecutor.m -// DTFoundation -// -// Created by Oliver Drobnik on 12.02.13. -// Copyright (c) 2013 Cocoanetics. All rights reserved. -// - -#import "DTObjectBlockExecutor.h" - - -@implementation DTObjectBlockExecutor - -+ (id)blockExecutorWithDeallocBlock:(void(^)())block -{ - DTObjectBlockExecutor *executor = [[DTObjectBlockExecutor alloc] init]; - executor.deallocBlock = block; // copy - return executor; -} - -- (void)dealloc -{ - if (_deallocBlock) - { - _deallocBlock(); - _deallocBlock = nil; - } -} - -@end diff --git a/LinphoneTester Tests/LinphoneTester_Tests.m b/LinphoneTester Tests/LinphoneTester_Tests.m deleted file mode 100644 index 89e1920e1..000000000 --- a/LinphoneTester Tests/LinphoneTester_Tests.m +++ /dev/null @@ -1,110 +0,0 @@ -// -// LinphoneTester_Tests.m -// LinphoneTester Tests -// -// Created by guillaume on 10/09/2014. -// -// - -#import -#include "linphone/linphonecore.h" -#include "linphone/liblinphone_tester.h" -#import "NSObject+DTRuntime.h" - -@interface LinphoneTester_Tests : XCTestCase -@property (retain, nonatomic) NSString* bundlePath; -@property (retain, nonatomic) NSString* documentPath; -@end - -@implementation LinphoneTester_Tests -static void linphone_log_function(OrtpLogLevel lev, const char *fmt, va_list args) { - NSString* log = [[NSString alloc] initWithFormat:[NSString stringWithUTF8String:fmt] arguments:args]; - NSLog(@"%@",log); -} - - -void LSLog(NSString* fmt, ...){ - va_list args; - va_start(args, fmt); - linphone_log_function(ORTP_MESSAGE, [fmt UTF8String], args); - va_end(args); -} - - -+ (NSArray*)skippedSuites { - NSArray* skipped_suites = @[@"Flexisip"]; - return skipped_suites; -} - - -+ (NSString*)safeifyTestString:(NSString*)testString{ - NSCharacterSet *charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet]; - return [[testString componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:@"_"]; -} - - - -+ (void)initialize { - - static char * bundle = NULL; - static char * documents = NULL; - liblinphone_tester_init(); - - NSString* bundlePath = [[NSBundle mainBundle] bundlePath]; - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - NSString* documentPath = [paths objectAtIndex:0]; - bundle = ms_strdup([bundlePath UTF8String]); - documents = ms_strdup([documentPath UTF8String]); - - LSLog(@"Bundle path: %@", bundlePath); - LSLog(@"Document path: %@", documentPath); - - liblinphone_tester_set_fileprefix(bundle); - liblinphone_tester_set_writable_dir_prefix(documents); - liblinphone_tester_keep_accounts(TRUE); - - int count = liblinphone_tester_nb_test_suites(); - - for (int i=0; i -#import "DTObjectBlockExecutor.h" - -@implementation NSObject (DTRuntime) - -static char DTRuntimeDeallocBlocks; - -#pragma mark - Blocks - -- (void)addDeallocBlock:(void(^)())block -{ - // don't accept NULL block - NSParameterAssert(block); - - NSMutableArray *deallocBlocks = objc_getAssociatedObject(self, &DTRuntimeDeallocBlocks); - - // add array of dealloc blocks if not existing yet - if (!deallocBlocks) - { - deallocBlocks = [[NSMutableArray alloc] init]; - - objc_setAssociatedObject(self, &DTRuntimeDeallocBlocks, deallocBlocks, OBJC_ASSOCIATION_RETAIN); - } - - DTObjectBlockExecutor *executor = [DTObjectBlockExecutor blockExecutorWithDeallocBlock:block]; - - [deallocBlocks addObject:executor]; -} - -+ (BOOL)addInstanceMethodWithSelectorName:(NSString *)selectorName block:(void(^)(id))block -{ - // don't accept nil name - NSParameterAssert(selectorName); - - // don't accept NULL block - NSParameterAssert(block); - - // See http://stackoverflow.com/questions/6357663/casting-a-block-to-a-void-for-dynamic-class-method-resolution - -#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_7 - void *impBlockForIMP = (void *)objc_unretainedPointer(block); -#else - id impBlockForIMP = (__bridge id)objc_unretainedPointer(block); -#endif - - IMP myIMP = imp_implementationWithBlock(impBlockForIMP); - - SEL selector = NSSelectorFromString(selectorName); - return class_addMethod(self, selector, myIMP, "v@:"); -} - -#pragma mark - Method Swizzling - -+ (void)swizzleMethod:(SEL)selector withMethod:(SEL)otherSelector -{ - // my own class is being targetted - Class c = [self class]; - - // get the methods from the selectors - Method originalMethod = class_getInstanceMethod(c, selector); - Method otherMethod = class_getInstanceMethod(c, otherSelector); - - if (class_addMethod(c, selector, method_getImplementation(otherMethod), method_getTypeEncoding(otherMethod))) - { - class_replaceMethod(c, otherSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); - } - else - { - method_exchangeImplementations(originalMethod, otherMethod); - } -} - -+ (void)swizzleClassMethod:(SEL)selector withMethod:(SEL)otherSelector -{ - // my own class is being targetted - Class c = [self class]; - - // get the methods from the selectors - Method originalMethod = class_getClassMethod(c, selector); - Method otherMethod = class_getClassMethod(c, otherSelector); - -// if (class_addMethod(c, selector, method_getImplementation(otherMethod), method_getTypeEncoding(otherMethod))) -// { -// class_replaceMethod(c, otherSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); -// } -// else -// { - method_exchangeImplementations(originalMethod, otherMethod); -// } - -} - -@end diff --git a/LinphoneTester/AppDelegate.m b/LinphoneTester/AppDelegate.m deleted file mode 100644 index f31a06abb..000000000 --- a/LinphoneTester/AppDelegate.m +++ /dev/null @@ -1,51 +0,0 @@ -// -// AppDelegate.m -// LinphoneTester -// -// Created by guillaume on 28/05/2014. -// -// - -#import "AppDelegate.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - // Override point for customization after application launch. - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { - UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController; - UINavigationController *navigationController = [splitViewController.viewControllers lastObject]; - splitViewController.delegate = (id)navigationController.topViewController; - } - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application -{ - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application -{ - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application -{ - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application -{ - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application -{ - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/LinphoneTester/DetailViewController.h b/LinphoneTester/DetailViewController.h deleted file mode 100644 index 7564fe5e5..000000000 --- a/LinphoneTester/DetailViewController.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// DetailViewController.h -// LinphoneTester -// -// Created by guillaume on 28/05/2014. -// -// - -#import - -typedef NS_ENUM(int, TestState) { - TestStateIdle, - TestStatePassed, - TestStateInProgress, - TestStateFailed -}; - -@interface TestItem : NSObject - - -@property (strong, nonatomic) NSString* suite; -@property (strong, nonatomic) NSString* name; -@property (nonatomic) TestState state; - --(id)initWithName:(NSString*)name fromSuite:(NSString*)suite; -+(TestItem*)testWithName:(NSString*)name fromSuite:(NSString*)suite; - -@end - -@interface DetailViewController : UITableViewController - -@property (strong, nonatomic) NSString* detailItem; - -@end diff --git a/LinphoneTester/DetailViewController.m b/LinphoneTester/DetailViewController.m deleted file mode 100644 index fb56a8dd7..000000000 --- a/LinphoneTester/DetailViewController.m +++ /dev/null @@ -1,210 +0,0 @@ -// -// DetailViewController.m -// LinphoneTester -// -// Created by guillaume on 28/05/2014. -// -// - -#import "DetailViewController.h" -#import "MasterViewController.h" -#import "LogsViewController.h" -#include "linphone/liblinphone_tester.h" - -static NSString* const kAllTestsName = @"Run All tests"; - -@implementation TestItem - --(id)initWithName:(NSString *)name fromSuite:(NSString *)suite { - self = [super init]; - if( self ){ - self.name = name; - self.suite = suite; - self.state = TestStateIdle; - } - return self; -} - -+(TestItem *)testWithName:(NSString *)name fromSuite:(NSString *)suite{ - return [[TestItem alloc] initWithName:name fromSuite:suite]; -} - --(NSString*)description { - return [NSString stringWithFormat:@"{suite:'%@', test:'%@', state:%d}", _suite, _name, _state]; -} - -@end - -@interface DetailViewController () { - NSMutableArray* _tests; - BOOL in_progress; -} -@property (strong, nonatomic) UIPopoverController *masterPopoverController; -- (void)configureView; -@end - -@implementation DetailViewController - -#pragma mark - Managing the detail item - -- (void)setDetailItem:(id)newDetailItem -{ - if (_detailItem != newDetailItem) { - _detailItem = newDetailItem; - - // Update the view. - [self configureView]; - [self.tableView reloadData]; - } - - if (self.masterPopoverController != nil) { - [self.masterPopoverController dismissPopoverAnimated:YES]; - } -} - -- (void)configureView -{ - const char* suite = [self.detailItem UTF8String]; - if( suite == NULL ) return; - NSString* nssuite = [NSString stringWithUTF8String:suite]; - int count = liblinphone_tester_nb_tests(suite); - _tests = [[NSMutableArray alloc] initWithCapacity:count]; - - [_tests addObject:[TestItem testWithName:kAllTestsName fromSuite:nssuite]]; - - for (int i=0; i - -void LSLog(NSString* fmt, ...); - -NSMutableArray* lastLogs; -NSString* const kLogsUpdateNotification; - -@class DetailViewController; - -@interface MasterViewController : UITableViewController - -@property (strong, nonatomic) DetailViewController *detailViewController; - -@end - diff --git a/LinphoneTester/MasterViewController.m b/LinphoneTester/MasterViewController.m deleted file mode 100644 index 16d6686d0..000000000 --- a/LinphoneTester/MasterViewController.m +++ /dev/null @@ -1,170 +0,0 @@ -// -// MasterViewController.m -// LinphoneTester -// -// Created by guillaume on 28/05/2014. -// -// - -#import "MasterViewController.h" -#import "LogsViewController.h" -#import "DetailViewController.h" - -#include "linphone/liblinphone_tester.h" - -@interface MasterViewController () { - NSMutableArray *_objects; - NSString* bundlePath; - NSString* documentPath; -} -@end - -@implementation MasterViewController - -- (void)awakeFromNib -{ - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { - self.clearsSelectionOnViewWillAppear = NO; - self.preferredContentSize = CGSizeMake(320.0, 600.0); - } - [super awakeFromNib]; -} - -NSMutableArray* lastLogs = nil; -NSMutableArray* logsBuffer = nil; -static int const kLastLogsCapacity = 5000; -static int const kLogsBufferCapacity = 10; -NSString* const kLogsUpdateNotification = @"kLogsUpdateNotification"; - -void LSLog(NSString* fmt, ...){ - va_list args; - va_start(args, fmt); - linphone_log_function(ORTP_MESSAGE, [fmt UTF8String], args); - va_end(args); -} - -static void linphone_log_function(OrtpLogLevel lev, const char *fmt, va_list args) { - NSString* log = [[NSString alloc] initWithFormat:[NSString stringWithUTF8String:fmt] arguments:args]; - NSLog(@"%@",log); -} - -- (void)setupLogging { - lastLogs = [[NSMutableArray alloc] initWithCapacity:kLastLogsCapacity]; - logsBuffer = [NSMutableArray arrayWithCapacity:kLogsBufferCapacity]; - - linphone_core_set_log_handler(linphone_log_function); - linphone_core_set_log_level(ORTP_DEBUG|ORTP_ERROR|ORTP_FATAL|ORTP_WARNING|ORTP_MESSAGE|ORTP_TRACE); - -} - - -- (void)viewDidLoad -{ - [super viewDidLoad]; - // Do any additional setup after loading the view, typically from a nib. - self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController]; - - [self setupLogging]; - - bundlePath = [[NSBundle mainBundle] bundlePath]; - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - documentPath = [paths objectAtIndex:0]; - liblinphone_tester_init(); - liblinphone_tester_set_fileprefix([bundlePath UTF8String]); - liblinphone_tester_set_writable_dir_prefix( ms_strdup([documentPath UTF8String]) ); - - LSLog(@"Bundle path: %@", bundlePath); - LSLog(@"Document path: %@", documentPath); - - int count = liblinphone_tester_nb_test_suites(); - _objects = [[NSMutableArray alloc] initWithCapacity:count]; - for (int i=0; i - -#import "AppDelegate.h" -#include -#include - -static NSString * const kKEY_CRASH_REPORT = @"CRASH_REPORT"; -static NSString * const kKEY_ExceptionName = @"UnhandledExceptionName"; -static NSString * const kKEY_ExceptionReason = @"UnhandledExceptionReason"; -static NSString * const kKEY_ExceptionUserInfo = @"UnhandledExceptionUserInfo"; -static NSString * const kKEY_ExceptionCallStack = @"UnhandledExceptionCallStack"; -static NSString * const kKEY_ExceptionScreenshot = @"UnhandledExceptionScreenshot"; -static NSString * const kKEY_ExceptionTimestamp = @"UnhandledExceptionTimestamp"; - -static void unhandledExceptionHandler(NSException *exception) { - NSMutableDictionary *crashReport = [NSMutableDictionary dictionary]; - crashReport[kKEY_ExceptionName] = exception.name; - crashReport[kKEY_ExceptionReason] = exception.reason; - crashReport[kKEY_ExceptionUserInfo] = exception.userInfo ?: [NSNull null].debugDescription; - crashReport[kKEY_ExceptionCallStack] = exception.callStackSymbols.debugDescription; - - NSLog(@"CRASH: %@ - %@", exception.name, exception.callStackSymbols.debugDescription); - - [[NSUserDefaults standardUserDefaults] setObject:[NSDictionary dictionaryWithDictionary:crashReport] forKey:kKEY_CRASH_REPORT]; - [[NSUserDefaults standardUserDefaults] synchronize]; - exit(1); -} - -/* SignalHandler - * - * Handle uncaught signals - */ - -void SignalHandler(int sig, siginfo_t *info, void *context) -{ - void *frames[128]; - int i,len = backtrace(frames, 128); - char **symbols = backtrace_symbols(frames,len); - - /* - * Now format into a message for sending to the user - */ - - NSMutableString *buffer = [[NSMutableString alloc] initWithCapacity:4096]; - - NSBundle *bundle = [NSBundle mainBundle]; - [buffer appendFormat:@"PComp version %@ build %@\n\n", - [bundle objectForInfoDictionaryKey:@"CFBundleVersion"], - [bundle objectForInfoDictionaryKey:@"CIMBuildNumber"]]; - [buffer appendString:@"Uncaught Signal\n"]; - [buffer appendFormat:@"si_signo %d\n",info->si_signo]; - [buffer appendFormat:@"si_code %d\n",info->si_code]; - [buffer appendFormat:@"si_value %d\n",info->si_value.sival_int]; - [buffer appendFormat:@"si_errno %d\n",info->si_errno]; - [buffer appendFormat:@"si_addr %p\n",info->si_addr]; - [buffer appendFormat:@"si_status %d\n",info->si_status]; - [buffer appendString:@"Stack trace:\n\n"]; - for (i = 0; i < len; ++i) { - [buffer appendFormat:@"%4d - %s\n",i,symbols[i]]; - } - - /* - * Get the error file to write this to - */ - - NSLog(@"Error %@",buffer); - exit(1); -} - - - -void InstallUncaughtExceptionHandler() -{ - NSSetUncaughtExceptionHandler(&unhandledExceptionHandler); - struct sigaction mySigAction; - mySigAction.sa_sigaction = SignalHandler; - mySigAction.sa_flags = SA_SIGINFO; - - sigemptyset(&mySigAction.sa_mask); - sigaction(SIGQUIT, &mySigAction, NULL); - sigaction(SIGILL, &mySigAction, NULL); - sigaction(SIGTRAP, &mySigAction, NULL); - sigaction(SIGABRT, &mySigAction, NULL); - sigaction(SIGEMT, &mySigAction, NULL); - sigaction(SIGFPE, &mySigAction, NULL); - sigaction(SIGBUS, &mySigAction, NULL); - sigaction(SIGSEGV, &mySigAction, NULL); - sigaction(SIGSYS, &mySigAction, NULL); -} - -int main(int argc, char * argv[]) -{ - InstallUncaughtExceptionHandler(); - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/NEWS b/NEWS deleted file mode 100644 index 0483219b8..000000000 --- a/NEWS +++ /dev/null @@ -1,13 +0,0 @@ -linphone-iphone-2.0.0 -- October 4, 2012 - * Wizard - * Enhanced history - * New UI - * Chat - * Image transfert in chat - * Contact list: iPhone contact book with SIP addresses - * Contact edition - * Internationalization - * Settings in application - * ICE: Using stun server - * Push notifications (with linphone.org) - diff --git a/README.md b/README.md index a8c22f7c2..ab27c85e3 100644 --- a/README.md +++ b/README.md @@ -1,125 +1,150 @@ -# Linphone on iPhone +[![Build Status](https://travis-ci.org/BelledonneCommunications/linphone-iphone.svg?branch=master)](https://travis-ci.org/BelledonneCommunications/linphone-iphone) -[![Build Status](https://travis-ci.org/Gui13/linphone-iphone.svg?branch=kif)](https://travis-ci.org/Gui13/linphone-iphone) +Linphone is a free VoIP and video softphone based on the SIP protocol. -## Build prerequisite +![Dialer screenshot](http://www.linphone.org/img/slideshow-phone.png) + +# Getting started + +Here's how to launch Linphone for iPhone (more details below): + +1. Install [Xcode from AppStore](https://itunes.apple.com/us/app/Xcode/id497799835?mt=12#). +2. Install [HomeBrew, a package manager for OS X](http://brew.sh) (MacPorts is supported but deprecated). +3. Install Linphone dependencies: open iTerm.app in the current directory and list dependencies to install using: + `./prepare.py` +4. Reorder your path so that brew tools are used instead of Apple's ones which are obsolete: + `export PATH=/usr/local/bin:$PATH` +5. Build SDK (see below for options and explanations): + `./prepare.py -c && ./prepare.py && make` +6. Open linphone.xcodeproj in Xcode: `open linphone.xcodeproj` +7. Press `⌘R` and voilà! + +# How can I contribute? + +Thanks for asking! We love pull requests from everyone. Depending on what you want to do, you can help us improve Linphone in +various ways: + +## Help on translations + +Top translations: linphone-ios
+
+ +Interested in helping translate Linphone? Contribute [on Transifex](https://www.transifex.com/belledonne-communications/linphone-ios). + +## Report bugs and submit patchs + +If you want to dig through Linphone code or report a bug, please read CONTRIBUTING.md first. You should also read this README entirely ;-). + +# Building the SDK Linphone for iPhone depends on liblinphone SDK. This SDK is generated from makefiles and shell scripts. -* Xcode (download from apple or using appstore application) -* [Java SE](http://www.oracle.com/technetwork/java/javase/downloads/index.html) or openJDK - This is required to generate a C sourcefile from SIP grammar using [antlr3](http://www.antlr3.org/) generator. -* [HomeBrew](http://brew.sh) or [Macports](http://www.macports.org/). + To generate the liblinphone multi-arch SDK in GPL mode, simply invoke: + ./prepare.py [options] && make -### Install dependencies +**The resulting SDK is located in `liblinphone-sdk/` root directory.** -* Using HomeBrew: +## Licensing: GPL third parties versus non GPL third parties - brew install autoconf automake pkg-config doxygen java nasm gettext wget yasm optipng imagemagick coreutils intltool - # antlr3.2 is faster than default homebrew version 3.4 - you can install official antlr3 though - brew tap Gui13/linphone - brew install antlr3.2 +This SDK can be generated in 2 flavors: -* Using MacPorts: +* GPL third parties enabled means that liblinphone includes GPL third parties like FFmpeg or X264. If you choose this flavor, your final application **must comply with GPL in any case**. This is the default mode. - sudo port install autoconf automake pkg-config doxygen antlr3 java nasm gettext wget yasm optipng ImageMagick coreutils intltool +* NO GPL third parties means that Linphone will only use non GPL code except for `liblinphone`, `mediastreamer2`, `oRTP` and `belle-sip`. If you choose this flavor, your final application is **still subject to GPL except if you have a [commercial license for the mentioned libraries](http://www.belledonne-communications.com/products.html)**. + To generate the liblinphone multi arch SDK without GPL third parties, invoke: -### System linking + ./prepare.py --disable-gpl-third-parties [other options] && make -* For this part, we assume that `LOCAL_BIN_DIR` is set as following depending on which tool you use: +## Customizing features - For MacPorts: `LOCAL_BIN_DIR=/opt/local/bin` +You can enable non-free codecs by using `--enable-non-free-codecs` and `-DENABLE_=ON`. To get a list of all features, the simplest way is to invoke `prepare.py` with `--list-features`: - For HomeBrew: `LOCAL_BIN_DIR=/usr/local/bin` + ./prepare.py --list-features -* Modify your `PATH` so that the tools are taken in place of the versions brought by Apple in `/usr/bin`. Otherwise the build will fail with obscure errors: +You can for instance enable X264 by using: - export PATH=$LOCAL_BIN_DIR:$PATH + ./prepare.py --enable-non-free-codecs -DENABLE_X264=ON [other options] -* Install [gas-preprosessor.pl](http://github.com/yuvi/gas-preprocessor/) (version above July 2013) into your PATH. Suppose you use `LOCAL_BIN_DIR` directory: +## Built architectures - wget --no-check-certificate https://raw.github.com/yuvi/gas-preprocessor/master/gas-preprocessor.pl - chmod +x gas-preprocessor.pl - sudo mv gas-preprocessor.pl $LOCAL_BIN_DIR +4 architectures currently exists on iOS: -* (HomeBrew only) Link `libtoolize` to `glibtoolize` +- 64 bits ARM64 for iPhone 5s, iPad Air, iPad mini 2, iPhone 6, iPhone 6 Plus, iPad Air 2, iPad mini 3. +- 32 bits ARMv7 for older devices. +- 64 bits x86_64 for simulator for all ARM64 devices. +- 32 bits i386 for simulator for all ARMv7 older devices. - sudo ln -s $LOCAL_BIN_DIR/glibtoolize $LOCAL_BIN_DIR/libtoolize + Note: We are not compiling for the 32 bits i386 simulator by default because Xcode default device (iPhone 6) runs in 64 bits. If you want to enable it, you should invoke `prepare.py` with `i386` argument: `./prepare.py i386 [other options]`. -* Link host's `strings` to simulator SDK +## Upgrading your iOS SDK - sudo ln -s /usr/bin/strings /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/strings +Simply re-invoking `make` should update your SDK. If compilation fails, you may need to rebuilding everything by invoking: + ./prepare.py -c && ./prepare.py [options] && make -## BUILDING THE SDK - -* GPL third parties versus non GPL third parties - - This SDK can be generated in 2 flavors. First is with GPL third parties, it means liblinphone includes GPL third parties like FFMPEG or X264. - If you choose this flavor, your final application must comply with GPL in any case. This is the default mode. - - To generate the liblinphone multi arch sdk in GPL mode, do: - - cd submodules/build && make all - - ALTERNATIVELY, you can force liblinphone to use only non GPL code except for liblinphone, mediastreamer2, oRTP, belle-sip. - If you choose this flavor, your final application is still subject to GPL except if you have a commercial license for liblinphone, mediastreamer2, oRTP, belle-sip. - - To generate the liblinphone multi arch sdk in non GPL mode, do: - - cd submodules/build && make all enable_gpl_third_parties=no - -* For Xcode prior to 4.5, use: - - make -f Makefile.xcode4.4 - -* ZRTP support - - You can disable ZRTP support with: - - make all enable_zrtp=no - -* In case you upgrade your IOS SDK, you may force rebuilding everything, by doing - - make veryclean && make all - -**The resulting sdk is in `liblinphone-sdk/` root directory.** - -## BUILDING THE APPLICATION +# Building the application After the SDK is built, just open the Linphone Xcode project with Xcode, and press `Run`. -* Note regarding third party components subject to license: +## Note regarding third party components subject to license - The liblinphone-sdk is compiled with third parties code that are subject to patent license, specially: AMR, SILK G729 and H264 codecs. - Linphone controls the embedding of these codecs thanks to the preprocessor macros HAVE_SILK, HAVE_AMR, HAVE_G729 HAVE_OPENH264 positioned in Xcode project. - Before embedding these 4 codecs in the final application, make sure to have the right to do so. + The liblinphone SDK is compiled with third parties code that are subject to patent license, specially: AMR, SILK G729 and H264 codecs. + Linphone controls the embedding of these codecs by generating dummy libraries when there are not available. You can enable them using `prepare.py` + script (see `--enable-non-free-codecs` option). Before embedding these 4 codecs in the final application, **make sure to have the right to do so**. -## TESTING THE APPLICATION +# Testing the application We are using the KIF framework to test the UI of Linphone. It is used as a submodule (instead of CocoaPods) for ease. -Simply press `Command + U` and the default simulator / device will launch and try to pass all the tests. +Simply press `⌘U` and the default simulator / device will launch and try to pass all the tests. -## LIMITATIONS, KNOWN BUGS +# Limitations and known bugs -* Video capture does not work in simulator (not implemented by simulator?). +* Video capture will not work in simulator (not implemented in it). -* Link errors with x86_64: this happens when you try to run linphone on the iPhone 5S/6/6+ simulators. - This is due to the fact that we're not building the SDK for the x86_64 architecture, due to it being redundant with i386 (and increasing dramatically the compile time and build size). - The solution (temporary) is to force the acceptable architectures to be 'armv7' only (remove 'arm64') and disable the "build active architecture" flag in the linphone, XMLRPC and NinePatch projects. - Don't forget to re-enable them when archiving your project. +# Debugging the SDK -## DEBUGING THE SDK +Sometime it can be useful to step into liblinphone SDK functions. To allow Xcode to enable breakpoint within liblinphone, SDK must be built with debug symbols by using option `--debug`: -Sometime it can be useful to step into liblinphone SDK functions. To allow Xcode to enable breakpoint within liblinphone, SDK must be built with debug symbols. -To add debug symbol to liblinphone SDK, add make option `enable_debug=yes`: + ./prepare.py --debug [other options] && make - make all enable_gpl_third_parties=no enable_debug=yes - -## DEBUGING MEDIASTREAMER2 +## Debugging mediastreamer2 For iOS specific media development like audio video capture/playback it may be interesting to use `mediastream` test tool. The project `submodule/liblinphone.xcodeproj` can be used for this purpose. + +# Quick UI reference + +- The app is contained in a window, which resides in the MainStoryboard file. +- The delegate is set to LinphoneAppDelegate in main.m, in the UIApplicationMain() by passing its class +- Basic layout: + +MainStoryboard + | + | (rootViewController) + | + PhoneMainView ---> view #--> app background + | | + | #--> statusbar background + | + | (mainViewController) + | + UICompositeView : TPMultilayout + | + #---> view #--> statusBar + | + #--> contentView + | + #--> tabBar + + +When the application is started, the phoneMainView gets asked to transition to the Dialer view or the Assistant view. +PhoneMainView exposes the -changeCurrentView: method, which will setup its +Any Linphone view is actually presented in the UICompositeView, with or without a statusBar and tabBar. + +The UICompositeView consists of 3 areas laid out vertically. From top to bottom: StatusBar, Content and TabBar. +The TabBar is usually the UIMainBar, which is used as a navigation controller: clicking on each of the buttons will trigger +a transition to another "view". diff --git a/Resources/Images.xcassets/AppIcon.appiconset/Contents.json b/Resources/Images.xcassets/AppIcon.appiconset/Contents.json index 80ca25902..90730a624 100644 --- a/Resources/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/Resources/Images.xcassets/AppIcon.appiconset/Contents.json @@ -10,11 +10,21 @@ "size" : "29x29", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, { "size" : "57x57", "idiom" : "iphone", @@ -91,10 +101,16 @@ "idiom" : "ipad", "filename" : "linphone_icon_152.png", "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "linphone_icon_167.png", + "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } -} \ No newline at end of file +} diff --git a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_120.png b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_120.png index eb43effe4..662f657bb 100644 Binary files a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_120.png and b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_120.png differ diff --git a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_152.png b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_152.png index 2cd0dc749..26a4e5269 100644 Binary files a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_152.png and b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_152.png differ diff --git a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_167.png b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_167.png new file mode 100644 index 000000000..9eec1c7f7 Binary files /dev/null and b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_167.png differ diff --git a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_57.png b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_57.png index 14e274350..4ef4e5fe2 100644 Binary files a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_57.png and b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_57.png differ diff --git a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_57@2x.png b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_57@2x.png index 2e9e6bd88..277dbd653 100644 Binary files a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_57@2x.png and b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_57@2x.png differ diff --git a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_72.png b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_72.png index b01eef8c4..ae1756067 100644 Binary files a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_72.png and b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_72.png differ diff --git a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_72@2x.png b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_72@2x.png index 58680e9d1..09d035946 100644 Binary files a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_72@2x.png and b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_72@2x.png differ diff --git a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_76.png b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_76.png index c324627c1..dfc02b4c9 100644 Binary files a/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_76.png and b/Resources/Images.xcassets/AppIcon.appiconset/linphone_icon_76.png differ diff --git a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-568h@2x.png b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-568h@2x.png index 168900c1c..5a133eb4b 100644 Binary files a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-568h@2x.png and b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-568h@2x.png differ diff --git a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-568hios6@2x.png b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-568hios6@2x.png index 168900c1c..5a133eb4b 100644 Binary files a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-568hios6@2x.png and b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-568hios6@2x.png differ diff --git a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Landscape.png b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Landscape.png index 2c6cbb5dd..83897cb2f 100644 Binary files a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Landscape.png and b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Landscape.png differ diff --git a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Landscape@2x.png b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Landscape@2x.png index 6ef7aa0c1..c7d7ee588 100644 Binary files a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Landscape@2x.png and b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Landscape@2x.png differ diff --git a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Portrait.png b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Portrait.png index a804375e9..e3b3e9a06 100644 Binary files a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Portrait.png and b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Portrait.png differ diff --git a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Portrait@2x.png b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Portrait@2x.png index d70d94ba5..e9c4329da 100644 Binary files a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Portrait@2x.png and b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen-Portrait@2x.png differ diff --git a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen.png b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen.png index da0882120..9c311c35e 100644 Binary files a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen.png and b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen.png differ diff --git a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen@2x.png b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen@2x.png index ce8263422..3d756f901 100644 Binary files a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen@2x.png and b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreen@2x.png differ diff --git a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreenios6@2x.png b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreenios6@2x.png index ce8263422..3d756f901 100644 Binary files a/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreenios6@2x.png and b/Resources/Images.xcassets/LaunchImage.launchimage/linphone_splashscreenios6@2x.png differ diff --git a/Resources/accept_default.png b/Resources/accept_default.png deleted file mode 100644 index 5a58ead67..000000000 Binary files a/Resources/accept_default.png and /dev/null differ diff --git a/Resources/accept_default_landscape~ipad.png b/Resources/accept_default_landscape~ipad.png deleted file mode 100644 index ae00a8bf2..000000000 Binary files a/Resources/accept_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/accept_default~ipad.png b/Resources/accept_default~ipad.png deleted file mode 100644 index 4109e1ed4..000000000 Binary files a/Resources/accept_default~ipad.png and /dev/null differ diff --git a/Resources/accept_over.png b/Resources/accept_over.png deleted file mode 100644 index 274529d6b..000000000 Binary files a/Resources/accept_over.png and /dev/null differ diff --git a/Resources/accept_over_landscape~ipad.png b/Resources/accept_over_landscape~ipad.png deleted file mode 100644 index f0477c74c..000000000 Binary files a/Resources/accept_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/accept_over~ipad.png b/Resources/accept_over~ipad.png deleted file mode 100644 index 277e4770c..000000000 Binary files a/Resources/accept_over~ipad.png and /dev/null differ diff --git a/Resources/add_call_default.png b/Resources/add_call_default.png deleted file mode 100644 index 81d6c7ed4..000000000 Binary files a/Resources/add_call_default.png and /dev/null differ diff --git a/Resources/add_call_default~ipad.png b/Resources/add_call_default~ipad.png deleted file mode 100644 index a3ddce2f2..000000000 Binary files a/Resources/add_call_default~ipad.png and /dev/null differ diff --git a/Resources/add_call_disabled.png b/Resources/add_call_disabled.png deleted file mode 100644 index 1e629a0cf..000000000 Binary files a/Resources/add_call_disabled.png and /dev/null differ diff --git a/Resources/add_call_disabled~ipad.png b/Resources/add_call_disabled~ipad.png deleted file mode 100644 index 374aacc0b..000000000 Binary files a/Resources/add_call_disabled~ipad.png and /dev/null differ diff --git a/Resources/add_call_over.png b/Resources/add_call_over.png deleted file mode 100644 index 7561d358b..000000000 Binary files a/Resources/add_call_over.png and /dev/null differ diff --git a/Resources/add_call_over~ipad.png b/Resources/add_call_over~ipad.png deleted file mode 100644 index 24fdabed5..000000000 Binary files a/Resources/add_call_over~ipad.png and /dev/null differ diff --git a/Resources/add_contact_default.png b/Resources/add_contact_default.png deleted file mode 100644 index 5da115460..000000000 Binary files a/Resources/add_contact_default.png and /dev/null differ diff --git a/Resources/add_contact_default~ipad.png b/Resources/add_contact_default~ipad.png deleted file mode 100644 index 82611c172..000000000 Binary files a/Resources/add_contact_default~ipad.png and /dev/null differ diff --git a/Resources/add_contact_disabled.png b/Resources/add_contact_disabled.png deleted file mode 100644 index f140e980b..000000000 Binary files a/Resources/add_contact_disabled.png and /dev/null differ diff --git a/Resources/add_contact_disabled~ipad.png b/Resources/add_contact_disabled~ipad.png deleted file mode 100644 index ff863911b..000000000 Binary files a/Resources/add_contact_disabled~ipad.png and /dev/null differ diff --git a/Resources/add_contact_over.png b/Resources/add_contact_over.png deleted file mode 100644 index 0230d7e76..000000000 Binary files a/Resources/add_contact_over.png and /dev/null differ diff --git a/Resources/add_contact_over~ipad.png b/Resources/add_contact_over~ipad.png deleted file mode 100644 index 4eb38dddd..000000000 Binary files a/Resources/add_contact_over~ipad.png and /dev/null differ diff --git a/Resources/ar.lproj/Localizable.strings b/Resources/ar.lproj/Localizable.strings index 4f874d8c2..a61ce1f8e 100644 Binary files a/Resources/ar.lproj/Localizable.strings and b/Resources/ar.lproj/Localizable.strings differ diff --git a/Resources/wizard_remote.rc b/Resources/assistant_external_sip.rc similarity index 64% rename from Resources/wizard_remote.rc rename to Resources/assistant_external_sip.rc index 3df265ada..42a6d969a 100644 --- a/Resources/wizard_remote.rc +++ b/Resources/assistant_external_sip.rc @@ -2,23 +2,16 @@
+ 0 + 0 + 3600 + - - 3600 1 - 0 - 0 -
-
-
-
- 0 - - - +
+
- - \ No newline at end of file + diff --git a/Resources/assistant_linphone_create.rc b/Resources/assistant_linphone_create.rc new file mode 100644 index 000000000..39eb569a1 --- /dev/null +++ b/Resources/assistant_linphone_create.rc @@ -0,0 +1,21 @@ + + + +
+ 1 + 0 + 0 + sip:voip-metrics@sip.linphone.org;transport=tls + 1 + 180 + 1314000 + sip:?@sip.linphone.org + 1 +
+ +
+ sip.linphone.org + ^[a-z0-9_.\-]*$ + https://www.linphone.org/assistant.php +
+
diff --git a/Resources/assistant_linphone_existing.rc b/Resources/assistant_linphone_existing.rc new file mode 100644 index 000000000..39eb569a1 --- /dev/null +++ b/Resources/assistant_linphone_existing.rc @@ -0,0 +1,21 @@ + + + +
+ 1 + 0 + 0 + sip:voip-metrics@sip.linphone.org;transport=tls + 1 + 180 + 1314000 + sip:?@sip.linphone.org + 1 +
+ +
+ sip.linphone.org + ^[a-z0-9_.\-]*$ + https://www.linphone.org/assistant.php +
+
diff --git a/Resources/assistant_remote.rc b/Resources/assistant_remote.rc new file mode 100644 index 000000000..07ef93c7a --- /dev/null +++ b/Resources/assistant_remote.rc @@ -0,0 +1,16 @@ + + + +
+ 0 + 0 + 3600 + + + + 1 +
+
+ +
+
diff --git a/Resources/avatar_shadow.png b/Resources/avatar_shadow.png deleted file mode 100644 index 7a8aac483..000000000 Binary files a/Resources/avatar_shadow.png and /dev/null differ diff --git a/Resources/avatar_shadow_small.png b/Resources/avatar_shadow_small.png deleted file mode 100644 index 3ed9782c6..000000000 Binary files a/Resources/avatar_shadow_small.png and /dev/null differ diff --git a/Resources/avatar_unknown.png b/Resources/avatar_unknown.png deleted file mode 100644 index 1d1a7f705..000000000 Binary files a/Resources/avatar_unknown.png and /dev/null differ diff --git a/Resources/avatar_unknown_small.png b/Resources/avatar_unknown_small.png deleted file mode 100644 index 143da1512..000000000 Binary files a/Resources/avatar_unknown_small.png and /dev/null differ diff --git a/Resources/back_default.png b/Resources/back_default.png deleted file mode 100644 index d7088080a..000000000 Binary files a/Resources/back_default.png and /dev/null differ diff --git a/Resources/back_default~ipad.png b/Resources/back_default~ipad.png deleted file mode 100644 index 3dad47eb4..000000000 Binary files a/Resources/back_default~ipad.png and /dev/null differ diff --git a/Resources/back_disabled.png b/Resources/back_disabled.png deleted file mode 100644 index d6e641fa5..000000000 Binary files a/Resources/back_disabled.png and /dev/null differ diff --git a/Resources/back_disabled~ipad.png b/Resources/back_disabled~ipad.png deleted file mode 100644 index da4d42006..000000000 Binary files a/Resources/back_disabled~ipad.png and /dev/null differ diff --git a/Resources/back_over.png b/Resources/back_over.png deleted file mode 100644 index d06321994..000000000 Binary files a/Resources/back_over.png and /dev/null differ diff --git a/Resources/back_over~ipad.png b/Resources/back_over~ipad.png deleted file mode 100644 index 4dea8f4c8..000000000 Binary files a/Resources/back_over~ipad.png and /dev/null differ diff --git a/Resources/background.png b/Resources/background.png deleted file mode 100644 index 062a1eca5..000000000 Binary files a/Resources/background.png and /dev/null differ diff --git a/Resources/background_alt.png b/Resources/background_alt.png deleted file mode 100644 index 3e178844a..000000000 Binary files a/Resources/background_alt.png and /dev/null differ diff --git a/Resources/background_top~ipad.png b/Resources/background_top~ipad.png deleted file mode 100644 index 23f494369..000000000 Binary files a/Resources/background_top~ipad.png and /dev/null differ diff --git a/Resources/backspace_default.png b/Resources/backspace_default.png deleted file mode 100644 index b19ba4fa1..000000000 Binary files a/Resources/backspace_default.png and /dev/null differ diff --git a/Resources/backspace_default~ipad.png b/Resources/backspace_default~ipad.png deleted file mode 100644 index 274330951..000000000 Binary files a/Resources/backspace_default~ipad.png and /dev/null differ diff --git a/Resources/backspace_disabled.png b/Resources/backspace_disabled.png deleted file mode 100644 index 4953afb51..000000000 Binary files a/Resources/backspace_disabled.png and /dev/null differ diff --git a/Resources/backspace_disabled~ipad.png b/Resources/backspace_disabled~ipad.png deleted file mode 100644 index 825232600..000000000 Binary files a/Resources/backspace_disabled~ipad.png and /dev/null differ diff --git a/Resources/backspace_over.png b/Resources/backspace_over.png deleted file mode 100644 index abd0e13a6..000000000 Binary files a/Resources/backspace_over.png and /dev/null differ diff --git a/Resources/backspace_over~ipad.png b/Resources/backspace_over~ipad.png deleted file mode 100644 index 95e2137e7..000000000 Binary files a/Resources/backspace_over~ipad.png and /dev/null differ diff --git a/Resources/bubble.png b/Resources/bubble.png deleted file mode 100644 index 6644f4f98..000000000 Binary files a/Resources/bubble.png and /dev/null differ diff --git a/Resources/button_alert_background_default.png b/Resources/button_alert_background_default.png deleted file mode 100644 index eb9ba367d..000000000 Binary files a/Resources/button_alert_background_default.png and /dev/null differ diff --git a/Resources/button_alert_background_over.png b/Resources/button_alert_background_over.png deleted file mode 100644 index 1781eee3c..000000000 Binary files a/Resources/button_alert_background_over.png and /dev/null differ diff --git a/Resources/button_background_default.9.png b/Resources/button_background_default.9.png deleted file mode 100644 index ff37a4200..000000000 Binary files a/Resources/button_background_default.9.png and /dev/null differ diff --git a/Resources/button_background_default.9@2x.png b/Resources/button_background_default.9@2x.png deleted file mode 100644 index c19f88e0b..000000000 Binary files a/Resources/button_background_default.9@2x.png and /dev/null differ diff --git a/Resources/button_background_default.png b/Resources/button_background_default.png deleted file mode 100644 index 31efad8aa..000000000 Binary files a/Resources/button_background_default.png and /dev/null differ diff --git a/Resources/button_background_over.9.png b/Resources/button_background_over.9.png deleted file mode 100644 index 943d82484..000000000 Binary files a/Resources/button_background_over.9.png and /dev/null differ diff --git a/Resources/button_background_over.9@2x.png b/Resources/button_background_over.9@2x.png deleted file mode 100644 index c88681acf..000000000 Binary files a/Resources/button_background_over.9@2x.png and /dev/null differ diff --git a/Resources/button_background_over.png b/Resources/button_background_over.png deleted file mode 100644 index 44813921c..000000000 Binary files a/Resources/button_background_over.png and /dev/null differ diff --git a/Resources/call_default.png b/Resources/call_default.png deleted file mode 100644 index fc2792247..000000000 Binary files a/Resources/call_default.png and /dev/null differ diff --git a/Resources/call_default~ipad.png b/Resources/call_default~ipad.png deleted file mode 100644 index bbfa08f38..000000000 Binary files a/Resources/call_default~ipad.png and /dev/null differ diff --git a/Resources/call_disabled.png b/Resources/call_disabled.png deleted file mode 100644 index 5600f1945..000000000 Binary files a/Resources/call_disabled.png and /dev/null differ diff --git a/Resources/call_disabled~ipad.png b/Resources/call_disabled~ipad.png deleted file mode 100644 index f178ee9a2..000000000 Binary files a/Resources/call_disabled~ipad.png and /dev/null differ diff --git a/Resources/call_over.png b/Resources/call_over.png deleted file mode 100644 index 9cbf18c60..000000000 Binary files a/Resources/call_over.png and /dev/null differ diff --git a/Resources/call_over~ipad.png b/Resources/call_over~ipad.png deleted file mode 100644 index f03e156d6..000000000 Binary files a/Resources/call_over~ipad.png and /dev/null differ diff --git a/Resources/call_quality_indicator_0.png b/Resources/call_quality_indicator_0.png deleted file mode 100644 index 7bdaf40ab..000000000 Binary files a/Resources/call_quality_indicator_0.png and /dev/null differ diff --git a/Resources/call_quality_indicator_1.png b/Resources/call_quality_indicator_1.png deleted file mode 100644 index 2cca9b39c..000000000 Binary files a/Resources/call_quality_indicator_1.png and /dev/null differ diff --git a/Resources/call_quality_indicator_2.png b/Resources/call_quality_indicator_2.png deleted file mode 100644 index adab949fc..000000000 Binary files a/Resources/call_quality_indicator_2.png and /dev/null differ diff --git a/Resources/call_quality_indicator_3.png b/Resources/call_quality_indicator_3.png deleted file mode 100644 index 91118ff60..000000000 Binary files a/Resources/call_quality_indicator_3.png and /dev/null differ diff --git a/Resources/call_state_delete_default.png b/Resources/call_state_delete_default.png deleted file mode 100644 index 8c1843de8..000000000 Binary files a/Resources/call_state_delete_default.png and /dev/null differ diff --git a/Resources/call_state_delete_over.png b/Resources/call_state_delete_over.png deleted file mode 100644 index bc01f8f5d..000000000 Binary files a/Resources/call_state_delete_over.png and /dev/null differ diff --git a/Resources/call_state_outgoing_default.png b/Resources/call_state_outgoing_default.png deleted file mode 100644 index df3aa5e7e..000000000 Binary files a/Resources/call_state_outgoing_default.png and /dev/null differ diff --git a/Resources/call_state_pause_default.png b/Resources/call_state_pause_default.png deleted file mode 100644 index 0ca4db8c1..000000000 Binary files a/Resources/call_state_pause_default.png and /dev/null differ diff --git a/Resources/call_state_pause_over.png b/Resources/call_state_pause_over.png deleted file mode 100644 index a2a15e52b..000000000 Binary files a/Resources/call_state_pause_over.png and /dev/null differ diff --git a/Resources/call_state_play_default.png b/Resources/call_state_play_default.png deleted file mode 100644 index cf455e337..000000000 Binary files a/Resources/call_state_play_default.png and /dev/null differ diff --git a/Resources/call_state_play_over.png b/Resources/call_state_play_over.png deleted file mode 100644 index 42d81a845..000000000 Binary files a/Resources/call_state_play_over.png and /dev/null differ diff --git a/Resources/call_state_ringing_default.png b/Resources/call_state_ringing_default.png deleted file mode 100644 index f7314e148..000000000 Binary files a/Resources/call_state_ringing_default.png and /dev/null differ diff --git a/Resources/call_status_incoming.png b/Resources/call_status_incoming.png deleted file mode 100644 index 2ce5c676e..000000000 Binary files a/Resources/call_status_incoming.png and /dev/null differ diff --git a/Resources/call_status_missed.png b/Resources/call_status_missed.png deleted file mode 100644 index 426dee899..000000000 Binary files a/Resources/call_status_missed.png and /dev/null differ diff --git a/Resources/call_status_outgoing.png b/Resources/call_status_outgoing.png deleted file mode 100644 index 645875ce1..000000000 Binary files a/Resources/call_status_outgoing.png and /dev/null differ diff --git a/Resources/callbar_left_padding.png b/Resources/callbar_left_padding.png deleted file mode 100644 index c54a13b3c..000000000 Binary files a/Resources/callbar_left_padding.png and /dev/null differ diff --git a/Resources/callbar_right_padding.png b/Resources/callbar_right_padding.png deleted file mode 100644 index fc859f667..000000000 Binary files a/Resources/callbar_right_padding.png and /dev/null differ diff --git a/Resources/cancel_default.png b/Resources/cancel_default.png deleted file mode 100644 index 1535fe32d..000000000 Binary files a/Resources/cancel_default.png and /dev/null differ diff --git a/Resources/cancel_over.png b/Resources/cancel_over.png deleted file mode 100644 index adc42242b..000000000 Binary files a/Resources/cancel_over.png and /dev/null differ diff --git a/Resources/cell_call.png b/Resources/cell_call.png deleted file mode 100644 index f4fd83b8f..000000000 Binary files a/Resources/cell_call.png and /dev/null differ diff --git a/Resources/cell_call_first.png b/Resources/cell_call_first.png deleted file mode 100644 index 17b55ffef..000000000 Binary files a/Resources/cell_call_first.png and /dev/null differ diff --git a/Resources/cell_call_first_highlight.png b/Resources/cell_call_first_highlight.png deleted file mode 100644 index 99ea085a6..000000000 Binary files a/Resources/cell_call_first_highlight.png and /dev/null differ diff --git a/Resources/cell_call_highlight.png b/Resources/cell_call_highlight.png deleted file mode 100644 index 4aaf77e56..000000000 Binary files a/Resources/cell_call_highlight.png and /dev/null differ diff --git a/Resources/cell_conference.png b/Resources/cell_conference.png deleted file mode 100644 index ca5088ff3..000000000 Binary files a/Resources/cell_conference.png and /dev/null differ diff --git a/Resources/chat_add_default.png b/Resources/chat_add_default.png deleted file mode 100644 index f32f622d5..000000000 Binary files a/Resources/chat_add_default.png and /dev/null differ diff --git a/Resources/chat_add_over.png b/Resources/chat_add_over.png deleted file mode 100644 index c64f1d4f2..000000000 Binary files a/Resources/chat_add_over.png and /dev/null differ diff --git a/Resources/chat_back_default.png b/Resources/chat_back_default.png deleted file mode 100644 index 41088a304..000000000 Binary files a/Resources/chat_back_default.png and /dev/null differ diff --git a/Resources/chat_back_over.png b/Resources/chat_back_over.png deleted file mode 100644 index 4f499782b..000000000 Binary files a/Resources/chat_back_over.png and /dev/null differ diff --git a/Resources/chat_bubble_incoming.9.png b/Resources/chat_bubble_incoming.9.png deleted file mode 100644 index 68ef2b302..000000000 Binary files a/Resources/chat_bubble_incoming.9.png and /dev/null differ diff --git a/Resources/chat_bubble_incoming.png b/Resources/chat_bubble_incoming.png deleted file mode 100644 index a731fbd1d..000000000 Binary files a/Resources/chat_bubble_incoming.png and /dev/null differ diff --git a/Resources/chat_bubble_outgoing.9.png b/Resources/chat_bubble_outgoing.9.png deleted file mode 100644 index 1aa640f8c..000000000 Binary files a/Resources/chat_bubble_outgoing.9.png and /dev/null differ diff --git a/Resources/chat_bubble_outgoing.png b/Resources/chat_bubble_outgoing.png deleted file mode 100644 index 2c17e038f..000000000 Binary files a/Resources/chat_bubble_outgoing.png and /dev/null differ diff --git a/Resources/chat_cancel_default.png b/Resources/chat_cancel_default.png deleted file mode 100644 index b5e87a2e1..000000000 Binary files a/Resources/chat_cancel_default.png and /dev/null differ diff --git a/Resources/chat_cancel_over.png b/Resources/chat_cancel_over.png deleted file mode 100644 index 5d2abd3f8..000000000 Binary files a/Resources/chat_cancel_over.png and /dev/null differ diff --git a/Resources/chat_default.png b/Resources/chat_default.png deleted file mode 100644 index d388b571f..000000000 Binary files a/Resources/chat_default.png and /dev/null differ diff --git a/Resources/chat_default_landscape~ipad.png b/Resources/chat_default_landscape~ipad.png deleted file mode 100644 index 65948d8c5..000000000 Binary files a/Resources/chat_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/chat_default~ipad.png b/Resources/chat_default~ipad.png deleted file mode 100644 index cef5de443..000000000 Binary files a/Resources/chat_default~ipad.png and /dev/null differ diff --git a/Resources/chat_edit_default.png b/Resources/chat_edit_default.png deleted file mode 100644 index e24e112a8..000000000 Binary files a/Resources/chat_edit_default.png and /dev/null differ diff --git a/Resources/chat_edit_over.png b/Resources/chat_edit_over.png deleted file mode 100644 index 55cffff7a..000000000 Binary files a/Resources/chat_edit_over.png and /dev/null differ diff --git a/Resources/chat_message_background.9.png b/Resources/chat_message_background.9.png deleted file mode 100644 index 90fefbc6d..000000000 Binary files a/Resources/chat_message_background.9.png and /dev/null differ diff --git a/Resources/chat_message_background.9@2x.png b/Resources/chat_message_background.9@2x.png deleted file mode 100644 index 5fa3959b7..000000000 Binary files a/Resources/chat_message_background.9@2x.png and /dev/null differ diff --git a/Resources/chat_message_background.png b/Resources/chat_message_background.png deleted file mode 100644 index c438371b0..000000000 Binary files a/Resources/chat_message_background.png and /dev/null differ diff --git a/Resources/chat_message_delivered.png b/Resources/chat_message_delivered.png deleted file mode 100644 index f8edc012d..000000000 Binary files a/Resources/chat_message_delivered.png and /dev/null differ diff --git a/Resources/chat_message_inprogress.png b/Resources/chat_message_inprogress.png deleted file mode 100644 index f725a3eb9..000000000 Binary files a/Resources/chat_message_inprogress.png and /dev/null differ diff --git a/Resources/chat_message_not_delivered.png b/Resources/chat_message_not_delivered.png deleted file mode 100644 index c174df390..000000000 Binary files a/Resources/chat_message_not_delivered.png and /dev/null differ diff --git a/Resources/chat_ok_default.png b/Resources/chat_ok_default.png deleted file mode 100644 index 7a66efef8..000000000 Binary files a/Resources/chat_ok_default.png and /dev/null differ diff --git a/Resources/chat_ok_over.png b/Resources/chat_ok_over.png deleted file mode 100644 index f318946b0..000000000 Binary files a/Resources/chat_ok_over.png and /dev/null differ diff --git a/Resources/chat_over.png b/Resources/chat_over.png deleted file mode 100644 index 415b33a84..000000000 Binary files a/Resources/chat_over.png and /dev/null differ diff --git a/Resources/chat_over_landscape~ipad.png b/Resources/chat_over_landscape~ipad.png deleted file mode 100644 index 9fa7332c2..000000000 Binary files a/Resources/chat_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/chat_over~ipad.png b/Resources/chat_over~ipad.png deleted file mode 100644 index 741a78bf2..000000000 Binary files a/Resources/chat_over~ipad.png and /dev/null differ diff --git a/Resources/chat_photo_default.png b/Resources/chat_photo_default.png deleted file mode 100644 index 98b1a452b..000000000 Binary files a/Resources/chat_photo_default.png and /dev/null differ diff --git a/Resources/chat_photo_disabled.png b/Resources/chat_photo_disabled.png deleted file mode 100644 index 950f52623..000000000 Binary files a/Resources/chat_photo_disabled.png and /dev/null differ diff --git a/Resources/chat_photo_over.png b/Resources/chat_photo_over.png deleted file mode 100644 index c8b9783f7..000000000 Binary files a/Resources/chat_photo_over.png and /dev/null differ diff --git a/Resources/chat_progressbar_background.png b/Resources/chat_progressbar_background.png deleted file mode 100644 index abd966e86..000000000 Binary files a/Resources/chat_progressbar_background.png and /dev/null differ diff --git a/Resources/chat_selected.png b/Resources/chat_selected.png deleted file mode 100644 index a7fff16a8..000000000 Binary files a/Resources/chat_selected.png and /dev/null differ diff --git a/Resources/chat_selected_landscape~ipad.png b/Resources/chat_selected_landscape~ipad.png deleted file mode 100644 index 9b38ab106..000000000 Binary files a/Resources/chat_selected_landscape~ipad.png and /dev/null differ diff --git a/Resources/chat_selected~ipad.png b/Resources/chat_selected~ipad.png deleted file mode 100644 index c75a19e0f..000000000 Binary files a/Resources/chat_selected~ipad.png and /dev/null differ diff --git a/Resources/chat_send_default.png b/Resources/chat_send_default.png deleted file mode 100644 index 2ded0fc46..000000000 Binary files a/Resources/chat_send_default.png and /dev/null differ diff --git a/Resources/chat_send_disabled.png b/Resources/chat_send_disabled.png deleted file mode 100644 index 2efe5869f..000000000 Binary files a/Resources/chat_send_disabled.png and /dev/null differ diff --git a/Resources/chat_send_over.png b/Resources/chat_send_over.png deleted file mode 100644 index ef07e43ce..000000000 Binary files a/Resources/chat_send_over.png and /dev/null differ diff --git a/Resources/conference_default.png b/Resources/conference_default.png deleted file mode 100644 index ca03a9940..000000000 Binary files a/Resources/conference_default.png and /dev/null differ diff --git a/Resources/conference_default_landscape.png b/Resources/conference_default_landscape.png deleted file mode 100644 index c3f3c62b6..000000000 Binary files a/Resources/conference_default_landscape.png and /dev/null differ diff --git a/Resources/conference_default_landscape~ipad.png b/Resources/conference_default_landscape~ipad.png deleted file mode 100644 index 12f4072e6..000000000 Binary files a/Resources/conference_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/conference_default~ipad.png b/Resources/conference_default~ipad.png deleted file mode 100644 index 12f4072e6..000000000 Binary files a/Resources/conference_default~ipad.png and /dev/null differ diff --git a/Resources/conference_over.png b/Resources/conference_over.png deleted file mode 100644 index 6446f9dea..000000000 Binary files a/Resources/conference_over.png and /dev/null differ diff --git a/Resources/conference_over_landscape.png b/Resources/conference_over_landscape.png deleted file mode 100644 index cb6ff9a91..000000000 Binary files a/Resources/conference_over_landscape.png and /dev/null differ diff --git a/Resources/conference_over_landscape~ipad.png b/Resources/conference_over_landscape~ipad.png deleted file mode 100644 index edc71a961..000000000 Binary files a/Resources/conference_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/conference_over~ipad.png b/Resources/conference_over~ipad.png deleted file mode 100644 index edc71a961..000000000 Binary files a/Resources/conference_over~ipad.png and /dev/null differ diff --git a/Resources/contact_back_default.png b/Resources/contact_back_default.png deleted file mode 100644 index 41088a304..000000000 Binary files a/Resources/contact_back_default.png and /dev/null differ diff --git a/Resources/contact_back_over.png b/Resources/contact_back_over.png deleted file mode 100644 index 649e57811..000000000 Binary files a/Resources/contact_back_over.png and /dev/null differ diff --git a/Resources/contact_cancel_default.png b/Resources/contact_cancel_default.png deleted file mode 100644 index db0cb4ee5..000000000 Binary files a/Resources/contact_cancel_default.png and /dev/null differ diff --git a/Resources/contact_cancel_over.png b/Resources/contact_cancel_over.png deleted file mode 100644 index b0c420bb1..000000000 Binary files a/Resources/contact_cancel_over.png and /dev/null differ diff --git a/Resources/contact_edit_default.png b/Resources/contact_edit_default.png deleted file mode 100644 index fff17bdf8..000000000 Binary files a/Resources/contact_edit_default.png and /dev/null differ diff --git a/Resources/contact_edit_over.png b/Resources/contact_edit_over.png deleted file mode 100644 index 55cffff7a..000000000 Binary files a/Resources/contact_edit_over.png and /dev/null differ diff --git a/Resources/contact_number.png b/Resources/contact_number.png deleted file mode 100644 index 31efad8aa..000000000 Binary files a/Resources/contact_number.png and /dev/null differ diff --git a/Resources/contact_number_over.png b/Resources/contact_number_over.png deleted file mode 100644 index 44813921c..000000000 Binary files a/Resources/contact_number_over.png and /dev/null differ diff --git a/Resources/contact_ok_default.png b/Resources/contact_ok_default.png deleted file mode 100644 index 1617cced9..000000000 Binary files a/Resources/contact_ok_default.png and /dev/null differ diff --git a/Resources/contact_ok_disabled.png b/Resources/contact_ok_disabled.png deleted file mode 100644 index 2c0ad7d62..000000000 Binary files a/Resources/contact_ok_disabled.png and /dev/null differ diff --git a/Resources/contact_ok_over.png b/Resources/contact_ok_over.png deleted file mode 100644 index 73759e8b7..000000000 Binary files a/Resources/contact_ok_over.png and /dev/null differ diff --git a/Resources/contacts_add_default.png b/Resources/contacts_add_default.png deleted file mode 100644 index d108e869a..000000000 Binary files a/Resources/contacts_add_default.png and /dev/null differ diff --git a/Resources/contacts_add_over.png b/Resources/contacts_add_over.png deleted file mode 100644 index c71ef3341..000000000 Binary files a/Resources/contacts_add_over.png and /dev/null differ diff --git a/Resources/contacts_all_default.png b/Resources/contacts_all_default.png deleted file mode 100644 index 2aceb2b41..000000000 Binary files a/Resources/contacts_all_default.png and /dev/null differ diff --git a/Resources/contacts_all_selected.png b/Resources/contacts_all_selected.png deleted file mode 100644 index d5dd11195..000000000 Binary files a/Resources/contacts_all_selected.png and /dev/null differ diff --git a/Resources/contacts_back_default.png b/Resources/contacts_back_default.png deleted file mode 100644 index 99abdeb5e..000000000 Binary files a/Resources/contacts_back_default.png and /dev/null differ diff --git a/Resources/contacts_back_over.png b/Resources/contacts_back_over.png deleted file mode 100644 index 25690d98b..000000000 Binary files a/Resources/contacts_back_over.png and /dev/null differ diff --git a/Resources/contacts_default.png b/Resources/contacts_default.png deleted file mode 100644 index fb2146a91..000000000 Binary files a/Resources/contacts_default.png and /dev/null differ diff --git a/Resources/contacts_default_landscape~ipad.png b/Resources/contacts_default_landscape~ipad.png deleted file mode 100644 index 65bdf1ac0..000000000 Binary files a/Resources/contacts_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/contacts_default~ipad.png b/Resources/contacts_default~ipad.png deleted file mode 100644 index 804169f9e..000000000 Binary files a/Resources/contacts_default~ipad.png and /dev/null differ diff --git a/Resources/contacts_linphone_default.png b/Resources/contacts_linphone_default.png deleted file mode 100644 index c4a013fd5..000000000 Binary files a/Resources/contacts_linphone_default.png and /dev/null differ diff --git a/Resources/contacts_linphone_selected.png b/Resources/contacts_linphone_selected.png deleted file mode 100644 index eff04f247..000000000 Binary files a/Resources/contacts_linphone_selected.png and /dev/null differ diff --git a/Resources/contacts_over.png b/Resources/contacts_over.png deleted file mode 100644 index 7e0f661ba..000000000 Binary files a/Resources/contacts_over.png and /dev/null differ diff --git a/Resources/contacts_over_landscape~ipad.png b/Resources/contacts_over_landscape~ipad.png deleted file mode 100644 index 9362d7c69..000000000 Binary files a/Resources/contacts_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/contacts_over~ipad.png b/Resources/contacts_over~ipad.png deleted file mode 100644 index 0dbf32da5..000000000 Binary files a/Resources/contacts_over~ipad.png and /dev/null differ diff --git a/Resources/contacts_selected.png b/Resources/contacts_selected.png deleted file mode 100644 index 04f579806..000000000 Binary files a/Resources/contacts_selected.png and /dev/null differ diff --git a/Resources/contacts_selected_landscape~ipad.png b/Resources/contacts_selected_landscape~ipad.png deleted file mode 100644 index 96e4f90da..000000000 Binary files a/Resources/contacts_selected_landscape~ipad.png and /dev/null differ diff --git a/Resources/contacts_selected~ipad.png b/Resources/contacts_selected~ipad.png deleted file mode 100644 index 575088e31..000000000 Binary files a/Resources/contacts_selected~ipad.png and /dev/null differ diff --git a/Resources/de.lproj/Localizable.strings b/Resources/de.lproj/Localizable.strings index 1259548b0..aea6c8863 100644 Binary files a/Resources/de.lproj/Localizable.strings and b/Resources/de.lproj/Localizable.strings differ diff --git a/Resources/decline_default.png b/Resources/decline_default.png deleted file mode 100644 index 4e4fbc0e5..000000000 Binary files a/Resources/decline_default.png and /dev/null differ diff --git a/Resources/decline_default_landscape~ipad.png b/Resources/decline_default_landscape~ipad.png deleted file mode 100644 index eb6ddca49..000000000 Binary files a/Resources/decline_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/decline_default~ipad.png b/Resources/decline_default~ipad.png deleted file mode 100644 index a73c165bd..000000000 Binary files a/Resources/decline_default~ipad.png and /dev/null differ diff --git a/Resources/decline_over.png b/Resources/decline_over.png deleted file mode 100644 index a5460064d..000000000 Binary files a/Resources/decline_over.png and /dev/null differ diff --git a/Resources/decline_over_landscape~ipad.png b/Resources/decline_over_landscape~ipad.png deleted file mode 100644 index d14a93ed8..000000000 Binary files a/Resources/decline_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/decline_over~ipad.png b/Resources/decline_over~ipad.png deleted file mode 100644 index 85593ce6a..000000000 Binary files a/Resources/decline_over~ipad.png and /dev/null differ diff --git a/Resources/dialer_address_background.png b/Resources/dialer_address_background.png deleted file mode 100644 index 78be45dbf..000000000 Binary files a/Resources/dialer_address_background.png and /dev/null differ diff --git a/Resources/dialer_address_background_landscape~ipad.png b/Resources/dialer_address_background_landscape~ipad.png deleted file mode 100644 index 67fae34a3..000000000 Binary files a/Resources/dialer_address_background_landscape~ipad.png and /dev/null differ diff --git a/Resources/dialer_address_background~ipad.png b/Resources/dialer_address_background~ipad.png deleted file mode 100644 index c5a7342e9..000000000 Binary files a/Resources/dialer_address_background~ipad.png and /dev/null differ diff --git a/Resources/dialer_alt_back_default.png b/Resources/dialer_alt_back_default.png deleted file mode 100644 index bacd50f44..000000000 Binary files a/Resources/dialer_alt_back_default.png and /dev/null differ diff --git a/Resources/dialer_alt_back_default_landscape.png b/Resources/dialer_alt_back_default_landscape.png deleted file mode 100644 index 9adc1d2a5..000000000 Binary files a/Resources/dialer_alt_back_default_landscape.png and /dev/null differ diff --git a/Resources/dialer_alt_back_default_landscape~ipad.png b/Resources/dialer_alt_back_default_landscape~ipad.png deleted file mode 100644 index 969dec7af..000000000 Binary files a/Resources/dialer_alt_back_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/dialer_alt_back_default~ipad.png b/Resources/dialer_alt_back_default~ipad.png deleted file mode 100644 index 969dec7af..000000000 Binary files a/Resources/dialer_alt_back_default~ipad.png and /dev/null differ diff --git a/Resources/dialer_alt_back_over.png b/Resources/dialer_alt_back_over.png deleted file mode 100644 index 3e3a6dfd2..000000000 Binary files a/Resources/dialer_alt_back_over.png and /dev/null differ diff --git a/Resources/dialer_alt_back_over_landscape.png b/Resources/dialer_alt_back_over_landscape.png deleted file mode 100644 index 73606b5e6..000000000 Binary files a/Resources/dialer_alt_back_over_landscape.png and /dev/null differ diff --git a/Resources/dialer_alt_back_over_landscape~ipad.png b/Resources/dialer_alt_back_over_landscape~ipad.png deleted file mode 100644 index a2105442f..000000000 Binary files a/Resources/dialer_alt_back_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/dialer_alt_back_over~ipad.png b/Resources/dialer_alt_back_over~ipad.png deleted file mode 100644 index a2105442f..000000000 Binary files a/Resources/dialer_alt_back_over~ipad.png and /dev/null differ diff --git a/Resources/dialer_alt_background.png b/Resources/dialer_alt_background.png deleted file mode 100644 index 86b6c3f02..000000000 Binary files a/Resources/dialer_alt_background.png and /dev/null differ diff --git a/Resources/dialer_alt_default.png b/Resources/dialer_alt_default.png deleted file mode 100644 index 43d512c04..000000000 Binary files a/Resources/dialer_alt_default.png and /dev/null differ diff --git a/Resources/dialer_alt_default_landscape.png b/Resources/dialer_alt_default_landscape.png deleted file mode 100644 index f1b2d39cf..000000000 Binary files a/Resources/dialer_alt_default_landscape.png and /dev/null differ diff --git a/Resources/dialer_alt_default_landscape~ipad.png b/Resources/dialer_alt_default_landscape~ipad.png deleted file mode 100644 index 335163e0f..000000000 Binary files a/Resources/dialer_alt_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/dialer_alt_default~ipad.png b/Resources/dialer_alt_default~ipad.png deleted file mode 100644 index 335163e0f..000000000 Binary files a/Resources/dialer_alt_default~ipad.png and /dev/null differ diff --git a/Resources/dialer_alt_disabled.png b/Resources/dialer_alt_disabled.png deleted file mode 100644 index d85d7fa76..000000000 Binary files a/Resources/dialer_alt_disabled.png and /dev/null differ diff --git a/Resources/dialer_alt_disabled_landscape.png b/Resources/dialer_alt_disabled_landscape.png deleted file mode 100644 index 00a72ac47..000000000 Binary files a/Resources/dialer_alt_disabled_landscape.png and /dev/null differ diff --git a/Resources/dialer_alt_disabled_landscape~ipad.png b/Resources/dialer_alt_disabled_landscape~ipad.png deleted file mode 100644 index 24441f3fe..000000000 Binary files a/Resources/dialer_alt_disabled_landscape~ipad.png and /dev/null differ diff --git a/Resources/dialer_alt_disabled~ipad.png b/Resources/dialer_alt_disabled~ipad.png deleted file mode 100644 index dc5c084d2..000000000 Binary files a/Resources/dialer_alt_disabled~ipad.png and /dev/null differ diff --git a/Resources/dialer_alt_over.png b/Resources/dialer_alt_over.png deleted file mode 100644 index 28567955d..000000000 Binary files a/Resources/dialer_alt_over.png and /dev/null differ diff --git a/Resources/dialer_alt_over_landscape.png b/Resources/dialer_alt_over_landscape.png deleted file mode 100644 index d07a14243..000000000 Binary files a/Resources/dialer_alt_over_landscape.png and /dev/null differ diff --git a/Resources/dialer_alt_over_landscape~ipad.png b/Resources/dialer_alt_over_landscape~ipad.png deleted file mode 100644 index 117a8614a..000000000 Binary files a/Resources/dialer_alt_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/dialer_alt_over~ipad.png b/Resources/dialer_alt_over~ipad.png deleted file mode 100644 index 117a8614a..000000000 Binary files a/Resources/dialer_alt_over~ipad.png and /dev/null differ diff --git a/Resources/dialer_default.png b/Resources/dialer_default.png deleted file mode 100644 index 2fc61b3af..000000000 Binary files a/Resources/dialer_default.png and /dev/null differ diff --git a/Resources/dialer_over.png b/Resources/dialer_over.png deleted file mode 100644 index 7b718469f..000000000 Binary files a/Resources/dialer_over.png and /dev/null differ diff --git a/Resources/dialer_padding_left.png b/Resources/dialer_padding_left.png deleted file mode 100644 index 910daae9e..000000000 Binary files a/Resources/dialer_padding_left.png and /dev/null differ diff --git a/Resources/dialer_padding_right.png b/Resources/dialer_padding_right.png deleted file mode 100644 index 188b4e3e5..000000000 Binary files a/Resources/dialer_padding_right.png and /dev/null differ diff --git a/Resources/dialer_selected.png b/Resources/dialer_selected.png deleted file mode 100644 index 80cd520f5..000000000 Binary files a/Resources/dialer_selected.png and /dev/null differ diff --git a/Resources/en.lproj/Localizable.strings b/Resources/en.lproj/Localizable.strings index 81e470851..84e02ca9b 100644 Binary files a/Resources/en.lproj/Localizable.strings and b/Resources/en.lproj/Localizable.strings differ diff --git a/Resources/field_background.9.png b/Resources/field_background.9.png deleted file mode 100644 index c8b34cdbf..000000000 Binary files a/Resources/field_background.9.png and /dev/null differ diff --git a/Resources/field_background.9@2x.png b/Resources/field_background.9@2x.png deleted file mode 100644 index f24e08706..000000000 Binary files a/Resources/field_background.9@2x.png and /dev/null differ diff --git a/Resources/field_background.png b/Resources/field_background.png deleted file mode 100644 index 7b8cb1ed5..000000000 Binary files a/Resources/field_background.png and /dev/null differ diff --git a/Resources/form_invalid.png b/Resources/form_invalid.png deleted file mode 100644 index c174df390..000000000 Binary files a/Resources/form_invalid.png and /dev/null differ diff --git a/Resources/form_valid.png b/Resources/form_valid.png deleted file mode 100644 index f8edc012d..000000000 Binary files a/Resources/form_valid.png and /dev/null differ diff --git a/Resources/fr.lproj/Localizable.strings b/Resources/fr.lproj/Localizable.strings index 5b7ba9cfe..9f08fd7e1 100644 Binary files a/Resources/fr.lproj/Localizable.strings and b/Resources/fr.lproj/Localizable.strings differ diff --git a/Resources/hangup_default.png b/Resources/hangup_default.png deleted file mode 100644 index c84ea15b2..000000000 Binary files a/Resources/hangup_default.png and /dev/null differ diff --git a/Resources/hangup_default_landscape.png b/Resources/hangup_default_landscape.png deleted file mode 100644 index e7f49a1c6..000000000 Binary files a/Resources/hangup_default_landscape.png and /dev/null differ diff --git a/Resources/hangup_default_landscape~ipad.png b/Resources/hangup_default_landscape~ipad.png deleted file mode 100644 index 0c88f12d7..000000000 Binary files a/Resources/hangup_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/hangup_default~ipad.png b/Resources/hangup_default~ipad.png deleted file mode 100644 index 0c88f12d7..000000000 Binary files a/Resources/hangup_default~ipad.png and /dev/null differ diff --git a/Resources/hangup_over.png b/Resources/hangup_over.png deleted file mode 100644 index 2c95c5c1a..000000000 Binary files a/Resources/hangup_over.png and /dev/null differ diff --git a/Resources/hangup_over_landscape.png b/Resources/hangup_over_landscape.png deleted file mode 100644 index ffc1fb469..000000000 Binary files a/Resources/hangup_over_landscape.png and /dev/null differ diff --git a/Resources/hangup_over_landscape~ipad.png b/Resources/hangup_over_landscape~ipad.png deleted file mode 100644 index 00fd688b6..000000000 Binary files a/Resources/hangup_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/hangup_over~ipad.png b/Resources/hangup_over~ipad.png deleted file mode 100644 index 00fd688b6..000000000 Binary files a/Resources/hangup_over~ipad.png and /dev/null differ diff --git a/Resources/header_conference.png b/Resources/header_conference.png deleted file mode 100644 index 47ec0a043..000000000 Binary files a/Resources/header_conference.png and /dev/null differ diff --git a/Resources/header_incoming.png b/Resources/header_incoming.png deleted file mode 100644 index 7214ac413..000000000 Binary files a/Resources/header_incoming.png and /dev/null differ diff --git a/Resources/history_all_default.png b/Resources/history_all_default.png deleted file mode 100644 index de254cd75..000000000 Binary files a/Resources/history_all_default.png and /dev/null differ diff --git a/Resources/history_all_selected.png b/Resources/history_all_selected.png deleted file mode 100644 index c9b1b36f3..000000000 Binary files a/Resources/history_all_selected.png and /dev/null differ diff --git a/Resources/history_default.png b/Resources/history_default.png deleted file mode 100644 index 92a298d2f..000000000 Binary files a/Resources/history_default.png and /dev/null differ diff --git a/Resources/history_default_landscape~ipad.png b/Resources/history_default_landscape~ipad.png deleted file mode 100644 index df85f226d..000000000 Binary files a/Resources/history_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/history_default~ipad.png b/Resources/history_default~ipad.png deleted file mode 100644 index 7fe690c29..000000000 Binary files a/Resources/history_default~ipad.png and /dev/null differ diff --git a/Resources/history_delete_default.png b/Resources/history_delete_default.png deleted file mode 100644 index a26dd76e4..000000000 Binary files a/Resources/history_delete_default.png and /dev/null differ diff --git a/Resources/history_delete_over.png b/Resources/history_delete_over.png deleted file mode 100644 index c48a1acd9..000000000 Binary files a/Resources/history_delete_over.png and /dev/null differ diff --git a/Resources/history_details_add_default.png b/Resources/history_details_add_default.png deleted file mode 100644 index c56999232..000000000 Binary files a/Resources/history_details_add_default.png and /dev/null differ diff --git a/Resources/history_details_add_over.png b/Resources/history_details_add_over.png deleted file mode 100644 index e6a77f53d..000000000 Binary files a/Resources/history_details_add_over.png and /dev/null differ diff --git a/Resources/history_details_back_default.png b/Resources/history_details_back_default.png deleted file mode 100644 index 41088a304..000000000 Binary files a/Resources/history_details_back_default.png and /dev/null differ diff --git a/Resources/history_details_back_over.png b/Resources/history_details_back_over.png deleted file mode 100644 index 4f499782b..000000000 Binary files a/Resources/history_details_back_over.png and /dev/null differ diff --git a/Resources/history_edit_default.png b/Resources/history_edit_default.png deleted file mode 100644 index 5c425b640..000000000 Binary files a/Resources/history_edit_default.png and /dev/null differ diff --git a/Resources/history_edit_over.png b/Resources/history_edit_over.png deleted file mode 100644 index fbc14af94..000000000 Binary files a/Resources/history_edit_over.png and /dev/null differ diff --git a/Resources/history_missed_default.png b/Resources/history_missed_default.png deleted file mode 100644 index ce4e49cc7..000000000 Binary files a/Resources/history_missed_default.png and /dev/null differ diff --git a/Resources/history_missed_selected.png b/Resources/history_missed_selected.png deleted file mode 100644 index 1bfbc9234..000000000 Binary files a/Resources/history_missed_selected.png and /dev/null differ diff --git a/Resources/history_notification.png b/Resources/history_notification.png deleted file mode 100644 index 7eb396f7b..000000000 Binary files a/Resources/history_notification.png and /dev/null differ diff --git a/Resources/history_ok_default.png b/Resources/history_ok_default.png deleted file mode 100644 index 9b3e82af6..000000000 Binary files a/Resources/history_ok_default.png and /dev/null differ diff --git a/Resources/history_ok_over.png b/Resources/history_ok_over.png deleted file mode 100644 index b9d68102b..000000000 Binary files a/Resources/history_ok_over.png and /dev/null differ diff --git a/Resources/history_over.png b/Resources/history_over.png deleted file mode 100644 index 1d2ddf91c..000000000 Binary files a/Resources/history_over.png and /dev/null differ diff --git a/Resources/history_over_landscape~ipad.png b/Resources/history_over_landscape~ipad.png deleted file mode 100644 index f7a79f397..000000000 Binary files a/Resources/history_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/history_over~ipad.png b/Resources/history_over~ipad.png deleted file mode 100644 index 6a483b1f6..000000000 Binary files a/Resources/history_over~ipad.png and /dev/null differ diff --git a/Resources/history_selected.png b/Resources/history_selected.png deleted file mode 100644 index bf1a0867c..000000000 Binary files a/Resources/history_selected.png and /dev/null differ diff --git a/Resources/history_selected_landscape~ipad.png b/Resources/history_selected_landscape~ipad.png deleted file mode 100644 index d21790090..000000000 Binary files a/Resources/history_selected_landscape~ipad.png and /dev/null differ diff --git a/Resources/history_selected~ipad.png b/Resources/history_selected~ipad.png deleted file mode 100644 index 751866a9f..000000000 Binary files a/Resources/history_selected~ipad.png and /dev/null differ diff --git a/Resources/image_back_default.png b/Resources/image_back_default.png deleted file mode 100644 index 18ec0869e..000000000 Binary files a/Resources/image_back_default.png and /dev/null differ diff --git a/Resources/image_back_over.png b/Resources/image_back_over.png deleted file mode 100644 index 8f4563934..000000000 Binary files a/Resources/image_back_over.png and /dev/null differ diff --git a/Resources/images/add_field_default.png b/Resources/images/add_field_default.png new file mode 100644 index 000000000..50e4b6f72 Binary files /dev/null and b/Resources/images/add_field_default.png differ diff --git a/Resources/images/add_field_default@2x.png b/Resources/images/add_field_default@2x.png new file mode 100644 index 000000000..bcfe6dc83 Binary files /dev/null and b/Resources/images/add_field_default@2x.png differ diff --git a/Resources/images/add_field_over.png b/Resources/images/add_field_over.png new file mode 100644 index 000000000..8b8656078 Binary files /dev/null and b/Resources/images/add_field_over.png differ diff --git a/Resources/images/add_field_over@2x.png b/Resources/images/add_field_over@2x.png new file mode 100644 index 000000000..42283c20d Binary files /dev/null and b/Resources/images/add_field_over@2x.png differ diff --git a/Resources/images/avatar.png b/Resources/images/avatar.png new file mode 100644 index 000000000..6c9409881 Binary files /dev/null and b/Resources/images/avatar.png differ diff --git a/Resources/images/avatar@2x.png b/Resources/images/avatar@2x.png new file mode 100644 index 000000000..ce4e7ef5d Binary files /dev/null and b/Resources/images/avatar@2x.png differ diff --git a/Resources/images/back_default.png b/Resources/images/back_default.png new file mode 100644 index 000000000..8ea5b68d9 Binary files /dev/null and b/Resources/images/back_default.png differ diff --git a/Resources/images/back_default@2x.png b/Resources/images/back_default@2x.png new file mode 100644 index 000000000..350249b87 Binary files /dev/null and b/Resources/images/back_default@2x.png differ diff --git a/Resources/images/back_disabled.png b/Resources/images/back_disabled.png new file mode 100644 index 000000000..b01a65b2f Binary files /dev/null and b/Resources/images/back_disabled.png differ diff --git a/Resources/images/back_disabled@2x.png b/Resources/images/back_disabled@2x.png new file mode 100644 index 000000000..1ab995345 Binary files /dev/null and b/Resources/images/back_disabled@2x.png differ diff --git a/Resources/images/backspace_default.png b/Resources/images/backspace_default.png new file mode 100644 index 000000000..bb6a070fd Binary files /dev/null and b/Resources/images/backspace_default.png differ diff --git a/Resources/images/backspace_default@2x.png b/Resources/images/backspace_default@2x.png new file mode 100644 index 000000000..363187d5b Binary files /dev/null and b/Resources/images/backspace_default@2x.png differ diff --git a/Resources/images/backspace_disabled.png b/Resources/images/backspace_disabled.png new file mode 100644 index 000000000..09bfd90bd Binary files /dev/null and b/Resources/images/backspace_disabled.png differ diff --git a/Resources/images/backspace_disabled@2x.png b/Resources/images/backspace_disabled@2x.png new file mode 100644 index 000000000..577cba160 Binary files /dev/null and b/Resources/images/backspace_disabled@2x.png differ diff --git a/Resources/images/backspace_over.png b/Resources/images/backspace_over.png new file mode 100644 index 000000000..54bd8c461 Binary files /dev/null and b/Resources/images/backspace_over.png differ diff --git a/Resources/images/backspace_over@2x.png b/Resources/images/backspace_over@2x.png new file mode 100644 index 000000000..68a1ceebb Binary files /dev/null and b/Resources/images/backspace_over@2x.png differ diff --git a/Resources/images/call_add_default.png b/Resources/images/call_add_default.png new file mode 100644 index 000000000..3d7790f6a Binary files /dev/null and b/Resources/images/call_add_default.png differ diff --git a/Resources/images/call_add_default@2x.png b/Resources/images/call_add_default@2x.png new file mode 100644 index 000000000..91101a564 Binary files /dev/null and b/Resources/images/call_add_default@2x.png differ diff --git a/Resources/images/call_add_disabled.png b/Resources/images/call_add_disabled.png new file mode 100644 index 000000000..929174aeb Binary files /dev/null and b/Resources/images/call_add_disabled.png differ diff --git a/Resources/images/call_add_disabled@2x.png b/Resources/images/call_add_disabled@2x.png new file mode 100644 index 000000000..d37f931c5 Binary files /dev/null and b/Resources/images/call_add_disabled@2x.png differ diff --git a/Resources/images/call_alt_back_default.png b/Resources/images/call_alt_back_default.png new file mode 100644 index 000000000..2c31d1ca9 Binary files /dev/null and b/Resources/images/call_alt_back_default.png differ diff --git a/Resources/images/call_alt_back_default@2x.png b/Resources/images/call_alt_back_default@2x.png new file mode 100644 index 000000000..fd2318c9c Binary files /dev/null and b/Resources/images/call_alt_back_default@2x.png differ diff --git a/Resources/images/call_alt_back_disabled.png b/Resources/images/call_alt_back_disabled.png new file mode 100644 index 000000000..3ae7e6e0b Binary files /dev/null and b/Resources/images/call_alt_back_disabled.png differ diff --git a/Resources/images/call_alt_back_disabled@2x.png b/Resources/images/call_alt_back_disabled@2x.png new file mode 100644 index 000000000..ba6a10b2f Binary files /dev/null and b/Resources/images/call_alt_back_disabled@2x.png differ diff --git a/Resources/images/call_alt_start_default.png b/Resources/images/call_alt_start_default.png new file mode 100644 index 000000000..bf5a7a79e Binary files /dev/null and b/Resources/images/call_alt_start_default.png differ diff --git a/Resources/images/call_alt_start_default@2x.png b/Resources/images/call_alt_start_default@2x.png new file mode 100644 index 000000000..c6c11e33e Binary files /dev/null and b/Resources/images/call_alt_start_default@2x.png differ diff --git a/Resources/images/call_alt_start_disabled.png b/Resources/images/call_alt_start_disabled.png new file mode 100644 index 000000000..82276498d Binary files /dev/null and b/Resources/images/call_alt_start_disabled.png differ diff --git a/Resources/images/call_alt_start_disabled@2x.png b/Resources/images/call_alt_start_disabled@2x.png new file mode 100644 index 000000000..dc47a8365 Binary files /dev/null and b/Resources/images/call_alt_start_disabled@2x.png differ diff --git a/Resources/images/call_audio_start_default.png b/Resources/images/call_audio_start_default.png new file mode 100644 index 000000000..b0e330a1f Binary files /dev/null and b/Resources/images/call_audio_start_default.png differ diff --git a/Resources/images/call_audio_start_default@2x.png b/Resources/images/call_audio_start_default@2x.png new file mode 100644 index 000000000..c0480602b Binary files /dev/null and b/Resources/images/call_audio_start_default@2x.png differ diff --git a/Resources/images/call_audio_start_disabled.png b/Resources/images/call_audio_start_disabled.png new file mode 100644 index 000000000..766061c6e Binary files /dev/null and b/Resources/images/call_audio_start_disabled.png differ diff --git a/Resources/images/call_audio_start_disabled@2x.png b/Resources/images/call_audio_start_disabled@2x.png new file mode 100644 index 000000000..6745d669e Binary files /dev/null and b/Resources/images/call_audio_start_disabled@2x.png differ diff --git a/Resources/images/call_back_default.png b/Resources/images/call_back_default.png new file mode 100644 index 000000000..3dcf50187 Binary files /dev/null and b/Resources/images/call_back_default.png differ diff --git a/Resources/images/call_back_default@2x.png b/Resources/images/call_back_default@2x.png new file mode 100644 index 000000000..981317c63 Binary files /dev/null and b/Resources/images/call_back_default@2x.png differ diff --git a/Resources/images/call_back_disabled.png b/Resources/images/call_back_disabled.png new file mode 100644 index 000000000..bebdde29f Binary files /dev/null and b/Resources/images/call_back_disabled.png differ diff --git a/Resources/images/call_back_disabled@2x.png b/Resources/images/call_back_disabled@2x.png new file mode 100644 index 000000000..1b3928606 Binary files /dev/null and b/Resources/images/call_back_disabled@2x.png differ diff --git a/Resources/images/call_hangup_default.png b/Resources/images/call_hangup_default.png new file mode 100644 index 000000000..742a740fe Binary files /dev/null and b/Resources/images/call_hangup_default.png differ diff --git a/Resources/images/call_hangup_default@2x.png b/Resources/images/call_hangup_default@2x.png new file mode 100644 index 000000000..c599618c2 Binary files /dev/null and b/Resources/images/call_hangup_default@2x.png differ diff --git a/Resources/images/call_hangup_disabled.png b/Resources/images/call_hangup_disabled.png new file mode 100644 index 000000000..5a8d6b7ea Binary files /dev/null and b/Resources/images/call_hangup_disabled.png differ diff --git a/Resources/images/call_hangup_disabled@2x.png b/Resources/images/call_hangup_disabled@2x.png new file mode 100644 index 000000000..b9bf1224b Binary files /dev/null and b/Resources/images/call_hangup_disabled@2x.png differ diff --git a/Resources/images/call_incoming.png b/Resources/images/call_incoming.png new file mode 100644 index 000000000..c5d01c2b1 Binary files /dev/null and b/Resources/images/call_incoming.png differ diff --git a/Resources/images/call_incoming@2x.png b/Resources/images/call_incoming@2x.png new file mode 100644 index 000000000..4cb6dfd87 Binary files /dev/null and b/Resources/images/call_incoming@2x.png differ diff --git a/Resources/images/call_missed.png b/Resources/images/call_missed.png new file mode 100644 index 000000000..c3306f173 Binary files /dev/null and b/Resources/images/call_missed.png differ diff --git a/Resources/images/call_missed@2x.png b/Resources/images/call_missed@2x.png new file mode 100644 index 000000000..5faeae4b4 Binary files /dev/null and b/Resources/images/call_missed@2x.png differ diff --git a/Resources/images/call_outgoing.png b/Resources/images/call_outgoing.png new file mode 100644 index 000000000..3853b174a Binary files /dev/null and b/Resources/images/call_outgoing.png differ diff --git a/Resources/images/call_outgoing@2x.png b/Resources/images/call_outgoing@2x.png new file mode 100644 index 000000000..d734e7975 Binary files /dev/null and b/Resources/images/call_outgoing@2x.png differ diff --git a/Resources/images/call_quality_indicator_0.png b/Resources/images/call_quality_indicator_0.png new file mode 100644 index 000000000..8de54e2dd Binary files /dev/null and b/Resources/images/call_quality_indicator_0.png differ diff --git a/Resources/images/call_quality_indicator_0@2x.png b/Resources/images/call_quality_indicator_0@2x.png new file mode 100644 index 000000000..5e21e5099 Binary files /dev/null and b/Resources/images/call_quality_indicator_0@2x.png differ diff --git a/Resources/images/call_quality_indicator_1.png b/Resources/images/call_quality_indicator_1.png new file mode 100644 index 000000000..882df7128 Binary files /dev/null and b/Resources/images/call_quality_indicator_1.png differ diff --git a/Resources/images/call_quality_indicator_1@2x.png b/Resources/images/call_quality_indicator_1@2x.png new file mode 100644 index 000000000..779ead493 Binary files /dev/null and b/Resources/images/call_quality_indicator_1@2x.png differ diff --git a/Resources/images/call_quality_indicator_2.png b/Resources/images/call_quality_indicator_2.png new file mode 100644 index 000000000..b9bc73cfd Binary files /dev/null and b/Resources/images/call_quality_indicator_2.png differ diff --git a/Resources/images/call_quality_indicator_2@2x.png b/Resources/images/call_quality_indicator_2@2x.png new file mode 100644 index 000000000..782e0fa1a Binary files /dev/null and b/Resources/images/call_quality_indicator_2@2x.png differ diff --git a/Resources/images/call_quality_indicator_3.png b/Resources/images/call_quality_indicator_3.png new file mode 100644 index 000000000..2c9e0dc62 Binary files /dev/null and b/Resources/images/call_quality_indicator_3.png differ diff --git a/Resources/images/call_quality_indicator_3@2x.png b/Resources/images/call_quality_indicator_3@2x.png new file mode 100644 index 000000000..f7c5728c6 Binary files /dev/null and b/Resources/images/call_quality_indicator_3@2x.png differ diff --git a/Resources/images/call_quality_indicator_4.png b/Resources/images/call_quality_indicator_4.png new file mode 100644 index 000000000..8de54e2dd Binary files /dev/null and b/Resources/images/call_quality_indicator_4.png differ diff --git a/Resources/images/call_quality_indicator_4@2x.png b/Resources/images/call_quality_indicator_4@2x.png new file mode 100644 index 000000000..5e21e5099 Binary files /dev/null and b/Resources/images/call_quality_indicator_4@2x.png differ diff --git a/Resources/images/call_start_body_default.png b/Resources/images/call_start_body_default.png new file mode 100644 index 000000000..afa4aefb3 Binary files /dev/null and b/Resources/images/call_start_body_default.png differ diff --git a/Resources/images/call_start_body_default@2x.png b/Resources/images/call_start_body_default@2x.png new file mode 100644 index 000000000..c9a2e742f Binary files /dev/null and b/Resources/images/call_start_body_default@2x.png differ diff --git a/Resources/images/call_start_body_disabled.png b/Resources/images/call_start_body_disabled.png new file mode 100644 index 000000000..a86f8b119 Binary files /dev/null and b/Resources/images/call_start_body_disabled.png differ diff --git a/Resources/images/call_start_body_disabled@2x.png b/Resources/images/call_start_body_disabled@2x.png new file mode 100644 index 000000000..4c3cfe693 Binary files /dev/null and b/Resources/images/call_start_body_disabled@2x.png differ diff --git a/Resources/images/call_start_body_over.png b/Resources/images/call_start_body_over.png new file mode 100644 index 000000000..4d8ce6d0e Binary files /dev/null and b/Resources/images/call_start_body_over.png differ diff --git a/Resources/images/call_start_body_over@2x.png b/Resources/images/call_start_body_over@2x.png new file mode 100644 index 000000000..3b640bab2 Binary files /dev/null and b/Resources/images/call_start_body_over@2x.png differ diff --git a/Resources/images/call_status_incoming.png b/Resources/images/call_status_incoming.png new file mode 100644 index 000000000..8db060a68 Binary files /dev/null and b/Resources/images/call_status_incoming.png differ diff --git a/Resources/images/call_status_incoming@2x.png b/Resources/images/call_status_incoming@2x.png new file mode 100644 index 000000000..6cb67ba30 Binary files /dev/null and b/Resources/images/call_status_incoming@2x.png differ diff --git a/Resources/images/call_status_missed.png b/Resources/images/call_status_missed.png new file mode 100644 index 000000000..2ad8b36fa Binary files /dev/null and b/Resources/images/call_status_missed.png differ diff --git a/Resources/images/call_status_missed@2x.png b/Resources/images/call_status_missed@2x.png new file mode 100644 index 000000000..12c2123f9 Binary files /dev/null and b/Resources/images/call_status_missed@2x.png differ diff --git a/Resources/images/call_status_outgoing.png b/Resources/images/call_status_outgoing.png new file mode 100644 index 000000000..fd9e19a95 Binary files /dev/null and b/Resources/images/call_status_outgoing.png differ diff --git a/Resources/images/call_status_outgoing@2x.png b/Resources/images/call_status_outgoing@2x.png new file mode 100644 index 000000000..337875f72 Binary files /dev/null and b/Resources/images/call_status_outgoing@2x.png differ diff --git a/Resources/images/call_transfer_default.png b/Resources/images/call_transfer_default.png new file mode 100644 index 000000000..79aaad67a Binary files /dev/null and b/Resources/images/call_transfer_default.png differ diff --git a/Resources/images/call_transfer_default@2x.png b/Resources/images/call_transfer_default@2x.png new file mode 100644 index 000000000..43c47e864 Binary files /dev/null and b/Resources/images/call_transfer_default@2x.png differ diff --git a/Resources/images/call_transfer_disabled.png b/Resources/images/call_transfer_disabled.png new file mode 100644 index 000000000..fbf51e1bb Binary files /dev/null and b/Resources/images/call_transfer_disabled.png differ diff --git a/Resources/images/call_transfer_disabled@2x.png b/Resources/images/call_transfer_disabled@2x.png new file mode 100644 index 000000000..562ca6a85 Binary files /dev/null and b/Resources/images/call_transfer_disabled@2x.png differ diff --git a/Resources/images/call_video_start_default.png b/Resources/images/call_video_start_default.png new file mode 100644 index 000000000..00b9d1862 Binary files /dev/null and b/Resources/images/call_video_start_default.png differ diff --git a/Resources/images/call_video_start_default@2x.png b/Resources/images/call_video_start_default@2x.png new file mode 100644 index 000000000..efa229d6b Binary files /dev/null and b/Resources/images/call_video_start_default@2x.png differ diff --git a/Resources/images/call_video_start_disabled.png b/Resources/images/call_video_start_disabled.png new file mode 100644 index 000000000..cb0f07972 Binary files /dev/null and b/Resources/images/call_video_start_disabled.png differ diff --git a/Resources/images/call_video_start_disabled@2x.png b/Resources/images/call_video_start_disabled@2x.png new file mode 100644 index 000000000..53b4040b8 Binary files /dev/null and b/Resources/images/call_video_start_disabled@2x.png differ diff --git a/Resources/images/camera_default.png b/Resources/images/camera_default.png new file mode 100644 index 000000000..322d818f8 Binary files /dev/null and b/Resources/images/camera_default.png differ diff --git a/Resources/images/camera_default@2x.png b/Resources/images/camera_default@2x.png new file mode 100644 index 000000000..a4190c8ad Binary files /dev/null and b/Resources/images/camera_default@2x.png differ diff --git a/Resources/images/camera_disabled.png b/Resources/images/camera_disabled.png new file mode 100644 index 000000000..ee66d14b5 Binary files /dev/null and b/Resources/images/camera_disabled.png differ diff --git a/Resources/images/camera_disabled@2x.png b/Resources/images/camera_disabled@2x.png new file mode 100644 index 000000000..3f48071b7 Binary files /dev/null and b/Resources/images/camera_disabled@2x.png differ diff --git a/Resources/images/camera_selected.png b/Resources/images/camera_selected.png new file mode 100644 index 000000000..7620a6db8 Binary files /dev/null and b/Resources/images/camera_selected.png differ diff --git a/Resources/images/camera_selected@2x.png b/Resources/images/camera_selected@2x.png new file mode 100644 index 000000000..610ad8634 Binary files /dev/null and b/Resources/images/camera_selected@2x.png differ diff --git a/Resources/images/camera_switch_default.png b/Resources/images/camera_switch_default.png new file mode 100644 index 000000000..488800dc2 Binary files /dev/null and b/Resources/images/camera_switch_default.png differ diff --git a/Resources/images/camera_switch_default@2x.png b/Resources/images/camera_switch_default@2x.png new file mode 100644 index 000000000..93a44bc18 Binary files /dev/null and b/Resources/images/camera_switch_default@2x.png differ diff --git a/Resources/images/camera_switch_disabled.png b/Resources/images/camera_switch_disabled.png new file mode 100644 index 000000000..c1f11c235 Binary files /dev/null and b/Resources/images/camera_switch_disabled.png differ diff --git a/Resources/images/camera_switch_disabled@2x.png b/Resources/images/camera_switch_disabled@2x.png new file mode 100644 index 000000000..a0029e1b5 Binary files /dev/null and b/Resources/images/camera_switch_disabled@2x.png differ diff --git a/Resources/images/camera_switch_over.png b/Resources/images/camera_switch_over.png new file mode 100644 index 000000000..63174b4cb Binary files /dev/null and b/Resources/images/camera_switch_over.png differ diff --git a/Resources/images/camera_switch_over@2x.png b/Resources/images/camera_switch_over@2x.png new file mode 100644 index 000000000..ad3dbae3f Binary files /dev/null and b/Resources/images/camera_switch_over@2x.png differ diff --git a/Resources/images/cancel_edit_default.png b/Resources/images/cancel_edit_default.png new file mode 100644 index 000000000..5f38f51ba Binary files /dev/null and b/Resources/images/cancel_edit_default.png differ diff --git a/Resources/images/cancel_edit_default@2x.png b/Resources/images/cancel_edit_default@2x.png new file mode 100644 index 000000000..b937b0338 Binary files /dev/null and b/Resources/images/cancel_edit_default@2x.png differ diff --git a/Resources/images/cancel_edit_disabled.png b/Resources/images/cancel_edit_disabled.png new file mode 100644 index 000000000..6a64e5200 Binary files /dev/null and b/Resources/images/cancel_edit_disabled.png differ diff --git a/Resources/images/cancel_edit_disabled@2x.png b/Resources/images/cancel_edit_disabled@2x.png new file mode 100644 index 000000000..21782e3aa Binary files /dev/null and b/Resources/images/cancel_edit_disabled@2x.png differ diff --git a/Resources/images/chat_add_default.png b/Resources/images/chat_add_default.png new file mode 100644 index 000000000..1c0fccebf Binary files /dev/null and b/Resources/images/chat_add_default.png differ diff --git a/Resources/images/chat_add_default@2x.png b/Resources/images/chat_add_default@2x.png new file mode 100644 index 000000000..fd7c444c7 Binary files /dev/null and b/Resources/images/chat_add_default@2x.png differ diff --git a/Resources/images/chat_add_disabled.png b/Resources/images/chat_add_disabled.png new file mode 100644 index 000000000..20e95fad2 Binary files /dev/null and b/Resources/images/chat_add_disabled.png differ diff --git a/Resources/images/chat_add_disabled@2x.png b/Resources/images/chat_add_disabled@2x.png new file mode 100644 index 000000000..7a275aa3d Binary files /dev/null and b/Resources/images/chat_add_disabled@2x.png differ diff --git a/Resources/images/chat_attachment_default.png b/Resources/images/chat_attachment_default.png new file mode 100644 index 000000000..d7d0ff0c1 Binary files /dev/null and b/Resources/images/chat_attachment_default.png differ diff --git a/Resources/images/chat_attachment_default@2x.png b/Resources/images/chat_attachment_default@2x.png new file mode 100644 index 000000000..8d70ff810 Binary files /dev/null and b/Resources/images/chat_attachment_default@2x.png differ diff --git a/Resources/images/chat_attachment_disabled.png b/Resources/images/chat_attachment_disabled.png new file mode 100644 index 000000000..c6ad25af2 Binary files /dev/null and b/Resources/images/chat_attachment_disabled.png differ diff --git a/Resources/images/chat_attachment_disabled@2x.png b/Resources/images/chat_attachment_disabled@2x.png new file mode 100644 index 000000000..eafbe0956 Binary files /dev/null and b/Resources/images/chat_attachment_disabled@2x.png differ diff --git a/Resources/images/chat_attachment_over.png b/Resources/images/chat_attachment_over.png new file mode 100644 index 000000000..2a83012f6 Binary files /dev/null and b/Resources/images/chat_attachment_over.png differ diff --git a/Resources/images/chat_attachment_over@2x.png b/Resources/images/chat_attachment_over@2x.png new file mode 100644 index 000000000..696b24f06 Binary files /dev/null and b/Resources/images/chat_attachment_over@2x.png differ diff --git a/Resources/images/chat_message_not_delivered.png b/Resources/images/chat_message_not_delivered.png new file mode 100644 index 000000000..02becbccb Binary files /dev/null and b/Resources/images/chat_message_not_delivered.png differ diff --git a/Resources/images/chat_message_not_delivered@2x.png b/Resources/images/chat_message_not_delivered@2x.png new file mode 100644 index 000000000..85e4c6c14 Binary files /dev/null and b/Resources/images/chat_message_not_delivered@2x.png differ diff --git a/Resources/images/chat_send_default.png b/Resources/images/chat_send_default.png new file mode 100644 index 000000000..07f3b7b3a Binary files /dev/null and b/Resources/images/chat_send_default.png differ diff --git a/Resources/images/chat_send_default@2x.png b/Resources/images/chat_send_default@2x.png new file mode 100644 index 000000000..a5d659beb Binary files /dev/null and b/Resources/images/chat_send_default@2x.png differ diff --git a/Resources/images/chat_send_disabled.png b/Resources/images/chat_send_disabled.png new file mode 100644 index 000000000..9efc5564f Binary files /dev/null and b/Resources/images/chat_send_disabled.png differ diff --git a/Resources/images/chat_send_disabled@2x.png b/Resources/images/chat_send_disabled@2x.png new file mode 100644 index 000000000..20ec4fda5 Binary files /dev/null and b/Resources/images/chat_send_disabled@2x.png differ diff --git a/Resources/images/chat_send_over.png b/Resources/images/chat_send_over.png new file mode 100644 index 000000000..af9e1b85f Binary files /dev/null and b/Resources/images/chat_send_over.png differ diff --git a/Resources/images/chat_send_over@2x.png b/Resources/images/chat_send_over@2x.png new file mode 100644 index 000000000..67b35d842 Binary files /dev/null and b/Resources/images/chat_send_over@2x.png differ diff --git a/Resources/images/chat_start_body_default.png b/Resources/images/chat_start_body_default.png new file mode 100644 index 000000000..522010fb3 Binary files /dev/null and b/Resources/images/chat_start_body_default.png differ diff --git a/Resources/images/chat_start_body_default@2x.png b/Resources/images/chat_start_body_default@2x.png new file mode 100644 index 000000000..36e772805 Binary files /dev/null and b/Resources/images/chat_start_body_default@2x.png differ diff --git a/Resources/images/chat_start_body_disabled.png b/Resources/images/chat_start_body_disabled.png new file mode 100644 index 000000000..09c186379 Binary files /dev/null and b/Resources/images/chat_start_body_disabled.png differ diff --git a/Resources/images/chat_start_body_disabled@2x.png b/Resources/images/chat_start_body_disabled@2x.png new file mode 100644 index 000000000..26d669bbe Binary files /dev/null and b/Resources/images/chat_start_body_disabled@2x.png differ diff --git a/Resources/images/chat_start_body_over.png b/Resources/images/chat_start_body_over.png new file mode 100644 index 000000000..c66066d5f Binary files /dev/null and b/Resources/images/chat_start_body_over.png differ diff --git a/Resources/images/chat_start_body_over@2x.png b/Resources/images/chat_start_body_over@2x.png new file mode 100644 index 000000000..f1d48d10d Binary files /dev/null and b/Resources/images/chat_start_body_over@2x.png differ diff --git a/Resources/images/checkbox_checked.png b/Resources/images/checkbox_checked.png new file mode 100644 index 000000000..42716f5bd Binary files /dev/null and b/Resources/images/checkbox_checked.png differ diff --git a/Resources/images/checkbox_checked@2x.png b/Resources/images/checkbox_checked@2x.png new file mode 100644 index 000000000..1e13a875a Binary files /dev/null and b/Resources/images/checkbox_checked@2x.png differ diff --git a/Resources/images/checkbox_unchecked.png b/Resources/images/checkbox_unchecked.png new file mode 100644 index 000000000..8615429a7 Binary files /dev/null and b/Resources/images/checkbox_unchecked.png differ diff --git a/Resources/images/checkbox_unchecked@2x.png b/Resources/images/checkbox_unchecked@2x.png new file mode 100644 index 000000000..3248e8122 Binary files /dev/null and b/Resources/images/checkbox_unchecked@2x.png differ diff --git a/Resources/images/color_A.png b/Resources/images/color_A.png new file mode 100644 index 000000000..cd49d4b5e Binary files /dev/null and b/Resources/images/color_A.png differ diff --git a/Resources/images/color_C.png b/Resources/images/color_C.png new file mode 100644 index 000000000..acb5708cf Binary files /dev/null and b/Resources/images/color_C.png differ diff --git a/Resources/images/color_D.png b/Resources/images/color_D.png new file mode 100644 index 000000000..589c5b981 Binary files /dev/null and b/Resources/images/color_D.png differ diff --git a/Resources/images/color_E.png b/Resources/images/color_E.png new file mode 100644 index 000000000..34ad7df2c Binary files /dev/null and b/Resources/images/color_E.png differ diff --git a/Resources/images/color_F.png b/Resources/images/color_F.png new file mode 100644 index 000000000..76db80c3b Binary files /dev/null and b/Resources/images/color_F.png differ diff --git a/Resources/images/color_G.png b/Resources/images/color_G.png new file mode 100644 index 000000000..2c608140c Binary files /dev/null and b/Resources/images/color_G.png differ diff --git a/Resources/images/color_H.png b/Resources/images/color_H.png new file mode 100644 index 000000000..60f3a7459 Binary files /dev/null and b/Resources/images/color_H.png differ diff --git a/Resources/images/color_I.png b/Resources/images/color_I.png new file mode 100644 index 000000000..1859a8bdb Binary files /dev/null and b/Resources/images/color_I.png differ diff --git a/Resources/images/color_L.png b/Resources/images/color_L.png new file mode 100644 index 000000000..e0f593c7b Binary files /dev/null and b/Resources/images/color_L.png differ diff --git a/Resources/images/color_M.png b/Resources/images/color_M.png new file mode 100644 index 000000000..709a8e917 Binary files /dev/null and b/Resources/images/color_M.png differ diff --git a/Resources/images/conference_exit_default.png b/Resources/images/conference_exit_default.png new file mode 100644 index 000000000..825a7c479 Binary files /dev/null and b/Resources/images/conference_exit_default.png differ diff --git a/Resources/images/conference_exit_default@2x.png b/Resources/images/conference_exit_default@2x.png new file mode 100644 index 000000000..cb199863d Binary files /dev/null and b/Resources/images/conference_exit_default@2x.png differ diff --git a/Resources/images/conference_exit_over.png b/Resources/images/conference_exit_over.png new file mode 100644 index 000000000..356a67e6d Binary files /dev/null and b/Resources/images/conference_exit_over.png differ diff --git a/Resources/images/conference_exit_over@2x.png b/Resources/images/conference_exit_over@2x.png new file mode 100644 index 000000000..b2b4d2b89 Binary files /dev/null and b/Resources/images/conference_exit_over@2x.png differ diff --git a/Resources/images/contact_add_default.png b/Resources/images/contact_add_default.png new file mode 100644 index 000000000..d4c24a48e Binary files /dev/null and b/Resources/images/contact_add_default.png differ diff --git a/Resources/images/contact_add_default@2x.png b/Resources/images/contact_add_default@2x.png new file mode 100644 index 000000000..10a708034 Binary files /dev/null and b/Resources/images/contact_add_default@2x.png differ diff --git a/Resources/images/contact_add_disabled.png b/Resources/images/contact_add_disabled.png new file mode 100644 index 000000000..6c2b5c47f Binary files /dev/null and b/Resources/images/contact_add_disabled.png differ diff --git a/Resources/images/contact_add_disabled@2x.png b/Resources/images/contact_add_disabled@2x.png new file mode 100644 index 000000000..fcf75ba20 Binary files /dev/null and b/Resources/images/contact_add_disabled@2x.png differ diff --git a/Resources/images/contacts_all_default.png b/Resources/images/contacts_all_default.png new file mode 100644 index 000000000..2783f8ae7 Binary files /dev/null and b/Resources/images/contacts_all_default.png differ diff --git a/Resources/images/contacts_all_default@2x.png b/Resources/images/contacts_all_default@2x.png new file mode 100644 index 000000000..ce084e60d Binary files /dev/null and b/Resources/images/contacts_all_default@2x.png differ diff --git a/Resources/images/contacts_all_disabled.png b/Resources/images/contacts_all_disabled.png new file mode 100644 index 000000000..365de44b8 Binary files /dev/null and b/Resources/images/contacts_all_disabled.png differ diff --git a/Resources/images/contacts_all_disabled@2x.png b/Resources/images/contacts_all_disabled@2x.png new file mode 100644 index 000000000..924cc7d57 Binary files /dev/null and b/Resources/images/contacts_all_disabled@2x.png differ diff --git a/Resources/images/contacts_all_selected.png b/Resources/images/contacts_all_selected.png new file mode 100644 index 000000000..2620c9f45 Binary files /dev/null and b/Resources/images/contacts_all_selected.png differ diff --git a/Resources/images/contacts_all_selected@2x.png b/Resources/images/contacts_all_selected@2x.png new file mode 100644 index 000000000..998386d18 Binary files /dev/null and b/Resources/images/contacts_all_selected@2x.png differ diff --git a/Resources/images/contacts_sip_default.png b/Resources/images/contacts_sip_default.png new file mode 100644 index 000000000..0efaa3f2a Binary files /dev/null and b/Resources/images/contacts_sip_default.png differ diff --git a/Resources/images/contacts_sip_default@2x.png b/Resources/images/contacts_sip_default@2x.png new file mode 100644 index 000000000..8b370d73f Binary files /dev/null and b/Resources/images/contacts_sip_default@2x.png differ diff --git a/Resources/images/contacts_sip_disabled.png b/Resources/images/contacts_sip_disabled.png new file mode 100644 index 000000000..cd515faa1 Binary files /dev/null and b/Resources/images/contacts_sip_disabled.png differ diff --git a/Resources/images/contacts_sip_disabled@2x.png b/Resources/images/contacts_sip_disabled@2x.png new file mode 100644 index 000000000..81465e378 Binary files /dev/null and b/Resources/images/contacts_sip_disabled@2x.png differ diff --git a/Resources/images/contacts_sip_selected.png b/Resources/images/contacts_sip_selected.png new file mode 100644 index 000000000..95bc49047 Binary files /dev/null and b/Resources/images/contacts_sip_selected.png differ diff --git a/Resources/images/contacts_sip_selected@2x.png b/Resources/images/contacts_sip_selected@2x.png new file mode 100644 index 000000000..625924411 Binary files /dev/null and b/Resources/images/contacts_sip_selected@2x.png differ diff --git a/Resources/images/delete_default.png b/Resources/images/delete_default.png new file mode 100644 index 000000000..0263f17cc Binary files /dev/null and b/Resources/images/delete_default.png differ diff --git a/Resources/images/delete_default@2x.png b/Resources/images/delete_default@2x.png new file mode 100644 index 000000000..2859f5e33 Binary files /dev/null and b/Resources/images/delete_default@2x.png differ diff --git a/Resources/images/delete_disabled.png b/Resources/images/delete_disabled.png new file mode 100644 index 000000000..f2f12cdc6 Binary files /dev/null and b/Resources/images/delete_disabled.png differ diff --git a/Resources/images/delete_disabled@2x.png b/Resources/images/delete_disabled@2x.png new file mode 100644 index 000000000..d1e8bedb5 Binary files /dev/null and b/Resources/images/delete_disabled@2x.png differ diff --git a/Resources/images/delete_field_default.png b/Resources/images/delete_field_default.png new file mode 100644 index 000000000..fb16c0d97 Binary files /dev/null and b/Resources/images/delete_field_default.png differ diff --git a/Resources/images/delete_field_default@2x.png b/Resources/images/delete_field_default@2x.png new file mode 100644 index 000000000..1e517887d Binary files /dev/null and b/Resources/images/delete_field_default@2x.png differ diff --git a/Resources/images/delete_field_over.png b/Resources/images/delete_field_over.png new file mode 100644 index 000000000..f6f874edf Binary files /dev/null and b/Resources/images/delete_field_over.png differ diff --git a/Resources/images/delete_field_over@2x.png b/Resources/images/delete_field_over@2x.png new file mode 100644 index 000000000..4c6f32478 Binary files /dev/null and b/Resources/images/delete_field_over@2x.png differ diff --git a/Resources/images/deselect_all.png b/Resources/images/deselect_all.png new file mode 100644 index 000000000..9b44c48ed Binary files /dev/null and b/Resources/images/deselect_all.png differ diff --git a/Resources/images/deselect_all@2x.png b/Resources/images/deselect_all@2x.png new file mode 100644 index 000000000..2b8c3cf79 Binary files /dev/null and b/Resources/images/deselect_all@2x.png differ diff --git a/Resources/images/dialer_alt_back.png b/Resources/images/dialer_alt_back.png new file mode 100644 index 000000000..8dc8b29a4 Binary files /dev/null and b/Resources/images/dialer_alt_back.png differ diff --git a/Resources/images/dialer_alt_back@2x.png b/Resources/images/dialer_alt_back@2x.png new file mode 100644 index 000000000..1731f6fd2 Binary files /dev/null and b/Resources/images/dialer_alt_back@2x.png differ diff --git a/Resources/images/dialer_back_default.png b/Resources/images/dialer_back_default.png new file mode 100644 index 000000000..0a5378ff0 Binary files /dev/null and b/Resources/images/dialer_back_default.png differ diff --git a/Resources/images/dialer_back_default@2x.png b/Resources/images/dialer_back_default@2x.png new file mode 100644 index 000000000..d593d186f Binary files /dev/null and b/Resources/images/dialer_back_default@2x.png differ diff --git a/Resources/images/dialer_back_disabled.png b/Resources/images/dialer_back_disabled.png new file mode 100644 index 000000000..650c950e4 Binary files /dev/null and b/Resources/images/dialer_back_disabled.png differ diff --git a/Resources/images/dialer_back_disabled@2x.png b/Resources/images/dialer_back_disabled@2x.png new file mode 100644 index 000000000..d8a8f2aba Binary files /dev/null and b/Resources/images/dialer_back_disabled@2x.png differ diff --git a/Resources/images/dialer_background.png b/Resources/images/dialer_background.png new file mode 100644 index 000000000..053ab339d Binary files /dev/null and b/Resources/images/dialer_background.png differ diff --git a/Resources/images/dialer_background@2x.png b/Resources/images/dialer_background@2x.png new file mode 100644 index 000000000..425d31aa4 Binary files /dev/null and b/Resources/images/dialer_background@2x.png differ diff --git a/Resources/images/edit_default.png b/Resources/images/edit_default.png new file mode 100644 index 000000000..e55a7bc37 Binary files /dev/null and b/Resources/images/edit_default.png differ diff --git a/Resources/images/edit_default@2x.png b/Resources/images/edit_default@2x.png new file mode 100644 index 000000000..5fe831d26 Binary files /dev/null and b/Resources/images/edit_default@2x.png differ diff --git a/Resources/images/edit_disabled.png b/Resources/images/edit_disabled.png new file mode 100644 index 000000000..c14a06b5b Binary files /dev/null and b/Resources/images/edit_disabled.png differ diff --git a/Resources/images/edit_disabled@2x.png b/Resources/images/edit_disabled@2x.png new file mode 100644 index 000000000..af6f5930e Binary files /dev/null and b/Resources/images/edit_disabled@2x.png differ diff --git a/Resources/images/edit_list_default.png b/Resources/images/edit_list_default.png new file mode 100644 index 000000000..16d2f0132 Binary files /dev/null and b/Resources/images/edit_list_default.png differ diff --git a/Resources/images/edit_list_default@2x.png b/Resources/images/edit_list_default@2x.png new file mode 100644 index 000000000..cfb65c39e Binary files /dev/null and b/Resources/images/edit_list_default@2x.png differ diff --git a/Resources/images/edit_list_disabled.png b/Resources/images/edit_list_disabled.png new file mode 100644 index 000000000..80c3ce414 Binary files /dev/null and b/Resources/images/edit_list_disabled.png differ diff --git a/Resources/images/edit_list_disabled@2x.png b/Resources/images/edit_list_disabled@2x.png new file mode 100644 index 000000000..28fbc02ba Binary files /dev/null and b/Resources/images/edit_list_disabled@2x.png differ diff --git a/Resources/images/footer_chat_default.png b/Resources/images/footer_chat_default.png new file mode 100644 index 000000000..4e0d5286b Binary files /dev/null and b/Resources/images/footer_chat_default.png differ diff --git a/Resources/images/footer_chat_default@2x.png b/Resources/images/footer_chat_default@2x.png new file mode 100644 index 000000000..9f688ed83 Binary files /dev/null and b/Resources/images/footer_chat_default@2x.png differ diff --git a/Resources/images/footer_chat_disabled.png b/Resources/images/footer_chat_disabled.png new file mode 100644 index 000000000..a31687432 Binary files /dev/null and b/Resources/images/footer_chat_disabled.png differ diff --git a/Resources/images/footer_chat_disabled@2x.png b/Resources/images/footer_chat_disabled@2x.png new file mode 100644 index 000000000..8ef385c95 Binary files /dev/null and b/Resources/images/footer_chat_disabled@2x.png differ diff --git a/Resources/images/footer_contacts_default.png b/Resources/images/footer_contacts_default.png new file mode 100644 index 000000000..a74119719 Binary files /dev/null and b/Resources/images/footer_contacts_default.png differ diff --git a/Resources/images/footer_contacts_default@2x.png b/Resources/images/footer_contacts_default@2x.png new file mode 100644 index 000000000..2ad0d4c33 Binary files /dev/null and b/Resources/images/footer_contacts_default@2x.png differ diff --git a/Resources/images/footer_contacts_disabled.png b/Resources/images/footer_contacts_disabled.png new file mode 100644 index 000000000..4cf83f330 Binary files /dev/null and b/Resources/images/footer_contacts_disabled.png differ diff --git a/Resources/images/footer_contacts_disabled@2x.png b/Resources/images/footer_contacts_disabled@2x.png new file mode 100644 index 000000000..1680b9da7 Binary files /dev/null and b/Resources/images/footer_contacts_disabled@2x.png differ diff --git a/Resources/images/footer_dialer_default.png b/Resources/images/footer_dialer_default.png new file mode 100644 index 000000000..77f32be59 Binary files /dev/null and b/Resources/images/footer_dialer_default.png differ diff --git a/Resources/images/footer_dialer_default@2x.png b/Resources/images/footer_dialer_default@2x.png new file mode 100644 index 000000000..04425a2f7 Binary files /dev/null and b/Resources/images/footer_dialer_default@2x.png differ diff --git a/Resources/images/footer_dialer_disabled.png b/Resources/images/footer_dialer_disabled.png new file mode 100644 index 000000000..aef564671 Binary files /dev/null and b/Resources/images/footer_dialer_disabled.png differ diff --git a/Resources/images/footer_dialer_disabled@2x.png b/Resources/images/footer_dialer_disabled@2x.png new file mode 100644 index 000000000..7e467ef92 Binary files /dev/null and b/Resources/images/footer_dialer_disabled@2x.png differ diff --git a/Resources/images/footer_history_default.png b/Resources/images/footer_history_default.png new file mode 100644 index 000000000..9da3469a7 Binary files /dev/null and b/Resources/images/footer_history_default.png differ diff --git a/Resources/images/footer_history_default@2x.png b/Resources/images/footer_history_default@2x.png new file mode 100644 index 000000000..9d7d954b6 Binary files /dev/null and b/Resources/images/footer_history_default@2x.png differ diff --git a/Resources/images/footer_history_disabled.png b/Resources/images/footer_history_disabled.png new file mode 100644 index 000000000..5adb7ce78 Binary files /dev/null and b/Resources/images/footer_history_disabled.png differ diff --git a/Resources/images/footer_history_disabled@2x.png b/Resources/images/footer_history_disabled@2x.png new file mode 100644 index 000000000..dce58b1fb Binary files /dev/null and b/Resources/images/footer_history_disabled@2x.png differ diff --git a/Resources/images/history_all_default.png b/Resources/images/history_all_default.png new file mode 100644 index 000000000..16c76b995 Binary files /dev/null and b/Resources/images/history_all_default.png differ diff --git a/Resources/images/history_all_default@2x.png b/Resources/images/history_all_default@2x.png new file mode 100644 index 000000000..7459878f9 Binary files /dev/null and b/Resources/images/history_all_default@2x.png differ diff --git a/Resources/images/history_all_disabled.png b/Resources/images/history_all_disabled.png new file mode 100644 index 000000000..cef8e42af Binary files /dev/null and b/Resources/images/history_all_disabled.png differ diff --git a/Resources/images/history_all_disabled@2x.png b/Resources/images/history_all_disabled@2x.png new file mode 100644 index 000000000..8d3e3934e Binary files /dev/null and b/Resources/images/history_all_disabled@2x.png differ diff --git a/Resources/images/history_all_selected.png b/Resources/images/history_all_selected.png new file mode 100644 index 000000000..8a9abd3e8 Binary files /dev/null and b/Resources/images/history_all_selected.png differ diff --git a/Resources/images/history_all_selected@2x.png b/Resources/images/history_all_selected@2x.png new file mode 100644 index 000000000..5a819e94e Binary files /dev/null and b/Resources/images/history_all_selected@2x.png differ diff --git a/Resources/images/history_chat_indicator.png b/Resources/images/history_chat_indicator.png new file mode 100644 index 000000000..7097ddc9a Binary files /dev/null and b/Resources/images/history_chat_indicator.png differ diff --git a/Resources/images/history_chat_indicator@2x.png b/Resources/images/history_chat_indicator@2x.png new file mode 100644 index 000000000..d261a26ee Binary files /dev/null and b/Resources/images/history_chat_indicator@2x.png differ diff --git a/Resources/images/history_missed_default.png b/Resources/images/history_missed_default.png new file mode 100644 index 000000000..c624d422b Binary files /dev/null and b/Resources/images/history_missed_default.png differ diff --git a/Resources/images/history_missed_default@2x.png b/Resources/images/history_missed_default@2x.png new file mode 100644 index 000000000..46bdd7cb4 Binary files /dev/null and b/Resources/images/history_missed_default@2x.png differ diff --git a/Resources/images/history_missed_disabled.png b/Resources/images/history_missed_disabled.png new file mode 100644 index 000000000..dd07a5da2 Binary files /dev/null and b/Resources/images/history_missed_disabled.png differ diff --git a/Resources/images/history_missed_disabled@2x.png b/Resources/images/history_missed_disabled@2x.png new file mode 100644 index 000000000..e013b76e8 Binary files /dev/null and b/Resources/images/history_missed_disabled@2x.png differ diff --git a/Resources/images/history_missed_selected.png b/Resources/images/history_missed_selected.png new file mode 100644 index 000000000..df77bb434 Binary files /dev/null and b/Resources/images/history_missed_selected.png differ diff --git a/Resources/images/history_missed_selected@2x.png b/Resources/images/history_missed_selected@2x.png new file mode 100644 index 000000000..9bc9f5a62 Binary files /dev/null and b/Resources/images/history_missed_selected@2x.png differ diff --git a/Resources/images/led_connected.png b/Resources/images/led_connected.png new file mode 100644 index 000000000..3789d3fa3 Binary files /dev/null and b/Resources/images/led_connected.png differ diff --git a/Resources/images/led_connected@2x.png b/Resources/images/led_connected@2x.png new file mode 100644 index 000000000..9c6ccf56f Binary files /dev/null and b/Resources/images/led_connected@2x.png differ diff --git a/Resources/images/led_disconnected.png b/Resources/images/led_disconnected.png new file mode 100644 index 000000000..8040797a8 Binary files /dev/null and b/Resources/images/led_disconnected.png differ diff --git a/Resources/images/led_disconnected@2x.png b/Resources/images/led_disconnected@2x.png new file mode 100644 index 000000000..b864ea244 Binary files /dev/null and b/Resources/images/led_disconnected@2x.png differ diff --git a/Resources/images/led_error.png b/Resources/images/led_error.png new file mode 100644 index 000000000..863c885de Binary files /dev/null and b/Resources/images/led_error.png differ diff --git a/Resources/images/led_error@2x.png b/Resources/images/led_error@2x.png new file mode 100644 index 000000000..0fbe91384 Binary files /dev/null and b/Resources/images/led_error@2x.png differ diff --git a/Resources/images/led_inprogress.png b/Resources/images/led_inprogress.png new file mode 100644 index 000000000..56c46dc2b Binary files /dev/null and b/Resources/images/led_inprogress.png differ diff --git a/Resources/images/led_inprogress@2x.png b/Resources/images/led_inprogress@2x.png new file mode 100644 index 000000000..6204da881 Binary files /dev/null and b/Resources/images/led_inprogress@2x.png differ diff --git a/Resources/images/linphone_logo.png b/Resources/images/linphone_logo.png new file mode 100644 index 000000000..aa72bb925 Binary files /dev/null and b/Resources/images/linphone_logo.png differ diff --git a/Resources/images/linphone_logo@2x.png b/Resources/images/linphone_logo@2x.png new file mode 100644 index 000000000..8f16b0776 Binary files /dev/null and b/Resources/images/linphone_logo@2x.png differ diff --git a/Resources/images/linphone_user.png b/Resources/images/linphone_user.png new file mode 100644 index 000000000..aa72bb925 Binary files /dev/null and b/Resources/images/linphone_user.png differ diff --git a/Resources/images/linphone_user@2x.png b/Resources/images/linphone_user@2x.png new file mode 100644 index 000000000..8f16b0776 Binary files /dev/null and b/Resources/images/linphone_user@2x.png differ diff --git a/Resources/images/list_details_default.png b/Resources/images/list_details_default.png new file mode 100644 index 000000000..82fd769a3 Binary files /dev/null and b/Resources/images/list_details_default.png differ diff --git a/Resources/images/list_details_default@2x.png b/Resources/images/list_details_default@2x.png new file mode 100644 index 000000000..b552326d8 Binary files /dev/null and b/Resources/images/list_details_default@2x.png differ diff --git a/Resources/images/list_details_over.png b/Resources/images/list_details_over.png new file mode 100644 index 000000000..c2d467cfb Binary files /dev/null and b/Resources/images/list_details_over.png differ diff --git a/Resources/images/list_details_over@2x.png b/Resources/images/list_details_over@2x.png new file mode 100644 index 000000000..e57833872 Binary files /dev/null and b/Resources/images/list_details_over@2x.png differ diff --git a/Resources/images/menu.png b/Resources/images/menu.png new file mode 100644 index 000000000..2aad3f90c Binary files /dev/null and b/Resources/images/menu.png differ diff --git a/Resources/images/menu@2x.png b/Resources/images/menu@2x.png new file mode 100644 index 000000000..5a781e1a5 Binary files /dev/null and b/Resources/images/menu@2x.png differ diff --git a/Resources/images/micro_default.png b/Resources/images/micro_default.png new file mode 100644 index 000000000..afcb9f05f Binary files /dev/null and b/Resources/images/micro_default.png differ diff --git a/Resources/images/micro_default@2x.png b/Resources/images/micro_default@2x.png new file mode 100644 index 000000000..2af308d25 Binary files /dev/null and b/Resources/images/micro_default@2x.png differ diff --git a/Resources/images/micro_disabled.png b/Resources/images/micro_disabled.png new file mode 100644 index 000000000..2770d1817 Binary files /dev/null and b/Resources/images/micro_disabled.png differ diff --git a/Resources/images/micro_disabled@2x.png b/Resources/images/micro_disabled@2x.png new file mode 100644 index 000000000..313b6b118 Binary files /dev/null and b/Resources/images/micro_disabled@2x.png differ diff --git a/Resources/images/micro_selected.png b/Resources/images/micro_selected.png new file mode 100644 index 000000000..181433de2 Binary files /dev/null and b/Resources/images/micro_selected.png differ diff --git a/Resources/images/micro_selected@2x.png b/Resources/images/micro_selected@2x.png new file mode 100644 index 000000000..c0d104c81 Binary files /dev/null and b/Resources/images/micro_selected@2x.png differ diff --git a/Resources/images/numpad_0_default.png b/Resources/images/numpad_0_default.png new file mode 100644 index 000000000..702622011 Binary files /dev/null and b/Resources/images/numpad_0_default.png differ diff --git a/Resources/images/numpad_0_default@2x.png b/Resources/images/numpad_0_default@2x.png new file mode 100644 index 000000000..bc8814a21 Binary files /dev/null and b/Resources/images/numpad_0_default@2x.png differ diff --git a/Resources/images/numpad_0_over.png b/Resources/images/numpad_0_over.png new file mode 100644 index 000000000..f0deeee1e Binary files /dev/null and b/Resources/images/numpad_0_over.png differ diff --git a/Resources/images/numpad_0_over@2x.png b/Resources/images/numpad_0_over@2x.png new file mode 100644 index 000000000..382302355 Binary files /dev/null and b/Resources/images/numpad_0_over@2x.png differ diff --git a/Resources/images/numpad_1_default.png b/Resources/images/numpad_1_default.png new file mode 100644 index 000000000..7c2087689 Binary files /dev/null and b/Resources/images/numpad_1_default.png differ diff --git a/Resources/images/numpad_1_default@2x.png b/Resources/images/numpad_1_default@2x.png new file mode 100644 index 000000000..8e6541777 Binary files /dev/null and b/Resources/images/numpad_1_default@2x.png differ diff --git a/Resources/images/numpad_1_over.png b/Resources/images/numpad_1_over.png new file mode 100644 index 000000000..6ec5eab69 Binary files /dev/null and b/Resources/images/numpad_1_over.png differ diff --git a/Resources/images/numpad_1_over@2x.png b/Resources/images/numpad_1_over@2x.png new file mode 100644 index 000000000..682481d16 Binary files /dev/null and b/Resources/images/numpad_1_over@2x.png differ diff --git a/Resources/images/numpad_2_default.png b/Resources/images/numpad_2_default.png new file mode 100644 index 000000000..cf6dd9d38 Binary files /dev/null and b/Resources/images/numpad_2_default.png differ diff --git a/Resources/images/numpad_2_default@2x.png b/Resources/images/numpad_2_default@2x.png new file mode 100644 index 000000000..54b4ab42f Binary files /dev/null and b/Resources/images/numpad_2_default@2x.png differ diff --git a/Resources/images/numpad_2_over.png b/Resources/images/numpad_2_over.png new file mode 100644 index 000000000..e0f710e99 Binary files /dev/null and b/Resources/images/numpad_2_over.png differ diff --git a/Resources/images/numpad_2_over@2x.png b/Resources/images/numpad_2_over@2x.png new file mode 100644 index 000000000..b5e1dbd49 Binary files /dev/null and b/Resources/images/numpad_2_over@2x.png differ diff --git a/Resources/images/numpad_3_default.png b/Resources/images/numpad_3_default.png new file mode 100644 index 000000000..407d0f3f0 Binary files /dev/null and b/Resources/images/numpad_3_default.png differ diff --git a/Resources/images/numpad_3_default@2x.png b/Resources/images/numpad_3_default@2x.png new file mode 100644 index 000000000..c548ea5a8 Binary files /dev/null and b/Resources/images/numpad_3_default@2x.png differ diff --git a/Resources/images/numpad_3_over.png b/Resources/images/numpad_3_over.png new file mode 100644 index 000000000..007d64907 Binary files /dev/null and b/Resources/images/numpad_3_over.png differ diff --git a/Resources/images/numpad_3_over@2x.png b/Resources/images/numpad_3_over@2x.png new file mode 100644 index 000000000..c6b004aa6 Binary files /dev/null and b/Resources/images/numpad_3_over@2x.png differ diff --git a/Resources/images/numpad_4_default.png b/Resources/images/numpad_4_default.png new file mode 100644 index 000000000..4bdb8f227 Binary files /dev/null and b/Resources/images/numpad_4_default.png differ diff --git a/Resources/images/numpad_4_default@2x.png b/Resources/images/numpad_4_default@2x.png new file mode 100644 index 000000000..33d73545f Binary files /dev/null and b/Resources/images/numpad_4_default@2x.png differ diff --git a/Resources/images/numpad_4_over.png b/Resources/images/numpad_4_over.png new file mode 100644 index 000000000..3304ea566 Binary files /dev/null and b/Resources/images/numpad_4_over.png differ diff --git a/Resources/images/numpad_4_over@2x.png b/Resources/images/numpad_4_over@2x.png new file mode 100644 index 000000000..d60dc1f60 Binary files /dev/null and b/Resources/images/numpad_4_over@2x.png differ diff --git a/Resources/images/numpad_5_default.png b/Resources/images/numpad_5_default.png new file mode 100644 index 000000000..752d2b0f5 Binary files /dev/null and b/Resources/images/numpad_5_default.png differ diff --git a/Resources/images/numpad_5_default@2x.png b/Resources/images/numpad_5_default@2x.png new file mode 100644 index 000000000..c4690b6ba Binary files /dev/null and b/Resources/images/numpad_5_default@2x.png differ diff --git a/Resources/images/numpad_5_over.png b/Resources/images/numpad_5_over.png new file mode 100644 index 000000000..3d71249e9 Binary files /dev/null and b/Resources/images/numpad_5_over.png differ diff --git a/Resources/images/numpad_5_over@2x.png b/Resources/images/numpad_5_over@2x.png new file mode 100644 index 000000000..17f11404c Binary files /dev/null and b/Resources/images/numpad_5_over@2x.png differ diff --git a/Resources/images/numpad_6_default.png b/Resources/images/numpad_6_default.png new file mode 100644 index 000000000..e02afb9d8 Binary files /dev/null and b/Resources/images/numpad_6_default.png differ diff --git a/Resources/images/numpad_6_default@2x.png b/Resources/images/numpad_6_default@2x.png new file mode 100644 index 000000000..56e510052 Binary files /dev/null and b/Resources/images/numpad_6_default@2x.png differ diff --git a/Resources/images/numpad_6_over.png b/Resources/images/numpad_6_over.png new file mode 100644 index 000000000..6881b758d Binary files /dev/null and b/Resources/images/numpad_6_over.png differ diff --git a/Resources/images/numpad_6_over@2x.png b/Resources/images/numpad_6_over@2x.png new file mode 100644 index 000000000..d23468529 Binary files /dev/null and b/Resources/images/numpad_6_over@2x.png differ diff --git a/Resources/images/numpad_7_default.png b/Resources/images/numpad_7_default.png new file mode 100644 index 000000000..0217c2eac Binary files /dev/null and b/Resources/images/numpad_7_default.png differ diff --git a/Resources/images/numpad_7_default@2x.png b/Resources/images/numpad_7_default@2x.png new file mode 100644 index 000000000..0a12730be Binary files /dev/null and b/Resources/images/numpad_7_default@2x.png differ diff --git a/Resources/images/numpad_7_over.png b/Resources/images/numpad_7_over.png new file mode 100644 index 000000000..7a91dfe7c Binary files /dev/null and b/Resources/images/numpad_7_over.png differ diff --git a/Resources/images/numpad_7_over@2x.png b/Resources/images/numpad_7_over@2x.png new file mode 100644 index 000000000..827d20937 Binary files /dev/null and b/Resources/images/numpad_7_over@2x.png differ diff --git a/Resources/images/numpad_8_default.png b/Resources/images/numpad_8_default.png new file mode 100644 index 000000000..9f37f32e8 Binary files /dev/null and b/Resources/images/numpad_8_default.png differ diff --git a/Resources/images/numpad_8_default@2x.png b/Resources/images/numpad_8_default@2x.png new file mode 100644 index 000000000..e576a52fb Binary files /dev/null and b/Resources/images/numpad_8_default@2x.png differ diff --git a/Resources/images/numpad_8_over.png b/Resources/images/numpad_8_over.png new file mode 100644 index 000000000..93ff078a2 Binary files /dev/null and b/Resources/images/numpad_8_over.png differ diff --git a/Resources/images/numpad_8_over@2x.png b/Resources/images/numpad_8_over@2x.png new file mode 100644 index 000000000..98a6927fb Binary files /dev/null and b/Resources/images/numpad_8_over@2x.png differ diff --git a/Resources/images/numpad_9_default.png b/Resources/images/numpad_9_default.png new file mode 100644 index 000000000..126c8a5ab Binary files /dev/null and b/Resources/images/numpad_9_default.png differ diff --git a/Resources/images/numpad_9_default@2x.png b/Resources/images/numpad_9_default@2x.png new file mode 100644 index 000000000..93acaecc8 Binary files /dev/null and b/Resources/images/numpad_9_default@2x.png differ diff --git a/Resources/images/numpad_9_over.png b/Resources/images/numpad_9_over.png new file mode 100644 index 000000000..52903130b Binary files /dev/null and b/Resources/images/numpad_9_over.png differ diff --git a/Resources/images/numpad_9_over@2x.png b/Resources/images/numpad_9_over@2x.png new file mode 100644 index 000000000..7c775b384 Binary files /dev/null and b/Resources/images/numpad_9_over@2x.png differ diff --git a/Resources/images/numpad_hash_default.png b/Resources/images/numpad_hash_default.png new file mode 100644 index 000000000..f689fa551 Binary files /dev/null and b/Resources/images/numpad_hash_default.png differ diff --git a/Resources/images/numpad_hash_default@2x.png b/Resources/images/numpad_hash_default@2x.png new file mode 100644 index 000000000..c43d30d54 Binary files /dev/null and b/Resources/images/numpad_hash_default@2x.png differ diff --git a/Resources/images/numpad_hash_over.png b/Resources/images/numpad_hash_over.png new file mode 100644 index 000000000..38c124f07 Binary files /dev/null and b/Resources/images/numpad_hash_over.png differ diff --git a/Resources/images/numpad_hash_over@2x.png b/Resources/images/numpad_hash_over@2x.png new file mode 100644 index 000000000..f97fb3f0a Binary files /dev/null and b/Resources/images/numpad_hash_over@2x.png differ diff --git a/Resources/images/numpad_over_background.png b/Resources/images/numpad_over_background.png new file mode 100644 index 000000000..1da019a54 Binary files /dev/null and b/Resources/images/numpad_over_background.png differ diff --git a/Resources/images/numpad_star_default.png b/Resources/images/numpad_star_default.png new file mode 100644 index 000000000..24316dc6e Binary files /dev/null and b/Resources/images/numpad_star_default.png differ diff --git a/Resources/images/numpad_star_default@2x.png b/Resources/images/numpad_star_default@2x.png new file mode 100644 index 000000000..43e60e9a8 Binary files /dev/null and b/Resources/images/numpad_star_default@2x.png differ diff --git a/Resources/images/numpad_star_over.png b/Resources/images/numpad_star_over.png new file mode 100644 index 000000000..7548259bd Binary files /dev/null and b/Resources/images/numpad_star_over.png differ diff --git a/Resources/images/numpad_star_over@2x.png b/Resources/images/numpad_star_over@2x.png new file mode 100644 index 000000000..0ede457ab Binary files /dev/null and b/Resources/images/numpad_star_over@2x.png differ diff --git a/Resources/images/options_add_call_default.png b/Resources/images/options_add_call_default.png new file mode 100644 index 000000000..a8b97bb50 Binary files /dev/null and b/Resources/images/options_add_call_default.png differ diff --git a/Resources/images/options_add_call_default@2x.png b/Resources/images/options_add_call_default@2x.png new file mode 100644 index 000000000..824aa2495 Binary files /dev/null and b/Resources/images/options_add_call_default@2x.png differ diff --git a/Resources/images/options_add_call_disabled.png b/Resources/images/options_add_call_disabled.png new file mode 100644 index 000000000..1ac61d61f Binary files /dev/null and b/Resources/images/options_add_call_disabled.png differ diff --git a/Resources/images/options_add_call_disabled@2x.png b/Resources/images/options_add_call_disabled@2x.png new file mode 100644 index 000000000..e395f70ca Binary files /dev/null and b/Resources/images/options_add_call_disabled@2x.png differ diff --git a/Resources/images/options_default.png b/Resources/images/options_default.png new file mode 100644 index 000000000..8431086b0 Binary files /dev/null and b/Resources/images/options_default.png differ diff --git a/Resources/images/options_default@2x.png b/Resources/images/options_default@2x.png new file mode 100644 index 000000000..f93c7356f Binary files /dev/null and b/Resources/images/options_default@2x.png differ diff --git a/Resources/images/options_disabled.png b/Resources/images/options_disabled.png new file mode 100644 index 000000000..b13b985d5 Binary files /dev/null and b/Resources/images/options_disabled.png differ diff --git a/Resources/images/options_disabled@2x.png b/Resources/images/options_disabled@2x.png new file mode 100644 index 000000000..6264ff3cf Binary files /dev/null and b/Resources/images/options_disabled@2x.png differ diff --git a/Resources/images/options_selected.png b/Resources/images/options_selected.png new file mode 100644 index 000000000..b4ba41a01 Binary files /dev/null and b/Resources/images/options_selected.png differ diff --git a/Resources/images/options_selected@2x.png b/Resources/images/options_selected@2x.png new file mode 100644 index 000000000..080409b42 Binary files /dev/null and b/Resources/images/options_selected@2x.png differ diff --git a/Resources/images/options_start_conference_default.png b/Resources/images/options_start_conference_default.png new file mode 100644 index 000000000..184220aef Binary files /dev/null and b/Resources/images/options_start_conference_default.png differ diff --git a/Resources/images/options_start_conference_default@2x.png b/Resources/images/options_start_conference_default@2x.png new file mode 100644 index 000000000..7bede1c9e Binary files /dev/null and b/Resources/images/options_start_conference_default@2x.png differ diff --git a/Resources/images/options_start_conference_disabled.png b/Resources/images/options_start_conference_disabled.png new file mode 100644 index 000000000..75b142b30 Binary files /dev/null and b/Resources/images/options_start_conference_disabled.png differ diff --git a/Resources/images/options_start_conference_disabled@2x.png b/Resources/images/options_start_conference_disabled@2x.png new file mode 100644 index 000000000..25bf4e9c8 Binary files /dev/null and b/Resources/images/options_start_conference_disabled@2x.png differ diff --git a/Resources/images/options_transfer_call_default.png b/Resources/images/options_transfer_call_default.png new file mode 100644 index 000000000..aaeb9b671 Binary files /dev/null and b/Resources/images/options_transfer_call_default.png differ diff --git a/Resources/images/options_transfer_call_default@2x.png b/Resources/images/options_transfer_call_default@2x.png new file mode 100644 index 000000000..1ead36be0 Binary files /dev/null and b/Resources/images/options_transfer_call_default@2x.png differ diff --git a/Resources/images/options_transfer_call_disabled.png b/Resources/images/options_transfer_call_disabled.png new file mode 100644 index 000000000..682eb335b Binary files /dev/null and b/Resources/images/options_transfer_call_disabled.png differ diff --git a/Resources/images/options_transfer_call_disabled@2x.png b/Resources/images/options_transfer_call_disabled@2x.png new file mode 100644 index 000000000..33b697cc5 Binary files /dev/null and b/Resources/images/options_transfer_call_disabled@2x.png differ diff --git a/Resources/images/pause_big_default.png b/Resources/images/pause_big_default.png new file mode 100644 index 000000000..82f3b472d Binary files /dev/null and b/Resources/images/pause_big_default.png differ diff --git a/Resources/images/pause_big_default@2x.png b/Resources/images/pause_big_default@2x.png new file mode 100644 index 000000000..5e754cb48 Binary files /dev/null and b/Resources/images/pause_big_default@2x.png differ diff --git a/Resources/images/pause_big_disabled.png b/Resources/images/pause_big_disabled.png new file mode 100644 index 000000000..7cd8ac14f Binary files /dev/null and b/Resources/images/pause_big_disabled.png differ diff --git a/Resources/images/pause_big_disabled@2x.png b/Resources/images/pause_big_disabled@2x.png new file mode 100644 index 000000000..aebc2557d Binary files /dev/null and b/Resources/images/pause_big_disabled@2x.png differ diff --git a/Resources/images/pause_big_over_selected.png b/Resources/images/pause_big_over_selected.png new file mode 100644 index 000000000..c7e10bce6 Binary files /dev/null and b/Resources/images/pause_big_over_selected.png differ diff --git a/Resources/images/pause_big_over_selected@2x.png b/Resources/images/pause_big_over_selected@2x.png new file mode 100644 index 000000000..dd51a1751 Binary files /dev/null and b/Resources/images/pause_big_over_selected@2x.png differ diff --git a/Resources/images/pause_small_default.png b/Resources/images/pause_small_default.png new file mode 100644 index 000000000..1345d121d Binary files /dev/null and b/Resources/images/pause_small_default.png differ diff --git a/Resources/images/pause_small_default@2x.png b/Resources/images/pause_small_default@2x.png new file mode 100644 index 000000000..2dfa7f88b Binary files /dev/null and b/Resources/images/pause_small_default@2x.png differ diff --git a/Resources/images/pause_small_disabled.png b/Resources/images/pause_small_disabled.png new file mode 100644 index 000000000..91f0d0685 Binary files /dev/null and b/Resources/images/pause_small_disabled.png differ diff --git a/Resources/images/pause_small_disabled@2x.png b/Resources/images/pause_small_disabled@2x.png new file mode 100644 index 000000000..64c812ab9 Binary files /dev/null and b/Resources/images/pause_small_disabled@2x.png differ diff --git a/Resources/images/pause_small_over_selected.png b/Resources/images/pause_small_over_selected.png new file mode 100644 index 000000000..5e50311cf Binary files /dev/null and b/Resources/images/pause_small_over_selected.png differ diff --git a/Resources/images/pause_small_over_selected@2x.png b/Resources/images/pause_small_over_selected@2x.png new file mode 100644 index 000000000..c4b98b07c Binary files /dev/null and b/Resources/images/pause_small_over_selected@2x.png differ diff --git a/Resources/images/route_bluetooth_default.png b/Resources/images/route_bluetooth_default.png new file mode 100644 index 000000000..4d6cdd279 Binary files /dev/null and b/Resources/images/route_bluetooth_default.png differ diff --git a/Resources/images/route_bluetooth_default@2x.png b/Resources/images/route_bluetooth_default@2x.png new file mode 100644 index 000000000..1096856a0 Binary files /dev/null and b/Resources/images/route_bluetooth_default@2x.png differ diff --git a/Resources/images/route_bluetooth_disabled.png b/Resources/images/route_bluetooth_disabled.png new file mode 100644 index 000000000..29650c968 Binary files /dev/null and b/Resources/images/route_bluetooth_disabled.png differ diff --git a/Resources/images/route_bluetooth_disabled@2x.png b/Resources/images/route_bluetooth_disabled@2x.png new file mode 100644 index 000000000..c6a041fed Binary files /dev/null and b/Resources/images/route_bluetooth_disabled@2x.png differ diff --git a/Resources/images/route_bluetooth_selected.png b/Resources/images/route_bluetooth_selected.png new file mode 100644 index 000000000..35fa48395 Binary files /dev/null and b/Resources/images/route_bluetooth_selected.png differ diff --git a/Resources/images/route_bluetooth_selected@2x.png b/Resources/images/route_bluetooth_selected@2x.png new file mode 100644 index 000000000..42db039aa Binary files /dev/null and b/Resources/images/route_bluetooth_selected@2x.png differ diff --git a/Resources/images/route_earpiece_default.png b/Resources/images/route_earpiece_default.png new file mode 100644 index 000000000..c39fe06e0 Binary files /dev/null and b/Resources/images/route_earpiece_default.png differ diff --git a/Resources/images/route_earpiece_default@2x.png b/Resources/images/route_earpiece_default@2x.png new file mode 100644 index 000000000..7de006643 Binary files /dev/null and b/Resources/images/route_earpiece_default@2x.png differ diff --git a/Resources/images/route_earpiece_disabled.png b/Resources/images/route_earpiece_disabled.png new file mode 100644 index 000000000..b432a8408 Binary files /dev/null and b/Resources/images/route_earpiece_disabled.png differ diff --git a/Resources/images/route_earpiece_disabled@2x.png b/Resources/images/route_earpiece_disabled@2x.png new file mode 100644 index 000000000..e0cb3af8d Binary files /dev/null and b/Resources/images/route_earpiece_disabled@2x.png differ diff --git a/Resources/images/route_earpiece_selected.png b/Resources/images/route_earpiece_selected.png new file mode 100644 index 000000000..e44b80cc9 Binary files /dev/null and b/Resources/images/route_earpiece_selected.png differ diff --git a/Resources/images/route_earpiece_selected@2x.png b/Resources/images/route_earpiece_selected@2x.png new file mode 100644 index 000000000..d30cc7852 Binary files /dev/null and b/Resources/images/route_earpiece_selected@2x.png differ diff --git a/Resources/images/route_speaker_default.png b/Resources/images/route_speaker_default.png new file mode 100644 index 000000000..a61d89478 Binary files /dev/null and b/Resources/images/route_speaker_default.png differ diff --git a/Resources/images/route_speaker_default@2x.png b/Resources/images/route_speaker_default@2x.png new file mode 100644 index 000000000..d5747f5d6 Binary files /dev/null and b/Resources/images/route_speaker_default@2x.png differ diff --git a/Resources/images/route_speaker_disabled.png b/Resources/images/route_speaker_disabled.png new file mode 100644 index 000000000..c64f73534 Binary files /dev/null and b/Resources/images/route_speaker_disabled.png differ diff --git a/Resources/images/route_speaker_disabled@2x.png b/Resources/images/route_speaker_disabled@2x.png new file mode 100644 index 000000000..8f6a165ad Binary files /dev/null and b/Resources/images/route_speaker_disabled@2x.png differ diff --git a/Resources/images/route_speaker_selected.png b/Resources/images/route_speaker_selected.png new file mode 100644 index 000000000..8f09449e6 Binary files /dev/null and b/Resources/images/route_speaker_selected.png differ diff --git a/Resources/images/route_speaker_selected@2x.png b/Resources/images/route_speaker_selected@2x.png new file mode 100644 index 000000000..39bebfc4e Binary files /dev/null and b/Resources/images/route_speaker_selected@2x.png differ diff --git a/Resources/images/routes_default.png b/Resources/images/routes_default.png new file mode 100644 index 000000000..f1b99cb17 Binary files /dev/null and b/Resources/images/routes_default.png differ diff --git a/Resources/images/routes_default@2x.png b/Resources/images/routes_default@2x.png new file mode 100644 index 000000000..bdcd07438 Binary files /dev/null and b/Resources/images/routes_default@2x.png differ diff --git a/Resources/images/routes_disabled.png b/Resources/images/routes_disabled.png new file mode 100644 index 000000000..9f0235d12 Binary files /dev/null and b/Resources/images/routes_disabled.png differ diff --git a/Resources/images/routes_disabled@2x.png b/Resources/images/routes_disabled@2x.png new file mode 100644 index 000000000..2b2bb47b5 Binary files /dev/null and b/Resources/images/routes_disabled@2x.png differ diff --git a/Resources/images/routes_selected.png b/Resources/images/routes_selected.png new file mode 100644 index 000000000..41ee121f4 Binary files /dev/null and b/Resources/images/routes_selected.png differ diff --git a/Resources/images/routes_selected@2x.png b/Resources/images/routes_selected@2x.png new file mode 100644 index 000000000..9343021fc Binary files /dev/null and b/Resources/images/routes_selected@2x.png differ diff --git a/Resources/images/security_ko.png b/Resources/images/security_ko.png new file mode 100644 index 000000000..310239d52 Binary files /dev/null and b/Resources/images/security_ko.png differ diff --git a/Resources/images/security_ko@2x.png b/Resources/images/security_ko@2x.png new file mode 100644 index 000000000..9a8f162f0 Binary files /dev/null and b/Resources/images/security_ko@2x.png differ diff --git a/Resources/images/security_ok.png b/Resources/images/security_ok.png new file mode 100644 index 000000000..4e1715143 Binary files /dev/null and b/Resources/images/security_ok.png differ diff --git a/Resources/images/security_ok@2x.png b/Resources/images/security_ok@2x.png new file mode 100644 index 000000000..c85e3f47c Binary files /dev/null and b/Resources/images/security_ok@2x.png differ diff --git a/Resources/images/security_pending.png b/Resources/images/security_pending.png new file mode 100644 index 000000000..abbc975c6 Binary files /dev/null and b/Resources/images/security_pending.png differ diff --git a/Resources/images/security_pending@2x.png b/Resources/images/security_pending@2x.png new file mode 100644 index 000000000..84771cf5f Binary files /dev/null and b/Resources/images/security_pending@2x.png differ diff --git a/Resources/images/select_all_default.png b/Resources/images/select_all_default.png new file mode 100644 index 000000000..eec578227 Binary files /dev/null and b/Resources/images/select_all_default.png differ diff --git a/Resources/images/select_all_default@2x.png b/Resources/images/select_all_default@2x.png new file mode 100644 index 000000000..24557bdd4 Binary files /dev/null and b/Resources/images/select_all_default@2x.png differ diff --git a/Resources/images/select_all_disabled.png b/Resources/images/select_all_disabled.png new file mode 100644 index 000000000..a7cb3e387 Binary files /dev/null and b/Resources/images/select_all_disabled.png differ diff --git a/Resources/images/select_all_disabled@2x.png b/Resources/images/select_all_disabled@2x.png new file mode 100644 index 000000000..a153faabe Binary files /dev/null and b/Resources/images/select_all_disabled@2x.png differ diff --git a/Resources/images/speaker_default.png b/Resources/images/speaker_default.png new file mode 100644 index 000000000..a61d89478 Binary files /dev/null and b/Resources/images/speaker_default.png differ diff --git a/Resources/images/speaker_default@2x.png b/Resources/images/speaker_default@2x.png new file mode 100644 index 000000000..d5747f5d6 Binary files /dev/null and b/Resources/images/speaker_default@2x.png differ diff --git a/Resources/images/speaker_disabled.png b/Resources/images/speaker_disabled.png new file mode 100644 index 000000000..3e6230eb7 Binary files /dev/null and b/Resources/images/speaker_disabled.png differ diff --git a/Resources/images/speaker_disabled@2x.png b/Resources/images/speaker_disabled@2x.png new file mode 100644 index 000000000..7ab9b5b64 Binary files /dev/null and b/Resources/images/speaker_disabled@2x.png differ diff --git a/Resources/images/speaker_selected.png b/Resources/images/speaker_selected.png new file mode 100644 index 000000000..6e9a447b1 Binary files /dev/null and b/Resources/images/speaker_selected.png differ diff --git a/Resources/images/speaker_selected@2x.png b/Resources/images/speaker_selected@2x.png new file mode 100644 index 000000000..598b63a47 Binary files /dev/null and b/Resources/images/speaker_selected@2x.png differ diff --git a/Resources/images/splashscreen.png b/Resources/images/splashscreen.png new file mode 100644 index 000000000..b5e2e3509 Binary files /dev/null and b/Resources/images/splashscreen.png differ diff --git a/Resources/images/splashscreen@2x.png b/Resources/images/splashscreen@2x.png new file mode 100644 index 000000000..2fc8e64f9 Binary files /dev/null and b/Resources/images/splashscreen@2x.png differ diff --git a/Resources/images/valid_default.png b/Resources/images/valid_default.png new file mode 100644 index 000000000..268f6454c Binary files /dev/null and b/Resources/images/valid_default.png differ diff --git a/Resources/images/valid_default@2x.png b/Resources/images/valid_default@2x.png new file mode 100644 index 000000000..74b701dd8 Binary files /dev/null and b/Resources/images/valid_default@2x.png differ diff --git a/Resources/images/valid_disabled.png b/Resources/images/valid_disabled.png new file mode 100644 index 000000000..0da05c2ea Binary files /dev/null and b/Resources/images/valid_disabled.png differ diff --git a/Resources/images/valid_disabled@2x.png b/Resources/images/valid_disabled@2x.png new file mode 100644 index 000000000..e12c02d44 Binary files /dev/null and b/Resources/images/valid_disabled@2x.png differ diff --git a/Resources/images/voicemail.png b/Resources/images/voicemail.png new file mode 100644 index 000000000..26949d26e Binary files /dev/null and b/Resources/images/voicemail.png differ diff --git a/Resources/images/voicemail@2x.png b/Resources/images/voicemail@2x.png new file mode 100644 index 000000000..8ccd54ffc Binary files /dev/null and b/Resources/images/voicemail@2x.png differ diff --git a/Resources/images/waiting_time.png b/Resources/images/waiting_time.png new file mode 100644 index 000000000..bd9d66d47 Binary files /dev/null and b/Resources/images/waiting_time.png differ diff --git a/Resources/images/waiting_time@2x.png b/Resources/images/waiting_time@2x.png new file mode 100644 index 000000000..d604ce27e Binary files /dev/null and b/Resources/images/waiting_time@2x.png differ diff --git a/Resources/incall_padding_left.png b/Resources/incall_padding_left.png deleted file mode 100644 index b253ace05..000000000 Binary files a/Resources/incall_padding_left.png and /dev/null differ diff --git a/Resources/incall_padding_left_landscape.png b/Resources/incall_padding_left_landscape.png deleted file mode 100644 index dbf38a8a7..000000000 Binary files a/Resources/incall_padding_left_landscape.png and /dev/null differ diff --git a/Resources/incall_padding_right.png b/Resources/incall_padding_right.png deleted file mode 100644 index 5178d283c..000000000 Binary files a/Resources/incall_padding_right.png and /dev/null differ diff --git a/Resources/incall_padding_right_landscape.png b/Resources/incall_padding_right_landscape.png deleted file mode 100644 index 78a05e8da..000000000 Binary files a/Resources/incall_padding_right_landscape.png and /dev/null differ diff --git a/Resources/ja.lproj/Localizable.strings b/Resources/ja.lproj/Localizable.strings index e8274a38f..ad922e880 100644 Binary files a/Resources/ja.lproj/Localizable.strings and b/Resources/ja.lproj/Localizable.strings differ diff --git a/Resources/launchscreen/background-launch.png b/Resources/launchscreen/background-launch.png deleted file mode 100644 index d8d76a666..000000000 Binary files a/Resources/launchscreen/background-launch.png and /dev/null differ diff --git a/Resources/launchscreen/corner-left-bottom.png b/Resources/launchscreen/corner-left-bottom.png deleted file mode 100644 index aa0e9b38a..000000000 Binary files a/Resources/launchscreen/corner-left-bottom.png and /dev/null differ diff --git a/Resources/launchscreen/corner-left-top.png b/Resources/launchscreen/corner-left-top.png deleted file mode 100644 index 7c921efcd..000000000 Binary files a/Resources/launchscreen/corner-left-top.png and /dev/null differ diff --git a/Resources/launchscreen/corner-right-bottom.png b/Resources/launchscreen/corner-right-bottom.png deleted file mode 100644 index efca2de7f..000000000 Binary files a/Resources/launchscreen/corner-right-bottom.png and /dev/null differ diff --git a/Resources/launchscreen/corner-right-top.png b/Resources/launchscreen/corner-right-top.png deleted file mode 100644 index 425904796..000000000 Binary files a/Resources/launchscreen/corner-right-top.png and /dev/null differ diff --git a/Resources/launchscreen/logo.png b/Resources/launchscreen/logo.png deleted file mode 100644 index 9f4590e19..000000000 Binary files a/Resources/launchscreen/logo.png and /dev/null differ diff --git a/Resources/launchscreen/strech-bottom.png b/Resources/launchscreen/strech-bottom.png deleted file mode 100644 index b2bb1076d..000000000 Binary files a/Resources/launchscreen/strech-bottom.png and /dev/null differ diff --git a/Resources/launchscreen/strech-top.png b/Resources/launchscreen/strech-top.png deleted file mode 100644 index 32cd7496a..000000000 Binary files a/Resources/launchscreen/strech-top.png and /dev/null differ diff --git a/Resources/led_connected.png b/Resources/led_connected.png deleted file mode 100644 index e788e2b07..000000000 Binary files a/Resources/led_connected.png and /dev/null differ diff --git a/Resources/led_disconnected.png b/Resources/led_disconnected.png deleted file mode 100644 index 11455fb1b..000000000 Binary files a/Resources/led_disconnected.png and /dev/null differ diff --git a/Resources/led_error.png b/Resources/led_error.png deleted file mode 100644 index e7617832b..000000000 Binary files a/Resources/led_error.png and /dev/null differ diff --git a/Resources/led_inprogress.png b/Resources/led_inprogress.png deleted file mode 100644 index d2fe9da56..000000000 Binary files a/Resources/led_inprogress.png and /dev/null differ diff --git a/Resources/licenses.html b/Resources/licenses.html index 31b1bdba7..183077683 100644 --- a/Resources/licenses.html +++ b/Resources/licenses.html @@ -37,6 +37,11 @@ http://www.tortuga22.com
Apache license

+

Ryan Maxwell

+

UIAlertview+Blocks

+https://github.com/ryanmaxwell/UIAlertView-Blocks
+MIT license +

OrderedDictionary

Matt Gallagher
http://cocoawithlove.com

diff --git a/Resources/licenses.md b/Resources/licenses.md deleted file mode 100644 index db2568c6e..000000000 --- a/Resources/licenses.md +++ /dev/null @@ -1,75 +0,0 @@ -#Third party softwares -###CAAnimationBlocks -Xissburg - - - -###ColorConverter -Matteo Alessani - - - -###DCRoundSwitch -Patrick Richards - -_MIT license_ - - -###DTFoundation -Oliver Drobnik - -_BSD license_ - - -###HPGrowingTextView -Hans Pinckaers - -_MIT license_ - - -###InAppSettingsKit -Luc Vandal, Edovia Inc., Ortwin Gentz, FutureTap GmbH - -_BSD license_ - - -###NinePatch -Tortuga 22, Inc. - -_Apache license_ - - -###OrderedDictionary -Matt Gallagher - - - -###TPMultiLayoutViewController -Michael Tyson - -_MIT license_ - - -###UACellBackgroundView -Matt Coneybeare - - - -###XMLRPC -Eric Czarny - -_MIT license_ - - -#Graphics -###Kerosine - - -#Translations -###Russian -Maxim Solodovnik - - -#Utilitary softwares -###Localization Suite - diff --git a/Resources/linphone_logo.png b/Resources/linphone_logo.png deleted file mode 100644 index f3695de8b..000000000 Binary files a/Resources/linphone_logo.png and /dev/null differ diff --git a/Resources/linphonerc b/Resources/linphonerc index 6812b6238..2e92dc016 100644 --- a/Resources/linphonerc +++ b/Resources/linphonerc @@ -1,14 +1,34 @@ +[net] +mtu=1300 +activate_edge_workarounds=0 +edge_ping_time=10 +edge_bw=10 + [sip] contact="Linphone iPhone" keepalive_period=30000 -default_proxy=0 sip_port=-1 sip_tcp_port=-1 use_ipv6=0 +inc_timeout=45 +use_info=0 +guess_hostname=1 +register_only_when_network_is_up=1 +auto_net_state_mon=0 +keepalive_period=30000 +ping_with_options=0 +rtcp_xr_enabled=1 +rtcp_xr_rcvr_rtt_mode=all +rtcp_xr_rcvr_rtt_max_size=10000 +rtcp_xr_stat_summary_enabled=1 +rtcp_xr_voip_metrics_enabled=1 [rtp] -audio_rtp_port=7076 -video_rtp_port=9078 +audio_rtp_port=7200-7299 +video_rtp_port=9200-9299 +audio_jitt_comp=60 +video_jitt_comp=60 +nortp_timeout=30 [video] display=1 @@ -20,9 +40,10 @@ automatically_initiate=0 automatically_accept=0 [net] -firewall_policy=0 download_bw=380 upload_bw=380 +firewall_policy=ice +stun_server=stun.linphone.org [sound] playback_dev_id=AU: Audio Unit Receiver @@ -30,14 +51,23 @@ capture_dev_id=AU: Audio Unit Receiver eq_active=0 [app] +preview_preference=0 animations_preference=1 edge_opt_preference=0 -use_system_contacts=0 start_at_boot_preference=1 backgroundmode_preference=1 autoanswer_notif_preference=1 voiceproc_preference=1 enable_log_collect=0 +file_transfer_migration_done=1 +pushnotification_preference=1 +ice_preference=1 +stun_preference=stun.linphone.org +random_port_preference=1 [default_values] -reg_expires=600 \ No newline at end of file +reg_expires=1314000 + +[misc] +max_calls=3 +file_transfer_server_url=https://www.linphone.org:444/lft.php diff --git a/Resources/linphonerc-factory b/Resources/linphonerc-factory index c3064bf5f..77e05a713 100644 --- a/Resources/linphonerc-factory +++ b/Resources/linphonerc-factory @@ -1,28 +1,6 @@ -[net] -mtu=1300 -activate_edge_workarounds=0 -edge_ping_time=10 -edge_bw=10 - [sip] -guess_hostname=1 -inc_timeout=45 -use_info=0 -register_only_when_network_is_up=1 -auto_net_state_mon=0 -keepalive_period=30000 -ping_with_options=0 sip_random_port=0 -rtcp_xr_enabled=1 -rtcp_xr_rcvr_rtt_mode=all -rtcp_xr_rcvr_rtt_max_size=10000 -rtcp_xr_stat_summary_enabled=1 -rtcp_xr_voip_metrics_enabled=1 - -[rtp] -audio_jitt_comp=60 -video_jitt_comp=60 -nortp_timeout=30 +store_ha1_passwd=0 [sound] ringer_dev_id=AQ: Audio Queue Device @@ -31,26 +9,23 @@ dtmf_player_amp=0.007 eq_location=mic eq_gains=50:2:50 100:2:50 -[misc] -history_max_size=30 -max_calls=3 - -[wizard] -service_url=https://www.linphone.org/wizard.php -domain=sip.linphone.org -proxy=sip.linphone.org:5223 -password_length=6 -username_length=4 -expires=1314000 -push_notification=1 -transport=tls -sharing_server=https://www.linphone.org:444/upload.php -ice=1 -stun=stun.linphone.org - [video] display_filter_auto_rotate=0 [app] #contact_display_username_only=1 -#contact_filter_on_default_domain=1 \ No newline at end of file +#contact_filter_on_default_domain=1 +#use_phone_number=0 +send_logs_include_linphonerc_and_chathistory=0 +fallback_view=DialerView +unauthorized_views=FirstView + +[assistant] +username_regex=^[a-z0-9_.\-]*$ + +[in_app_purchase] +enabled=0 + +[misc] +#by default it is set to 30 by liblinphone +history_max_size=-1 \ No newline at end of file diff --git a/Resources/linphonerc-factory~ipad b/Resources/linphonerc-factory~ipad deleted file mode 100644 index 20371b043..000000000 --- a/Resources/linphonerc-factory~ipad +++ /dev/null @@ -1,54 +0,0 @@ -[net] -mtu=1300 -activate_edge_workarounds=0 -edge_ping_time=200 -edge_bw=10 - -[sip] -guess_hostname=1 -inc_timeout=45 -use_info=0 -register_only_when_network_is_up=1 -auto_net_state_mon=0 -keepalive_period=30000 -ping_with_options=0 -sip_random_port=0 -rtcp_xr_enabled=1 -rtcp_xr_rcvr_rtt_mode=all -rtcp_xr_rcvr_rtt_max_size=10000 -rtcp_xr_stat_summary_enabled=1 -rtcp_xr_voip_metrics_enabled=1 - -[rtp] -audio_jitt_comp=60 -video_jitt_comp=60 -nortp_timeout=30 - -[sound] -ringer_dev_id=AQ: Audio Queue Device -echocancellation=0 -dtmf_player_amp=0.007 -eq_location=mic -eq_gains=50:2:50 100:2:50 - -[misc] -history_max_size=30 -max_calls=3 - -[wizard] -service_url=https://www.linphone.org/wizard.php -domain=sip.linphone.org -proxy=sip.linphone.org:5223 -password_length=6 -username_length=4 -expires=1314000 -push_notification=1 -transport=tls -sharing_server=https://www.linphone.org:444/upload.php -ice=1 -stun=stun.linphone.org - -[video] -display_filter_auto_rotate=0 - - diff --git a/Resources/linphonerc~ipad b/Resources/linphonerc~ipad index 1b6ff9d07..f3f5ad09d 100644 --- a/Resources/linphonerc~ipad +++ b/Resources/linphonerc~ipad @@ -1,14 +1,34 @@ +[net] +mtu=1300 +activate_edge_workarounds=0 +edge_ping_time=10 +edge_bw=10 + [sip] contact="Linphone iPhone" keepalive_period=30000 -default_proxy=0 sip_port=-1 sip_tcp_port=-1 use_ipv6=0 +inc_timeout=45 +use_info=0 +guess_hostname=1 +register_only_when_network_is_up=1 +auto_net_state_mon=0 +keepalive_period=30000 +ping_with_options=0 +rtcp_xr_enabled=1 +rtcp_xr_rcvr_rtt_mode=all +rtcp_xr_rcvr_rtt_max_size=10000 +rtcp_xr_stat_summary_enabled=1 +rtcp_xr_voip_metrics_enabled=1 [rtp] -audio_rtp_port=7076 -video_rtp_port=9078 +audio_rtp_port=7200-7299 +video_rtp_port=9200-9299 +audio_jitt_comp=60 +video_jitt_comp=60 +nortp_timeout=30 [video] display=1 @@ -20,9 +40,10 @@ automatically_initiate=0 automatically_accept=0 [net] -firewall_policy=0 download_bw=512 upload_bw=512 +firewall_policy=ice +stun_server=stun.linphone.org [sound] playback_dev_id=AU: Audio Unit Receiver @@ -33,12 +54,20 @@ eq_active=0 preview_preference=1 animations_preference=1 edge_opt_preference=0 -use_system_contacts=0 start_at_boot_preference=1 backgroundmode_preference=1 autoanswer_notif_preference=1 voiceproc_preference=1 +enable_log_collect=0 +file_transfer_migration_done=1 +pushnotification_preference=1 +ice_preference=1 +stun_preference=stun.linphone.org +random_port_preference=1 [default_values] -reg_expires=600 +reg_expires=1314000 +[misc] +max_calls=3 +file_transfer_server_url=https://www.linphone.org:444/lft.php diff --git a/Resources/list_delete_default.png b/Resources/list_delete_default.png deleted file mode 100644 index ef1ae410e..000000000 Binary files a/Resources/list_delete_default.png and /dev/null differ diff --git a/Resources/list_delete_over.png b/Resources/list_delete_over.png deleted file mode 100644 index ec9522b3b..000000000 Binary files a/Resources/list_delete_over.png and /dev/null differ diff --git a/Resources/list_details_default.png b/Resources/list_details_default.png deleted file mode 100644 index a4856294d..000000000 Binary files a/Resources/list_details_default.png and /dev/null differ diff --git a/Resources/list_details_over.png b/Resources/list_details_over.png deleted file mode 100644 index 9cecd5e59..000000000 Binary files a/Resources/list_details_over.png and /dev/null differ diff --git a/Resources/logo_linphone_trame_background.png b/Resources/logo_linphone_trame_background.png deleted file mode 100644 index 749d70f30..000000000 Binary files a/Resources/logo_linphone_trame_background.png and /dev/null differ diff --git a/Resources/micro_off_default.png b/Resources/micro_off_default.png deleted file mode 100644 index a877f654c..000000000 Binary files a/Resources/micro_off_default.png and /dev/null differ diff --git a/Resources/micro_off_default_landscape.png b/Resources/micro_off_default_landscape.png deleted file mode 100644 index 297071951..000000000 Binary files a/Resources/micro_off_default_landscape.png and /dev/null differ diff --git a/Resources/micro_off_default_landscape~ipad.png b/Resources/micro_off_default_landscape~ipad.png deleted file mode 100644 index 45a5e3686..000000000 Binary files a/Resources/micro_off_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/micro_off_default~ipad.png b/Resources/micro_off_default~ipad.png deleted file mode 100644 index 33e86a703..000000000 Binary files a/Resources/micro_off_default~ipad.png and /dev/null differ diff --git a/Resources/micro_off_disabled.png b/Resources/micro_off_disabled.png deleted file mode 100644 index 4baf0de70..000000000 Binary files a/Resources/micro_off_disabled.png and /dev/null differ diff --git a/Resources/micro_off_disabled_landscape.png b/Resources/micro_off_disabled_landscape.png deleted file mode 100644 index ef133210a..000000000 Binary files a/Resources/micro_off_disabled_landscape.png and /dev/null differ diff --git a/Resources/micro_off_disabled_landscape~ipad.png b/Resources/micro_off_disabled_landscape~ipad.png deleted file mode 100644 index 1a890b399..000000000 Binary files a/Resources/micro_off_disabled_landscape~ipad.png and /dev/null differ diff --git a/Resources/micro_off_disabled~ipad.png b/Resources/micro_off_disabled~ipad.png deleted file mode 100644 index 546155e91..000000000 Binary files a/Resources/micro_off_disabled~ipad.png and /dev/null differ diff --git a/Resources/micro_off_over.png b/Resources/micro_off_over.png deleted file mode 100644 index 8663a11ef..000000000 Binary files a/Resources/micro_off_over.png and /dev/null differ diff --git a/Resources/micro_off_over_landscape.png b/Resources/micro_off_over_landscape.png deleted file mode 100644 index 772d734fb..000000000 Binary files a/Resources/micro_off_over_landscape.png and /dev/null differ diff --git a/Resources/micro_off_over_landscape~ipad.png b/Resources/micro_off_over_landscape~ipad.png deleted file mode 100644 index 747f22b75..000000000 Binary files a/Resources/micro_off_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/micro_off_over~ipad.png b/Resources/micro_off_over~ipad.png deleted file mode 100644 index 704a59e1e..000000000 Binary files a/Resources/micro_off_over~ipad.png and /dev/null differ diff --git a/Resources/micro_on_default.png b/Resources/micro_on_default.png deleted file mode 100644 index 8c73609fe..000000000 Binary files a/Resources/micro_on_default.png and /dev/null differ diff --git a/Resources/micro_on_default_landscape.png b/Resources/micro_on_default_landscape.png deleted file mode 100644 index 0f8be95ea..000000000 Binary files a/Resources/micro_on_default_landscape.png and /dev/null differ diff --git a/Resources/micro_on_default_landscape~ipad.png b/Resources/micro_on_default_landscape~ipad.png deleted file mode 100644 index 29cdd5723..000000000 Binary files a/Resources/micro_on_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/micro_on_default~ipad.png b/Resources/micro_on_default~ipad.png deleted file mode 100644 index 4c99b34d4..000000000 Binary files a/Resources/micro_on_default~ipad.png and /dev/null differ diff --git a/Resources/micro_on_disabled.png b/Resources/micro_on_disabled.png deleted file mode 100644 index 35fb4bfeb..000000000 Binary files a/Resources/micro_on_disabled.png and /dev/null differ diff --git a/Resources/micro_on_disabled_landscape.png b/Resources/micro_on_disabled_landscape.png deleted file mode 100644 index 9165841a8..000000000 Binary files a/Resources/micro_on_disabled_landscape.png and /dev/null differ diff --git a/Resources/micro_on_disabled_landscape~ipad.png b/Resources/micro_on_disabled_landscape~ipad.png deleted file mode 100644 index 9221d6277..000000000 Binary files a/Resources/micro_on_disabled_landscape~ipad.png and /dev/null differ diff --git a/Resources/micro_on_disabled~ipad.png b/Resources/micro_on_disabled~ipad.png deleted file mode 100644 index 762b400fd..000000000 Binary files a/Resources/micro_on_disabled~ipad.png and /dev/null differ diff --git a/Resources/micro_on_over.png b/Resources/micro_on_over.png deleted file mode 100644 index 96f645d52..000000000 Binary files a/Resources/micro_on_over.png and /dev/null differ diff --git a/Resources/micro_on_over_landscape.png b/Resources/micro_on_over_landscape.png deleted file mode 100644 index 8afa26cee..000000000 Binary files a/Resources/micro_on_over_landscape.png and /dev/null differ diff --git a/Resources/micro_on_over_landscape~ipad.png b/Resources/micro_on_over_landscape~ipad.png deleted file mode 100644 index 1f47f646c..000000000 Binary files a/Resources/micro_on_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/micro_on_over~ipad.png b/Resources/micro_on_over~ipad.png deleted file mode 100644 index 975e12123..000000000 Binary files a/Resources/micro_on_over~ipad.png and /dev/null differ diff --git a/Resources/msg.caf b/Resources/msg.caf deleted file mode 100644 index 7d843230a..000000000 Binary files a/Resources/msg.caf and /dev/null differ diff --git a/Resources/msg.wav b/Resources/msg.wav deleted file mode 100755 index a6ffd42f2..000000000 Binary files a/Resources/msg.wav and /dev/null differ diff --git a/Resources/nl.lproj/Localizable.strings b/Resources/nl.lproj/Localizable.strings new file mode 100644 index 000000000..db9a97a4d Binary files /dev/null and b/Resources/nl.lproj/Localizable.strings differ diff --git a/Resources/numpad_eight_default.png b/Resources/numpad_eight_default.png deleted file mode 100644 index a3c0d8033..000000000 Binary files a/Resources/numpad_eight_default.png and /dev/null differ diff --git a/Resources/numpad_eight_over.png b/Resources/numpad_eight_over.png deleted file mode 100644 index 2ccb7f97c..000000000 Binary files a/Resources/numpad_eight_over.png and /dev/null differ diff --git a/Resources/numpad_five_default.png b/Resources/numpad_five_default.png deleted file mode 100644 index 023eee43b..000000000 Binary files a/Resources/numpad_five_default.png and /dev/null differ diff --git a/Resources/numpad_five_over.png b/Resources/numpad_five_over.png deleted file mode 100644 index 3b4a62e63..000000000 Binary files a/Resources/numpad_five_over.png and /dev/null differ diff --git a/Resources/numpad_four_default.png b/Resources/numpad_four_default.png deleted file mode 100644 index fa788a745..000000000 Binary files a/Resources/numpad_four_default.png and /dev/null differ diff --git a/Resources/numpad_four_over.png b/Resources/numpad_four_over.png deleted file mode 100644 index 2bffe94d5..000000000 Binary files a/Resources/numpad_four_over.png and /dev/null differ diff --git a/Resources/numpad_nine_default.png b/Resources/numpad_nine_default.png deleted file mode 100644 index 594a49d5f..000000000 Binary files a/Resources/numpad_nine_default.png and /dev/null differ diff --git a/Resources/numpad_nine_over.png b/Resources/numpad_nine_over.png deleted file mode 100644 index c457e8400..000000000 Binary files a/Resources/numpad_nine_over.png and /dev/null differ diff --git a/Resources/numpad_one_default.png b/Resources/numpad_one_default.png deleted file mode 100644 index 07f8d0ecf..000000000 Binary files a/Resources/numpad_one_default.png and /dev/null differ diff --git a/Resources/numpad_one_over.png b/Resources/numpad_one_over.png deleted file mode 100644 index abe10c6e7..000000000 Binary files a/Resources/numpad_one_over.png and /dev/null differ diff --git a/Resources/numpad_one_voicemail_default.png b/Resources/numpad_one_voicemail_default.png deleted file mode 100644 index 07f8d0ecf..000000000 Binary files a/Resources/numpad_one_voicemail_default.png and /dev/null differ diff --git a/Resources/numpad_one_voicemail_over.png b/Resources/numpad_one_voicemail_over.png deleted file mode 100644 index abe10c6e7..000000000 Binary files a/Resources/numpad_one_voicemail_over.png and /dev/null differ diff --git a/Resources/numpad_seven_default.png b/Resources/numpad_seven_default.png deleted file mode 100644 index 85ea3ddcf..000000000 Binary files a/Resources/numpad_seven_default.png and /dev/null differ diff --git a/Resources/numpad_seven_over.png b/Resources/numpad_seven_over.png deleted file mode 100644 index 9ec319835..000000000 Binary files a/Resources/numpad_seven_over.png and /dev/null differ diff --git a/Resources/numpad_sharp_default.png b/Resources/numpad_sharp_default.png deleted file mode 100644 index c551d9121..000000000 Binary files a/Resources/numpad_sharp_default.png and /dev/null differ diff --git a/Resources/numpad_sharp_over.png b/Resources/numpad_sharp_over.png deleted file mode 100644 index dffb1b062..000000000 Binary files a/Resources/numpad_sharp_over.png and /dev/null differ diff --git a/Resources/numpad_six_default.png b/Resources/numpad_six_default.png deleted file mode 100644 index 5404d14ec..000000000 Binary files a/Resources/numpad_six_default.png and /dev/null differ diff --git a/Resources/numpad_six_over.png b/Resources/numpad_six_over.png deleted file mode 100644 index aee8556d7..000000000 Binary files a/Resources/numpad_six_over.png and /dev/null differ diff --git a/Resources/numpad_star_default.png b/Resources/numpad_star_default.png deleted file mode 100644 index 6034e1a99..000000000 Binary files a/Resources/numpad_star_default.png and /dev/null differ diff --git a/Resources/numpad_star_over.png b/Resources/numpad_star_over.png deleted file mode 100644 index ac9639ff7..000000000 Binary files a/Resources/numpad_star_over.png and /dev/null differ diff --git a/Resources/numpad_three_default.png b/Resources/numpad_three_default.png deleted file mode 100644 index 5a489c493..000000000 Binary files a/Resources/numpad_three_default.png and /dev/null differ diff --git a/Resources/numpad_three_over.png b/Resources/numpad_three_over.png deleted file mode 100644 index 8fb1e1dc8..000000000 Binary files a/Resources/numpad_three_over.png and /dev/null differ diff --git a/Resources/numpad_two_default.png b/Resources/numpad_two_default.png deleted file mode 100644 index 0de47b0bb..000000000 Binary files a/Resources/numpad_two_default.png and /dev/null differ diff --git a/Resources/numpad_two_over.png b/Resources/numpad_two_over.png deleted file mode 100644 index da5f95e90..000000000 Binary files a/Resources/numpad_two_over.png and /dev/null differ diff --git a/Resources/numpad_zero_default.png b/Resources/numpad_zero_default.png deleted file mode 100644 index 465a3c9f6..000000000 Binary files a/Resources/numpad_zero_default.png and /dev/null differ diff --git a/Resources/numpad_zero_over.png b/Resources/numpad_zero_over.png deleted file mode 100644 index 86c14f38c..000000000 Binary files a/Resources/numpad_zero_over.png and /dev/null differ diff --git a/Resources/options_add_default.png b/Resources/options_add_default.png deleted file mode 100644 index 59ea816e7..000000000 Binary files a/Resources/options_add_default.png and /dev/null differ diff --git a/Resources/options_add_default_landscape.png b/Resources/options_add_default_landscape.png deleted file mode 100644 index f85f44628..000000000 Binary files a/Resources/options_add_default_landscape.png and /dev/null differ diff --git a/Resources/options_add_default_landscape~ipad.png b/Resources/options_add_default_landscape~ipad.png deleted file mode 100644 index 16e482c1a..000000000 Binary files a/Resources/options_add_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/options_add_default~ipad.png b/Resources/options_add_default~ipad.png deleted file mode 100644 index 13406878a..000000000 Binary files a/Resources/options_add_default~ipad.png and /dev/null differ diff --git a/Resources/options_add_disabled.png b/Resources/options_add_disabled.png deleted file mode 100644 index a8d6f75d8..000000000 Binary files a/Resources/options_add_disabled.png and /dev/null differ diff --git a/Resources/options_add_disabled_landscape.png b/Resources/options_add_disabled_landscape.png deleted file mode 100644 index 2b9997731..000000000 Binary files a/Resources/options_add_disabled_landscape.png and /dev/null differ diff --git a/Resources/options_add_disabled_landscape~ipad.png b/Resources/options_add_disabled_landscape~ipad.png deleted file mode 100644 index d515be37f..000000000 Binary files a/Resources/options_add_disabled_landscape~ipad.png and /dev/null differ diff --git a/Resources/options_add_disabled~ipad.png b/Resources/options_add_disabled~ipad.png deleted file mode 100644 index 48323660d..000000000 Binary files a/Resources/options_add_disabled~ipad.png and /dev/null differ diff --git a/Resources/options_add_over.png b/Resources/options_add_over.png deleted file mode 100644 index 06ec439f1..000000000 Binary files a/Resources/options_add_over.png and /dev/null differ diff --git a/Resources/options_add_over_landscape.png b/Resources/options_add_over_landscape.png deleted file mode 100644 index eddae5444..000000000 Binary files a/Resources/options_add_over_landscape.png and /dev/null differ diff --git a/Resources/options_add_over_landscape~ipad.png b/Resources/options_add_over_landscape~ipad.png deleted file mode 100644 index 44b79256d..000000000 Binary files a/Resources/options_add_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/options_add_over~ipad.png b/Resources/options_add_over~ipad.png deleted file mode 100644 index 511a72640..000000000 Binary files a/Resources/options_add_over~ipad.png and /dev/null differ diff --git a/Resources/options_default.png b/Resources/options_default.png deleted file mode 100644 index cdec05400..000000000 Binary files a/Resources/options_default.png and /dev/null differ diff --git a/Resources/options_default_landscape.png b/Resources/options_default_landscape.png deleted file mode 100644 index e835f0829..000000000 Binary files a/Resources/options_default_landscape.png and /dev/null differ diff --git a/Resources/options_default_landscape~ipad.png b/Resources/options_default_landscape~ipad.png deleted file mode 100644 index 77379da0e..000000000 Binary files a/Resources/options_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/options_default~ipad.png b/Resources/options_default~ipad.png deleted file mode 100644 index 7e765d8cc..000000000 Binary files a/Resources/options_default~ipad.png and /dev/null differ diff --git a/Resources/options_disabled.png b/Resources/options_disabled.png deleted file mode 100644 index 6199d95b9..000000000 Binary files a/Resources/options_disabled.png and /dev/null differ diff --git a/Resources/options_disabled_landscape.png b/Resources/options_disabled_landscape.png deleted file mode 100644 index 25bee610a..000000000 Binary files a/Resources/options_disabled_landscape.png and /dev/null differ diff --git a/Resources/options_disabled_landscape~ipad.png b/Resources/options_disabled_landscape~ipad.png deleted file mode 100644 index c56fae1ca..000000000 Binary files a/Resources/options_disabled_landscape~ipad.png and /dev/null differ diff --git a/Resources/options_disabled~ipad.png b/Resources/options_disabled~ipad.png deleted file mode 100644 index 20e8abe6e..000000000 Binary files a/Resources/options_disabled~ipad.png and /dev/null differ diff --git a/Resources/options_over.png b/Resources/options_over.png deleted file mode 100644 index 4000c7b53..000000000 Binary files a/Resources/options_over.png and /dev/null differ diff --git a/Resources/options_over_landscape.png b/Resources/options_over_landscape.png deleted file mode 100644 index dc2bb8404..000000000 Binary files a/Resources/options_over_landscape.png and /dev/null differ diff --git a/Resources/options_over_landscape~ipad.png b/Resources/options_over_landscape~ipad.png deleted file mode 100644 index b32bd7274..000000000 Binary files a/Resources/options_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/options_over~ipad.png b/Resources/options_over~ipad.png deleted file mode 100644 index 35605bd12..000000000 Binary files a/Resources/options_over~ipad.png and /dev/null differ diff --git a/Resources/options_selected.png b/Resources/options_selected.png deleted file mode 100644 index ab105de64..000000000 Binary files a/Resources/options_selected.png and /dev/null differ diff --git a/Resources/options_selected_landscape.png b/Resources/options_selected_landscape.png deleted file mode 100644 index 4de39f880..000000000 Binary files a/Resources/options_selected_landscape.png and /dev/null differ diff --git a/Resources/options_selected_landscape~ipad.png b/Resources/options_selected_landscape~ipad.png deleted file mode 100644 index 4dde52145..000000000 Binary files a/Resources/options_selected_landscape~ipad.png and /dev/null differ diff --git a/Resources/options_selected~ipad.png b/Resources/options_selected~ipad.png deleted file mode 100644 index 09ffcfe12..000000000 Binary files a/Resources/options_selected~ipad.png and /dev/null differ diff --git a/Resources/options_transfer_default.png b/Resources/options_transfer_default.png deleted file mode 100644 index 409193c81..000000000 Binary files a/Resources/options_transfer_default.png and /dev/null differ diff --git a/Resources/options_transfer_default_landscape.png b/Resources/options_transfer_default_landscape.png deleted file mode 100644 index 3c9ad5cb1..000000000 Binary files a/Resources/options_transfer_default_landscape.png and /dev/null differ diff --git a/Resources/options_transfer_default_landscape~ipad.png b/Resources/options_transfer_default_landscape~ipad.png deleted file mode 100644 index 17d2efa75..000000000 Binary files a/Resources/options_transfer_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/options_transfer_default~ipad.png b/Resources/options_transfer_default~ipad.png deleted file mode 100644 index 35387e901..000000000 Binary files a/Resources/options_transfer_default~ipad.png and /dev/null differ diff --git a/Resources/options_transfer_disabled.png b/Resources/options_transfer_disabled.png deleted file mode 100644 index 6e8cd79a2..000000000 Binary files a/Resources/options_transfer_disabled.png and /dev/null differ diff --git a/Resources/options_transfer_disabled_landscape.png b/Resources/options_transfer_disabled_landscape.png deleted file mode 100644 index 95fea9ef3..000000000 Binary files a/Resources/options_transfer_disabled_landscape.png and /dev/null differ diff --git a/Resources/options_transfer_disabled_landscape~ipad.png b/Resources/options_transfer_disabled_landscape~ipad.png deleted file mode 100644 index 10aba5a24..000000000 Binary files a/Resources/options_transfer_disabled_landscape~ipad.png and /dev/null differ diff --git a/Resources/options_transfer_disabled~ipad.png b/Resources/options_transfer_disabled~ipad.png deleted file mode 100644 index b39220651..000000000 Binary files a/Resources/options_transfer_disabled~ipad.png and /dev/null differ diff --git a/Resources/options_transfer_over.png b/Resources/options_transfer_over.png deleted file mode 100644 index ea07e8d7f..000000000 Binary files a/Resources/options_transfer_over.png and /dev/null differ diff --git a/Resources/options_transfer_over_landscape.png b/Resources/options_transfer_over_landscape.png deleted file mode 100644 index 4e13b8a6a..000000000 Binary files a/Resources/options_transfer_over_landscape.png and /dev/null differ diff --git a/Resources/options_transfer_over_landscape~ipad.png b/Resources/options_transfer_over_landscape~ipad.png deleted file mode 100644 index c90279aa6..000000000 Binary files a/Resources/options_transfer_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/options_transfer_over~ipad.png b/Resources/options_transfer_over~ipad.png deleted file mode 100644 index 96c5fb1ca..000000000 Binary files a/Resources/options_transfer_over~ipad.png and /dev/null differ diff --git a/Resources/pause_off_default.png b/Resources/pause_off_default.png deleted file mode 100644 index c6bf04de7..000000000 Binary files a/Resources/pause_off_default.png and /dev/null differ diff --git a/Resources/pause_off_default_landscape.png b/Resources/pause_off_default_landscape.png deleted file mode 100644 index 4c73470f8..000000000 Binary files a/Resources/pause_off_default_landscape.png and /dev/null differ diff --git a/Resources/pause_off_default_landscape~ipad.png b/Resources/pause_off_default_landscape~ipad.png deleted file mode 100644 index c7d17c130..000000000 Binary files a/Resources/pause_off_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/pause_off_default~ipad.png b/Resources/pause_off_default~ipad.png deleted file mode 100644 index c7d17c130..000000000 Binary files a/Resources/pause_off_default~ipad.png and /dev/null differ diff --git a/Resources/pause_off_over.png b/Resources/pause_off_over.png deleted file mode 100644 index 7289286c2..000000000 Binary files a/Resources/pause_off_over.png and /dev/null differ diff --git a/Resources/pause_off_over_landscape.png b/Resources/pause_off_over_landscape.png deleted file mode 100644 index 66545c2d4..000000000 Binary files a/Resources/pause_off_over_landscape.png and /dev/null differ diff --git a/Resources/pause_off_over_landscape~ipad.png b/Resources/pause_off_over_landscape~ipad.png deleted file mode 100644 index 72cfef5e2..000000000 Binary files a/Resources/pause_off_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/pause_off_over~ipad.png b/Resources/pause_off_over~ipad.png deleted file mode 100644 index 72cfef5e2..000000000 Binary files a/Resources/pause_off_over~ipad.png and /dev/null differ diff --git a/Resources/pause_on_default.png b/Resources/pause_on_default.png deleted file mode 100644 index f6c266768..000000000 Binary files a/Resources/pause_on_default.png and /dev/null differ diff --git a/Resources/pause_on_default_landscape.png b/Resources/pause_on_default_landscape.png deleted file mode 100644 index 58c98a583..000000000 Binary files a/Resources/pause_on_default_landscape.png and /dev/null differ diff --git a/Resources/pause_on_default_landscape~ipad.png b/Resources/pause_on_default_landscape~ipad.png deleted file mode 100644 index 2aba53412..000000000 Binary files a/Resources/pause_on_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/pause_on_default~ipad.png b/Resources/pause_on_default~ipad.png deleted file mode 100644 index 2aba53412..000000000 Binary files a/Resources/pause_on_default~ipad.png and /dev/null differ diff --git a/Resources/pause_on_over.png b/Resources/pause_on_over.png deleted file mode 100644 index 8268d1f8a..000000000 Binary files a/Resources/pause_on_over.png and /dev/null differ diff --git a/Resources/pause_on_over_landscape.png b/Resources/pause_on_over_landscape.png deleted file mode 100644 index 37b2875db..000000000 Binary files a/Resources/pause_on_over_landscape.png and /dev/null differ diff --git a/Resources/pause_on_over_landscape~ipad.png b/Resources/pause_on_over_landscape~ipad.png deleted file mode 100644 index 60eb8a551..000000000 Binary files a/Resources/pause_on_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/pause_on_over~ipad.png b/Resources/pause_on_over~ipad.png deleted file mode 100644 index 60eb8a551..000000000 Binary files a/Resources/pause_on_over~ipad.png and /dev/null differ diff --git a/Resources/ring.caf b/Resources/ring.caf deleted file mode 100644 index 148592939..000000000 Binary files a/Resources/ring.caf and /dev/null differ diff --git a/Resources/ring.wav b/Resources/ring.wav deleted file mode 100644 index 39a1c9a80..000000000 Binary files a/Resources/ring.wav and /dev/null differ diff --git a/Resources/route_bluetooth_off_default.png b/Resources/route_bluetooth_off_default.png deleted file mode 100644 index 01bc1f291..000000000 Binary files a/Resources/route_bluetooth_off_default.png and /dev/null differ diff --git a/Resources/route_bluetooth_off_default_landscape.png b/Resources/route_bluetooth_off_default_landscape.png deleted file mode 100644 index 84a001275..000000000 Binary files a/Resources/route_bluetooth_off_default_landscape.png and /dev/null differ diff --git a/Resources/route_bluetooth_off_disabled.png b/Resources/route_bluetooth_off_disabled.png deleted file mode 100644 index 3d03f1cba..000000000 Binary files a/Resources/route_bluetooth_off_disabled.png and /dev/null differ diff --git a/Resources/route_bluetooth_off_disabled_landscape.png b/Resources/route_bluetooth_off_disabled_landscape.png deleted file mode 100644 index f523bd6c3..000000000 Binary files a/Resources/route_bluetooth_off_disabled_landscape.png and /dev/null differ diff --git a/Resources/route_bluetooth_off_over.png b/Resources/route_bluetooth_off_over.png deleted file mode 100644 index 66112a8d7..000000000 Binary files a/Resources/route_bluetooth_off_over.png and /dev/null differ diff --git a/Resources/route_bluetooth_off_over_landscape.png b/Resources/route_bluetooth_off_over_landscape.png deleted file mode 100644 index ebaffea54..000000000 Binary files a/Resources/route_bluetooth_off_over_landscape.png and /dev/null differ diff --git a/Resources/route_bluetooth_on_default.png b/Resources/route_bluetooth_on_default.png deleted file mode 100644 index 841c93b65..000000000 Binary files a/Resources/route_bluetooth_on_default.png and /dev/null differ diff --git a/Resources/route_bluetooth_on_default_landscape.png b/Resources/route_bluetooth_on_default_landscape.png deleted file mode 100644 index 9cbdf574d..000000000 Binary files a/Resources/route_bluetooth_on_default_landscape.png and /dev/null differ diff --git a/Resources/route_phone_off_default.png b/Resources/route_phone_off_default.png deleted file mode 100644 index 4510f0bcb..000000000 Binary files a/Resources/route_phone_off_default.png and /dev/null differ diff --git a/Resources/route_phone_off_default_landscape.png b/Resources/route_phone_off_default_landscape.png deleted file mode 100644 index e9b944cc6..000000000 Binary files a/Resources/route_phone_off_default_landscape.png and /dev/null differ diff --git a/Resources/route_phone_off_disabled.png b/Resources/route_phone_off_disabled.png deleted file mode 100644 index 8c9405533..000000000 Binary files a/Resources/route_phone_off_disabled.png and /dev/null differ diff --git a/Resources/route_phone_off_disabled_landscape.png b/Resources/route_phone_off_disabled_landscape.png deleted file mode 100644 index 1d58d39c8..000000000 Binary files a/Resources/route_phone_off_disabled_landscape.png and /dev/null differ diff --git a/Resources/route_phone_off_over.png b/Resources/route_phone_off_over.png deleted file mode 100644 index bc383167e..000000000 Binary files a/Resources/route_phone_off_over.png and /dev/null differ diff --git a/Resources/route_phone_off_over_landscape.png b/Resources/route_phone_off_over_landscape.png deleted file mode 100644 index f9b8f9734..000000000 Binary files a/Resources/route_phone_off_over_landscape.png and /dev/null differ diff --git a/Resources/route_phone_on_default.png b/Resources/route_phone_on_default.png deleted file mode 100644 index 16cc9e2f3..000000000 Binary files a/Resources/route_phone_on_default.png and /dev/null differ diff --git a/Resources/route_phone_on_default_landscape.png b/Resources/route_phone_on_default_landscape.png deleted file mode 100644 index b35b9aa64..000000000 Binary files a/Resources/route_phone_on_default_landscape.png and /dev/null differ diff --git a/Resources/route_speaker_off_default.png b/Resources/route_speaker_off_default.png deleted file mode 100644 index 908031972..000000000 Binary files a/Resources/route_speaker_off_default.png and /dev/null differ diff --git a/Resources/route_speaker_off_default_landscape.png b/Resources/route_speaker_off_default_landscape.png deleted file mode 100644 index d6c7eacde..000000000 Binary files a/Resources/route_speaker_off_default_landscape.png and /dev/null differ diff --git a/Resources/route_speaker_off_disabled.png b/Resources/route_speaker_off_disabled.png deleted file mode 100644 index 8294f5251..000000000 Binary files a/Resources/route_speaker_off_disabled.png and /dev/null differ diff --git a/Resources/route_speaker_off_disabled_landscape.png b/Resources/route_speaker_off_disabled_landscape.png deleted file mode 100644 index f750b1610..000000000 Binary files a/Resources/route_speaker_off_disabled_landscape.png and /dev/null differ diff --git a/Resources/route_speaker_off_over.png b/Resources/route_speaker_off_over.png deleted file mode 100644 index f6c5ce9f6..000000000 Binary files a/Resources/route_speaker_off_over.png and /dev/null differ diff --git a/Resources/route_speaker_off_over_landscape.png b/Resources/route_speaker_off_over_landscape.png deleted file mode 100644 index 74bf86fa1..000000000 Binary files a/Resources/route_speaker_off_over_landscape.png and /dev/null differ diff --git a/Resources/route_speaker_on_default.png b/Resources/route_speaker_on_default.png deleted file mode 100644 index 8cfdc036a..000000000 Binary files a/Resources/route_speaker_on_default.png and /dev/null differ diff --git a/Resources/route_speaker_on_default_landscape.png b/Resources/route_speaker_on_default_landscape.png deleted file mode 100644 index 293e675e2..000000000 Binary files a/Resources/route_speaker_on_default_landscape.png and /dev/null differ diff --git a/Resources/routes_default.png b/Resources/routes_default.png deleted file mode 100644 index a0502e293..000000000 Binary files a/Resources/routes_default.png and /dev/null differ diff --git a/Resources/routes_default_landscape.png b/Resources/routes_default_landscape.png deleted file mode 100644 index cc68859a8..000000000 Binary files a/Resources/routes_default_landscape.png and /dev/null differ diff --git a/Resources/routes_disabled.png b/Resources/routes_disabled.png deleted file mode 100644 index aa54e1ab5..000000000 Binary files a/Resources/routes_disabled.png and /dev/null differ diff --git a/Resources/routes_disabled_landscape.png b/Resources/routes_disabled_landscape.png deleted file mode 100644 index 437bdcb35..000000000 Binary files a/Resources/routes_disabled_landscape.png and /dev/null differ diff --git a/Resources/routes_over.png b/Resources/routes_over.png deleted file mode 100644 index c6e555a46..000000000 Binary files a/Resources/routes_over.png and /dev/null differ diff --git a/Resources/routes_over_landscape.png b/Resources/routes_over_landscape.png deleted file mode 100644 index 958cdc28c..000000000 Binary files a/Resources/routes_over_landscape.png and /dev/null differ diff --git a/Resources/routes_selected.png b/Resources/routes_selected.png deleted file mode 100644 index 9930fd81e..000000000 Binary files a/Resources/routes_selected.png and /dev/null differ diff --git a/Resources/routes_selected_landscape.png b/Resources/routes_selected_landscape.png deleted file mode 100644 index 54a0aa48c..000000000 Binary files a/Resources/routes_selected_landscape.png and /dev/null differ diff --git a/Resources/ru.lproj/Localizable.strings b/Resources/ru.lproj/Localizable.strings index 0a9e737e4..8afed6079 100644 Binary files a/Resources/ru.lproj/Localizable.strings and b/Resources/ru.lproj/Localizable.strings differ diff --git a/Resources/security_ko.png b/Resources/security_ko.png deleted file mode 100644 index bf75d1b27..000000000 Binary files a/Resources/security_ko.png and /dev/null differ diff --git a/Resources/security_ok.png b/Resources/security_ok.png deleted file mode 100644 index 0a48c7d14..000000000 Binary files a/Resources/security_ok.png and /dev/null differ diff --git a/Resources/security_pending.png b/Resources/security_pending.png deleted file mode 100644 index 1f68accf2..000000000 Binary files a/Resources/security_pending.png and /dev/null differ diff --git a/Resources/settings_default.png b/Resources/settings_default.png deleted file mode 100644 index ea82dcf74..000000000 Binary files a/Resources/settings_default.png and /dev/null differ diff --git a/Resources/settings_default_landscape~ipad.png b/Resources/settings_default_landscape~ipad.png deleted file mode 100644 index 70e72c43d..000000000 Binary files a/Resources/settings_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/settings_default~ipad.png b/Resources/settings_default~ipad.png deleted file mode 100644 index da8f27fe7..000000000 Binary files a/Resources/settings_default~ipad.png and /dev/null differ diff --git a/Resources/settings_over.png b/Resources/settings_over.png deleted file mode 100644 index c73168440..000000000 Binary files a/Resources/settings_over.png and /dev/null differ diff --git a/Resources/settings_over_landscape~ipad.png b/Resources/settings_over_landscape~ipad.png deleted file mode 100644 index 0dbd9da35..000000000 Binary files a/Resources/settings_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/settings_over~ipad.png b/Resources/settings_over~ipad.png deleted file mode 100644 index ffa58e3e6..000000000 Binary files a/Resources/settings_over~ipad.png and /dev/null differ diff --git a/Resources/settings_selected.png b/Resources/settings_selected.png deleted file mode 100644 index 6070b2c09..000000000 Binary files a/Resources/settings_selected.png and /dev/null differ diff --git a/Resources/settings_selected_landscape~ipad.png b/Resources/settings_selected_landscape~ipad.png deleted file mode 100644 index 0c374fb14..000000000 Binary files a/Resources/settings_selected_landscape~ipad.png and /dev/null differ diff --git a/Resources/settings_selected~ipad.png b/Resources/settings_selected~ipad.png deleted file mode 100644 index 8918116e5..000000000 Binary files a/Resources/settings_selected~ipad.png and /dev/null differ diff --git a/Resources/setup_back_default.png b/Resources/setup_back_default.png deleted file mode 100644 index ddb63847f..000000000 Binary files a/Resources/setup_back_default.png and /dev/null differ diff --git a/Resources/setup_back_default_landscape~ipad.png b/Resources/setup_back_default_landscape~ipad.png deleted file mode 100644 index 24df95c3b..000000000 Binary files a/Resources/setup_back_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/setup_back_default~ipad.png b/Resources/setup_back_default~ipad.png deleted file mode 100644 index 8da3a3da0..000000000 Binary files a/Resources/setup_back_default~ipad.png and /dev/null differ diff --git a/Resources/setup_back_disabled.png b/Resources/setup_back_disabled.png deleted file mode 100644 index bbc23f190..000000000 Binary files a/Resources/setup_back_disabled.png and /dev/null differ diff --git a/Resources/setup_back_disabled_landscape~ipad.png b/Resources/setup_back_disabled_landscape~ipad.png deleted file mode 100644 index a3bf99b0a..000000000 Binary files a/Resources/setup_back_disabled_landscape~ipad.png and /dev/null differ diff --git a/Resources/setup_back_disabled~ipad.png b/Resources/setup_back_disabled~ipad.png deleted file mode 100644 index 9bd7d70f1..000000000 Binary files a/Resources/setup_back_disabled~ipad.png and /dev/null differ diff --git a/Resources/setup_back_over.png b/Resources/setup_back_over.png deleted file mode 100644 index aa86ad542..000000000 Binary files a/Resources/setup_back_over.png and /dev/null differ diff --git a/Resources/setup_back_over_landscape~ipad.png b/Resources/setup_back_over_landscape~ipad.png deleted file mode 100644 index b4b2cc8b7..000000000 Binary files a/Resources/setup_back_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/setup_back_over~ipad.png b/Resources/setup_back_over~ipad.png deleted file mode 100644 index 6e0a20d98..000000000 Binary files a/Resources/setup_back_over~ipad.png and /dev/null differ diff --git a/Resources/setup_cancel_default.png b/Resources/setup_cancel_default.png deleted file mode 100644 index 411381928..000000000 Binary files a/Resources/setup_cancel_default.png and /dev/null differ diff --git a/Resources/setup_cancel_default_landscape~ipad.png b/Resources/setup_cancel_default_landscape~ipad.png deleted file mode 100644 index a0557c5e9..000000000 Binary files a/Resources/setup_cancel_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/setup_cancel_default~ipad.png b/Resources/setup_cancel_default~ipad.png deleted file mode 100644 index 766ba949a..000000000 Binary files a/Resources/setup_cancel_default~ipad.png and /dev/null differ diff --git a/Resources/setup_cancel_disabled.png b/Resources/setup_cancel_disabled.png deleted file mode 100644 index 97674e02c..000000000 Binary files a/Resources/setup_cancel_disabled.png and /dev/null differ diff --git a/Resources/setup_cancel_disabled_landscape~ipad.png b/Resources/setup_cancel_disabled_landscape~ipad.png deleted file mode 100644 index e72f7b4d5..000000000 Binary files a/Resources/setup_cancel_disabled_landscape~ipad.png and /dev/null differ diff --git a/Resources/setup_cancel_disabled~ipad.png b/Resources/setup_cancel_disabled~ipad.png deleted file mode 100644 index 6e6a394a3..000000000 Binary files a/Resources/setup_cancel_disabled~ipad.png and /dev/null differ diff --git a/Resources/setup_cancel_over.png b/Resources/setup_cancel_over.png deleted file mode 100644 index cf48a5173..000000000 Binary files a/Resources/setup_cancel_over.png and /dev/null differ diff --git a/Resources/setup_cancel_over_landscape~ipad.png b/Resources/setup_cancel_over_landscape~ipad.png deleted file mode 100644 index edf9a2624..000000000 Binary files a/Resources/setup_cancel_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/setup_cancel_over~ipad.png b/Resources/setup_cancel_over~ipad.png deleted file mode 100644 index a8be0feb8..000000000 Binary files a/Resources/setup_cancel_over~ipad.png and /dev/null differ diff --git a/Resources/setup_start_default.png b/Resources/setup_start_default.png deleted file mode 100644 index 342a59a6c..000000000 Binary files a/Resources/setup_start_default.png and /dev/null differ diff --git a/Resources/setup_start_default_landscape~ipad.png b/Resources/setup_start_default_landscape~ipad.png deleted file mode 100644 index 8d1af16b9..000000000 Binary files a/Resources/setup_start_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/setup_start_default~ipad.png b/Resources/setup_start_default~ipad.png deleted file mode 100644 index 753f7ddbd..000000000 Binary files a/Resources/setup_start_default~ipad.png and /dev/null differ diff --git a/Resources/setup_start_disabled.png b/Resources/setup_start_disabled.png deleted file mode 100644 index c57868e0a..000000000 Binary files a/Resources/setup_start_disabled.png and /dev/null differ diff --git a/Resources/setup_start_disabled_landscape~ipad.png b/Resources/setup_start_disabled_landscape~ipad.png deleted file mode 100644 index 20b0b5b73..000000000 Binary files a/Resources/setup_start_disabled_landscape~ipad.png and /dev/null differ diff --git a/Resources/setup_start_disabled~ipad.png b/Resources/setup_start_disabled~ipad.png deleted file mode 100644 index da787553b..000000000 Binary files a/Resources/setup_start_disabled~ipad.png and /dev/null differ diff --git a/Resources/setup_start_over.png b/Resources/setup_start_over.png deleted file mode 100644 index 7fc26c6fd..000000000 Binary files a/Resources/setup_start_over.png and /dev/null differ diff --git a/Resources/setup_start_over_landscape~ipad.png b/Resources/setup_start_over_landscape~ipad.png deleted file mode 100644 index fc030704e..000000000 Binary files a/Resources/setup_start_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/setup_start_over~ipad.png b/Resources/setup_start_over~ipad.png deleted file mode 100644 index ab7cb0e06..000000000 Binary files a/Resources/setup_start_over~ipad.png and /dev/null differ diff --git a/Resources/setup_welcome_logo.png b/Resources/setup_welcome_logo.png deleted file mode 100644 index f3992007a..000000000 Binary files a/Resources/setup_welcome_logo.png and /dev/null differ diff --git a/Resources/setup_welcome_logo~ipad.png b/Resources/setup_welcome_logo~ipad.png deleted file mode 100644 index 1d7ab1d73..000000000 Binary files a/Resources/setup_welcome_logo~ipad.png and /dev/null differ diff --git a/Resources/shortring.caf b/Resources/shortring.caf deleted file mode 100644 index c3d9bc24a..000000000 Binary files a/Resources/shortring.caf and /dev/null differ diff --git a/Resources/sounds/hold.caf b/Resources/sounds/hold.caf new file mode 100644 index 000000000..80b62040e Binary files /dev/null and b/Resources/sounds/hold.caf differ diff --git a/Resources/sounds/msg.caf b/Resources/sounds/msg.caf new file mode 100644 index 000000000..9810a0390 Binary files /dev/null and b/Resources/sounds/msg.caf differ diff --git a/Resources/ringback.wav b/Resources/sounds/ringback.wav similarity index 100% rename from Resources/ringback.wav rename to Resources/sounds/ringback.wav diff --git a/Resources/sounds/rings/four_hands_together.caf b/Resources/sounds/rings/four_hands_together.caf new file mode 100644 index 000000000..91c7fe1dc Binary files /dev/null and b/Resources/sounds/rings/four_hands_together.caf differ diff --git a/Resources/sounds/rings/house_keeping.caf b/Resources/sounds/rings/house_keeping.caf new file mode 100644 index 000000000..426f90866 Binary files /dev/null and b/Resources/sounds/rings/house_keeping.caf differ diff --git a/Resources/sounds/rings/it_s_a_game.caf b/Resources/sounds/rings/it_s_a_game.caf new file mode 100644 index 000000000..4cae187d1 Binary files /dev/null and b/Resources/sounds/rings/it_s_a_game.caf differ diff --git a/Resources/sounds/rings/leaving_a_dream.caf b/Resources/sounds/rings/leaving_a_dream.caf new file mode 100644 index 000000000..d2b6cc03e Binary files /dev/null and b/Resources/sounds/rings/leaving_a_dream.caf differ diff --git a/Resources/sounds/rings/notes_of_the_optimistic.caf b/Resources/sounds/rings/notes_of_the_optimistic.caf new file mode 100644 index 000000000..b9b42fee1 Binary files /dev/null and b/Resources/sounds/rings/notes_of_the_optimistic.caf differ diff --git a/Resources/sounds/rings/soft_as_snow.caf b/Resources/sounds/rings/soft_as_snow.caf new file mode 100644 index 000000000..f2b5df1b9 Binary files /dev/null and b/Resources/sounds/rings/soft_as_snow.caf differ diff --git a/Resources/sounds/shortring.caf b/Resources/sounds/shortring.caf new file mode 100644 index 000000000..bed3c39ae Binary files /dev/null and b/Resources/sounds/shortring.caf differ diff --git a/Resources/speaker_off_default.png b/Resources/speaker_off_default.png deleted file mode 100644 index 43f95c20f..000000000 Binary files a/Resources/speaker_off_default.png and /dev/null differ diff --git a/Resources/speaker_off_default_landscape.png b/Resources/speaker_off_default_landscape.png deleted file mode 100644 index a8c06fa29..000000000 Binary files a/Resources/speaker_off_default_landscape.png and /dev/null differ diff --git a/Resources/speaker_off_default_landscape~ipad.png b/Resources/speaker_off_default_landscape~ipad.png deleted file mode 100644 index 4b611178c..000000000 Binary files a/Resources/speaker_off_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/speaker_off_default~ipad.png b/Resources/speaker_off_default~ipad.png deleted file mode 100644 index f2beb56ac..000000000 Binary files a/Resources/speaker_off_default~ipad.png and /dev/null differ diff --git a/Resources/speaker_off_disabled.png b/Resources/speaker_off_disabled.png deleted file mode 100644 index 440af308e..000000000 Binary files a/Resources/speaker_off_disabled.png and /dev/null differ diff --git a/Resources/speaker_off_disabled_landscape.png b/Resources/speaker_off_disabled_landscape.png deleted file mode 100644 index 71e614e16..000000000 Binary files a/Resources/speaker_off_disabled_landscape.png and /dev/null differ diff --git a/Resources/speaker_off_disabled_landscape~ipad.png b/Resources/speaker_off_disabled_landscape~ipad.png deleted file mode 100644 index ebd857da7..000000000 Binary files a/Resources/speaker_off_disabled_landscape~ipad.png and /dev/null differ diff --git a/Resources/speaker_off_disabled~ipad.png b/Resources/speaker_off_disabled~ipad.png deleted file mode 100644 index 5f12dfb26..000000000 Binary files a/Resources/speaker_off_disabled~ipad.png and /dev/null differ diff --git a/Resources/speaker_off_over.png b/Resources/speaker_off_over.png deleted file mode 100644 index 0b42163d2..000000000 Binary files a/Resources/speaker_off_over.png and /dev/null differ diff --git a/Resources/speaker_off_over_landscape.png b/Resources/speaker_off_over_landscape.png deleted file mode 100644 index 66d3c8992..000000000 Binary files a/Resources/speaker_off_over_landscape.png and /dev/null differ diff --git a/Resources/speaker_off_over_landscape~ipad.png b/Resources/speaker_off_over_landscape~ipad.png deleted file mode 100644 index a68c3eb9b..000000000 Binary files a/Resources/speaker_off_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/speaker_off_over~ipad.png b/Resources/speaker_off_over~ipad.png deleted file mode 100644 index 5a78dc698..000000000 Binary files a/Resources/speaker_off_over~ipad.png and /dev/null differ diff --git a/Resources/speaker_on_default.png b/Resources/speaker_on_default.png deleted file mode 100644 index ffc9d1763..000000000 Binary files a/Resources/speaker_on_default.png and /dev/null differ diff --git a/Resources/speaker_on_default_landscape.png b/Resources/speaker_on_default_landscape.png deleted file mode 100644 index 5f9ffbbb1..000000000 Binary files a/Resources/speaker_on_default_landscape.png and /dev/null differ diff --git a/Resources/speaker_on_default_landscape~ipad.png b/Resources/speaker_on_default_landscape~ipad.png deleted file mode 100644 index 75a192643..000000000 Binary files a/Resources/speaker_on_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/speaker_on_default~ipad.png b/Resources/speaker_on_default~ipad.png deleted file mode 100644 index c50b97172..000000000 Binary files a/Resources/speaker_on_default~ipad.png and /dev/null differ diff --git a/Resources/speaker_on_disabled.png b/Resources/speaker_on_disabled.png deleted file mode 100644 index 1869a1327..000000000 Binary files a/Resources/speaker_on_disabled.png and /dev/null differ diff --git a/Resources/speaker_on_disabled_landscape.png b/Resources/speaker_on_disabled_landscape.png deleted file mode 100644 index 7a8c6023a..000000000 Binary files a/Resources/speaker_on_disabled_landscape.png and /dev/null differ diff --git a/Resources/speaker_on_disabled_landscape~ipad.png b/Resources/speaker_on_disabled_landscape~ipad.png deleted file mode 100644 index d2447d870..000000000 Binary files a/Resources/speaker_on_disabled_landscape~ipad.png and /dev/null differ diff --git a/Resources/speaker_on_disabled~ipad.png b/Resources/speaker_on_disabled~ipad.png deleted file mode 100644 index 41b2d0af8..000000000 Binary files a/Resources/speaker_on_disabled~ipad.png and /dev/null differ diff --git a/Resources/speaker_on_over.png b/Resources/speaker_on_over.png deleted file mode 100644 index adc72500d..000000000 Binary files a/Resources/speaker_on_over.png and /dev/null differ diff --git a/Resources/speaker_on_over_landscape.png b/Resources/speaker_on_over_landscape.png deleted file mode 100644 index db44d5a07..000000000 Binary files a/Resources/speaker_on_over_landscape.png and /dev/null differ diff --git a/Resources/speaker_on_over_landscape~ipad.png b/Resources/speaker_on_over_landscape~ipad.png deleted file mode 100644 index 28483bf59..000000000 Binary files a/Resources/speaker_on_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/speaker_on_over~ipad.png b/Resources/speaker_on_over~ipad.png deleted file mode 100644 index 0bfd8df64..000000000 Binary files a/Resources/speaker_on_over~ipad.png and /dev/null differ diff --git a/Resources/statebar_background.png b/Resources/statebar_background.png deleted file mode 100644 index 001991fb0..000000000 Binary files a/Resources/statebar_background.png and /dev/null differ diff --git a/Resources/statebar_background_landscape.png b/Resources/statebar_background_landscape.png deleted file mode 100644 index 26f042d99..000000000 Binary files a/Resources/statebar_background_landscape.png and /dev/null differ diff --git a/Resources/statebar_background_landscape~ipad.png b/Resources/statebar_background_landscape~ipad.png deleted file mode 100644 index 3cef78053..000000000 Binary files a/Resources/statebar_background_landscape~ipad.png and /dev/null differ diff --git a/Resources/statebar_background~ipad.png b/Resources/statebar_background~ipad.png deleted file mode 100644 index a9ba49f10..000000000 Binary files a/Resources/statebar_background~ipad.png and /dev/null differ diff --git a/Resources/sv.lproj/Localizable.strings b/Resources/sv.lproj/Localizable.strings new file mode 100644 index 000000000..4d651c1c5 Binary files /dev/null and b/Resources/sv.lproj/Localizable.strings differ diff --git a/Resources/switch_camera_default.png b/Resources/switch_camera_default.png deleted file mode 100644 index 01a51b8ce..000000000 Binary files a/Resources/switch_camera_default.png and /dev/null differ diff --git a/Resources/switch_camera_over.png b/Resources/switch_camera_over.png deleted file mode 100644 index b8086a045..000000000 Binary files a/Resources/switch_camera_over.png and /dev/null differ diff --git a/Resources/test_failed.png b/Resources/test_failed.png deleted file mode 100644 index c174df390..000000000 Binary files a/Resources/test_failed.png and /dev/null differ diff --git a/Resources/test_inprogress.png b/Resources/test_inprogress.png deleted file mode 100644 index f725a3eb9..000000000 Binary files a/Resources/test_inprogress.png and /dev/null differ diff --git a/Resources/test_passed.png b/Resources/test_passed.png deleted file mode 100644 index f8edc012d..000000000 Binary files a/Resources/test_passed.png and /dev/null differ diff --git a/Resources/toolsbar_background.png b/Resources/toolsbar_background.png deleted file mode 100644 index 033f7c052..000000000 Binary files a/Resources/toolsbar_background.png and /dev/null differ diff --git a/Resources/transfer_call_default.png b/Resources/transfer_call_default.png deleted file mode 100644 index b67e4509e..000000000 Binary files a/Resources/transfer_call_default.png and /dev/null differ diff --git a/Resources/transfer_call_default~ipad.png b/Resources/transfer_call_default~ipad.png deleted file mode 100644 index cd2b3579c..000000000 Binary files a/Resources/transfer_call_default~ipad.png and /dev/null differ diff --git a/Resources/transfer_call_disabled.png b/Resources/transfer_call_disabled.png deleted file mode 100644 index 0307f6bf8..000000000 Binary files a/Resources/transfer_call_disabled.png and /dev/null differ diff --git a/Resources/transfer_call_disabled~ipad.png b/Resources/transfer_call_disabled~ipad.png deleted file mode 100644 index 948d87cd2..000000000 Binary files a/Resources/transfer_call_disabled~ipad.png and /dev/null differ diff --git a/Resources/transfer_call_over.png b/Resources/transfer_call_over.png deleted file mode 100644 index 9f3e9ac36..000000000 Binary files a/Resources/transfer_call_over.png and /dev/null differ diff --git a/Resources/transfer_call_over~ipad.png b/Resources/transfer_call_over~ipad.png deleted file mode 100644 index 94a1faa9f..000000000 Binary files a/Resources/transfer_call_over~ipad.png and /dev/null differ diff --git a/Resources/video_off_default.png b/Resources/video_off_default.png deleted file mode 100644 index 088412bd7..000000000 Binary files a/Resources/video_off_default.png and /dev/null differ diff --git a/Resources/video_off_default_landscape.png b/Resources/video_off_default_landscape.png deleted file mode 100644 index bdf806f04..000000000 Binary files a/Resources/video_off_default_landscape.png and /dev/null differ diff --git a/Resources/video_off_default_landscape~ipad.png b/Resources/video_off_default_landscape~ipad.png deleted file mode 100644 index c479bf714..000000000 Binary files a/Resources/video_off_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/video_off_default~ipad.png b/Resources/video_off_default~ipad.png deleted file mode 100644 index d7ac1ca51..000000000 Binary files a/Resources/video_off_default~ipad.png and /dev/null differ diff --git a/Resources/video_off_disabled.png b/Resources/video_off_disabled.png deleted file mode 100644 index cccfe8d25..000000000 Binary files a/Resources/video_off_disabled.png and /dev/null differ diff --git a/Resources/video_off_disabled_landscape.png b/Resources/video_off_disabled_landscape.png deleted file mode 100644 index bba655b46..000000000 Binary files a/Resources/video_off_disabled_landscape.png and /dev/null differ diff --git a/Resources/video_off_disabled_landscape~ipad.png b/Resources/video_off_disabled_landscape~ipad.png deleted file mode 100644 index 036ec556d..000000000 Binary files a/Resources/video_off_disabled_landscape~ipad.png and /dev/null differ diff --git a/Resources/video_off_disabled~ipad.png b/Resources/video_off_disabled~ipad.png deleted file mode 100644 index fdbb7e40e..000000000 Binary files a/Resources/video_off_disabled~ipad.png and /dev/null differ diff --git a/Resources/video_off_over.png b/Resources/video_off_over.png deleted file mode 100644 index b4bb25bda..000000000 Binary files a/Resources/video_off_over.png and /dev/null differ diff --git a/Resources/video_off_over_landscape.png b/Resources/video_off_over_landscape.png deleted file mode 100644 index f93047c62..000000000 Binary files a/Resources/video_off_over_landscape.png and /dev/null differ diff --git a/Resources/video_off_over_landscape~ipad.png b/Resources/video_off_over_landscape~ipad.png deleted file mode 100644 index 292042214..000000000 Binary files a/Resources/video_off_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/video_off_over~ipad.png b/Resources/video_off_over~ipad.png deleted file mode 100644 index 46162cefe..000000000 Binary files a/Resources/video_off_over~ipad.png and /dev/null differ diff --git a/Resources/video_on_default.png b/Resources/video_on_default.png deleted file mode 100644 index 5c852ac03..000000000 Binary files a/Resources/video_on_default.png and /dev/null differ diff --git a/Resources/video_on_default_landscape.png b/Resources/video_on_default_landscape.png deleted file mode 100644 index 3ca9fabdf..000000000 Binary files a/Resources/video_on_default_landscape.png and /dev/null differ diff --git a/Resources/video_on_default_landscape~ipad.png b/Resources/video_on_default_landscape~ipad.png deleted file mode 100644 index fa3976e72..000000000 Binary files a/Resources/video_on_default_landscape~ipad.png and /dev/null differ diff --git a/Resources/video_on_default~ipad.png b/Resources/video_on_default~ipad.png deleted file mode 100644 index 39c1a7a84..000000000 Binary files a/Resources/video_on_default~ipad.png and /dev/null differ diff --git a/Resources/video_on_disabled.png b/Resources/video_on_disabled.png deleted file mode 100644 index bdfcbe8f6..000000000 Binary files a/Resources/video_on_disabled.png and /dev/null differ diff --git a/Resources/video_on_disabled_landscape.png b/Resources/video_on_disabled_landscape.png deleted file mode 100644 index f122718f0..000000000 Binary files a/Resources/video_on_disabled_landscape.png and /dev/null differ diff --git a/Resources/video_on_disabled_landscape~ipad.png b/Resources/video_on_disabled_landscape~ipad.png deleted file mode 100644 index 52a3515d3..000000000 Binary files a/Resources/video_on_disabled_landscape~ipad.png and /dev/null differ diff --git a/Resources/video_on_disabled~ipad.png b/Resources/video_on_disabled~ipad.png deleted file mode 100644 index f5701af1e..000000000 Binary files a/Resources/video_on_disabled~ipad.png and /dev/null differ diff --git a/Resources/video_on_over.png b/Resources/video_on_over.png deleted file mode 100644 index 13dd3546e..000000000 Binary files a/Resources/video_on_over.png and /dev/null differ diff --git a/Resources/video_on_over_landscape.png b/Resources/video_on_over_landscape.png deleted file mode 100644 index 252f88441..000000000 Binary files a/Resources/video_on_over_landscape.png and /dev/null differ diff --git a/Resources/video_on_over_landscape~ipad.png b/Resources/video_on_over_landscape~ipad.png deleted file mode 100644 index 23abeffa5..000000000 Binary files a/Resources/video_on_over_landscape~ipad.png and /dev/null differ diff --git a/Resources/video_on_over~ipad.png b/Resources/video_on_over~ipad.png deleted file mode 100644 index cd1ec1e0d..000000000 Binary files a/Resources/video_on_over~ipad.png and /dev/null differ diff --git a/Resources/wizard_external_sip.rc b/Resources/wizard_external_sip.rc deleted file mode 100644 index f427f2758..000000000 --- a/Resources/wizard_external_sip.rc +++ /dev/null @@ -1,37 +0,0 @@ - - - -
- - - - 3600 - 1 - 0 - 0 -
- -
- -
- -
- 0 - - 1 - stun.linphone.org - 1 -
- -
- none - -
- -
- -1 - -1 - -1 -
- -
\ No newline at end of file diff --git a/Resources/wizard_linphone_create.rc b/Resources/wizard_linphone_create.rc deleted file mode 100644 index 292d662d4..000000000 --- a/Resources/wizard_linphone_create.rc +++ /dev/null @@ -1,42 +0,0 @@ - - - -
- <sip:sip.linphone.org:5223;transport=tls> - <sip:sip.linphone.org:5223;transport=tls> - sip:?@sip.linphone.org - 1314000 - 1 - 0 - 0 - 1 - sip:voip-metrics@sip.linphone.org - 1 - 180 - sip.linphone.org -
- -
- https://www.linphone.org/wizard.php -
- -
- 1 - https://www.linphone.org:444/upload.php - 1 - stun.linphone.org - 1 -
- -
- ice - stun.linphone.org -
- -
- -1 - -1 - -1 -
- -
diff --git a/Resources/wizard_linphone_existing.rc b/Resources/wizard_linphone_existing.rc deleted file mode 100644 index 2244776e8..000000000 --- a/Resources/wizard_linphone_existing.rc +++ /dev/null @@ -1,41 +0,0 @@ - - - -
- <sip:sip.linphone.org:5223;transport=tls> - <sip:sip.linphone.org:5223;transport=tls> - sip:?@sip.linphone.org - 1314000 - 1 - 0 - 0 - 1 - sip:voip-metrics@sip.linphone.org - 1 - 180 - sip.linphone.org -
- -
- -
- -
- 1 - https://www.linphone.org:444/upload.php - 1 - stun.linphone.org - 1 -
- -
- ice - stun.linphone.org -
- -
- -1 - -1 - -1 -
-
diff --git a/Resources/zh_TW.lproj/Localizable.strings b/Resources/zh_TW.lproj/Localizable.strings index f51670b73..745c33043 100644 Binary files a/Resources/zh_TW.lproj/Localizable.strings and b/Resources/zh_TW.lproj/Localizable.strings differ diff --git a/Settings/InAppSettings.bundle/Account.plist b/Settings/InAppSettings.bundle/Account.plist new file mode 100644 index 000000000..52d668dfa --- /dev/null +++ b/Settings/InAppSettings.bundle/Account.plist @@ -0,0 +1,244 @@ + + + + + PreferenceSpecifiers + + + + Type + PSToggleSwitchSpecifier + Title + More options + Key + account_mandatory_advanced_preference + DefaultValue + + + + Type + PSToggleSwitchSpecifier + Title + Default account + Key + account_is_default_preference + DefaultValue + + + + AutocapitalizationType + None + AutocorrectionType + No + DefaultValue + + IsSecure + + Key + account_mandatory_username_preference + KeyboardType + Alphabet + Title + Username + Type + PSTextFieldSpecifier + + + AutocapitalizationType + None + AutocorrectionType + No + DefaultValue + + IsSecure + + Key + account_display_name_preference + KeyboardType + Alphabet + Title + Display name + Type + PSTextFieldSpecifier + + + AutocapitalizationType + None + AutocorrectionType + No + DefaultValue + + IsSecure + + Key + account_userid_preference + KeyboardType + Alphabet + Title + User ID + Type + PSTextFieldSpecifier + + + AutocapitalizationType + None + AutocorrectionType + No + DefaultValue + + IsSecure + + Key + account_mandatory_password_preference + KeyboardType + Alphabet + Title + Password + Type + PSTextFieldSpecifier + + + AutocapitalizationType + None + AutocorrectionType + No + DefaultValue + + IsSecure + + Key + account_mandatory_domain_preference + KeyboardType + URL + Title + Domain + Type + PSTextFieldSpecifier + + + AutocapitalizationType + None + AutocorrectionType + No + DefaultValue + + IsSecure + + Key + account_proxy_preference + KeyboardType + URL + Title + Proxy + Type + PSTextFieldSpecifier + + + DefaultValue + udp + Key + account_transport_preference + Title + Transport + Titles + + UDP + TCP + TLS + + Type + PSMultiValueSpecifier + Values + + udp + tcp + tls + + + + Title + Outbound proxy + DefaultValue + + Key + account_outbound_proxy_preference + Type + PSToggleSwitchSpecifier + + + Title + AVPF + DefaultValue + + Key + account_avpf_preference + Type + PSToggleSwitchSpecifier + + + Key + account_expire_preference + Title + Expire + Type + PSTextFieldSpecifier + AutocapitalizationType + None + AutocorrectionType + No + KeyboardType + NumberPad + DefaultValue + 600 + IASKTextAlignment + IASKUITextAlignmentRight + + + AutocapitalizationType + None + AutocorrectionType + No + DefaultValue + + IsSecure + + Key + account_prefix_preference + Title + Prefix + Type + PSTextFieldSpecifier + IASKTextAlignment + IASKUITextAlignmentRight + + + DefaultValue + + Key + account_substitute_+_by_00_preference + Title + Substitute + by 00 + Type + PSToggleSwitchSpecifier + + + Type + PSToggleSwitchSpecifier + Title + Account enabled + Key + account_is_enabled_preference + DefaultValue + + + + Key + account_mandatory_remove_button + Title + Remove Account + Type + IASKButtonSpecifier + + + + diff --git a/Settings/InAppSettings.bundle/Advanced.plist b/Settings/InAppSettings.bundle/Advanced.plist index 80632bbb7..9d778bd59 100644 --- a/Settings/InAppSettings.bundle/Advanced.plist +++ b/Settings/InAppSettings.bundle/Advanced.plist @@ -38,7 +38,33 @@ Title - + Notifications + Type + PSGroupSpecifier + + + DefaultValue + + Key + show_msg_in_notif + Title + Show message in notification + Type + PSToggleSwitchSpecifier + + + DefaultValue + + Key + autoanswer_notif_preference + Title + Auto-answer after notification + Type + PSToggleSwitchSpecifier + + + Title + Other Type PSGroupSpecifier @@ -52,16 +78,6 @@ Type PSToggleSwitchSpecifier - - DefaultValue - - Key - backgroundmode_preference - Title - Background mode - Type - PSToggleSwitchSpecifier - DefaultValue @@ -72,16 +88,6 @@ Type PSToggleSwitchSpecifier - - DefaultValue - - Key - autoanswer_notif_preference - Title - Auto-answer after notification - Type - PSToggleSwitchSpecifier - DefaultValue @@ -92,24 +98,6 @@ Type PSToggleSwitchSpecifier - - Key - expire_preference - Title - Expire - Type - PSTextFieldSpecifier - AutocapitalizationType - None - AutocorrectionType - No - KeyboardType - NumberPad - DefaultValue - 600 - IASKTextAlignment - IASKUITextAlignmentRight - Title Primary account @@ -162,7 +150,7 @@ Type PSGroupSpecifier Title - + File sharing AutocapitalizationType @@ -174,9 +162,9 @@ Type PSTextFieldSpecifier Title - Sharing server + Server URL Key - sharing_server_preference + file_transfer_server_url_preference IASKTextAlignment IASKUITextAlignmentRight diff --git a/Settings/InAppSettings.bundle/Audio.plist b/Settings/InAppSettings.bundle/Audio.plist index 58f5cf6d0..3dcf3a293 100644 --- a/Settings/InAppSettings.bundle/Audio.plist +++ b/Settings/InAppSettings.bundle/Audio.plist @@ -16,7 +16,7 @@ Key speex_16k_preference Title - Speex 16Khz + Speex 16kHz Type PSToggleSwitchSpecifier @@ -26,7 +26,7 @@ Key speex_8k_preference Title - Speex 8Khz + Speex 8kHz Type PSToggleSwitchSpecifier @@ -46,7 +46,7 @@ Key silk_24k_preference Title - Silk 24Khz + Silk 24kHz Type PSToggleSwitchSpecifier @@ -56,7 +56,7 @@ Key silk_16k_preference Title - Silk 16Khz + Silk 16kHz Type PSToggleSwitchSpecifier @@ -128,7 +128,7 @@ Key g722_preference Title - G722 + G.722 Type PSToggleSwitchSpecifier @@ -138,7 +138,7 @@ Key g729_preference Title - G729 + G.729 Type PSToggleSwitchSpecifier @@ -158,7 +158,17 @@ Key ilbc_preference Title - ILBC + iLBC + Type + PSToggleSwitchSpecifier + + + DefaultValue + + Key + isac_preference + Title + iSAC Type PSToggleSwitchSpecifier @@ -218,36 +228,6 @@ IASKTextAlignment IASKUITextAlignmentRight - - DefaultValue - - Key - adaptive_rate_control_preference - Title - Adaptive rate control - Type - PSToggleSwitchSpecifier - - - DefaultValue - Simple - Key - adaptive_rate_algorithm_preference - Title - Adaptive rate algorithm - Titles - - Simple - Stateful - - Type - PSMultiValueSpecifier - Values - - Simple - Stateful - - DefaultValue 36 diff --git a/Settings/InAppSettings.bundle/Call.plist b/Settings/InAppSettings.bundle/Call.plist index 3b2503bfd..01b42eb1e 100644 --- a/Settings/InAppSettings.bundle/Call.plist +++ b/Settings/InAppSettings.bundle/Call.plist @@ -4,34 +4,6 @@ PreferenceSpecifiers - - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - - Key - prefix_preference - Title - Prefix - Type - PSTextFieldSpecifier - IASKTextAlignment - IASKUITextAlignmentRight - - - DefaultValue - - Key - substitute_+_by_00_preference - Title - Substitue + by 00 - Type - PSToggleSwitchSpecifier - Type PSToggleSwitchSpecifier @@ -106,6 +78,50 @@ IASKTextAlignment IASKUITextAlignmentRight + + DefaultValue + + Key + repeat_call_notification_preference + Title + Repeat call notification + Type + PSToggleSwitchSpecifier + + + Key + call_ringtone_preference + Title + Ringtone + Type + PSMultiValueSpecifier + Titles + + Four hands together + It's a game + Notes of the optimistic + Soft as snow + Leaving a dream + House Keeping + + Values + + four_hands_together.caf + it_s_a_game.caf + notes_of_the_optimistic.caf + soft_as_snow.caf + leaving_a_dream.caf + house_keeping.caf + + + + Key + preview_ringtone_button + Title + Listen ringtone + Type + IASKButtonSpecifier + diff --git a/Settings/InAppSettings.bundle/Network.plist b/Settings/InAppSettings.bundle/Network.plist index 4eb893d65..4a87839d1 100644 --- a/Settings/InAppSettings.bundle/Network.plist +++ b/Settings/InAppSettings.bundle/Network.plist @@ -156,31 +156,21 @@ Key - upload_bandwidth_preference + adaptive_rate_control_group Title - Upload bandwidth + Adaptive rate control Type - PSTextFieldSpecifier - KeyboardType - NumberPad - DefaultValue - 0 - IASKTextAlignment - IASKUITextAlignmentRight + PSGroupSpecifier - Key - download_bandwidth_preference - Title - Download bandwidth - Type - PSTextFieldSpecifier - KeyboardType - NumberPad DefaultValue - 0 - IASKTextAlignment - IASKUITextAlignmentRight + + Key + adaptive_rate_control_preference + Title + Adaptive rate control + Type + PSToggleSwitchSpecifier diff --git a/Settings/InAppSettings.bundle/Root.plist b/Settings/InAppSettings.bundle/Root.plist index 62dbcc5ec..30e709696 100644 --- a/Settings/InAppSettings.bundle/Root.plist +++ b/Settings/InAppSettings.bundle/Root.plist @@ -6,167 +6,67 @@ Title - SIP account + SIP accounts Type PSGroupSpecifier Key - wizard_button + assistant_button Title - Wizard + Run assistant Type IASKButtonSpecifier Key - clear_proxy_button + menu_account_1 + File + Account Title - Clear Account + Account 1 Type - IASKButtonSpecifier + PSChildPaneSpecifier - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - Key - username_preference - KeyboardType - Alphabet + menu_account_2 + File + Account Title - User name + Account 2 Type - PSTextFieldSpecifier + PSChildPaneSpecifier - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - Key - userid_preference - KeyboardType - Alphabet + menu_account_3 + File + Account Title - User ID + Account 3 Type - PSTextFieldSpecifier + PSChildPaneSpecifier - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - Key - password_preference - KeyboardType - Alphabet + menu_account_4 + File + Account Title - Password + Account 4 Type - PSTextFieldSpecifier + PSChildPaneSpecifier - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - Key - domain_preference - KeyboardType - URL + menu_account_5 + File + Account Title - Domain + Account 5 Type - PSTextFieldSpecifier - - - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - - Key - proxy_preference - KeyboardType - URL - Title - Proxy - Type - PSTextFieldSpecifier - - - DefaultValue - udp - Key - transport_preference - Title - Transport - Titles - - UDP - TCP - TLS - - Type - PSMultiValueSpecifier - Values - - udp - tcp - tls - - - - Title - Outbound proxy - DefaultValue - - Key - outbound_proxy_preference - Type - PSToggleSwitchSpecifier - - - Title - AVPF - DefaultValue - - Key - avpf_preference - Type - PSToggleSwitchSpecifier - - - Type - PSToggleSwitchSpecifier - Title - More options - Key - advanced_account_preference - DefaultValue - + PSChildPaneSpecifier Title @@ -244,7 +144,9 @@ Title - + Development debug actions + Key + debug_actions_group Type PSGroupSpecifier @@ -268,7 +170,7 @@ Key release_button Title - Exit + Release core Type IASKButtonSpecifier @@ -288,6 +190,24 @@ Type IASKButtonSpecifier + + Key + flush_images_button + Title + Flush downloaded images + Type + IASKButtonSpecifier + + + Type + PSToggleSwitchSpecifier + Title + Auto answer call immediately + Key + enable_auto_answer_preference + DefaultValue + + StringsTable Root diff --git a/Settings/InAppSettings.bundle/Video.plist b/Settings/InAppSettings.bundle/Video.plist index dfcd404b4..4d72625e6 100644 --- a/Settings/InAppSettings.bundle/Video.plist +++ b/Settings/InAppSettings.bundle/Video.plist @@ -41,8 +41,28 @@ preview_preference + Key + video_preset_preference + Title + Video preset + Titles + + Default + High FPS + Custom + + Type + PSMultiValueSpecifier + Values + + default + high-fps + custom + DefaultValue - 1 + default + + Key video_preferred_size_preference Title @@ -61,6 +81,56 @@ 1 2 + DefaultValue + 1 + + + Key + video_preferred_fps_preference + Title + Preferred FPS + Type + PSMultiValueSpecifier + Titles + + No preference + 5 + 10 + 15 + 20 + 25 + 30 + + Values + + 0 + 5 + 10 + 15 + 20 + 25 + 30 + + DefaultValue + 0 + + + Key + download_bandwidth_preference + Title + Bandwidth limit in kbits/s + Type + PSTextFieldSpecifier + AutocapitalizationType + None + AutocorrectionType + No + KeyboardType + NumberPad + DefaultValue + 380 + IASKTextAlignment + IASKUITextAlignmentRight Title @@ -74,7 +144,7 @@ Key mp4v-es_preference Title - mpeg4 + MPEG-4 Type PSToggleSwitchSpecifier @@ -84,7 +154,7 @@ Key h264_preference Title - h264 + H.264 Type PSToggleSwitchSpecifier diff --git a/Settings/InAppSettings.bundle/ar.lproj/Account.strings b/Settings/InAppSettings.bundle/ar.lproj/Account.strings new file mode 100644 index 000000000..7119e0e87 Binary files /dev/null and b/Settings/InAppSettings.bundle/ar.lproj/Account.strings differ diff --git a/Settings/InAppSettings.bundle/ar.lproj/Advanced.strings b/Settings/InAppSettings.bundle/ar.lproj/Advanced.strings index 596d79598..14ef3fe7c 100644 Binary files a/Settings/InAppSettings.bundle/ar.lproj/Advanced.strings and b/Settings/InAppSettings.bundle/ar.lproj/Advanced.strings differ diff --git a/Settings/InAppSettings.bundle/ar.lproj/Audio.strings b/Settings/InAppSettings.bundle/ar.lproj/Audio.strings index ca6362e1f..e82411dff 100644 Binary files a/Settings/InAppSettings.bundle/ar.lproj/Audio.strings and b/Settings/InAppSettings.bundle/ar.lproj/Audio.strings differ diff --git a/Settings/InAppSettings.bundle/ar.lproj/Call.strings b/Settings/InAppSettings.bundle/ar.lproj/Call.strings index c3a9fc437..2f0f7d299 100644 Binary files a/Settings/InAppSettings.bundle/ar.lproj/Call.strings and b/Settings/InAppSettings.bundle/ar.lproj/Call.strings differ diff --git a/Settings/InAppSettings.bundle/ar.lproj/Network.strings b/Settings/InAppSettings.bundle/ar.lproj/Network.strings index d64b82fe4..39af69ecb 100644 Binary files a/Settings/InAppSettings.bundle/ar.lproj/Network.strings and b/Settings/InAppSettings.bundle/ar.lproj/Network.strings differ diff --git a/Settings/InAppSettings.bundle/ar.lproj/Root.strings b/Settings/InAppSettings.bundle/ar.lproj/Root.strings index 030f39138..12d8424cd 100644 Binary files a/Settings/InAppSettings.bundle/ar.lproj/Root.strings and b/Settings/InAppSettings.bundle/ar.lproj/Root.strings differ diff --git a/Settings/InAppSettings.bundle/ar.lproj/Tunnel.strings b/Settings/InAppSettings.bundle/ar.lproj/Tunnel.strings index 4ac2635db..e9565b65d 100644 Binary files a/Settings/InAppSettings.bundle/ar.lproj/Tunnel.strings and b/Settings/InAppSettings.bundle/ar.lproj/Tunnel.strings differ diff --git a/Settings/InAppSettings.bundle/ar.lproj/Video.strings b/Settings/InAppSettings.bundle/ar.lproj/Video.strings index 61eea26e7..f64008c00 100644 Binary files a/Settings/InAppSettings.bundle/ar.lproj/Video.strings and b/Settings/InAppSettings.bundle/ar.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/de.lproj/Account.strings b/Settings/InAppSettings.bundle/de.lproj/Account.strings new file mode 100644 index 000000000..70af42e9e Binary files /dev/null and b/Settings/InAppSettings.bundle/de.lproj/Account.strings differ diff --git a/Settings/InAppSettings.bundle/de.lproj/Advanced.strings b/Settings/InAppSettings.bundle/de.lproj/Advanced.strings new file mode 100644 index 000000000..87aaab5bd Binary files /dev/null and b/Settings/InAppSettings.bundle/de.lproj/Advanced.strings differ diff --git a/Settings/InAppSettings.bundle/de.lproj/Audio.strings b/Settings/InAppSettings.bundle/de.lproj/Audio.strings new file mode 100644 index 000000000..32b1fb205 Binary files /dev/null and b/Settings/InAppSettings.bundle/de.lproj/Audio.strings differ diff --git a/Settings/InAppSettings.bundle/de.lproj/Call.strings b/Settings/InAppSettings.bundle/de.lproj/Call.strings new file mode 100644 index 000000000..29a12e46e Binary files /dev/null and b/Settings/InAppSettings.bundle/de.lproj/Call.strings differ diff --git a/Settings/InAppSettings.bundle/de.lproj/Network.strings b/Settings/InAppSettings.bundle/de.lproj/Network.strings new file mode 100644 index 000000000..714fa62e6 Binary files /dev/null and b/Settings/InAppSettings.bundle/de.lproj/Network.strings differ diff --git a/Settings/InAppSettings.bundle/de.lproj/Root.strings b/Settings/InAppSettings.bundle/de.lproj/Root.strings new file mode 100644 index 000000000..bd0a0f89b Binary files /dev/null and b/Settings/InAppSettings.bundle/de.lproj/Root.strings differ diff --git a/Settings/InAppSettings.bundle/de.lproj/Tunnel.strings b/Settings/InAppSettings.bundle/de.lproj/Tunnel.strings new file mode 100644 index 000000000..4ff7fc16b Binary files /dev/null and b/Settings/InAppSettings.bundle/de.lproj/Tunnel.strings differ diff --git a/Settings/InAppSettings.bundle/de.lproj/Video.strings b/Settings/InAppSettings.bundle/de.lproj/Video.strings new file mode 100644 index 000000000..2eaf397ee Binary files /dev/null and b/Settings/InAppSettings.bundle/de.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/en.lproj/Account.strings b/Settings/InAppSettings.bundle/en.lproj/Account.strings new file mode 100644 index 000000000..0cbc6232c --- /dev/null +++ b/Settings/InAppSettings.bundle/en.lproj/Account.strings @@ -0,0 +1,16 @@ +"More options" = "More options"; +"Default account" = "Default account"; +"Username" = "Username"; +"Display name" = "Display name"; +"User ID" = "User ID"; +"Password" = "Password"; +"Domain" = "Domain"; +"Proxy" = "Proxy"; +"Transport" = "Transport"; +"Outbound proxy" = "Outbound proxy"; +"AVPF" = "AVPF"; +"Expire" = "Expire"; +"Prefix" = "Prefix"; +"Substitute + by 00" = "Substitute + by 00"; +"Account enabled" = "Account enabled"; +"Remove Account" = "Remove Account"; diff --git a/Settings/InAppSettings.bundle/en.lproj/Advanced.strings b/Settings/InAppSettings.bundle/en.lproj/Advanced.strings index c962e7a60..0c2e24ca3 100644 --- a/Settings/InAppSettings.bundle/en.lproj/Advanced.strings +++ b/Settings/InAppSettings.bundle/en.lproj/Advanced.strings @@ -1,55 +1,16 @@ -/* Debug */ "Debug" = "Debug"; - -/* Debug */ "Debug" = "Debug"; - -/* Console */ -"Console" = "Console"; - -/* */ -"" = ""; - -/* Animations */ +"Send Logs" = "Send Logs"; +"Clear Logs" = "Clear Logs"; +"Notifications" = "Notifications"; +"Show message in notification" = "Show message in notification"; +"Auto-answer after notification" = "Auto-answer after notification"; +"Other" = "Other"; "Animations" = "Animations"; - -/* Rotation */ -"Rotation" = "Rotation"; - -/* Background mode */ -"Background mode" = "Background mode"; - -/* Start at boot */ "Start at boot" = "Start at boot"; - -/* First login view */ "First login view" = "First login view"; - -/* Expire */ -"Expire" = "Expire"; - -/* Primary account */ -"Primary account" = "Standalone calls (no proxy)"; - -/* Display name */ +"Primary account" = "Primary account"; "Display name" = "Display name"; - -/* Sharing server */ -"Sharing server" = "Sharing server"; - -/* Username */ "Username" = "Username"; - -/* Rotation */ -"Rotation" = "Rotation"; - -/* Automatic */ -"Automatic" = "Automatic"; - -/* Portrait */ -"Portrait" = "Portrait"; - -/* Landscape */ -"Landscape" = "Landscape"; - -"Auto-answer after notification" = "Auto-answer after notification"; \ No newline at end of file +"File sharing" = "File sharing"; +"Server URL" = "Server URL"; diff --git a/Settings/InAppSettings.bundle/en.lproj/Audio.strings b/Settings/InAppSettings.bundle/en.lproj/Audio.strings index 86403612c..f6d77bfc8 100644 --- a/Settings/InAppSettings.bundle/en.lproj/Audio.strings +++ b/Settings/InAppSettings.bundle/en.lproj/Audio.strings @@ -1,56 +1,25 @@ -/* Codecs */ "Codecs" = "Codecs"; - -/* AMR */ +"Speex 16kHz" = "Speex 16kHz"; +"Speex 8kHz" = "Speex 8kHz"; +"Opus 48kHz" = "Opus 48kHz"; +"Silk 24kHz" = "Silk 24kHz"; +"Silk 16kHz" = "Silk 16kHz"; +"AAC-ELD 16kHz" = "AAC-ELD 16kHz"; +"AAC-ELD 22kHz" = "AAC-ELD 22kHz"; +"AAC-ELD 32kHz" = "AAC-ELD 32kHz"; +"AAC-ELD 44kHz" = "AAC-ELD 44kHz"; +"AAC-ELD 48kHz" = "AAC-ELD 48kHz"; "AMR" = "AMR"; - -/* Speex 16Khz */ -"Speex 16Khz" = "Speex 16Khz"; - -/* Speex 8Khz */ -"Speex 8Khz" = "Speex 8Khz"; - -/* Silk 24Khz */ -"Silk 24Khz" = "Silk 24Khz"; - -/* Silk 16Khz */ -"Silk 16Khz" = "Silk 16Khz"; - -/* G722 */ -"G722" = "G722"; - -/* G729 */ -"G729" = "G729"; - -/* GSM */ +"G.722" = "G.722"; +"G.729" = "G.729"; "GSM" = "GSM"; - -/* ILBC */ -"ILBC" = "ILBC"; - -/* PCMU */ +"iLBC" = "iLBC"; +"iSAC" = "iSAC"; "PCMU" = "PCMU"; - -/* PCMA */ "PCMA" = "PCMA"; - -/* Advanced */ "Advanced" = "Advanced"; - -/* Playback gain */ "Playback gain" = "Playback gain"; - -/* Microphone gain */ "Microphone gain" = "Microphone gain"; - -/* Adaptive rate control */ -"Adaptive rate control" = "Adaptive rate control"; - -/* Network bitrate limit */ -"Network bitrate limit" = "Network bitrate limit"; - -/* Voice processing */ -"Enable Voice Processing"="Enable Voice Processing"; - -/* Bass Boost / equalizer */ -"Enable Bass Boost"="Enable Bass Boost"; \ No newline at end of file +"Codec bitrate limit" = "Codec bitrate limit"; +"Enable Voice Processing" = "Enable Voice Processing"; +"Enable Bass Boost" = "Enable Bass Boost"; diff --git a/Settings/InAppSettings.bundle/en.lproj/Call.strings b/Settings/InAppSettings.bundle/en.lproj/Call.strings index 58a723b05..caaeb44e3 100644 --- a/Settings/InAppSettings.bundle/en.lproj/Call.strings +++ b/Settings/InAppSettings.bundle/en.lproj/Call.strings @@ -1,17 +1,8 @@ -/* Prefix */ -"Prefix" = "Prefix"; - -/* Substitue + by 00 */ -"Substitue + by 00" = "Substitue + by 00"; - -/* Send inband DTMFs */ "Send inband DTMFs" = "Send inband DTMFs"; - -/* Send SIP INFO DTMFs */ "Send SIP INFO DTMFs" = "Send SIP INFO DTMFs"; - -/* Incoming call timeout */ "Incoming call timeout" = "Incoming call timeout"; - -/* In call timeout */ -"In call timeout" = "In call timeout"; \ No newline at end of file +"In call timeout" = "In call timeout"; +"Voice mail URI" = "Voice mail URI"; +"Repeat call notification" = "Repeat call notification"; +"Ringtone" = "Ringtone"; +"Listen ringtone" = "Listen ringtone"; diff --git a/Settings/InAppSettings.bundle/en.lproj/Network.strings b/Settings/InAppSettings.bundle/en.lproj/Network.strings index 0d4466218..398390089 100644 --- a/Settings/InAppSettings.bundle/en.lproj/Network.strings +++ b/Settings/InAppSettings.bundle/en.lproj/Network.strings @@ -1,65 +1,14 @@ -/* Wifi only */ -"Wifi only" = "Wifi only"; - -/* Edge optimization */ "Edge optimization" = "Edge optimization"; - -/* Stun Server */ +"Wifi only" = "Wifi only"; "Stun Server" = "Stun Server"; - -/* ICE */ "ICE" = "ICE"; - -/* Random Port */ "Random Port" = "Random Port"; - -/* Port */ "Port" = "Port"; - -/* Audio Port(s) */ "Audio Port(s)" = "Audio Port(s)"; - -/* Video Port(s) */ "Video Port(s)" = "Video Port(s)"; - -/* Transport */ -"Transport" = "Transport"; - -/* Media Encryption */ +"Use IPv6" = "Use IPv6"; "Media Encryption" = "Media Encryption"; - -/* Push Notifications */ "Push Notification" = "Push Notification"; - -/* Transport */ -"Transport" = "Transport"; - -/* UDP */ -"UDP" = "UDP"; - -/* TCP */ -"TCP" = "TCP"; - -/* TLS */ -"TLS" = "TLS"; - -/* None */ -"None" = "None"; - -/* SRTP */ -"SRTP" = "SRTP"; - -/* ZRTP */ -"ZRTP" = "ZRTP"; - -/* Limits */ "Limits" = "Limits"; - -/* Upload bandwidth */ -"Upload bandwidth" = "Upload bandwidth"; - -/* Download bandwidth */ -"Download bandwidth" = "Download bandwidth"; - -/* IPv6 */ -"Use IPv6" = "Use IPv6"; \ No newline at end of file +"Adaptive rate control" = "Adaptive rate control"; +"Adaptive rate control" = "Adaptive rate control"; diff --git a/Settings/InAppSettings.bundle/en.lproj/Root.strings b/Settings/InAppSettings.bundle/en.lproj/Root.strings index 442bf4709..e6aefd61f 100644 --- a/Settings/InAppSettings.bundle/en.lproj/Root.strings +++ b/Settings/InAppSettings.bundle/en.lproj/Root.strings @@ -1,65 +1,23 @@ -/* SIP account */ -"SIP account" = "SIP account"; - -/* Wizard */ -"Wizard" = "Run assistant"; - -/* User name */ -"User name" = "User name"; - -/* User ID */ -"User ID" = "User ID"; - -/* Password */ -"Password" = "Password"; - -/* Domain */ -"Domain" = "Domain"; - -/* Proxy */ -"Proxy" = "Proxy"; - -/* Outbound proxy */ -"Outbound proxy" = "Outbound proxy"; - -/* Settings */ +"SIP accounts" = "SIP accounts"; +"Run assistant" = "Run assistant"; +"Account 1" = "Account 1"; +"Account 2" = "Account 2"; +"Account 3" = "Account 3"; +"Account 4" = "Account 4"; +"Account 5" = "Account 5"; "Settings" = "Settings"; - -/* Enable video */ "Enable video" = "Enable video"; - -/* Audio */ "Audio" = "Audio"; - -/* Video */ "Video" = "Video"; - -/* Call */ "Call" = "Call"; - -/* Network */ "Network" = "Network"; - -/* Advanced */ +"Tunnel" = "Tunnel"; "Advanced" = "Advanced"; - -/* */ -"" = ""; - -/* About */ +"Development debug actions" = "Development debug actions"; "About" = "About"; - -/* Quit */ "Quit" = "Quit"; - -/* Release */ -"Release" = "Release"; - -/* Clear cache */ +"Release core" = "Release core"; "Clear cache" = "Clear cache"; - -/* More options */ -"More options" = "More options"; - -/* Clear Account */ -"Clear Account" = "Clear Account"; \ No newline at end of file +"Battery alert" = "Battery alert"; +"Flush downloaded images" = "Flush downloaded images"; +"Auto answer call immediately" = "Auto answer call immediately"; diff --git a/Settings/InAppSettings.bundle/en.lproj/Tunnel.strings b/Settings/InAppSettings.bundle/en.lproj/Tunnel.strings index 3e4f1957c..dc1f514a4 100644 --- a/Settings/InAppSettings.bundle/en.lproj/Tunnel.strings +++ b/Settings/InAppSettings.bundle/en.lproj/Tunnel.strings @@ -1,20 +1,3 @@ -/* Auto */ -"Auto" = "Auto"; - -/* Address */ -"Address" = "Address"; - -/* Mode */ "Mode" = "Mode"; - -/* Off */ -"Off" = "Off"; - -/* On */ -"On" = "On"; - -/* Port */ +"Address" = "Address"; "Port" = "Port"; - -/* WWAN */ -"WWAN" = "WWAN"; \ No newline at end of file diff --git a/Settings/InAppSettings.bundle/en.lproj/Video.strings b/Settings/InAppSettings.bundle/en.lproj/Video.strings index 3d8acf107..c30eed42b 100644 --- a/Settings/InAppSettings.bundle/en.lproj/Video.strings +++ b/Settings/InAppSettings.bundle/en.lproj/Video.strings @@ -1,27 +1,12 @@ -/* Automatically start video */ "Automatically start" = "Automatically start"; - -/* Automatically accept video */ "Automatically accept" = "Automatically accept"; - -/* Show self view */ "Show self view" = "Show self view"; - -/* Show preview */ "Show preview" = "Show preview"; - -/* Preferred video size */ +"Video preset" = "Video preset"; "Preferred video size" = "Preferred video size"; - -/* Codecs */ +"Preferred FPS" = "Preferred FPS"; +"Bandwidth limit in kbits/s" = "Bandwidth limit in kbits/s"; "Codecs" = "Codecs"; - -/* mpeg4 */ -"mpeg4" = "mpeg4"; - -/* h264 */ -"h264" = "h264"; - -/* VP8 */ +"MPEG-4" = "MPEG-4"; +"H.264" = "H.264"; "VP8" = "VP8"; - diff --git a/Settings/InAppSettings.bundle/fr.lproj/Account.strings b/Settings/InAppSettings.bundle/fr.lproj/Account.strings new file mode 100644 index 000000000..3e474f084 Binary files /dev/null and b/Settings/InAppSettings.bundle/fr.lproj/Account.strings differ diff --git a/Settings/InAppSettings.bundle/fr.lproj/Advanced.strings b/Settings/InAppSettings.bundle/fr.lproj/Advanced.strings index b73671ef1..5a7097876 100644 Binary files a/Settings/InAppSettings.bundle/fr.lproj/Advanced.strings and b/Settings/InAppSettings.bundle/fr.lproj/Advanced.strings differ diff --git a/Settings/InAppSettings.bundle/fr.lproj/Audio.strings b/Settings/InAppSettings.bundle/fr.lproj/Audio.strings index 76e400596..e124e98a6 100644 Binary files a/Settings/InAppSettings.bundle/fr.lproj/Audio.strings and b/Settings/InAppSettings.bundle/fr.lproj/Audio.strings differ diff --git a/Settings/InAppSettings.bundle/fr.lproj/Call.strings b/Settings/InAppSettings.bundle/fr.lproj/Call.strings index 7fec4c333..22fd977a0 100644 Binary files a/Settings/InAppSettings.bundle/fr.lproj/Call.strings and b/Settings/InAppSettings.bundle/fr.lproj/Call.strings differ diff --git a/Settings/InAppSettings.bundle/fr.lproj/Network.strings b/Settings/InAppSettings.bundle/fr.lproj/Network.strings index ef05be608..5596b1afd 100644 Binary files a/Settings/InAppSettings.bundle/fr.lproj/Network.strings and b/Settings/InAppSettings.bundle/fr.lproj/Network.strings differ diff --git a/Settings/InAppSettings.bundle/fr.lproj/Root.strings b/Settings/InAppSettings.bundle/fr.lproj/Root.strings index 46244e4a1..b2b623377 100644 Binary files a/Settings/InAppSettings.bundle/fr.lproj/Root.strings and b/Settings/InAppSettings.bundle/fr.lproj/Root.strings differ diff --git a/Settings/InAppSettings.bundle/fr.lproj/Tunnel.strings b/Settings/InAppSettings.bundle/fr.lproj/Tunnel.strings index 033e314eb..91c6ad49d 100644 Binary files a/Settings/InAppSettings.bundle/fr.lproj/Tunnel.strings and b/Settings/InAppSettings.bundle/fr.lproj/Tunnel.strings differ diff --git a/Settings/InAppSettings.bundle/fr.lproj/Video.strings b/Settings/InAppSettings.bundle/fr.lproj/Video.strings index 0109509a5..a530a1e8d 100644 Binary files a/Settings/InAppSettings.bundle/fr.lproj/Video.strings and b/Settings/InAppSettings.bundle/fr.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/ja.lproj/Account.strings b/Settings/InAppSettings.bundle/ja.lproj/Account.strings new file mode 100644 index 000000000..454d6a7fd Binary files /dev/null and b/Settings/InAppSettings.bundle/ja.lproj/Account.strings differ diff --git a/Settings/InAppSettings.bundle/ja.lproj/Advanced.strings b/Settings/InAppSettings.bundle/ja.lproj/Advanced.strings new file mode 100644 index 000000000..abf34c09e Binary files /dev/null and b/Settings/InAppSettings.bundle/ja.lproj/Advanced.strings differ diff --git a/Settings/InAppSettings.bundle/ja.lproj/Audio.strings b/Settings/InAppSettings.bundle/ja.lproj/Audio.strings new file mode 100644 index 000000000..2c781dc34 Binary files /dev/null and b/Settings/InAppSettings.bundle/ja.lproj/Audio.strings differ diff --git a/Settings/InAppSettings.bundle/ja.lproj/Call.strings b/Settings/InAppSettings.bundle/ja.lproj/Call.strings new file mode 100644 index 000000000..e3faf7286 Binary files /dev/null and b/Settings/InAppSettings.bundle/ja.lproj/Call.strings differ diff --git a/Settings/InAppSettings.bundle/ja.lproj/Network.strings b/Settings/InAppSettings.bundle/ja.lproj/Network.strings new file mode 100644 index 000000000..b7393dcb0 Binary files /dev/null and b/Settings/InAppSettings.bundle/ja.lproj/Network.strings differ diff --git a/Settings/InAppSettings.bundle/ja.lproj/Root.strings b/Settings/InAppSettings.bundle/ja.lproj/Root.strings new file mode 100644 index 000000000..cbee92d3c Binary files /dev/null and b/Settings/InAppSettings.bundle/ja.lproj/Root.strings differ diff --git a/Settings/InAppSettings.bundle/ja.lproj/Tunnel.strings b/Settings/InAppSettings.bundle/ja.lproj/Tunnel.strings new file mode 100644 index 000000000..333f824bc Binary files /dev/null and b/Settings/InAppSettings.bundle/ja.lproj/Tunnel.strings differ diff --git a/Settings/InAppSettings.bundle/ja.lproj/Video.strings b/Settings/InAppSettings.bundle/ja.lproj/Video.strings new file mode 100644 index 000000000..fa870bafc Binary files /dev/null and b/Settings/InAppSettings.bundle/ja.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/nl.lproj/Account.strings b/Settings/InAppSettings.bundle/nl.lproj/Account.strings new file mode 100644 index 000000000..c06cac2e4 Binary files /dev/null and b/Settings/InAppSettings.bundle/nl.lproj/Account.strings differ diff --git a/Settings/InAppSettings.bundle/nl.lproj/Advanced.strings b/Settings/InAppSettings.bundle/nl.lproj/Advanced.strings new file mode 100644 index 000000000..cdee922f2 Binary files /dev/null and b/Settings/InAppSettings.bundle/nl.lproj/Advanced.strings differ diff --git a/Settings/InAppSettings.bundle/nl.lproj/Audio.strings b/Settings/InAppSettings.bundle/nl.lproj/Audio.strings new file mode 100644 index 000000000..2c781dc34 Binary files /dev/null and b/Settings/InAppSettings.bundle/nl.lproj/Audio.strings differ diff --git a/Settings/InAppSettings.bundle/nl.lproj/Call.strings b/Settings/InAppSettings.bundle/nl.lproj/Call.strings new file mode 100644 index 000000000..cbb14da46 Binary files /dev/null and b/Settings/InAppSettings.bundle/nl.lproj/Call.strings differ diff --git a/Settings/InAppSettings.bundle/nl.lproj/Network.strings b/Settings/InAppSettings.bundle/nl.lproj/Network.strings new file mode 100644 index 000000000..b7393dcb0 Binary files /dev/null and b/Settings/InAppSettings.bundle/nl.lproj/Network.strings differ diff --git a/Settings/InAppSettings.bundle/nl.lproj/Root.strings b/Settings/InAppSettings.bundle/nl.lproj/Root.strings new file mode 100644 index 000000000..c971a0eec Binary files /dev/null and b/Settings/InAppSettings.bundle/nl.lproj/Root.strings differ diff --git a/Settings/InAppSettings.bundle/nl.lproj/Tunnel.strings b/Settings/InAppSettings.bundle/nl.lproj/Tunnel.strings new file mode 100644 index 000000000..fbbea5667 Binary files /dev/null and b/Settings/InAppSettings.bundle/nl.lproj/Tunnel.strings differ diff --git a/Settings/InAppSettings.bundle/nl.lproj/Video.strings b/Settings/InAppSettings.bundle/nl.lproj/Video.strings new file mode 100644 index 000000000..fa870bafc Binary files /dev/null and b/Settings/InAppSettings.bundle/nl.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Account.strings b/Settings/InAppSettings.bundle/ru.lproj/Account.strings new file mode 100644 index 000000000..f02e9b20a Binary files /dev/null and b/Settings/InAppSettings.bundle/ru.lproj/Account.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Advanced.strings b/Settings/InAppSettings.bundle/ru.lproj/Advanced.strings index bc18bd31d..96b1e1da8 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Advanced.strings and b/Settings/InAppSettings.bundle/ru.lproj/Advanced.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Audio.strings b/Settings/InAppSettings.bundle/ru.lproj/Audio.strings index f9ed568f0..28476bf72 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Audio.strings and b/Settings/InAppSettings.bundle/ru.lproj/Audio.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Call.strings b/Settings/InAppSettings.bundle/ru.lproj/Call.strings index 3262fa85a..289c55d71 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Call.strings and b/Settings/InAppSettings.bundle/ru.lproj/Call.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Network.strings b/Settings/InAppSettings.bundle/ru.lproj/Network.strings index ce62517f9..f8a969aeb 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Network.strings and b/Settings/InAppSettings.bundle/ru.lproj/Network.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Root.strings b/Settings/InAppSettings.bundle/ru.lproj/Root.strings index 58b135b33..f837d1e4d 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Root.strings and b/Settings/InAppSettings.bundle/ru.lproj/Root.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Tunnel.strings b/Settings/InAppSettings.bundle/ru.lproj/Tunnel.strings new file mode 100644 index 000000000..a53a82ffa Binary files /dev/null and b/Settings/InAppSettings.bundle/ru.lproj/Tunnel.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Video.strings b/Settings/InAppSettings.bundle/ru.lproj/Video.strings index 1e5d2b36e..7c377bb18 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Video.strings and b/Settings/InAppSettings.bundle/ru.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Account.strings b/Settings/InAppSettings.bundle/sv.lproj/Account.strings new file mode 100644 index 000000000..06964ad77 Binary files /dev/null and b/Settings/InAppSettings.bundle/sv.lproj/Account.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Advanced.strings b/Settings/InAppSettings.bundle/sv.lproj/Advanced.strings new file mode 100644 index 000000000..bb75ba20e Binary files /dev/null and b/Settings/InAppSettings.bundle/sv.lproj/Advanced.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Audio.strings b/Settings/InAppSettings.bundle/sv.lproj/Audio.strings new file mode 100644 index 000000000..21d17caab Binary files /dev/null and b/Settings/InAppSettings.bundle/sv.lproj/Audio.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Call.strings b/Settings/InAppSettings.bundle/sv.lproj/Call.strings new file mode 100644 index 000000000..525823e7f Binary files /dev/null and b/Settings/InAppSettings.bundle/sv.lproj/Call.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Network.strings b/Settings/InAppSettings.bundle/sv.lproj/Network.strings new file mode 100644 index 000000000..f4107ce16 Binary files /dev/null and b/Settings/InAppSettings.bundle/sv.lproj/Network.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Root.strings b/Settings/InAppSettings.bundle/sv.lproj/Root.strings new file mode 100644 index 000000000..7b5f657d2 Binary files /dev/null and b/Settings/InAppSettings.bundle/sv.lproj/Root.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Tunnel.strings b/Settings/InAppSettings.bundle/sv.lproj/Tunnel.strings new file mode 100644 index 000000000..05b9e2914 Binary files /dev/null and b/Settings/InAppSettings.bundle/sv.lproj/Tunnel.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Video.strings b/Settings/InAppSettings.bundle/sv.lproj/Video.strings new file mode 100644 index 000000000..ffa903af9 Binary files /dev/null and b/Settings/InAppSettings.bundle/sv.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/zh_TW.lproj/Account.strings b/Settings/InAppSettings.bundle/zh_TW.lproj/Account.strings new file mode 100644 index 000000000..6b931be54 Binary files /dev/null and b/Settings/InAppSettings.bundle/zh_TW.lproj/Account.strings differ diff --git a/Settings/InAppSettings.bundle/zh_TW.lproj/Advanced.strings b/Settings/InAppSettings.bundle/zh_TW.lproj/Advanced.strings new file mode 100644 index 000000000..d54652a1a Binary files /dev/null and b/Settings/InAppSettings.bundle/zh_TW.lproj/Advanced.strings differ diff --git a/Settings/InAppSettings.bundle/zh_TW.lproj/Audio.strings b/Settings/InAppSettings.bundle/zh_TW.lproj/Audio.strings new file mode 100644 index 000000000..2c781dc34 Binary files /dev/null and b/Settings/InAppSettings.bundle/zh_TW.lproj/Audio.strings differ diff --git a/Settings/InAppSettings.bundle/zh_TW.lproj/Network.strings b/Settings/InAppSettings.bundle/zh_TW.lproj/Network.strings new file mode 100644 index 000000000..b7393dcb0 Binary files /dev/null and b/Settings/InAppSettings.bundle/zh_TW.lproj/Network.strings differ diff --git a/Settings/InAppSettings.bundle/zh_TW.lproj/Root.strings b/Settings/InAppSettings.bundle/zh_TW.lproj/Root.strings new file mode 100644 index 000000000..d1219411f Binary files /dev/null and b/Settings/InAppSettings.bundle/zh_TW.lproj/Root.strings differ diff --git a/Settings/InAppSettings.bundle/zh_TW.lproj/Tunnel.strings b/Settings/InAppSettings.bundle/zh_TW.lproj/Tunnel.strings new file mode 100644 index 000000000..f235665a9 Binary files /dev/null and b/Settings/InAppSettings.bundle/zh_TW.lproj/Tunnel.strings differ diff --git a/Settings/InAppSettings.bundle/zh_TW.lproj/Video.strings b/Settings/InAppSettings.bundle/zh_TW.lproj/Video.strings new file mode 100644 index 000000000..fa870bafc Binary files /dev/null and b/Settings/InAppSettings.bundle/zh_TW.lproj/Video.strings differ diff --git a/LinphoneTester Tests/DTObjectBlockExecutor.h b/TestsLiblinphone/DTObjectBlockExecutor.h similarity index 83% rename from LinphoneTester Tests/DTObjectBlockExecutor.h rename to TestsLiblinphone/DTObjectBlockExecutor.h index 19926d805..764accb48 100644 --- a/LinphoneTester Tests/DTObjectBlockExecutor.h +++ b/TestsLiblinphone/DTObjectBlockExecutor.h @@ -16,11 +16,11 @@ Convenience method to create a block executor with a deallocation block @param block The block to execute when the created receiver is being deallocated */ -+ (id)blockExecutorWithDeallocBlock:(void(^)())block; ++ (id)blockExecutorWithDeallocBlock:(void (^)())block; /** Block to execute when dealloc of the receiver is called */ -@property (nonatomic, copy) void (^deallocBlock)(); +@property(nonatomic, copy) void (^deallocBlock)(); @end diff --git a/TestsLiblinphone/DTObjectBlockExecutor.m b/TestsLiblinphone/DTObjectBlockExecutor.m new file mode 100644 index 000000000..8b8bb0b1f --- /dev/null +++ b/TestsLiblinphone/DTObjectBlockExecutor.m @@ -0,0 +1,26 @@ +// +// DTObjectBlockExecutor.m +// DTFoundation +// +// Created by Oliver Drobnik on 12.02.13. +// Copyright (c) 2013 Cocoanetics. All rights reserved. +// + +#import "DTObjectBlockExecutor.h" + +@implementation DTObjectBlockExecutor + ++ (id)blockExecutorWithDeallocBlock:(void (^)())block { + DTObjectBlockExecutor *executor = [[DTObjectBlockExecutor alloc] init]; + executor.deallocBlock = block; // copy + return executor; +} + +- (void)dealloc { + if (_deallocBlock) { + _deallocBlock(); + _deallocBlock = nil; + } +} + +@end diff --git a/LinphoneTester Tests/LinphoneTester Tests-Info.plist b/TestsLiblinphone/LinphoneTesterTests-Info.plist similarity index 87% rename from LinphoneTester Tests/LinphoneTester Tests-Info.plist rename to TestsLiblinphone/LinphoneTesterTests-Info.plist index 8715e636e..169b6f710 100644 --- a/LinphoneTester Tests/LinphoneTester Tests-Info.plist +++ b/TestsLiblinphone/LinphoneTesterTests-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.belledonne-communications.tester.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType diff --git a/LinphoneTester Tests/LinphoneTester Tests-Prefix.pch b/TestsLiblinphone/LinphoneTesterTests-Prefix.pch similarity index 100% rename from LinphoneTester Tests/LinphoneTester Tests-Prefix.pch rename to TestsLiblinphone/LinphoneTesterTests-Prefix.pch diff --git a/TestsLiblinphone/LinphoneTester_Tests.m b/TestsLiblinphone/LinphoneTester_Tests.m new file mode 100644 index 000000000..21dc04a69 --- /dev/null +++ b/TestsLiblinphone/LinphoneTester_Tests.m @@ -0,0 +1,96 @@ +// +// LinphoneTester_Tests.m +// LinphoneTester Tests +// +// Created by guillaume on 10/09/2014. +// +// + +#import +#include "linphone/linphonecore.h" +#include "linphone/liblinphone_tester.h" +#import "NSObject+DTRuntime.h" +#import "Utils.h" + +@interface LinphoneTester_Tests : XCTestCase +@property(retain, nonatomic) NSString *bundlePath; +@property(retain, nonatomic) NSString *documentPath; +@end + +@implementation LinphoneTester_Tests + ++ (NSArray *)skippedSuites { + NSArray *skipped_suites = @[ @"Flexisip" ]; + return skipped_suites; +} + ++ (NSString *)safetyTestString:(NSString *)testString { + NSCharacterSet *charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet]; + return [[testString componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:@"_"]; +} + ++ (void)initialize { + + static char *bundle = NULL; + static char *documents = NULL; + bc_tester_init((void (*)(int, const char *fm, va_list))linphone_iphone_log_handler, ORTP_MESSAGE, ORTP_ERROR); + liblinphone_tester_add_suites(); + + NSString *bundlePath = [[NSBundle mainBundle] bundlePath]; + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentPath = [paths objectAtIndex:0]; + bundle = ms_strdup([bundlePath UTF8String]); + documents = ms_strdup([documentPath UTF8String]); + + LOGI(@"Bundle path: %@", bundlePath); + LOGI(@"Document path: %@", documentPath); + + bc_tester_set_resource_dir_prefix(bundle); + bc_tester_set_writable_dir_prefix(documents); + + liblinphone_tester_keep_accounts(TRUE); + int count = bc_tester_nb_suites(); + + for (int i = 0; i < count; i++) { + const char *suite = bc_tester_suite_name(i); + + int test_count = bc_tester_nb_tests(suite); + for (int k = 0; k < test_count; k++) { + const char *test = bc_tester_test_name(suite, k); + NSString *sSuite = [NSString stringWithUTF8String:suite]; + NSString *sTest = [NSString stringWithUTF8String:test]; + + if ([[LinphoneTester_Tests skippedSuites] containsObject:sSuite]) + continue; + // prepend "test_" so that it gets found by introspection + NSString *safesTest = [self safetyTestString:sTest]; + NSString *safesSuite = [self safetyTestString:sSuite]; + NSString *selectorName = [NSString stringWithFormat:@"test_%@__%@", safesSuite, safesTest]; + + [LinphoneTester_Tests addInstanceMethodWithSelectorName:selectorName + block:^(LinphoneTester_Tests *myself) { + [myself testForSuite:sSuite andTest:sTest]; + }]; + } + } +} + +- (void)setUp { + [super setUp]; +} + +- (void)tearDown { + [super tearDown]; +} + +- (void)testForSuite:(NSString *)suite andTest:(NSString *)test { + LOGI(@"Launching test %@ from suite %@", test, suite); + XCTAssertFalse(bc_tester_run_tests([suite UTF8String], [test UTF8String]), @"Suite '%@' / Test '%@' failed", suite, + test); +} + +- (void)dealloc { + liblinphone_tester_clear_accounts(); +} + +@end diff --git a/LinphoneTester Tests/NSObject+DTRuntime.h b/TestsLiblinphone/NSObject+DTRuntime.h similarity index 85% rename from LinphoneTester Tests/NSObject+DTRuntime.h rename to TestsLiblinphone/NSObject+DTRuntime.h index 3e2ad6e04..26b83684e 100644 --- a/LinphoneTester Tests/NSObject+DTRuntime.h +++ b/TestsLiblinphone/NSObject+DTRuntime.h @@ -21,17 +21,18 @@ Adds a block to be executed as soon as the receiver's memory is deallocated @param block The block to execute when the receiver is being deallocated */ -- (void)addDeallocBlock:(void(^)())block; +- (void)addDeallocBlock:(void (^)())block; /** Adds a new instance method to a class. All instances of this class will have this method. - - The block captures `self` in the calling context. To allow access to the instance from within the block it is passed as parameter to the block. + + The block captures `self` in the calling context. To allow access to the instance from within the block it is passed as + parameter to the block. @param selectorName The name of the method. @param block The block to execute for the instance method, a pointer to the instance is passed as the only parameter. @returns `YES` if the operation was successful */ -+ (BOOL)addInstanceMethodWithSelectorName:(NSString *)selectorName block:(void(^)(id))block; ++ (BOOL)addInstanceMethodWithSelectorName:(NSString *)selectorName block:(void (^)(id))block; /**------------------------------------------------------------------------------------- @name Method Swizzling @@ -39,15 +40,16 @@ */ /** - Exchanges two method implementations. After the call methods to the first selector will now go to the second one and vice versa. + Exchanges two method implementations. After the call methods to the first selector will now go to the second one and + vice versa. @param selector The first method @param otherSelector The second method */ + (void)swizzleMethod:(SEL)selector withMethod:(SEL)otherSelector; - - + /** - Exchanges two class method implementations. After the call methods to the first selector will now go to the second one and vice versa. + Exchanges two class method implementations. After the call methods to the first selector will now go to the second one + and vice versa. @param selector The first method @param otherSelector The second method */ diff --git a/TestsLiblinphone/NSObject+DTRuntime.m b/TestsLiblinphone/NSObject+DTRuntime.m new file mode 100644 index 000000000..84c032cd7 --- /dev/null +++ b/TestsLiblinphone/NSObject+DTRuntime.m @@ -0,0 +1,94 @@ +// +// NSObject_DTRuntime.h +// DTFoundation +// +// Created by Oliver Drobnik on 4/25/12. +// Copyright (c) 2012 Cocoanetics. All rights reserved. +// + +#import +#import "DTObjectBlockExecutor.h" + +@implementation NSObject (DTRuntime) + +static char DTRuntimeDeallocBlocks; + +#pragma mark - Blocks + +- (void)addDeallocBlock:(void (^)())block { + // don't accept NULL block + NSParameterAssert(block); + + NSMutableArray *deallocBlocks = objc_getAssociatedObject(self, &DTRuntimeDeallocBlocks); + + // add array of dealloc blocks if not existing yet + if (!deallocBlocks) { + deallocBlocks = [[NSMutableArray alloc] init]; + + objc_setAssociatedObject(self, &DTRuntimeDeallocBlocks, deallocBlocks, OBJC_ASSOCIATION_RETAIN); + } + + DTObjectBlockExecutor *executor = [DTObjectBlockExecutor blockExecutorWithDeallocBlock:block]; + + [deallocBlocks addObject:executor]; +} + ++ (BOOL)addInstanceMethodWithSelectorName:(NSString *)selectorName block:(void (^)(id))block { + // don't accept nil name + NSParameterAssert(selectorName); + + // don't accept NULL block + NSParameterAssert(block); + +// See http://stackoverflow.com/questions/6357663/casting-a-block-to-a-void-for-dynamic-class-method-resolution + +#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_7 + void *impBlockForIMP = (void *)objc_unretainedPointer(block); +#else + id impBlockForIMP = (__bridge id)objc_unretainedPointer(block); +#endif + + IMP myIMP = imp_implementationWithBlock(impBlockForIMP); + + SEL selector = NSSelectorFromString(selectorName); + return class_addMethod(self, selector, myIMP, "v@:"); +} + +#pragma mark - Method Swizzling + ++ (void)swizzleMethod:(SEL)selector withMethod:(SEL)otherSelector { + // my own class is being targetted + Class c = [self class]; + + // get the methods from the selectors + Method originalMethod = class_getInstanceMethod(c, selector); + Method otherMethod = class_getInstanceMethod(c, otherSelector); + + if (class_addMethod(c, selector, method_getImplementation(otherMethod), method_getTypeEncoding(otherMethod))) { + class_replaceMethod(c, otherSelector, method_getImplementation(originalMethod), + method_getTypeEncoding(originalMethod)); + } else { + method_exchangeImplementations(originalMethod, otherMethod); + } +} + ++ (void)swizzleClassMethod:(SEL)selector withMethod:(SEL)otherSelector { + // my own class is being targetted + Class c = [self class]; + + // get the methods from the selectors + Method originalMethod = class_getClassMethod(c, selector); + Method otherMethod = class_getClassMethod(c, otherSelector); + + // if (class_addMethod(c, selector, method_getImplementation(otherMethod), method_getTypeEncoding(otherMethod))) + // { + // class_replaceMethod(c, otherSelector, method_getImplementation(originalMethod), + // method_getTypeEncoding(originalMethod)); + // } + // else + // { + method_exchangeImplementations(originalMethod, otherMethod); + // } +} + +@end diff --git a/LinphoneTester/ar.lproj/InfoPlist.strings b/TestsLiblinphone/ar.lproj/InfoPlist.strings similarity index 100% rename from LinphoneTester/ar.lproj/InfoPlist.strings rename to TestsLiblinphone/ar.lproj/InfoPlist.strings diff --git a/LinphoneTester/en.lproj/InfoPlist.strings b/TestsLiblinphone/en.lproj/InfoPlist.strings similarity index 100% rename from LinphoneTester/en.lproj/InfoPlist.strings rename to TestsLiblinphone/en.lproj/InfoPlist.strings diff --git a/KifTests/WizardTester.h b/TestsUI/AssistantTester.h similarity index 55% rename from KifTests/WizardTester.h rename to TestsUI/AssistantTester.h index ee02ad947..99b53c690 100644 --- a/KifTests/WizardTester.h +++ b/TestsUI/AssistantTester.h @@ -1,5 +1,5 @@ - // -// WizardTester.h +// +// AssistantTester.h // linphone // // Created by Guillaume on 17/01/2015. @@ -8,6 +8,6 @@ #import "LinphoneTestCase.h" -@interface WizardTester : LinphoneTestCase +@interface AssistantTester : LinphoneTestCase -@end \ No newline at end of file +@end diff --git a/TestsUI/AssistantTester.m b/TestsUI/AssistantTester.m new file mode 100644 index 000000000..f8db4fdd5 --- /dev/null +++ b/TestsUI/AssistantTester.m @@ -0,0 +1,121 @@ +// +// AssistantTester.m +// linphone +// +// Created by Guillaume on 17/01/2015. +// +// + +#import "AssistantTester.h" +#import +#import "LinphoneManager.h" + +@implementation AssistantTester + +- (void)beforeEach { + [super beforeEach]; + [UIView setAnimationsEnabled:false]; + + [tester tapViewWithAccessibilityLabel:@"Side menu button"]; + [tester tapViewWithAccessibilityLabel:@"Assistant"]; +} + +- (void)afterEach { + [super afterEach]; + [LinphoneManager.instance removeAllAccounts]; + if ([tester tryFindingTappableViewWithAccessibilityLabel:@"Cancel" error:nil]) { + [tester tapViewWithAccessibilityLabel:@"Cancel"]; + } + [tester tapViewWithAccessibilityLabel:@"Dialer"]; +} + +#pragma mark - Utilities + +- (void)_linphoneLogin:(NSString *)username withPW:(NSString *)pw { + [tester tapViewWithAccessibilityLabel:@"Use Linphone account"]; + + [tester enterText:username intoViewWithAccessibilityLabel:@"Username"]; + [tester enterText:pw intoViewWithAccessibilityLabel:@"Password"]; + + [tester tapViewWithAccessibilityLabel:@"Login"]; +} + +- (void)_externalLoginWithProtocol:(NSString *)protocol { + [tester tapViewWithAccessibilityLabel:@"Use SIP account"]; + + [tester enterText:[self me] intoViewWithAccessibilityLabel:@"Username"]; + [tester enterText:[self me] intoViewWithAccessibilityLabel:@"Password"]; + [tester clearTextFromViewWithAccessibilityLabel:@"Domain"]; + [tester enterText:[self accountDomain] intoViewWithAccessibilityLabel:@"Domain"]; + [tester tapViewWithAccessibilityLabel:protocol]; + + [tester tapViewWithAccessibilityLabel:@"Login"]; +} + +#pragma mark - Tests + +- (void)testAccountCreation { + NSString *username = [NSString stringWithFormat:@"%@-%.2f", [self getUUID], [[NSDate date] timeIntervalSince1970]]; + [tester tapViewWithAccessibilityLabel:@"Create account" traits:UIAccessibilityTraitButton]; + + [tester enterText:username intoViewWithAccessibilityLabel:@"Username"]; + [tester enterText:username intoViewWithAccessibilityLabel:@"Password "]; + [tester enterText:username intoViewWithAccessibilityLabel:@"Password confirmation"]; + [tester enterText:@"testios@.dev.null" intoViewWithAccessibilityLabel:@"Email"]; + + [tester tapViewWithAccessibilityLabel:@"Create account" traits:UIAccessibilityTraitButton]; + + [tester waitForViewWithAccessibilityLabel:@"Finish configuration" traits:UIAccessibilityTraitButton]; + [tester tapViewWithAccessibilityLabel:@"Finish configuration"]; + + [tester waitForViewWithAccessibilityLabel:@"Account validation failed"]; + [tester tapViewWithAccessibilityLabel:@"Skip verification"]; +} + +- (void)testExternalLoginWithTCP { + [self _externalLoginWithProtocol:@"TCP"]; + [self waitForRegistration]; +} + +- (void)testExternalLoginWithTLS { + [self _externalLoginWithProtocol:@"TLS"]; + [self waitForRegistration]; +} + +- (void)testExternalLoginWithUDP { + [self _externalLoginWithProtocol:@"UDP"]; + [self waitForRegistration]; +} + +- (void)testLinphoneLogin { + [self _linphoneLogin:@"testios" withPW:@"testtest"]; + [self waitForRegistration]; +} + +- (void)testLinphoneLoginWithBadPassword { + [self _linphoneLogin:@"testios" withPW:@"badPass"]; + + [self setInvalidAccountSet:true]; + + UIView *alertViewText = + [tester waitForViewWithAccessibilityLabel:@"Registration failure" traits:UIAccessibilityTraitStaticText]; + if (alertViewText) { + UIView *reason = [tester waitForViewWithAccessibilityLabel:@"Incorrect username or password." + traits:UIAccessibilityTraitStaticText]; + if (reason == nil) { + [tester fail]; + } else { + [tester tapViewWithAccessibilityLabel:@"Continue"]; + } + } else { + [tester fail]; + } +} + +- (void)testRemoteProvisioning { + [tester tapViewWithAccessibilityLabel:@"Fetch remote configuration"]; + [tester enterText:@"smtp.linphone.org/testios_xml" intoViewWithAccessibilityLabel:@"URL"]; + [tester tapViewWithAccessibilityLabel:@"Fetch and apply"]; + [self waitForRegistration]; +} +@end diff --git a/TestsUI/CallTester.h b/TestsUI/CallTester.h new file mode 100644 index 000000000..9f89b98e3 --- /dev/null +++ b/TestsUI/CallTester.h @@ -0,0 +1,13 @@ +// +// CallTester.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 24/08/15. +// +// + +#import "LinphoneTestCase.h" + +@interface CallTester : LinphoneTestCase + +@end diff --git a/TestsUI/CallTester.m b/TestsUI/CallTester.m new file mode 100644 index 000000000..bc2085602 --- /dev/null +++ b/TestsUI/CallTester.m @@ -0,0 +1,63 @@ +// +// CallTester.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 24/08/15. +// +// + +#import "CallTester.h" +#include "LinphoneManager.h" + +@implementation CallTester + +- (void)beforeAll { + [super beforeAll]; + [self switchToValidAccountIfNeeded]; +} + +- (void)beforeEach { + [super beforeEach]; + if ([tester tryFindingTappableViewWithAccessibilityLabel:@"Back" error:nil]) { + [tester tapViewWithAccessibilityLabel:@"Back"]; + } + [tester tapViewWithAccessibilityLabel:@"Dialer"]; +} + +- (void)afterEach { + if ([tester tryFindingTappableViewWithAccessibilityLabel:@"Hangup" error:nil]) { + [tester tapViewWithAccessibilityLabel:@"Hangup"]; + } + [super afterEach]; +} +#pragma mark - Tools + +- (void)callURI:(NSString *)address { + [tester enterText:address intoViewWithAccessibilityLabel:@"Enter an address"]; + [tester tapViewWithAccessibilityLabel:@"Call" traits:UIAccessibilityTraitButton]; +} + +#pragma mark - Tests + +- (void)testCallMeBusy { + [self callURI:[self me]]; + [tester waitForViewWithAccessibilityLabel:[NSString stringWithFormat:@"%@ is busy.", [self me]]]; + [tester tapViewWithAccessibilityLabel:@"Cancel" traits:UIAccessibilityTraitButton]; +} + +- (void)testCallUnregisteredUser { + NSString *unregisteredUser = [self getUUID]; + [self callURI:unregisteredUser]; + [tester waitForViewWithAccessibilityLabel:[NSString stringWithFormat:@"%@ is not registered.", unregisteredUser]]; + [tester tapViewWithAccessibilityLabel:@"Cancel" traits:UIAccessibilityTraitButton]; +} + +- (void)testDialInvalidSIPURI { + NSString *user = @"123 😀"; + [self callURI:user]; + [tester waitForViewWithAccessibilityLabel:[NSString + stringWithFormat:@"Cannot call %@.\nReason was: Call failed", user]]; + [tester tapViewWithAccessibilityLabel:@"Cancel" traits:UIAccessibilityTraitButton]; +} + +@end diff --git a/KifTests/ChatTester.h b/TestsUI/ChatTester.h similarity index 100% rename from KifTests/ChatTester.h rename to TestsUI/ChatTester.h diff --git a/TestsUI/ChatTester.m b/TestsUI/ChatTester.m new file mode 100644 index 000000000..908ecddbb --- /dev/null +++ b/TestsUI/ChatTester.m @@ -0,0 +1,314 @@ +// +// ChatTester.m +// linphone +// +// Created by Guillaume on 17/01/2015. +// +// + +#import "ChatTester.h" +#include "LinphoneManager.h" + +@implementation ChatTester + +#pragma mark - setup + +- (void)beforeAll { + [super beforeAll]; + [self switchToValidAccountIfNeeded]; +} + +- (void)beforeEach { + [super beforeEach]; + [self goBackFromChat]; + [tester tapViewWithAccessibilityLabel:@"Chat"]; + [self removeAllRooms]; +} + +- (void)afterAll { + [super afterAll]; + // at the end of tests, go back to chat rooms to display main bar + [self goBackFromChat]; + ASSERT_EQ([LinphoneManager instance].fileTransferDelegates.count, 0) +} + +#pragma mark - tools + +- (void)removeAllRooms { + if (![tester tryFindingTappableViewWithAccessibilityLabel:@"Edit" error:nil]) + return; + + [tester tapViewWithAccessibilityLabel:@"Edit" traits:UIAccessibilityTraitButton]; + [tester tapViewWithAccessibilityLabel:@"Select all" traits:UIAccessibilityTraitButton]; + [tester tapViewWithAccessibilityLabel:@"Delete all" traits:UIAccessibilityTraitButton]; + [tester tapViewWithAccessibilityLabel:@"DELETE" traits:UIAccessibilityTraitButton]; +} + +- (void)dismissKeyboard { + [tester tapScreenAtPoint:CGPointMake(0, 0)]; // dismiss keyboard, if any +} +- (void)goBackFromChat { + [self dismissKeyboard]; + if ([tester tryFindingTappableViewWithAccessibilityLabel:@"Back" error:nil]) { + [tester tapViewWithAccessibilityLabel:@"Back"]; + } +} + +- (void)startChatWith:(NSString *)user { + [tester tapViewWithAccessibilityLabel:@"New discussion"]; + [tester clearTextFromFirstResponder]; + [tester enterTextIntoCurrentFirstResponder:user]; + [tester tapRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] + inTableViewWithAccessibilityIdentifier:@"Suggested addresses"]; +} + +- (void)sendMessage:(NSString *)message { + [tester enterText:message intoViewWithAccessibilityLabel:@"Message field"]; + [tester tapViewWithAccessibilityLabel:@"Send"]; +} + +- (void)uploadImageWithQuality:(NSString *)quality { + UITableView *tv = [self findTableView:@"ChatRoom list"]; + + long messagesCount = [tv numberOfRowsInSection:0]; + [tester tapViewWithAccessibilityLabel:@"Send picture"]; + [tester tapViewWithAccessibilityLabel:@"Photo library"]; +// if popup "Linphone would access your photo" pops up, click OK. +#if TARGET_IPHONE_SIMULATOR + if ([tester acknowledgeSystemAlert]) { + [tester waitForTimeInterval:1]; + } +#endif + + // select random photo to avoid having the same multiple times + [tester choosePhotoInAlbum:@"Camera Roll" atRow:2 column:2 + (messagesCount % 2)]; + + // wait for the quality popup to show up + UIAccessibilityElement *element = nil; + float timeout = 10; + while (!element && timeout > 0.f) { + [tester waitForTimeInterval:.5]; + timeout -= .5f; + element = + [[UIApplication sharedApplication] accessibilityElementMatchingBlock:^BOOL(UIAccessibilityElement *e) { + return [e.accessibilityLabel containsString:quality]; + }]; + } + XCTAssertNotNil(element); + [tester tapViewWithAccessibilityLabel:element.accessibilityLabel]; +} + +- (void)downloadImage { + [self startChatWith:[self me]]; + [self uploadImageWithQuality:@"Minimum"]; + // wait for the upload to terminate... + for (int i = 0; i < 45; i++) { + [tester waitForTimeInterval:1.f]; + if ([[[LinphoneManager instance] fileTransferDelegates] count] == 0) + break; + } + [tester waitForViewWithAccessibilityLabel:@"Download"]; + [tester tapViewWithAccessibilityLabel:@"Download"]; + [tester waitForTimeInterval:.5f]; // just wait a few secs to start download + ASSERT_EQ(LinphoneManager.instance.fileTransferDelegates.count, 1); +} + +#pragma mark - tests + +- (void)testChatFromContactPhoneNumber { + [tester tapViewWithAccessibilityLabel:@"Contacts"]; + [tester tapViewWithAccessibilityLabel:@"Anna Haro"]; + [tester tapViewWithAccessibilityLabel:@"Chat with 555-522-8243"]; + [self goBackFromChat]; + UITableView *tv = [self findTableView:@"Chat list"]; + ASSERT_EQ([tv numberOfRowsInSection:0], 1); + [tester waitForViewWithAccessibilityLabel:@"Contact name, Message" + value:@"Anna Haro (0)" + traits:UIAccessibilityTraitStaticText]; +} + +- (void)testInvalidSIPAddress { + [self startChatWith:@"sip://toto"]; + + [tester waitForViewWithAccessibilityLabel:@"Invalid address" traits:UIAccessibilityTraitStaticText]; + [tester tapViewWithAccessibilityLabel:@"OK"]; +} + +- (void)testMessageRemoval { + NSString *user = [self getUUID]; + + [self startChatWith:user]; + [self sendMessage:user]; + [tester waitForViewWithAccessibilityLabel:@"Delivery failed" traits:UIAccessibilityTraitImage]; + [self dismissKeyboard]; + + [tester tapViewWithAccessibilityLabel:@"Edit" traits:UIAccessibilityTraitButton]; + [tester waitForViewWithAccessibilityLabel:@"Checkbox" value:@"Deselected" traits:UIAccessibilityTraitButton]; + [tester tapRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] + inTableViewWithAccessibilityIdentifier:@"ChatRoom list"]; + [tester waitForViewWithAccessibilityLabel:@"Checkbox" value:@"Selected" traits:UIAccessibilityTraitButton]; + [tester tapViewWithAccessibilityLabel:@"Delete all"]; + [tester tapViewWithAccessibilityLabel:@"DELETE" traits:UIAccessibilityTraitButton]; + + // check that the tableview is empty + UITableView *tv = [self findTableView:@"ChatRoom list"]; + ASSERT_EQ([tv numberOfRowsInSection:0], 0); // no more messages + + [self goBackFromChat]; +} + +- (void)testPerformanceHugeChatList { + [tester tapViewWithAccessibilityLabel:@"Dialer"]; + + // create lots of chat rooms... + LinphoneCore *lc = [LinphoneManager getLc]; + for (int i = 0; i < 100; i++) { + linphone_core_get_chat_room_from_uri(lc, [[NSString stringWithFormat:@"%@ - %d", [self me], i] UTF8String]); + } + + NSTimeInterval before = [[NSDate date] timeIntervalSince1970]; + [tester tapViewWithAccessibilityLabel:@"Chat"]; + NSTimeInterval after = [[NSDate date] timeIntervalSince1970]; + + XCTAssertEqual([[self findTableView:@"Chat list"] numberOfRowsInSection:0], 100); + // conversation loading MUST be less than 1 sec + XCTAssertLessThan(after - before, 1.); +} + +- (void)testPerformanceHugeConversation { + int count = 0; + LinphoneCore *lc = [LinphoneManager getLc]; + LinphoneChatRoom *room = linphone_core_get_chat_room_from_uri(lc, [[self me] UTF8String]); + + NSTimeInterval beforeEmpty = [[NSDate date] timeIntervalSince1970]; + [self startChatWith:[self me]]; + NSTimeInterval afterEmpty = [[NSDate date] timeIntervalSince1970]; + [self goBackFromChat]; + + // generate lots of messages... + for (; count < 50; count++) { + LinphoneChatMessage *msg = + linphone_chat_room_create_message(room, [[NSString stringWithFormat:@"Message %d", count + 1] UTF8String]); + linphone_chat_room_send_chat_message(room, msg); + } + + for (int i = 0; i < 25; i++) { + [tester waitForTimeInterval:1.f]; + if (linphone_chat_room_get_history_size(room) == count * 2) { + break; + } + } + + [tester waitForViewWithAccessibilityLabel:@"Contact name, Message" + value:[NSString stringWithFormat:@"%@, Message %d (%d)", self.me, count, count] + traits:UIAccessibilityTraitStaticText]; + + NSTimeInterval before = [[NSDate date] timeIntervalSince1970]; + [self startChatWith:[self me]]; + NSTimeInterval after = [[NSDate date] timeIntervalSince1970]; + + // conversation loading MUST be less than 1 sec - loading messages only + XCTAssertLessThan(after - before, afterEmpty - beforeEmpty + 1.); +} + +- (void)testRemoveAllChats { + NSArray *uuids = [self getUUIDArrayOfSize:3]; + + for (NSString *uuid in uuids) { + [self startChatWith:uuid]; + [self sendMessage:@"Test"]; + [self goBackFromChat]; + } + + UITableView *tv = [self findTableView:@"Chat list"]; + + ASSERT_EQ([tv numberOfRowsInSection:0], uuids.count); + + [self removeAllRooms]; + + // check that the tableview is empty + ASSERT_EQ([tv numberOfRowsInSection:0], 0); + + // test that there's no more chatrooms in the core + ASSERT_EQ(linphone_core_get_chat_rooms([LinphoneManager getLc]), NULL); +} + +- (void)testSendMessageToMyself { + [self startChatWith:[self me]]; + + [self sendMessage:@"Hello"]; + [tester waitForViewWithAccessibilityLabel:@"Outgoing message" value:@"Hello" traits:UIAccessibilityTraitStaticText]; + [tester waitForViewWithAccessibilityLabel:@"Incoming message" value:@"Hello" traits:UIAccessibilityTraitStaticText]; + [tester waitForAbsenceOfViewWithAccessibilityLabel:@"Message status"]; + + [self goBackFromChat]; +} + +- (void)testSendToSIPAddress { + NSString *sipAddr = [NSString stringWithFormat:@"sip:%@@%@", [self me], [self accountDomain]]; + + [self startChatWith:sipAddr]; + + [tester waitForViewWithAccessibilityLabel:@"Contact name" value:[self me] traits:0]; + + [self goBackFromChat]; +} + +- (void)testTransferCancelDownloadImage { + [self downloadImage]; + [tester tapViewWithAccessibilityLabel:@"Cancel"]; + ASSERT_EQ([[[LinphoneManager instance] fileTransferDelegates] count], 0); +} + +- (void)testTransferCancelUploadImage { + [self startChatWith:[self me]]; + [self uploadImageWithQuality:@"Minimum"]; + [tester tapViewWithAccessibilityLabel:@"Cancel"]; + ASSERT_EQ([[[LinphoneManager instance] fileTransferDelegates] count], 0); +} + +- (void)testTransferDestroyRoomWhileUploading { + [self startChatWith:[self me]]; + [self uploadImageWithQuality:@"Maximum"]; + [self goBackFromChat]; + [self removeAllRooms]; +} + +- (void)testTransferDownloadImage { + [self downloadImage]; + [tester waitForAbsenceOfViewWithAccessibilityLabel:@"Cancel"]; + ASSERT_EQ([[[LinphoneManager instance] fileTransferDelegates] count], 0); +} + +- (void)testTransferSimultanouslyDownload { + [self startChatWith:[self me]]; + [self uploadImageWithQuality:@"Minimum"]; + [self uploadImageWithQuality:@"Minimum"]; + UITableView *tv = [self findTableView:@"ChatRoom list"]; + // wait for ALL uploads to terminate... + for (int i = 0; i < 90; i++) { + [tester waitForTimeInterval:1.f]; + if ([tv numberOfRowsInSection:0] == 4) + break; + } + [tester waitForTimeInterval:.5f]; + ASSERT_EQ([[LinphoneManager instance] fileTransferDelegates].count, 0); + [tester scrollViewWithAccessibilityIdentifier:@"ChatRoom list" byFractionOfSizeHorizontal:0.f vertical:1.f]; + for (int i = 0; i < 2; i++) { + // messages order is not known: if upload bitrate is huge, first image can be uploaded before last started + while (![tester tryFindingTappableViewWithAccessibilityLabel:@"Download" error:nil]) { + [tester scrollViewWithAccessibilityIdentifier:@"ChatRoom list" + byFractionOfSizeHorizontal:0.f + vertical:-.1f]; + } + [tester waitForViewWithAccessibilityLabel:@"Download"]; + [tester tapViewWithAccessibilityLabel:@"Download"]; + [tester waitForTimeInterval:.2f]; // just wait a few secs to start download + } + while ([LinphoneManager instance].fileTransferDelegates.count > 0) { + [tester waitForTimeInterval:.5]; + } + [self goBackFromChat]; +} + +@end diff --git a/KifTests/ContactsTester.h b/TestsUI/ContactsTester.h similarity index 100% rename from KifTests/ContactsTester.h rename to TestsUI/ContactsTester.h diff --git a/TestsUI/ContactsTester.m b/TestsUI/ContactsTester.m new file mode 100644 index 000000000..70706942d --- /dev/null +++ b/TestsUI/ContactsTester.m @@ -0,0 +1,168 @@ +// +// ContactsTester.m +// linphone +// +// Created by Guillaume BIENKOWSKI on 17/02/2015. +// +// + +#import "ContactsTester.h" + +#import "ContactDetailsTableView.h" + +@implementation ContactsTester + +#pragma mark - Setup + +- (void)beforeAll { + [self switchToValidAccountIfNeeded]; +} + +- (void)beforeEach { + [super beforeEach]; + if ([tester tryFindingTappableViewWithAccessibilityLabel:@"Back" error:nil]) { + [tester tapViewWithAccessibilityLabel:@"Back"]; + } + [tester tapViewWithAccessibilityLabel:@"Contacts"]; +} + +#pragma mark - Utils + +- (void)setText:(NSString *)text forIndex:(NSInteger)idx inSection:(NSInteger)section { + [tester tapRowAtIndexPath:[NSIndexPath indexPathForRow:idx inSection:section] + inTableViewWithAccessibilityIdentifier:@"Contact table"]; + [tester enterTextIntoCurrentFirstResponder:text]; +} + +- (void)createContact:(NSString *)firstName + lastName:(NSString *)lastName + phoneNumber:(NSString *)phone + SIPAddress:(NSString *)sip { + + XCTAssert(firstName != nil); + [tester tapViewWithAccessibilityLabel:@"Add contact"]; + + // check that the OK button is disabled + [tester waitForViewWithAccessibilityLabel:@"Edit" + traits:UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled | + UIAccessibilityTraitSelected]; + + [self setText:firstName forIndex:0 inSection:ContactSections_First_Name]; + + // entering text should enable the "edit" button + [tester waitForViewWithAccessibilityLabel:@"Edit" traits:UIAccessibilityTraitButton | UIAccessibilityTraitSelected]; + + if (lastName) { + [self setText:lastName forIndex:0 inSection:ContactSections_Last_Name]; + } + + if (phone) { + [self setText:phone forIndex:0 inSection:ContactSections_Number]; + } + + if (sip) { + [self setText:sip forIndex:0 inSection:ContactSections_Sip]; + } + + [tester tapViewWithAccessibilityLabel:@"Edit"]; +} + +- (void)tapCellForRowAtIndexPath:(NSInteger)idx inSection:(NSInteger)section atX:(CGFloat)x { + UITableView *tv = [self findTableView:@"Contact table"]; + NSIndexPath *path = [NSIndexPath indexPathForRow:idx inSection:section]; + UITableViewCell *last = + [tester waitForCellAtIndexPath:path inTableViewWithAccessibilityIdentifier:@"Contact table"]; + XCTAssertNotNil(last); + + CGRect cellFrame = [last.contentView convertRect:last.contentView.frame toView:tv]; + [tv tapAtPoint:CGPointMake(x > 0 ? x : cellFrame.size.width + x, cellFrame.origin.y + cellFrame.size.height / 2.)]; + [tester waitForAnimationsToFinish]; +} + +- (void)tapRemoveButtonForRowAtIndexPath:(NSInteger)idx inSection:(NSInteger)section { + [self tapCellForRowAtIndexPath:idx inSection:section atX:-10]; +} + +- (void)addEntries:(NSArray *)numbers inSection:(NSInteger)section { + [tester tapViewWithAccessibilityLabel:@"Edit"]; + NSString *name = (section == ContactSections_Sip) ? @"Add new SIP address" : @"Add new phone number"; + [self setText:[numbers objectAtIndex:0] forIndex:0 inSection:section]; + for (NSInteger i = 1; i < numbers.count; i++) { + [tester tapViewWithAccessibilityLabel:name traits:UIAccessibilityTraitButton]; + [self setText:[numbers objectAtIndex:i] forIndex:i inSection:section]; + } + [tester tapViewWithAccessibilityLabel:@"Edit"]; + + for (NSInteger i = 0; i < numbers.count; i++) { + [tester waitForViewWithAccessibilityLabel:[@"Call " stringByAppendingString:[numbers objectAtIndex:i]] + traits:UIAccessibilityTraitButton]; + } +} + +- (void)deleteContactEntryForRowAtIndexPath:(NSInteger)idx inSection:(NSInteger)section { + if ([tester tryFindingTappableViewWithAccessibilityLabel:@"Delete" error:nil]) { + [tester tapViewWithAccessibilityLabel:@"Delete"]; + } else { + // hack: Travis seems to be unable to click on delete for what ever reason + [self tapRemoveButtonForRowAtIndexPath:idx inSection:section]; + } +} + +#pragma mark - Tests + +- (void)testCallContactWithInvalidPhoneNumber { + NSString *contactName = [self getUUID]; + NSString *phone = @"+5 15 #0664;447*46"; + [self createContact:contactName lastName:@"dummy" phoneNumber:phone SIPAddress:nil]; + [tester tapViewWithAccessibilityLabel:[@"Call " stringByAppendingString:phone]]; + [tester waitForViewWithAccessibilityLabel:[phone stringByAppendingString:@" is not registered."]]; + [tester tapViewWithAccessibilityLabel:@"Cancel"]; +} + +- (void)testDeleteContact { + NSString *contactName = [self getUUID]; + [self createContact:contactName lastName:@"dummy" phoneNumber:@"0102030405" SIPAddress:[self me]]; + [tester tapViewWithAccessibilityLabel:@"Back"]; + + NSString *fullName = [contactName stringByAppendingString:@" dummy"]; + + [tester tapViewWithAccessibilityLabel:fullName traits:UIAccessibilityTraitStaticText]; + + [tester tapViewWithAccessibilityLabel:@"Edit"]; + [tester scrollViewWithAccessibilityIdentifier:@"Contact table" byFractionOfSizeHorizontal:0 vertical:-0.9]; + + [tester tapViewWithAccessibilityLabel:@"Delete"]; + [tester tapViewWithAccessibilityLabel:@"DELETE"]; +} + +- (void)testEditContact { + NSString *contactName = [self getUUID]; + [self createContact:contactName lastName:@"dummy" phoneNumber:nil SIPAddress:nil]; + + /* Phone number */ + NSArray *phones = @[ @"01234", @"56789" ]; + [self addEntries:phones inSection:ContactSections_Number]; + NSArray *SIPs = @[ @"sip1", @"sip2" ]; + [self addEntries:SIPs inSection:ContactSections_Sip]; + + [tester tapViewWithAccessibilityLabel:@"Edit"]; + // remove all numbers + for (NSInteger i = 0; i < phones.count; i++) { + [self tapRemoveButtonForRowAtIndexPath:0 inSection:ContactSections_Number]; + } + // remove all SIPs + for (NSInteger i = 0; i < SIPs.count; i++) { + [self tapRemoveButtonForRowAtIndexPath:0 inSection:ContactSections_Sip]; + } + [tester tapViewWithAccessibilityLabel:@"Edit"]; + + // then remove the contact + [tester tapViewWithAccessibilityLabel:@"Edit"]; + + [tester scrollViewWithAccessibilityIdentifier:@"Contact table" byFractionOfSizeHorizontal:0 vertical:-0.9]; + + [tester tapViewWithAccessibilityLabel:@"Delete"]; + [tester tapViewWithAccessibilityLabel:@"DELETE"]; +} + +@end diff --git a/KifTests/Info.plist b/TestsUI/Info.plist similarity index 91% rename from KifTests/Info.plist rename to TestsUI/Info.plist index fddcb8263..ba72822e8 100644 --- a/KifTests/Info.plist +++ b/TestsUI/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - org.linphone.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/TestsUI/LinphoneTestCase.h b/TestsUI/LinphoneTestCase.h new file mode 100644 index 000000000..cd31947e6 --- /dev/null +++ b/TestsUI/LinphoneTestCase.h @@ -0,0 +1,39 @@ +// +// LinphoneTestCase.h +// linphone +// +// Created by Guillaume BIENKOWSKI on 19/01/2015. +// +// + +#import +#import + +#import "Utils.h" + +@interface LinphoneTestCase : KIFTestCase +@property BOOL invalidAccountSet; + +- (void)switchToValidAccountIfNeeded; +- (NSString *)me; +- (NSString *)accountDomain; + +- (NSString *)getUUID; +- (NSArray *)getUUIDArrayOfSize:(size_t)size; + +- (UITableView *)findTableView:(NSString *)table; + +- (void)waitForRegistration; + +@end + +#define ASSERT_EQ(actual, expected) \ + { \ + if ((actual) != (expected)) { \ + [[UIApplication sharedApplication] writeScreenshotForLine:__LINE__ \ + inFile:@__FILE__ \ + description:nil \ + error:NULL]; \ + } \ + XCTAssertEqual(actual, expected); \ + } diff --git a/TestsUI/LinphoneTestCase.m b/TestsUI/LinphoneTestCase.m new file mode 100644 index 000000000..f3753090c --- /dev/null +++ b/TestsUI/LinphoneTestCase.m @@ -0,0 +1,172 @@ +// +// LinphoneTestCase.m +// linphone +// +// Created by Guillaume BIENKOWSKI on 19/01/2015. +// +// + +#import "LinphoneTestCase.h" + +#import "LinphoneManager.h" + +#import "KIF/KIFTypist.h" +#import "Utils.h" + +@implementation LinphoneTestCase + ++ (void)initialize { + // default is 0.01, which sometimes confuses the simulator to the point that + // it will miss some keys + [KIFTypist setKeystrokeDelay:0.05]; + + NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0]; + if (!([language isEqualToString:@"en"] || [language containsString:@"en-"])) { + LOGF(@"Language must be 'en' (English) instead of %@", language); + } +} + +- (void)beforeAll { + [super beforeAll]; + +#if TARGET_IPHONE_SIMULATOR + while ([tester acknowledgeSystemAlert]) { + [tester waitForTimeInterval:.5f]; + }; +#endif + // remove any account + [LinphoneManager.instance removeAllAccounts]; + + // go to dialer + for (NSString *button in @[ @"Cancel", @"Back", @"Hangup", @"Dialer" ]) { + if ([tester tryFindingTappableViewWithAccessibilityLabel:button error:nil]) { + [tester tapViewWithAccessibilityLabel:button traits:UIAccessibilityTraitButton]; + } + } +} + +- (void)beforeEach { + [[LinphoneManager instance] lpConfigSetInt:NO forKey:@"animations_preference"]; +} + +- (NSString *)me { + return [NSString stringWithFormat:@"testios-%@", + [[UIDevice currentDevice].identifierForVendor.UUIDString substringToIndex:6]] + .lowercaseString; +} + +- (NSString *)accountDomain { + return @"test.linphone.org"; +} + +- (NSString *)getUUID { + return [[[NSUUID UUID] UUIDString] substringToIndex:8].lowercaseString; +} + +- (NSArray *)getUUIDArrayOfSize:(size_t)size { + NSMutableArray *array = [NSMutableArray arrayWithCapacity:size]; + for (NSInteger i = 0; i < size; i++) { + [array setObject:[self getUUID] atIndexedSubscript:i]; + } + return array; +} + +- (BOOL)hasValidProxyConfig { + LinphoneCore *lc = [LinphoneManager getLc]; + const MSList *proxies = linphone_core_get_proxy_config_list(lc); + BOOL isOK = false; + while (proxies) { + LinphoneProxyConfig *cfg = (LinphoneProxyConfig *)proxies->data; + const char *domain = linphone_proxy_config_get_domain(cfg); + const LinphoneAddress *addr = linphone_proxy_config_get_identity_address(cfg); + const char *username = linphone_address_get_username(addr); + + if (addr && (username && strcmp(username, [[self me] UTF8String]) == 0) && + (domain && strcmp(domain, [[self accountDomain] UTF8String]) == 0) && + linphone_proxy_config_get_state(cfg) == LinphoneRegistrationOk) { + isOK = true; + break; + } + + proxies = proxies->next; + } + return isOK; +} + +- (void)switchToValidAccountIfNeeded { + [UIView setAnimationsEnabled:false]; + + if (![self hasValidProxyConfig]) { + LOGI(@"Switching to a test account..."); + + LinphoneCore *lc = [LinphoneManager getLc]; + linphone_core_clear_proxy_config(lc); + linphone_core_clear_all_auth_info(lc); + + LinphoneAddress *testAddr = linphone_address_new( + [[NSString stringWithFormat:@"sip:%@@%@", [self me], [self accountDomain]] UTF8String]); + linphone_address_set_header(testAddr, "X-Create-Account", "yes"); + linphone_address_set_transport(testAddr, LinphoneTransportTcp); + linphone_address_set_port(testAddr, 0); + + LinphoneProxyConfig *testProxy = linphone_proxy_config_new(); + linphone_proxy_config_set_identity_address(testProxy, testAddr); + char *server_addr = ms_strdup_printf("%s;transport=tcp", linphone_address_get_domain(testAddr)); + linphone_proxy_config_set_server_addr(testProxy, server_addr); + linphone_proxy_config_set_route(testProxy, server_addr); + ms_free(server_addr); + + LinphoneAuthInfo *testAuth = linphone_auth_info_new(linphone_address_get_username(testAddr), NULL, + linphone_address_get_username(testAddr), NULL, NULL, + linphone_address_get_domain(testAddr)); + + [[LinphoneManager instance] configurePushTokenForProxyConfig:testProxy]; + [[LinphoneManager instance] removeAllAccounts]; + + linphone_proxy_config_enable_register(testProxy, true); + linphone_core_add_auth_info(lc, testAuth); + linphone_core_add_proxy_config(lc, testProxy); + linphone_core_set_default_proxy_config(lc, testProxy); + + linphone_proxy_config_unref(testProxy); + linphone_auth_info_destroy(testAuth); + linphone_address_destroy(testAddr); + + linphone_core_set_file_transfer_server(lc, "https://www.linphone.org:444/lft.php"); + + // reload address book to prepend proxy config domain to contacts' phone number + [[[LinphoneManager instance] fastAddressBook] reload]; + + [self waitForRegistration]; + [[LinphoneManager instance] lpConfigSetInt:NO forKey:@"animations_preference"]; + } +} + +- (UITableView *)findTableView:(NSString *)table { + UITableView *tv = nil; + NSError *err = nil; + if ([tester tryFindingAccessibilityElement:nil view:&tv withIdentifier:table tappable:false error:&err]) { + XCTAssertNotNil(tv); + } else { + XCTFail(@"Error: %@", err); + } + return tv; +} + +- (void)waitForRegistration { + // wait for account to be registered + int timeout = 15; + while (timeout && + ![tester tryFindingViewWithAccessibilityLabel:@"Registration state" + value:@"Registered" + traits:UIAccessibilityTraitButton + error:nil]) { + [tester waitForTimeInterval:1]; + timeout--; + } + [tester waitForViewWithAccessibilityLabel:@"Registration state" + value:@"Registered" + traits:UIAccessibilityTraitButton]; +} + +@end diff --git a/Tools/change_ios_custom_font.sh b/Tools/change_ios_custom_font.sh index 20c024f95..bf25b1dd1 100755 --- a/Tools/change_ios_custom_font.sh +++ b/Tools/change_ios_custom_font.sh @@ -88,10 +88,10 @@ for font in "${fonts[@]}"; do new_font=${font#*:} echo "$system_font -> $new_font" - find . -name '*.xib' -exec \ - sed -E -i.font_backup \ - -e "s|\"|g" \ - -e "s||g" {} \; + find . -name '*.xib' -exec \ + sed -E -i.font_backup \ + -e "s|\"|g" \ + -e "s||g" {} \; done echo "********************** diff --git a/Tools/check_tools.sh b/Tools/check_tools.sh index 66bd67a2a..2e1c7af1a 100755 --- a/Tools/check_tools.sh +++ b/Tools/check_tools.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash error_on_quit=0 @@ -17,7 +17,10 @@ check_installed() { cd $(dirname $0)/.. -#autoconf pkg-config java ant yasm nasm wget +if grep -q ' ' <<< $PWD; then + echo_err "Invalid location: your location should not contain spaces" +fi + for prog in autoconf automake pkg-config doxygen java nasm gettext wget yasm optipng; do check_installed "$prog" "it" done @@ -26,13 +29,20 @@ check_installed "ginstall" "coreutils" check_installed "intltoolize" "intltool" check_installed "convert" "imagemagick" -if ! check_installed "libtoolize" "libtool"; then - if [ ! -z "$(which glibtoolize)" ]; then - echo_err "Note: it seems that you are using HomeBrew. Please do a symbolic link from " \ - "glibtoolize to libtoolize: 'ln -s $(which glibtoolize) /usr/local/bin/libtoolize'" +if [ -z "$(which libtoolize)" ]; then + glibtoolize=$(which glibtoolize) + if [ ! -z "$glibtoolize" ]; then + echo_err "Please do a symbolic link from glibtoolize to libtoolize: 'ln -s $glibtoolize ${glibtoolize/glibtoolize/libtoolize}'" + else + echo_err "Could not find libtoolize. Please install libtool." fi fi +# just ensure that JDK is installed - if not, it will display user a popup +if ! java -version &>/dev/null; then + echo_err "Please install Java JDK (not just JRE)" +fi + # needed by x264 check_installed "gas-preprocessor.pl" "it following the README.md" diff --git a/Tools/generate_strings_files.sh b/Tools/generate_strings_files.sh deleted file mode 100755 index 9619883c6..000000000 --- a/Tools/generate_strings_files.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/sh - -root_directory=$(cd "$(dirname $0)" && pwd)/../ - -set -e - -# The 2 only specific cases of the application: since we are length limited for push -# notifications, the ID is not matching the English translation... so we must keep -# the translations! -localizable_en=$root_directory/Resources/en.lproj/Localizable.strings -IC_MSG_EN=$(sed -nE 's/"IC_MSG" = "(.*)";/\1/p' $localizable_en) -IM_MSG_EN=$(sed -nE 's/"IM_MSG" = "(.*)";/\1/p' $localizable_en) -rm -f $localizable_en -find $root_directory/Classes -name '*.m' | xargs genstrings -u -a -o $(dirname $localizable_en) -iconv -f utf-16 -t utf-8 $localizable_en > $localizable_en.tmp -mv $localizable_en.tmp $localizable_en -sed -i.bak "s/= \"IC_MSG\";/= \"$IC_MSG_EN\";/" $localizable_en -sed -i.bak "s/= \"IM_MSG\";/= \"$IM_MSG_EN\";/" $localizable_en -rm $localizable_en.bak - -to_utf8=$(mktemp -t linphone) - -find $root_directory/Classes -not -path "$root_directory/Classes/KIF/*" -name Base.lproj -exec find {} -name '*.xib' \; | while read -r xibfile; do - stringsfile="${xibfile/.xib/.strings}" - - ibtool --generate-strings-file "$stringsfile" "$xibfile" - - # remove if empty - iconv -f utf-16 -t utf-8 "$stringsfile" > "$to_utf8" - if [ ! -s "$to_utf8" ]; then - echo "$(basename "$stringsfile") is empty, removing" - rm "$stringsfile" - else - echo "$(basename "$xibfile")->$(basename "$stringsfile")" - - res_name=$(basename "$stringsfile" | tr -d '_.~-' | tr '[:upper:]' '[:lower:]') - dir_name=$(echo $(dirname "$stringsfile") | sed -E "s|$root_directory/||") - # if not registered in transifex config file, register it - if ! grep -q $res_name $root_directory/.tx/config; then - echo "not found in .tx/config, adding it" - echo " -[linphone-ios.$res_name] -file_filter = $(echo $dir_name| sed 's/Base.lproj/.lproj/')/$(basename "$stringsfile") -source_file = $dir_name/$(basename "$stringsfile") -source_lang = en -" >> $root_directory/.tx/config - fi - fi -done -rm $to_utf8 diff --git a/Tools/i18n_generate_strings_files.sh b/Tools/i18n_generate_strings_files.sh new file mode 100755 index 000000000..f626ca7d3 --- /dev/null +++ b/Tools/i18n_generate_strings_files.sh @@ -0,0 +1,120 @@ +#!/bin/sh + +# Copyright (C) 2012 Belledonne Comunications, Grenoble, France +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Created by Gautier Pelloux-Prayer on 2014. +# Generate English translation files so that they can be pushed to Transifex +# for translation + +root_directory=$(cd "$(dirname $0)" && pwd)/../ + +set -e + +if [ $# != 0 ]; then + echo "No argument needed. This script will (re)generate .strings file from .xib files and register them in the transifex config file located in .tx/config." + exit 0 +fi + +function generate_transifex_config { + res_name=$1 + file_filter=$2 + source_file=$(test -f ${file_filter//en}&&echo ${file_filter//en}||echo ${file_filter//Base}) + if ! grep -q $res_name $root_directory/.tx/config; then + echo "not found in .tx/config, adding it" + echo " +[linphone-ios.$res_name] +source_lang = en +file_filter = $file_filter" >> $root_directory/.tx/config + if [ ! -z "$source_file" ]; then + echo "source_file = $source_file" >> $root_directory/.tx/config + fi + fi +} + +##### 1. Generate Localizable.strings from source files (.m) +function generate_localizable_from_sources { + #WARNING: in case of sed issue "extra characters at the end of g command", it means that + # we are trying to modify an UTF-16 file which is not supported.. + + localizable_en=$root_directory/Resources/en.lproj/Localizable.strings + # The 2 only specific cases of the application: since we are length limited for push + # notifications, the ID is not matching the English translation... so we must keep + # the translations! + iconv -f utf-16 -t utf-8 $localizable_en > $localizable_en.tmp + IC_MSG_EN=$(sed -nE 's/"IC_MSG" = "(.*)";/\1/p' $localizable_en.tmp) + IM_MSG_EN=$(sed -nE 's/"IM_MSG" = "(.*)";/\1/p' $localizable_en.tmp) + IM_FULLMSG_EN=$(sed -nE 's/"IM_FULLMSG" = "(.*)";/\1/p' $localizable_en.tmp) + rm -f $localizable_en $localizable_en.tmp + + find $root_directory/Classes -name '*.m' | xargs genstrings -u -a -o $(dirname $localizable_en) + iconv -f utf-16LE -t utf-8 $localizable_en > $localizable_en.tmp + sed -i.bak "s/= \"IC_MSG\";/= \"$IC_MSG_EN\";/" $localizable_en.tmp + sed -i.bak "s/= \"IM_MSG\";/= \"$IM_MSG_EN\";/" $localizable_en.tmp + sed -i.bak "s/= \"IM_FULLMSG\";/= \"$IM_FULLMSG_EN\";/" $localizable_en.tmp + iconv -f utf-8 -t utf-16LE $localizable_en.tmp > $localizable_en + rm $localizable_en.tmp.bak $localizable_en.tmp + + generate_transifex_config localizablestrings "Resources/.lproj/Localizable.strings" +} + +##### 2. Generate .strings for all XIB files +function generate_strings_from_xib { + to_utf8_file=$(mktemp -t linphone) + find $root_directory/Classes -not -path "$root_directory/Classes/KIF/*" -name Base.lproj -exec find {} -name '*.xib' \; | while read -r xibfile; do + stringsfile="${xibfile/.xib/.strings}" + + ibtool --generate-strings-file "$stringsfile" "$xibfile" + + # remove if empty + iconv -f utf-16 -t utf-8 "$stringsfile" > "$to_utf8_file" + if [ $(stat -f '%z' $to_utf8_file) -le 1 ]; then + echo "$(basename "$stringsfile") is empty, removing" + rm "$stringsfile" + else + echo "$(basename "$xibfile")->$(basename "$stringsfile")" + + res_name=$(basename "$stringsfile" | tr -d '_.~-' | tr '[:upper:]' '[:lower:]') + dir_name=$(echo $(dirname "$stringsfile") | sed -E "s|$root_directory/||") + + + generate_transifex_config $res_name $(echo $dir_name| sed 's/Base.lproj/.lproj/')/$(basename "$stringsfile") + fi + done + rm $to_utf8_file +} + +##### 3. Generate .strings for all InAppSettings PLIST files +function generate_strings_from_inappsettings_plist { + tmp_file=$(mktemp -t linphone) + find $root_directory/Settings/InAppSettings.bundle -name '*.plist' | while read -r plistfile; do + echo $plistfile + plistfilestrings="$(basename ${plistfile/.plist/.strings})" + printf '' > $tmp_file + while read title; do + echo "\"$title\" = \"$title\";" >> $tmp_file + done <<< "$(grep -e '>Title<' $plistfile -A 1 | sed -nE 's|.*(.*).*|\1|p')" + + mv $tmp_file $root_directory/Settings/InAppSettings.bundle/en.lproj/$plistfilestrings + + res_name=inappsettings$(echo "$plistfilestrings" | tr -d '_.~-' | tr '[:upper:]' '[:lower:]') + generate_transifex_config $res_name "Settings/InAppSettings.bundle/.lproj/$plistfilestrings" + done +} + +generate_localizable_from_sources +generate_strings_from_xib +generate_strings_from_inappsettings_plist diff --git a/Tools/i18n_update_strings_files.py b/Tools/i18n_update_strings_files.py new file mode 100755 index 000000000..966923c5c --- /dev/null +++ b/Tools/i18n_update_strings_files.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2012 Belledonne Comunications, Grenoble, France +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Created by Gautier Pelloux-Prayer on 2014. +# Update non-English translation by regenerating .strings files and reapplying +# existing translations after that + +import codecs +import re +import sys +import shutil + +kvpattern = re.compile('^(.*) = (.*);$') + + +def find_english_for_key(file, key): + with codecs.open(file, 'r', 'utf-16') as fp: + for line in fp: + match = kvpattern.match(line) + + if match is None: + continue + + if key == match.groups()[0]: + return match.groups()[1] + + return None + + +def update_messages_for_file(old_file, new_file): + translations = {} + with codecs.open(old_file, 'r', 'utf-16') as fp: + for line in fp: + match = kvpattern.match(line) + + if match is None: + continue + + english_value = find_english_for_key(new_file, match.groups()[0]) + foreign_value = match.groups()[1] + + translations[english_value] = foreign_value + with codecs.open(new_file, 'r', 'utf-16') as f: + lines = f.read() + for english_value, foreign_value in translations.items(): + print("replace {} with {}".format(english_value, foreign_value)) + lines = lines.replace("{};".format(english_value), "{};".format(foreign_value)) + with codecs.open(new_file, 'w', 'utf-16') as f1: + f1.write(lines) + return True + + return False + +if len(sys.argv) != 3: + print("Usage: {} English.strings CustomLanguage.strings".format(sys.argv[0])) + print("CustomLanguage.strings will be modified to take all English strings with its own translations") +else: + new_file = sys.argv[2] + ".new" + shutil.copyfile(sys.argv[1], new_file) + if (update_messages_for_file(sys.argv[2], new_file)): + shutil.move(new_file, sys.argv[2]) diff --git a/Tools/imgur_upload.sh b/Tools/imgur_upload.sh new file mode 100755 index 000000000..debd736f0 --- /dev/null +++ b/Tools/imgur_upload.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Install underscore-cli for hacking +if ! which underscore &> /dev/null; then + npm install -g underscore-cli &>/dev/null +fi + +cd $KIF_SCREENSHOTS + +if [ ! -z "$(find . -name "*.png")" ]; then + # Prepare location to collect delete commands + if test "$TRAVIS_BUILD_NUMBER" = ""; then + TRAVIS_BUILD_NUMBER="dev" + fi + download_cmds="" + + # curl from http://imgur.com/tools/imgurbash.sh via http://imgur.com/tools + # Documentation: http://code.google.com/p/imgur-api/source/browse/wiki/ImageUploading.wiki?r=82 + api_key=$IMGUR_KEY + for filepath in *.png; do + # echo "File $filepath" + # echo "Command: curl https://api.imgur.com/3/upload.json -H \"Authorization: Client-ID $api_key\" -F "image=@\"$filepath\""" + result="$(curl https://api.imgur.com/3/upload.json -H "Authorization: Client-ID $api_key" -F "image=@\"$filepath\"" )" + + # result='{"rsp":{"stat":"ok","image":{"image_hash":"dKZ0YK9","delete_hash":"r0MsZp11K9vawLf","original_image":"http:\/\/i.imgur.com\/dKZ0YK9.png","large_thumbnail":"http:\/\/i.imgur.com\/dKZ0YK9l.jpg","small_thumbnail":"http:\/\/i.imgur.com\/dKZ0YK9s.jpg","imgur_page":"http:\/\/imgur.com\/dKZ0YK9","delete_page":"http:\/\/imgur.com\/delete\/r0MsZp11K9vawLf"}}}' + succeeded="$(echo $result | underscore extract success)" + if [ "$succeeded" != "true" ]; then + echo "There was a problem uploading \"$filepath\": $result" + else + download_cmds="${download_cmds}\nwget $(echo "$result" | underscore extract 'data.link')" + fi + done + echo "All uploads complete!" + echo "" + printf "Download via: $download_cmds\n" +else + echo "Could not find any PNG in $PWD, something must be broken!" +fi diff --git a/Tools/tag_missing_resources.sh b/Tools/tag_missing_resources.sh index a568297f8..93a2df735 100755 --- a/Tools/tag_missing_resources.sh +++ b/Tools/tag_missing_resources.sh @@ -47,15 +47,19 @@ already_sync=$(mktemp -t tag_missing_resources) to_sync=$(mktemp -t tag_missing_resources) grep -oE '([^ /"])*.png' ../linphone.xcodeproj/project.pbxproj | sort -u > $already_sync -find ../Resources/ -name *.png -exec basename {} \; | sort -u > $to_sync +find ../Resources/ -not -path '*/Images.xcassets/*' -name '*.png' -exec basename {} \; | sort -u > $to_sync # clean red tags -cd ../Resources && tag -r red $(cat $to_sync $already_sync) && cd - 1>/dev/null +for file in $to_sync $already_sync; do + find ../Resources -name $file -exec tag -r red {} \; +done # 'comm' command output files contained in second file but not in first nor in common non_synced_files=$(comm -13 $already_sync $to_sync) -cd ../Resources/ && tag -a red $non_synced_files && cd - 1>/dev/null +for file in $non_synced_files; do + find ../Resources -name $file -exec tag -a red {} \; +done rm $already_sync $to_sync diff --git a/liblinphone-tutorials/hello-world/README b/TutorialHellowWorld/README similarity index 100% rename from liblinphone-tutorials/hello-world/README rename to TutorialHellowWorld/README diff --git a/TutorialHellowWorld/hello-world.xcodeproj/project.pbxproj b/TutorialHellowWorld/hello-world.xcodeproj/project.pbxproj new file mode 100755 index 000000000..384bfc2dc --- /dev/null +++ b/TutorialHellowWorld/hello-world.xcodeproj/project.pbxproj @@ -0,0 +1,1011 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2220D5D81278461C008F2C2E /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D71278461C008F2C2E /* CFNetwork.framework */; }; + 2220D5DA1278461C008F2C2E /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D91278461C008F2C2E /* CoreAudio.framework */; }; + 2220D5EA12784672008F2C2E /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5E912784672008F2C2E /* AudioToolbox.framework */; }; + 229499A612A5417D00D6CF48 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 229499A712A5417D00D6CF48 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 229499A812A5417D00D6CF48 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 229499B312A5417D00D6CF48 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D71278461C008F2C2E /* CFNetwork.framework */; }; + 229499B412A5417D00D6CF48 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D91278461C008F2C2E /* CoreAudio.framework */; }; + 229499B512A5417D00D6CF48 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5E912784672008F2C2E /* AudioToolbox.framework */; }; + 229499B612A5417D00D6CF48 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 22D1B6A012A3E159001AE361 /* libresolv.dylib */; }; + 229499EB12A5433F00D6CF48 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 229499EC12A5433F00D6CF48 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 229499ED12A5433F00D6CF48 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 229499F812A5433F00D6CF48 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D71278461C008F2C2E /* CFNetwork.framework */; }; + 229499F912A5433F00D6CF48 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D91278461C008F2C2E /* CoreAudio.framework */; }; + 229499FA12A5433F00D6CF48 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5E912784672008F2C2E /* AudioToolbox.framework */; }; + 229499FB12A5433F00D6CF48 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 22D1B6A012A3E159001AE361 /* libresolv.dylib */; }; + 22D1B6A112A3E159001AE361 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 22D1B6A012A3E159001AE361 /* libresolv.dylib */; }; + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 34F9E00314C41FB400E1BC69 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00214C41FB400E1BC69 /* OpenGLES.framework */; }; + 34F9E00B14C4202100E1BC69 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00A14C4202100E1BC69 /* QuartzCore.framework */; }; + 34F9E02214C420FA00E1BC69 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00A14C4202100E1BC69 /* QuartzCore.framework */; }; + 34F9E02314C4210100E1BC69 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00214C41FB400E1BC69 /* OpenGLES.framework */; }; + 34F9E02614C4212F00E1BC69 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00214C41FB400E1BC69 /* OpenGLES.framework */; }; + 34F9E02714C4212F00E1BC69 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00A14C4202100E1BC69 /* QuartzCore.framework */; }; + 34F9E03414C4247A00E1BC69 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03314C4247A00E1BC69 /* AVFoundation.framework */; }; + 34F9E03514C4249600E1BC69 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00814C41FE900E1BC69 /* CoreVideo.framework */; }; + 34F9E03714C424AF00E1BC69 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03614C424AF00E1BC69 /* CoreMedia.framework */; }; + 34F9E03814C4250B00E1BC69 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03314C4247A00E1BC69 /* AVFoundation.framework */; }; + 34F9E03914C4250B00E1BC69 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03614C424AF00E1BC69 /* CoreMedia.framework */; }; + 34F9E03A14C4250B00E1BC69 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00814C41FE900E1BC69 /* CoreVideo.framework */; }; + 34F9E03B14C4251B00E1BC69 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03314C4247A00E1BC69 /* AVFoundation.framework */; }; + 34F9E03C14C4251B00E1BC69 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03614C424AF00E1BC69 /* CoreMedia.framework */; }; + 34F9E03D14C4251B00E1BC69 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00814C41FE900E1BC69 /* CoreVideo.framework */; }; + 63D5C1001BA6E3EB002D1ABF /* helloworld.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D5C0FC1BA6E3EB002D1ABF /* helloworld.c */; }; + 63D5C1021BA6E3F7002D1ABF /* registration.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D5C0FD1BA6E3EB002D1ABF /* registration.c */; }; + 63D5C1031BA6E3FA002D1ABF /* chatroom.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D5C0FB1BA6E3EB002D1ABF /* chatroom.c */; }; + 63D5C1041BA6E3FE002D1ABF /* buddy_status.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D5C0FA1BA6E3EB002D1ABF /* buddy_status.c */; }; + 63D5C12C1BA6E504002D1ABF /* libantlr3c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1081BA6E4F0002D1ABF /* libantlr3c.a */; }; + 63D5C12D1BA6E504002D1ABF /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1091BA6E4F0002D1ABF /* libavcodec.a */; }; + 63D5C12E1BA6E504002D1ABF /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10A1BA6E4F0002D1ABF /* libavutil.a */; }; + 63D5C12F1BA6E504002D1ABF /* libbellesip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10B1BA6E4F0002D1ABF /* libbellesip.a */; }; + 63D5C1301BA6E504002D1ABF /* libbzrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10C1BA6E4F0002D1ABF /* libbzrtp.a */; }; + 63D5C1311BA6E504002D1ABF /* libcunit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10D1BA6E4F0002D1ABF /* libcunit.a */; }; + 63D5C1321BA6E504002D1ABF /* libgsm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10E1BA6E4F0002D1ABF /* libgsm.a */; }; + 63D5C1341BA6E504002D1ABF /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1101BA6E4F0002D1ABF /* liblinphone.a */; }; + 63D5C1351BA6E504002D1ABF /* liblinphonetester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1111BA6E4F0002D1ABF /* liblinphonetester.a */; }; + 63D5C1361BA6E504002D1ABF /* libmediastreamer_base.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1121BA6E4F0002D1ABF /* libmediastreamer_base.a */; }; + 63D5C1371BA6E504002D1ABF /* libmediastreamer_voip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1131BA6E4F0002D1ABF /* libmediastreamer_voip.a */; }; + 63D5C1381BA6E504002D1ABF /* libopencore-amrnb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1141BA6E4F0002D1ABF /* libopencore-amrnb.a */; }; + 63D5C1391BA6E504002D1ABF /* libopencore-amrwb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1151BA6E4F0002D1ABF /* libopencore-amrwb.a */; }; + 63D5C13A1BA6E504002D1ABF /* libopenh264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1161BA6E4F0002D1ABF /* libopenh264.a */; }; + 63D5C13B1BA6E504002D1ABF /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1171BA6E4F0002D1ABF /* libopus.a */; }; + 63D5C13C1BA6E504002D1ABF /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1181BA6E4F0002D1ABF /* libortp.a */; }; + 63D5C13D1BA6E504002D1ABF /* libpolarssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1191BA6E4F0002D1ABF /* libpolarssl.a */; }; + 63D5C13F1BA6E504002D1ABF /* libspeex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11B1BA6E4F0002D1ABF /* libspeex.a */; }; + 63D5C1401BA6E504002D1ABF /* libspeexdsp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11C1BA6E4F0002D1ABF /* libspeexdsp.a */; }; + 63D5C1411BA6E504002D1ABF /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11D1BA6E4F0002D1ABF /* libsrtp.a */; }; + 63D5C1421BA6E504002D1ABF /* libswresample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11E1BA6E4F0002D1ABF /* libswresample.a */; }; + 63D5C1431BA6E504002D1ABF /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11F1BA6E4F0002D1ABF /* libswscale.a */; }; + 63D5C1441BA6E504002D1ABF /* libtunnel.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1201BA6E4F0002D1ABF /* libtunnel.a */; }; + 63D5C1451BA6E504002D1ABF /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1211BA6E4F0002D1ABF /* libvpx.a */; }; + 63D5C1461BA6E504002D1ABF /* libx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1221BA6E4F0002D1ABF /* libx264.a */; }; + 63D5C1471BA6E516002D1ABF /* libmsamr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1251BA6E4F0002D1ABF /* libmsamr.a */; }; + 63D5C1481BA6E516002D1ABF /* libmsbcg729.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1261BA6E4F0002D1ABF /* libmsbcg729.a */; }; + 63D5C14A1BA6E516002D1ABF /* libmsopenh264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1281BA6E4F0002D1ABF /* libmsopenh264.a */; }; + 63D5C14B1BA6E516002D1ABF /* libmssilk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1291BA6E4F0002D1ABF /* libmssilk.a */; }; + 63D5C14C1BA6E516002D1ABF /* libmswebrtc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C12A1BA6E4F0002D1ABF /* libmswebrtc.a */; }; + 63D5C14D1BA6E516002D1ABF /* libmsx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C12B1BA6E4F0002D1ABF /* libmsx264.a */; }; + 63D5C14F1BA6E6D1002D1ABF /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C14E1BA6E6D1002D1ABF /* libz.dylib */; }; + 63D5C1511BA6E6E9002D1ABF /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1501BA6E6E9002D1ABF /* libiconv.dylib */; }; + 63D5C1531BA6E6F0002D1ABF /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1521BA6E6F0002D1ABF /* libxml2.dylib */; }; + 63D5C1571BA6E765002D1ABF /* libantlr3c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1081BA6E4F0002D1ABF /* libantlr3c.a */; }; + 63D5C1581BA6E765002D1ABF /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1091BA6E4F0002D1ABF /* libavcodec.a */; }; + 63D5C1591BA6E765002D1ABF /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10A1BA6E4F0002D1ABF /* libavutil.a */; }; + 63D5C15A1BA6E765002D1ABF /* libbellesip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10B1BA6E4F0002D1ABF /* libbellesip.a */; }; + 63D5C15B1BA6E765002D1ABF /* libbzrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10C1BA6E4F0002D1ABF /* libbzrtp.a */; }; + 63D5C15C1BA6E765002D1ABF /* libcunit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10D1BA6E4F0002D1ABF /* libcunit.a */; }; + 63D5C15D1BA6E765002D1ABF /* libgsm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10E1BA6E4F0002D1ABF /* libgsm.a */; }; + 63D5C15F1BA6E765002D1ABF /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1101BA6E4F0002D1ABF /* liblinphone.a */; }; + 63D5C1601BA6E765002D1ABF /* liblinphonetester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1111BA6E4F0002D1ABF /* liblinphonetester.a */; }; + 63D5C1611BA6E765002D1ABF /* libmediastreamer_base.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1121BA6E4F0002D1ABF /* libmediastreamer_base.a */; }; + 63D5C1621BA6E765002D1ABF /* libmediastreamer_voip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1131BA6E4F0002D1ABF /* libmediastreamer_voip.a */; }; + 63D5C1631BA6E765002D1ABF /* libopencore-amrnb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1141BA6E4F0002D1ABF /* libopencore-amrnb.a */; }; + 63D5C1641BA6E765002D1ABF /* libopencore-amrwb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1151BA6E4F0002D1ABF /* libopencore-amrwb.a */; }; + 63D5C1651BA6E765002D1ABF /* libopenh264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1161BA6E4F0002D1ABF /* libopenh264.a */; }; + 63D5C1661BA6E765002D1ABF /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1171BA6E4F0002D1ABF /* libopus.a */; }; + 63D5C1671BA6E765002D1ABF /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1181BA6E4F0002D1ABF /* libortp.a */; }; + 63D5C1681BA6E765002D1ABF /* libpolarssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1191BA6E4F0002D1ABF /* libpolarssl.a */; }; + 63D5C16A1BA6E765002D1ABF /* libspeex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11B1BA6E4F0002D1ABF /* libspeex.a */; }; + 63D5C16B1BA6E765002D1ABF /* libspeexdsp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11C1BA6E4F0002D1ABF /* libspeexdsp.a */; }; + 63D5C16C1BA6E765002D1ABF /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11D1BA6E4F0002D1ABF /* libsrtp.a */; }; + 63D5C16D1BA6E765002D1ABF /* libswresample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11E1BA6E4F0002D1ABF /* libswresample.a */; }; + 63D5C16E1BA6E765002D1ABF /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11F1BA6E4F0002D1ABF /* libswscale.a */; }; + 63D5C16F1BA6E765002D1ABF /* libtunnel.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1201BA6E4F0002D1ABF /* libtunnel.a */; }; + 63D5C1701BA6E765002D1ABF /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1211BA6E4F0002D1ABF /* libvpx.a */; }; + 63D5C1711BA6E765002D1ABF /* libx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1221BA6E4F0002D1ABF /* libx264.a */; }; + 63D5C1721BA6E778002D1ABF /* libmsamr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1251BA6E4F0002D1ABF /* libmsamr.a */; }; + 63D5C1731BA6E778002D1ABF /* libmsbcg729.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1261BA6E4F0002D1ABF /* libmsbcg729.a */; }; + 63D5C1751BA6E778002D1ABF /* libmsopenh264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1281BA6E4F0002D1ABF /* libmsopenh264.a */; }; + 63D5C1761BA6E778002D1ABF /* libmssilk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1291BA6E4F0002D1ABF /* libmssilk.a */; }; + 63D5C1771BA6E778002D1ABF /* libmswebrtc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C12A1BA6E4F0002D1ABF /* libmswebrtc.a */; }; + 63D5C1781BA6E778002D1ABF /* libmsx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C12B1BA6E4F0002D1ABF /* libmsx264.a */; }; + 63D5C17A1BA6E8BD002D1ABF /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D97A199A6905009C58AA /* libsqlite3.dylib */; }; + 63D5C17B1BA6E8C2002D1ABF /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C14E1BA6E6D1002D1ABF /* libz.dylib */; }; + 63D5C17C1BA6E8C6002D1ABF /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 22D1B6A012A3E159001AE361 /* libresolv.dylib */; }; + 63D5C17D1BA6E8CC002D1ABF /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1521BA6E6F0002D1ABF /* libxml2.dylib */; }; + 63D5C17E1BA6E8D1002D1ABF /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1501BA6E6E9002D1ABF /* libiconv.dylib */; }; + 63D5C17F1BA6E8D6002D1ABF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5E912784672008F2C2E /* AudioToolbox.framework */; }; + 63D5C1801BA6E8DE002D1ABF /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03314C4247A00E1BC69 /* AVFoundation.framework */; }; + 63D5C1811BA6E8E3002D1ABF /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D71278461C008F2C2E /* CFNetwork.framework */; }; + 63D5C1821BA6E8E8002D1ABF /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D91278461C008F2C2E /* CoreAudio.framework */; }; + 63D5C1831BA6E8EE002D1ABF /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 63D5C1841BA6E8F5002D1ABF /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03614C424AF00E1BC69 /* CoreMedia.framework */; }; + 63D5C1851BA6E8FA002D1ABF /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00814C41FE900E1BC69 /* CoreVideo.framework */; }; + 63D5C1861BA6E8FD002D1ABF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 63D5C1871BA6E902002D1ABF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 63D5C1881BA6E907002D1ABF /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00214C41FB400E1BC69 /* OpenGLES.framework */; }; + 63D5C1891BA6E90D002D1ABF /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00A14C4202100E1BC69 /* QuartzCore.framework */; }; + 63D5C18A1BA6E92A002D1ABF /* libantlr3c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1081BA6E4F0002D1ABF /* libantlr3c.a */; }; + 63D5C18B1BA6E92A002D1ABF /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1091BA6E4F0002D1ABF /* libavcodec.a */; }; + 63D5C18C1BA6E92A002D1ABF /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10A1BA6E4F0002D1ABF /* libavutil.a */; }; + 63D5C18D1BA6E92A002D1ABF /* libbellesip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10B1BA6E4F0002D1ABF /* libbellesip.a */; }; + 63D5C18E1BA6E92A002D1ABF /* libbzrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10C1BA6E4F0002D1ABF /* libbzrtp.a */; }; + 63D5C18F1BA6E92A002D1ABF /* libcunit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10D1BA6E4F0002D1ABF /* libcunit.a */; }; + 63D5C1901BA6E92A002D1ABF /* libgsm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10E1BA6E4F0002D1ABF /* libgsm.a */; }; + 63D5C1921BA6E92A002D1ABF /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1101BA6E4F0002D1ABF /* liblinphone.a */; }; + 63D5C1931BA6E92A002D1ABF /* liblinphonetester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1111BA6E4F0002D1ABF /* liblinphonetester.a */; }; + 63D5C1941BA6E92A002D1ABF /* libmediastreamer_base.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1121BA6E4F0002D1ABF /* libmediastreamer_base.a */; }; + 63D5C1951BA6E92A002D1ABF /* libmediastreamer_voip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1131BA6E4F0002D1ABF /* libmediastreamer_voip.a */; }; + 63D5C1961BA6E92A002D1ABF /* libopencore-amrnb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1141BA6E4F0002D1ABF /* libopencore-amrnb.a */; }; + 63D5C1971BA6E92A002D1ABF /* libopencore-amrwb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1151BA6E4F0002D1ABF /* libopencore-amrwb.a */; }; + 63D5C1981BA6E92A002D1ABF /* libopenh264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1161BA6E4F0002D1ABF /* libopenh264.a */; }; + 63D5C1991BA6E92A002D1ABF /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1171BA6E4F0002D1ABF /* libopus.a */; }; + 63D5C19A1BA6E92A002D1ABF /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1181BA6E4F0002D1ABF /* libortp.a */; }; + 63D5C19B1BA6E92A002D1ABF /* libpolarssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1191BA6E4F0002D1ABF /* libpolarssl.a */; }; + 63D5C19D1BA6E92A002D1ABF /* libspeex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11B1BA6E4F0002D1ABF /* libspeex.a */; }; + 63D5C19E1BA6E92A002D1ABF /* libspeexdsp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11C1BA6E4F0002D1ABF /* libspeexdsp.a */; }; + 63D5C19F1BA6E92A002D1ABF /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11D1BA6E4F0002D1ABF /* libsrtp.a */; }; + 63D5C1A01BA6E92A002D1ABF /* libswresample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11E1BA6E4F0002D1ABF /* libswresample.a */; }; + 63D5C1A11BA6E92B002D1ABF /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11F1BA6E4F0002D1ABF /* libswscale.a */; }; + 63D5C1A21BA6E92B002D1ABF /* libtunnel.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1201BA6E4F0002D1ABF /* libtunnel.a */; }; + 63D5C1A31BA6E92B002D1ABF /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1211BA6E4F0002D1ABF /* libvpx.a */; }; + 63D5C1A41BA6E92B002D1ABF /* libx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1221BA6E4F0002D1ABF /* libx264.a */; }; + 63D5C1A51BA6E937002D1ABF /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1501BA6E6E9002D1ABF /* libiconv.dylib */; }; + 63D5C1A61BA6E93D002D1ABF /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1521BA6E6F0002D1ABF /* libxml2.dylib */; }; + 63D5C1A71BA6E943002D1ABF /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C14E1BA6E6D1002D1ABF /* libz.dylib */; }; + 63D5C1A81BA6E95C002D1ABF /* libantlr3c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1081BA6E4F0002D1ABF /* libantlr3c.a */; }; + 63D5C1A91BA6E95C002D1ABF /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1091BA6E4F0002D1ABF /* libavcodec.a */; }; + 63D5C1AA1BA6E95C002D1ABF /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10A1BA6E4F0002D1ABF /* libavutil.a */; }; + 63D5C1AB1BA6E95C002D1ABF /* libbellesip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10B1BA6E4F0002D1ABF /* libbellesip.a */; }; + 63D5C1AC1BA6E95C002D1ABF /* libbzrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10C1BA6E4F0002D1ABF /* libbzrtp.a */; }; + 63D5C1AD1BA6E95C002D1ABF /* libcunit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10D1BA6E4F0002D1ABF /* libcunit.a */; }; + 63D5C1AE1BA6E95C002D1ABF /* libgsm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C10E1BA6E4F0002D1ABF /* libgsm.a */; }; + 63D5C1B01BA6E95C002D1ABF /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1101BA6E4F0002D1ABF /* liblinphone.a */; }; + 63D5C1B11BA6E95C002D1ABF /* liblinphonetester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1111BA6E4F0002D1ABF /* liblinphonetester.a */; }; + 63D5C1B21BA6E95C002D1ABF /* libmediastreamer_base.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1121BA6E4F0002D1ABF /* libmediastreamer_base.a */; }; + 63D5C1B31BA6E95C002D1ABF /* libmediastreamer_voip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1131BA6E4F0002D1ABF /* libmediastreamer_voip.a */; }; + 63D5C1B41BA6E95C002D1ABF /* libopencore-amrnb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1141BA6E4F0002D1ABF /* libopencore-amrnb.a */; }; + 63D5C1B51BA6E95C002D1ABF /* libopencore-amrwb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1151BA6E4F0002D1ABF /* libopencore-amrwb.a */; }; + 63D5C1B61BA6E95C002D1ABF /* libopenh264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1161BA6E4F0002D1ABF /* libopenh264.a */; }; + 63D5C1B71BA6E95C002D1ABF /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1171BA6E4F0002D1ABF /* libopus.a */; }; + 63D5C1B81BA6E95C002D1ABF /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1181BA6E4F0002D1ABF /* libortp.a */; }; + 63D5C1B91BA6E95C002D1ABF /* libpolarssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1191BA6E4F0002D1ABF /* libpolarssl.a */; }; + 63D5C1BB1BA6E95C002D1ABF /* libspeex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11B1BA6E4F0002D1ABF /* libspeex.a */; }; + 63D5C1BC1BA6E95C002D1ABF /* libspeexdsp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11C1BA6E4F0002D1ABF /* libspeexdsp.a */; }; + 63D5C1BD1BA6E95C002D1ABF /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11D1BA6E4F0002D1ABF /* libsrtp.a */; }; + 63D5C1BE1BA6E95C002D1ABF /* libswresample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11E1BA6E4F0002D1ABF /* libswresample.a */; }; + 63D5C1BF1BA6E95C002D1ABF /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C11F1BA6E4F0002D1ABF /* libswscale.a */; }; + 63D5C1C01BA6E95C002D1ABF /* libtunnel.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1201BA6E4F0002D1ABF /* libtunnel.a */; }; + 63D5C1C11BA6E95C002D1ABF /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1211BA6E4F0002D1ABF /* libvpx.a */; }; + 63D5C1C21BA6E95C002D1ABF /* libx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1221BA6E4F0002D1ABF /* libx264.a */; }; + 63D5C1C31BA6E963002D1ABF /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C14E1BA6E6D1002D1ABF /* libz.dylib */; }; + 63D5C1C41BA6E969002D1ABF /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1501BA6E6E9002D1ABF /* libiconv.dylib */; }; + 63D5C1C51BA6E96D002D1ABF /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 63D5C1521BA6E6F0002D1ABF /* libxml2.dylib */; }; + F079D97B199A6905009C58AA /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D97A199A6905009C58AA /* libsqlite3.dylib */; }; + F079D97D199A6913009C58AA /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D97A199A6905009C58AA /* libsqlite3.dylib */; }; + F079D97E199A6919009C58AA /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D97A199A6905009C58AA /* libsqlite3.dylib */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D6058910D05DD3D006BFB54 /* hello-world.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "hello-world.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2220D5D51278461C008F2C2E /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; + 2220D5D71278461C008F2C2E /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 2220D5D91278461C008F2C2E /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; + 2220D5E912784672008F2C2E /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 2294997D12A53FEE00D6CF48 /* hello-world.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "hello-world.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 229499BA12A5417D00D6CF48 /* hello-world.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "hello-world.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 229499FF12A5433F00D6CF48 /* hello-world.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "hello-world.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 22D1B6A012A3E159001AE361 /* libresolv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libresolv.dylib; path = usr/lib/libresolv.dylib; sourceTree = SDKROOT; }; + 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 32CA4F630368D1EE00C91783 /* hello_world_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hello_world_Prefix.pch; sourceTree = ""; }; + 34F9E00214C41FB400E1BC69 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 34F9E00814C41FE900E1BC69 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; + 34F9E00A14C4202100E1BC69 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 34F9E03314C4247A00E1BC69 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 34F9E03614C424AF00E1BC69 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; + 63D5C0FA1BA6E3EB002D1ABF /* buddy_status.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = buddy_status.c; path = ../submodules/linphone/coreapi/help/buddy_status.c; sourceTree = ""; }; + 63D5C0FB1BA6E3EB002D1ABF /* chatroom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = chatroom.c; path = ../submodules/linphone/coreapi/help/chatroom.c; sourceTree = ""; }; + 63D5C0FC1BA6E3EB002D1ABF /* helloworld.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = helloworld.c; path = ../submodules/linphone/coreapi/help/helloworld.c; sourceTree = ""; }; + 63D5C0FD1BA6E3EB002D1ABF /* registration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = registration.c; path = ../submodules/linphone/coreapi/help/registration.c; sourceTree = ""; }; + 63D5C1081BA6E4F0002D1ABF /* libantlr3c.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libantlr3c.a; path = "../liblinphone-sdk/apple-darwin/lib/libantlr3c.a"; sourceTree = ""; }; + 63D5C1091BA6E4F0002D1ABF /* libavcodec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavcodec.a; path = "../liblinphone-sdk/apple-darwin/lib/libavcodec.a"; sourceTree = ""; }; + 63D5C10A1BA6E4F0002D1ABF /* libavutil.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavutil.a; path = "../liblinphone-sdk/apple-darwin/lib/libavutil.a"; sourceTree = ""; }; + 63D5C10B1BA6E4F0002D1ABF /* libbellesip.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbellesip.a; path = "../liblinphone-sdk/apple-darwin/lib/libbellesip.a"; sourceTree = ""; }; + 63D5C10C1BA6E4F0002D1ABF /* libbzrtp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbzrtp.a; path = "../liblinphone-sdk/apple-darwin/lib/libbzrtp.a"; sourceTree = ""; }; + 63D5C10D1BA6E4F0002D1ABF /* libcunit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcunit.a; path = "../liblinphone-sdk/apple-darwin/lib/libcunit.a"; sourceTree = ""; }; + 63D5C10E1BA6E4F0002D1ABF /* libgsm.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgsm.a; path = "../liblinphone-sdk/apple-darwin/lib/libgsm.a"; sourceTree = ""; }; + 63D5C1101BA6E4F0002D1ABF /* liblinphone.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblinphone.a; path = "../liblinphone-sdk/apple-darwin/lib/liblinphone.a"; sourceTree = ""; }; + 63D5C1111BA6E4F0002D1ABF /* liblinphonetester.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblinphonetester.a; path = "../liblinphone-sdk/apple-darwin/lib/liblinphonetester.a"; sourceTree = ""; }; + 63D5C1121BA6E4F0002D1ABF /* libmediastreamer_base.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmediastreamer_base.a; path = "../liblinphone-sdk/apple-darwin/lib/libmediastreamer_base.a"; sourceTree = ""; }; + 63D5C1131BA6E4F0002D1ABF /* libmediastreamer_voip.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmediastreamer_voip.a; path = "../liblinphone-sdk/apple-darwin/lib/libmediastreamer_voip.a"; sourceTree = ""; }; + 63D5C1141BA6E4F0002D1ABF /* libopencore-amrnb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libopencore-amrnb.a"; path = "../liblinphone-sdk/apple-darwin/lib/libopencore-amrnb.a"; sourceTree = ""; }; + 63D5C1151BA6E4F0002D1ABF /* libopencore-amrwb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libopencore-amrwb.a"; path = "../liblinphone-sdk/apple-darwin/lib/libopencore-amrwb.a"; sourceTree = ""; }; + 63D5C1161BA6E4F0002D1ABF /* libopenh264.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopenh264.a; path = "../liblinphone-sdk/apple-darwin/lib/libopenh264.a"; sourceTree = ""; }; + 63D5C1171BA6E4F0002D1ABF /* libopus.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopus.a; path = "../liblinphone-sdk/apple-darwin/lib/libopus.a"; sourceTree = ""; }; + 63D5C1181BA6E4F0002D1ABF /* libortp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libortp.a; path = "../liblinphone-sdk/apple-darwin/lib/libortp.a"; sourceTree = ""; }; + 63D5C1191BA6E4F0002D1ABF /* libpolarssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpolarssl.a; path = "../liblinphone-sdk/apple-darwin/lib/libpolarssl.a"; sourceTree = ""; }; + 63D5C11A1BA6E4F0002D1ABF /* libSKP_SILK_SDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSKP_SILK_SDK.a; path = "../liblinphone-sdk/apple-darwin/lib/libSKP_SILK_SDK.a"; sourceTree = ""; }; + 63D5C11B1BA6E4F0002D1ABF /* libspeex.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libspeex.a; path = "../liblinphone-sdk/apple-darwin/lib/libspeex.a"; sourceTree = ""; }; + 63D5C11C1BA6E4F0002D1ABF /* libspeexdsp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libspeexdsp.a; path = "../liblinphone-sdk/apple-darwin/lib/libspeexdsp.a"; sourceTree = ""; }; + 63D5C11D1BA6E4F0002D1ABF /* libsrtp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsrtp.a; path = "../liblinphone-sdk/apple-darwin/lib/libsrtp.a"; sourceTree = ""; }; + 63D5C11E1BA6E4F0002D1ABF /* libswresample.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libswresample.a; path = "../liblinphone-sdk/apple-darwin/lib/libswresample.a"; sourceTree = ""; }; + 63D5C11F1BA6E4F0002D1ABF /* libswscale.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libswscale.a; path = "../liblinphone-sdk/apple-darwin/lib/libswscale.a"; sourceTree = ""; }; + 63D5C1201BA6E4F0002D1ABF /* libtunnel.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtunnel.a; path = "../liblinphone-sdk/apple-darwin/lib/libtunnel.a"; sourceTree = ""; }; + 63D5C1211BA6E4F0002D1ABF /* libvpx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvpx.a; path = "../liblinphone-sdk/apple-darwin/lib/libvpx.a"; sourceTree = ""; }; + 63D5C1221BA6E4F0002D1ABF /* libx264.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libx264.a; path = "../liblinphone-sdk/apple-darwin/lib/libx264.a"; sourceTree = ""; }; + 63D5C1251BA6E4F0002D1ABF /* libmsamr.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libmsamr.a; sourceTree = ""; }; + 63D5C1261BA6E4F0002D1ABF /* libmsbcg729.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libmsbcg729.a; sourceTree = ""; }; + 63D5C1281BA6E4F0002D1ABF /* libmsopenh264.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libmsopenh264.a; sourceTree = ""; }; + 63D5C1291BA6E4F0002D1ABF /* libmssilk.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libmssilk.a; sourceTree = ""; }; + 63D5C12A1BA6E4F0002D1ABF /* libmswebrtc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libmswebrtc.a; sourceTree = ""; }; + 63D5C12B1BA6E4F0002D1ABF /* libmsx264.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libmsx264.a; sourceTree = ""; }; + 63D5C14E1BA6E6D1002D1ABF /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + 63D5C1501BA6E6E9002D1ABF /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = usr/lib/libiconv.dylib; sourceTree = SDKROOT; }; + 63D5C1521BA6E6F0002D1ABF /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; }; + 63D5C1541BA6E734002D1ABF /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; + 8D1107310486CEB800E47090 /* helloworld-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "helloworld-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + F079D97A199A6905009C58AA /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 63D5C1471BA6E516002D1ABF /* libmsamr.a in Frameworks */, + 63D5C1481BA6E516002D1ABF /* libmsbcg729.a in Frameworks */, + 63D5C14A1BA6E516002D1ABF /* libmsopenh264.a in Frameworks */, + 63D5C14B1BA6E516002D1ABF /* libmssilk.a in Frameworks */, + 63D5C14C1BA6E516002D1ABF /* libmswebrtc.a in Frameworks */, + 63D5C14D1BA6E516002D1ABF /* libmsx264.a in Frameworks */, + 63D5C12C1BA6E504002D1ABF /* libantlr3c.a in Frameworks */, + 63D5C12D1BA6E504002D1ABF /* libavcodec.a in Frameworks */, + 63D5C12E1BA6E504002D1ABF /* libavutil.a in Frameworks */, + 63D5C12F1BA6E504002D1ABF /* libbellesip.a in Frameworks */, + 63D5C1301BA6E504002D1ABF /* libbzrtp.a in Frameworks */, + 63D5C1311BA6E504002D1ABF /* libcunit.a in Frameworks */, + 63D5C1321BA6E504002D1ABF /* libgsm.a in Frameworks */, + 63D5C1341BA6E504002D1ABF /* liblinphone.a in Frameworks */, + 63D5C1351BA6E504002D1ABF /* liblinphonetester.a in Frameworks */, + 63D5C1361BA6E504002D1ABF /* libmediastreamer_base.a in Frameworks */, + 63D5C1371BA6E504002D1ABF /* libmediastreamer_voip.a in Frameworks */, + 63D5C1381BA6E504002D1ABF /* libopencore-amrnb.a in Frameworks */, + 63D5C1391BA6E504002D1ABF /* libopencore-amrwb.a in Frameworks */, + 63D5C13A1BA6E504002D1ABF /* libopenh264.a in Frameworks */, + 63D5C13B1BA6E504002D1ABF /* libopus.a in Frameworks */, + 63D5C13C1BA6E504002D1ABF /* libortp.a in Frameworks */, + 63D5C13D1BA6E504002D1ABF /* libpolarssl.a in Frameworks */, + 63D5C13F1BA6E504002D1ABF /* libspeex.a in Frameworks */, + 63D5C1401BA6E504002D1ABF /* libspeexdsp.a in Frameworks */, + 63D5C1411BA6E504002D1ABF /* libsrtp.a in Frameworks */, + 63D5C1421BA6E504002D1ABF /* libswresample.a in Frameworks */, + 63D5C1431BA6E504002D1ABF /* libswscale.a in Frameworks */, + 63D5C1441BA6E504002D1ABF /* libtunnel.a in Frameworks */, + 63D5C1451BA6E504002D1ABF /* libvpx.a in Frameworks */, + 63D5C1461BA6E504002D1ABF /* libx264.a in Frameworks */, + F079D97B199A6905009C58AA /* libsqlite3.dylib in Frameworks */, + 63D5C14F1BA6E6D1002D1ABF /* libz.dylib in Frameworks */, + 22D1B6A112A3E159001AE361 /* libresolv.dylib in Frameworks */, + 63D5C1531BA6E6F0002D1ABF /* libxml2.dylib in Frameworks */, + 63D5C1511BA6E6E9002D1ABF /* libiconv.dylib in Frameworks */, + 2220D5EA12784672008F2C2E /* AudioToolbox.framework in Frameworks */, + 34F9E03414C4247A00E1BC69 /* AVFoundation.framework in Frameworks */, + 2220D5D81278461C008F2C2E /* CFNetwork.framework in Frameworks */, + 2220D5DA1278461C008F2C2E /* CoreAudio.framework in Frameworks */, + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + 34F9E03714C424AF00E1BC69 /* CoreMedia.framework in Frameworks */, + 34F9E03514C4249600E1BC69 /* CoreVideo.framework in Frameworks */, + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 34F9E00314C41FB400E1BC69 /* OpenGLES.framework in Frameworks */, + 34F9E00B14C4202100E1BC69 /* QuartzCore.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2294996812A53FEE00D6CF48 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 63D5C1891BA6E90D002D1ABF /* QuartzCore.framework in Frameworks */, + 63D5C1881BA6E907002D1ABF /* OpenGLES.framework in Frameworks */, + 63D5C1871BA6E902002D1ABF /* UIKit.framework in Frameworks */, + 63D5C1861BA6E8FD002D1ABF /* Foundation.framework in Frameworks */, + 63D5C1851BA6E8FA002D1ABF /* CoreVideo.framework in Frameworks */, + 63D5C1841BA6E8F5002D1ABF /* CoreMedia.framework in Frameworks */, + 63D5C1831BA6E8EE002D1ABF /* CoreGraphics.framework in Frameworks */, + 63D5C1821BA6E8E8002D1ABF /* CoreAudio.framework in Frameworks */, + 63D5C1811BA6E8E3002D1ABF /* CFNetwork.framework in Frameworks */, + 63D5C1801BA6E8DE002D1ABF /* AVFoundation.framework in Frameworks */, + 63D5C17F1BA6E8D6002D1ABF /* AudioToolbox.framework in Frameworks */, + 63D5C17E1BA6E8D1002D1ABF /* libiconv.dylib in Frameworks */, + 63D5C17D1BA6E8CC002D1ABF /* libxml2.dylib in Frameworks */, + 63D5C17C1BA6E8C6002D1ABF /* libresolv.dylib in Frameworks */, + 63D5C17B1BA6E8C2002D1ABF /* libz.dylib in Frameworks */, + 63D5C17A1BA6E8BD002D1ABF /* libsqlite3.dylib in Frameworks */, + 63D5C1721BA6E778002D1ABF /* libmsamr.a in Frameworks */, + 63D5C1731BA6E778002D1ABF /* libmsbcg729.a in Frameworks */, + 63D5C1751BA6E778002D1ABF /* libmsopenh264.a in Frameworks */, + 63D5C1761BA6E778002D1ABF /* libmssilk.a in Frameworks */, + 63D5C1771BA6E778002D1ABF /* libmswebrtc.a in Frameworks */, + 63D5C1781BA6E778002D1ABF /* libmsx264.a in Frameworks */, + 63D5C1571BA6E765002D1ABF /* libantlr3c.a in Frameworks */, + 63D5C1581BA6E765002D1ABF /* libavcodec.a in Frameworks */, + 63D5C1591BA6E765002D1ABF /* libavutil.a in Frameworks */, + 63D5C15A1BA6E765002D1ABF /* libbellesip.a in Frameworks */, + 63D5C15B1BA6E765002D1ABF /* libbzrtp.a in Frameworks */, + 63D5C15C1BA6E765002D1ABF /* libcunit.a in Frameworks */, + 63D5C15D1BA6E765002D1ABF /* libgsm.a in Frameworks */, + 63D5C15F1BA6E765002D1ABF /* liblinphone.a in Frameworks */, + 63D5C1601BA6E765002D1ABF /* liblinphonetester.a in Frameworks */, + 63D5C1611BA6E765002D1ABF /* libmediastreamer_base.a in Frameworks */, + 63D5C1621BA6E765002D1ABF /* libmediastreamer_voip.a in Frameworks */, + 63D5C1631BA6E765002D1ABF /* libopencore-amrnb.a in Frameworks */, + 63D5C1641BA6E765002D1ABF /* libopencore-amrwb.a in Frameworks */, + 63D5C1651BA6E765002D1ABF /* libopenh264.a in Frameworks */, + 63D5C1661BA6E765002D1ABF /* libopus.a in Frameworks */, + 63D5C1671BA6E765002D1ABF /* libortp.a in Frameworks */, + 63D5C1681BA6E765002D1ABF /* libpolarssl.a in Frameworks */, + 63D5C16A1BA6E765002D1ABF /* libspeex.a in Frameworks */, + 63D5C16B1BA6E765002D1ABF /* libspeexdsp.a in Frameworks */, + 63D5C16C1BA6E765002D1ABF /* libsrtp.a in Frameworks */, + 63D5C16D1BA6E765002D1ABF /* libswresample.a in Frameworks */, + 63D5C16E1BA6E765002D1ABF /* libswscale.a in Frameworks */, + 63D5C16F1BA6E765002D1ABF /* libtunnel.a in Frameworks */, + 63D5C1701BA6E765002D1ABF /* libvpx.a in Frameworks */, + 63D5C1711BA6E765002D1ABF /* libx264.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 229499A512A5417D00D6CF48 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 63D5C1A71BA6E943002D1ABF /* libz.dylib in Frameworks */, + 63D5C1A61BA6E93D002D1ABF /* libxml2.dylib in Frameworks */, + 63D5C1A51BA6E937002D1ABF /* libiconv.dylib in Frameworks */, + 63D5C18A1BA6E92A002D1ABF /* libantlr3c.a in Frameworks */, + 63D5C18B1BA6E92A002D1ABF /* libavcodec.a in Frameworks */, + 63D5C18C1BA6E92A002D1ABF /* libavutil.a in Frameworks */, + 63D5C18D1BA6E92A002D1ABF /* libbellesip.a in Frameworks */, + 63D5C18E1BA6E92A002D1ABF /* libbzrtp.a in Frameworks */, + 63D5C18F1BA6E92A002D1ABF /* libcunit.a in Frameworks */, + 63D5C1901BA6E92A002D1ABF /* libgsm.a in Frameworks */, + 63D5C1921BA6E92A002D1ABF /* liblinphone.a in Frameworks */, + 63D5C1931BA6E92A002D1ABF /* liblinphonetester.a in Frameworks */, + 63D5C1941BA6E92A002D1ABF /* libmediastreamer_base.a in Frameworks */, + 63D5C1951BA6E92A002D1ABF /* libmediastreamer_voip.a in Frameworks */, + 63D5C1961BA6E92A002D1ABF /* libopencore-amrnb.a in Frameworks */, + 63D5C1971BA6E92A002D1ABF /* libopencore-amrwb.a in Frameworks */, + 63D5C1981BA6E92A002D1ABF /* libopenh264.a in Frameworks */, + 63D5C1991BA6E92A002D1ABF /* libopus.a in Frameworks */, + 63D5C19A1BA6E92A002D1ABF /* libortp.a in Frameworks */, + 63D5C19B1BA6E92A002D1ABF /* libpolarssl.a in Frameworks */, + 63D5C19D1BA6E92A002D1ABF /* libspeex.a in Frameworks */, + 63D5C19E1BA6E92A002D1ABF /* libspeexdsp.a in Frameworks */, + 63D5C19F1BA6E92A002D1ABF /* libsrtp.a in Frameworks */, + 63D5C1A01BA6E92A002D1ABF /* libswresample.a in Frameworks */, + 63D5C1A11BA6E92B002D1ABF /* libswscale.a in Frameworks */, + 63D5C1A21BA6E92B002D1ABF /* libtunnel.a in Frameworks */, + 63D5C1A31BA6E92B002D1ABF /* libvpx.a in Frameworks */, + 63D5C1A41BA6E92B002D1ABF /* libx264.a in Frameworks */, + F079D97D199A6913009C58AA /* libsqlite3.dylib in Frameworks */, + 34F9E03B14C4251B00E1BC69 /* AVFoundation.framework in Frameworks */, + 34F9E03C14C4251B00E1BC69 /* CoreMedia.framework in Frameworks */, + 34F9E03D14C4251B00E1BC69 /* CoreVideo.framework in Frameworks */, + 34F9E02314C4210100E1BC69 /* OpenGLES.framework in Frameworks */, + 34F9E02214C420FA00E1BC69 /* QuartzCore.framework in Frameworks */, + 229499A612A5417D00D6CF48 /* Foundation.framework in Frameworks */, + 229499A712A5417D00D6CF48 /* UIKit.framework in Frameworks */, + 229499A812A5417D00D6CF48 /* CoreGraphics.framework in Frameworks */, + 229499B312A5417D00D6CF48 /* CFNetwork.framework in Frameworks */, + 229499B412A5417D00D6CF48 /* CoreAudio.framework in Frameworks */, + 229499B512A5417D00D6CF48 /* AudioToolbox.framework in Frameworks */, + 229499B612A5417D00D6CF48 /* libresolv.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 229499EA12A5433F00D6CF48 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 63D5C1C51BA6E96D002D1ABF /* libxml2.dylib in Frameworks */, + 63D5C1C41BA6E969002D1ABF /* libiconv.dylib in Frameworks */, + 63D5C1C31BA6E963002D1ABF /* libz.dylib in Frameworks */, + 63D5C1A81BA6E95C002D1ABF /* libantlr3c.a in Frameworks */, + 63D5C1A91BA6E95C002D1ABF /* libavcodec.a in Frameworks */, + 63D5C1AA1BA6E95C002D1ABF /* libavutil.a in Frameworks */, + 63D5C1AB1BA6E95C002D1ABF /* libbellesip.a in Frameworks */, + 63D5C1AC1BA6E95C002D1ABF /* libbzrtp.a in Frameworks */, + 63D5C1AD1BA6E95C002D1ABF /* libcunit.a in Frameworks */, + 63D5C1AE1BA6E95C002D1ABF /* libgsm.a in Frameworks */, + 63D5C1B01BA6E95C002D1ABF /* liblinphone.a in Frameworks */, + 63D5C1B11BA6E95C002D1ABF /* liblinphonetester.a in Frameworks */, + 63D5C1B21BA6E95C002D1ABF /* libmediastreamer_base.a in Frameworks */, + 63D5C1B31BA6E95C002D1ABF /* libmediastreamer_voip.a in Frameworks */, + 63D5C1B41BA6E95C002D1ABF /* libopencore-amrnb.a in Frameworks */, + 63D5C1B51BA6E95C002D1ABF /* libopencore-amrwb.a in Frameworks */, + 63D5C1B61BA6E95C002D1ABF /* libopenh264.a in Frameworks */, + 63D5C1B71BA6E95C002D1ABF /* libopus.a in Frameworks */, + 63D5C1B81BA6E95C002D1ABF /* libortp.a in Frameworks */, + 63D5C1B91BA6E95C002D1ABF /* libpolarssl.a in Frameworks */, + 63D5C1BB1BA6E95C002D1ABF /* libspeex.a in Frameworks */, + 63D5C1BC1BA6E95C002D1ABF /* libspeexdsp.a in Frameworks */, + 63D5C1BD1BA6E95C002D1ABF /* libsrtp.a in Frameworks */, + 63D5C1BE1BA6E95C002D1ABF /* libswresample.a in Frameworks */, + 63D5C1BF1BA6E95C002D1ABF /* libswscale.a in Frameworks */, + 63D5C1C01BA6E95C002D1ABF /* libtunnel.a in Frameworks */, + 63D5C1C11BA6E95C002D1ABF /* libvpx.a in Frameworks */, + 63D5C1C21BA6E95C002D1ABF /* libx264.a in Frameworks */, + F079D97E199A6919009C58AA /* libsqlite3.dylib in Frameworks */, + 34F9E03814C4250B00E1BC69 /* AVFoundation.framework in Frameworks */, + 34F9E03914C4250B00E1BC69 /* CoreMedia.framework in Frameworks */, + 34F9E03A14C4250B00E1BC69 /* CoreVideo.framework in Frameworks */, + 34F9E02614C4212F00E1BC69 /* OpenGLES.framework in Frameworks */, + 34F9E02714C4212F00E1BC69 /* QuartzCore.framework in Frameworks */, + 229499EB12A5433F00D6CF48 /* Foundation.framework in Frameworks */, + 229499EC12A5433F00D6CF48 /* UIKit.framework in Frameworks */, + 229499ED12A5433F00D6CF48 /* CoreGraphics.framework in Frameworks */, + 229499F812A5433F00D6CF48 /* CFNetwork.framework in Frameworks */, + 229499F912A5433F00D6CF48 /* CoreAudio.framework in Frameworks */, + 229499FA12A5433F00D6CF48 /* AudioToolbox.framework in Frameworks */, + 229499FB12A5433F00D6CF48 /* libresolv.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* hello-world.app */, + 2294997D12A53FEE00D6CF48 /* hello-world.app */, + 229499BA12A5417D00D6CF48 /* hello-world.app */, + 229499FF12A5433F00D6CF48 /* hello-world.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + 22D1B6A012A3E159001AE361 /* libresolv.dylib */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 63D5C0FA1BA6E3EB002D1ABF /* buddy_status.c */, + 63D5C0FB1BA6E3EB002D1ABF /* chatroom.c */, + 63D5C0FC1BA6E3EB002D1ABF /* helloworld.c */, + 63D5C0FD1BA6E3EB002D1ABF /* registration.c */, + 32CA4F630368D1EE00C91783 /* hello_world_Prefix.pch */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 8D1107310486CEB800E47090 /* helloworld-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 63D5C1541BA6E734002D1ABF /* Accelerate.framework */, + 63D5C1521BA6E6F0002D1ABF /* libxml2.dylib */, + 63D5C1501BA6E6E9002D1ABF /* libiconv.dylib */, + 63D5C14E1BA6E6D1002D1ABF /* libz.dylib */, + 63D5C1081BA6E4F0002D1ABF /* libantlr3c.a */, + 63D5C1091BA6E4F0002D1ABF /* libavcodec.a */, + 63D5C10A1BA6E4F0002D1ABF /* libavutil.a */, + 63D5C10B1BA6E4F0002D1ABF /* libbellesip.a */, + 63D5C10C1BA6E4F0002D1ABF /* libbzrtp.a */, + 63D5C10D1BA6E4F0002D1ABF /* libcunit.a */, + 63D5C10E1BA6E4F0002D1ABF /* libgsm.a */, + 63D5C1101BA6E4F0002D1ABF /* liblinphone.a */, + 63D5C1111BA6E4F0002D1ABF /* liblinphonetester.a */, + 63D5C1121BA6E4F0002D1ABF /* libmediastreamer_base.a */, + 63D5C1131BA6E4F0002D1ABF /* libmediastreamer_voip.a */, + 63D5C1141BA6E4F0002D1ABF /* libopencore-amrnb.a */, + 63D5C1151BA6E4F0002D1ABF /* libopencore-amrwb.a */, + 63D5C1161BA6E4F0002D1ABF /* libopenh264.a */, + 63D5C1171BA6E4F0002D1ABF /* libopus.a */, + 63D5C1181BA6E4F0002D1ABF /* libortp.a */, + 63D5C1191BA6E4F0002D1ABF /* libpolarssl.a */, + 63D5C11A1BA6E4F0002D1ABF /* libSKP_SILK_SDK.a */, + 63D5C11B1BA6E4F0002D1ABF /* libspeex.a */, + 63D5C11C1BA6E4F0002D1ABF /* libspeexdsp.a */, + 63D5C11D1BA6E4F0002D1ABF /* libsrtp.a */, + 63D5C11E1BA6E4F0002D1ABF /* libswresample.a */, + 63D5C11F1BA6E4F0002D1ABF /* libswscale.a */, + 63D5C1201BA6E4F0002D1ABF /* libtunnel.a */, + 63D5C1211BA6E4F0002D1ABF /* libvpx.a */, + 63D5C1221BA6E4F0002D1ABF /* libx264.a */, + 63D5C1231BA6E4F0002D1ABF /* mediastreamer */, + F079D97A199A6905009C58AA /* libsqlite3.dylib */, + 34F9E03614C424AF00E1BC69 /* CoreMedia.framework */, + 34F9E03314C4247A00E1BC69 /* AVFoundation.framework */, + 34F9E00A14C4202100E1BC69 /* QuartzCore.framework */, + 34F9E00814C41FE900E1BC69 /* CoreVideo.framework */, + 34F9E00214C41FB400E1BC69 /* OpenGLES.framework */, + 2220D5D51278461C008F2C2E /* AudioUnit.framework */, + 2220D5D71278461C008F2C2E /* CFNetwork.framework */, + 2220D5D91278461C008F2C2E /* CoreAudio.framework */, + 2220D5E912784672008F2C2E /* AudioToolbox.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765FC0DF74451002DB57D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 63D5C1231BA6E4F0002D1ABF /* mediastreamer */ = { + isa = PBXGroup; + children = ( + 63D5C1241BA6E4F0002D1ABF /* plugins */, + ); + name = mediastreamer; + path = "../liblinphone-sdk/apple-darwin/lib/mediastreamer"; + sourceTree = ""; + }; + 63D5C1241BA6E4F0002D1ABF /* plugins */ = { + isa = PBXGroup; + children = ( + 63D5C1251BA6E4F0002D1ABF /* libmsamr.a */, + 63D5C1261BA6E4F0002D1ABF /* libmsbcg729.a */, + 63D5C1281BA6E4F0002D1ABF /* libmsopenh264.a */, + 63D5C1291BA6E4F0002D1ABF /* libmssilk.a */, + 63D5C12A1BA6E4F0002D1ABF /* libmswebrtc.a */, + 63D5C12B1BA6E4F0002D1ABF /* libmsx264.a */, + ); + path = plugins; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* helloworld */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "helloworld" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = helloworld; + productName = "hello-world"; + productReference = 1D6058910D05DD3D006BFB54 /* hello-world.app */; + productType = "com.apple.product-type.application"; + }; + 2294996112A53FEE00D6CF48 /* registration */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2294997A12A53FEE00D6CF48 /* Build configuration list for PBXNativeTarget "registration" */; + buildPhases = ( + 2294996212A53FEE00D6CF48 /* Resources */, + 2294996312A53FEE00D6CF48 /* Sources */, + 2294996812A53FEE00D6CF48 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = registration; + productName = "hello-world"; + productReference = 2294997D12A53FEE00D6CF48 /* hello-world.app */; + productType = "com.apple.product-type.application"; + }; + 229499A112A5417D00D6CF48 /* chatroom */ = { + isa = PBXNativeTarget; + buildConfigurationList = 229499B712A5417D00D6CF48 /* Build configuration list for PBXNativeTarget "chatroom" */; + buildPhases = ( + 229499A212A5417D00D6CF48 /* Resources */, + 229499A312A5417D00D6CF48 /* Sources */, + 229499A512A5417D00D6CF48 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = chatroom; + productName = "hello-world"; + productReference = 229499BA12A5417D00D6CF48 /* hello-world.app */; + productType = "com.apple.product-type.application"; + }; + 229499E612A5433F00D6CF48 /* buddy_status */ = { + isa = PBXNativeTarget; + buildConfigurationList = 229499FC12A5433F00D6CF48 /* Build configuration list for PBXNativeTarget "buddy_status" */; + buildPhases = ( + 229499E712A5433F00D6CF48 /* Resources */, + 229499E812A5433F00D6CF48 /* Sources */, + 229499EA12A5433F00D6CF48 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = buddy_status; + productName = "hello-world"; + productReference = 229499FF12A5433F00D6CF48 /* hello-world.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0510; + }; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "hello-world" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* helloworld */, + 2294996112A53FEE00D6CF48 /* registration */, + 229499A112A5417D00D6CF48 /* chatroom */, + 229499E612A5433F00D6CF48 /* buddy_status */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2294996212A53FEE00D6CF48 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 229499A212A5417D00D6CF48 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 229499E712A5433F00D6CF48 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 63D5C1001BA6E3EB002D1ABF /* helloworld.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2294996312A53FEE00D6CF48 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 63D5C1021BA6E3F7002D1ABF /* registration.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 229499A312A5417D00D6CF48 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 63D5C1031BA6E3FA002D1ABF /* chatroom.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 229499E812A5433F00D6CF48 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 63D5C1041BA6E3FE002D1ABF /* buddy_status.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = hello_world_Prefix.pch; + GCC_VERSION = ""; + INFOPLIST_FILE = "helloworld-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "../liblinphone-sdk/apple-darwin/lib", + "../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", + ); + PRODUCT_NAME = "hello-world"; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = hello_world_Prefix.pch; + GCC_VERSION = ""; + INFOPLIST_FILE = "helloworld-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "../liblinphone-sdk/apple-darwin/lib", + "../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", + ); + PRODUCT_NAME = "hello-world"; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 2294997B12A53FEE00D6CF48 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = hello_world_Prefix.pch; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_FILE = "helloworld-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "../liblinphone-sdk/apple-darwin/lib", + "../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", + ); + PRODUCT_NAME = "hello-world"; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 2294997C12A53FEE00D6CF48 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = hello_world_Prefix.pch; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_FILE = "helloworld-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "../liblinphone-sdk/apple-darwin/lib", + "../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", + ); + PRODUCT_NAME = "hello-world"; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 229499B812A5417D00D6CF48 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = hello_world_Prefix.pch; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_FILE = "helloworld-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "../liblinphone-sdk/apple-darwin/lib", + ); + PRODUCT_NAME = "hello-world"; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 229499B912A5417D00D6CF48 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = hello_world_Prefix.pch; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_FILE = "helloworld-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "../liblinphone-sdk/apple-darwin/lib", + ); + PRODUCT_NAME = "hello-world"; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 229499FD12A5433F00D6CF48 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = hello_world_Prefix.pch; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_FILE = "helloworld-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "../liblinphone-sdk/apple-darwin/lib", + ); + PRODUCT_NAME = "hello-world"; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 229499FE12A5433F00D6CF48 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = hello_world_Prefix.pch; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_FILE = "helloworld-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "../liblinphone-sdk/apple-darwin/lib", + ); + PRODUCT_NAME = "hello-world"; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + ENABLE_BITCODE = NO; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_PREPROCESSOR_DEFINITIONS = DEBUG; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "../liblinphone-sdk/apple-darwin/include"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LIBRARY_SEARCH_PATHS = "../liblinphone-sdk/apple-darwin/lib"; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = iphoneos; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + ENABLE_BITCODE = NO; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "../liblinphone-sdk/apple-darwin/include"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LIBRARY_SEARCH_PATHS = "../liblinphone-sdk/apple-darwin/lib"; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + PREBINDING = NO; + SDKROOT = iphoneos; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "helloworld" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2294997A12A53FEE00D6CF48 /* Build configuration list for PBXNativeTarget "registration" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2294997B12A53FEE00D6CF48 /* Debug */, + 2294997C12A53FEE00D6CF48 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 229499B712A5417D00D6CF48 /* Build configuration list for PBXNativeTarget "chatroom" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 229499B812A5417D00D6CF48 /* Debug */, + 229499B912A5417D00D6CF48 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 229499FC12A5433F00D6CF48 /* Build configuration list for PBXNativeTarget "buddy_status" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 229499FD12A5433F00D6CF48 /* Debug */, + 229499FE12A5433F00D6CF48 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "hello-world" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/liblinphone-tutorials/hello-world/hello_world_Prefix.pch b/TutorialHellowWorld/hello_world_Prefix.pch similarity index 100% rename from liblinphone-tutorials/hello-world/hello_world_Prefix.pch rename to TutorialHellowWorld/hello_world_Prefix.pch diff --git a/liblinphone-tutorials/hello-world/helloworld-Info.plist b/TutorialHellowWorld/helloworld-Info.plist similarity index 100% rename from liblinphone-tutorials/hello-world/helloworld-Info.plist rename to TutorialHellowWorld/helloworld-Info.plist diff --git a/UI.md b/UI.md deleted file mode 100644 index e048dafdc..000000000 --- a/UI.md +++ /dev/null @@ -1,34 +0,0 @@ - -Quick UI reference for Linphone iOS: - -- The app is contained in a window, which resides in the MainStoryboard file. -- The delegate is set to LinphoneAppDelegate in main.m, in the UIApplicationMain() by passing its class -- Basic layout: - - -MainStoryboard - | - | (rootViewController) - | - PhoneMainView ---> view #--> app background - | | - | #--> statusbar background - | - | (mainViewController) - | - UICompositeViewController : TPMultilayout - | - #---> view #--> stateBar - | - #--> contentView - | - #--> tabBar - - -When the app is started, the phoneMainView gets asked to transition to the Dialer view or the Wizard view. -PhoneMainView exposes the -changeCurrentView: method, which will setup its -Any Linphone view is actually presented in the UICompositeViewController, with or without a stateBar and tabBar. - -The UICompositeViewController consists of 3 areas laid out vertically. From top to bottom: StateBar, Content and TabBar. -The TabBar is usually the UIMainBar, which is used as a navigation controller: clicking on each of the buttons will trigger -a transition to another "view". \ No newline at end of file diff --git a/iTunesArtwork b/iTunesArtwork index 511cb49f4..daafcb919 100644 Binary files a/iTunesArtwork and b/iTunesArtwork differ diff --git a/liblinphone-tutorials/hello-world/hello-world.xcodeproj/project.pbxproj b/liblinphone-tutorials/hello-world/hello-world.xcodeproj/project.pbxproj deleted file mode 100755 index bbd185c8f..000000000 --- a/liblinphone-tutorials/hello-world/hello-world.xcodeproj/project.pbxproj +++ /dev/null @@ -1,861 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 154E1A941715638900A0D168 /* libmediastreamer_base.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A931715638900A0D168 /* libmediastreamer_base.a */; }; - 154E1A961715639A00A0D168 /* libmediastreamer_voip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A951715639A00A0D168 /* libmediastreamer_voip.a */; }; - 154E1A981715642E00A0D168 /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A971715642E00A0D168 /* libavutil.a */; }; - 154E1A9A1715644400A0D168 /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A991715644400A0D168 /* libavcodec.a */; }; - 154E1A9C1715645F00A0D168 /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A9B1715645F00A0D168 /* libswscale.a */; }; - 154E1A9D171564B500A0D168 /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A991715644400A0D168 /* libavcodec.a */; }; - 154E1A9E171564B500A0D168 /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A991715644400A0D168 /* libavcodec.a */; }; - 154E1A9F171564B600A0D168 /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A991715644400A0D168 /* libavcodec.a */; }; - 154E1AA0171564BA00A0D168 /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A971715642E00A0D168 /* libavutil.a */; }; - 154E1AA1171564BA00A0D168 /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A971715642E00A0D168 /* libavutil.a */; }; - 154E1AA2171564BA00A0D168 /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A971715642E00A0D168 /* libavutil.a */; }; - 154E1AA3171564C100A0D168 /* libilbc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFED14C41EBA00E1BC69 /* libilbc.a */; }; - 154E1AA4171564C100A0D168 /* libilbc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFED14C41EBA00E1BC69 /* libilbc.a */; }; - 154E1AA5171564C200A0D168 /* libilbc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFED14C41EBA00E1BC69 /* libilbc.a */; }; - 154E1AA6171564C600A0D168 /* libmediastreamer_base.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A931715638900A0D168 /* libmediastreamer_base.a */; }; - 154E1AA7171564C600A0D168 /* libmediastreamer_base.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A931715638900A0D168 /* libmediastreamer_base.a */; }; - 154E1AA8171564C700A0D168 /* libmediastreamer_base.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A931715638900A0D168 /* libmediastreamer_base.a */; }; - 154E1AA9171564C900A0D168 /* libmediastreamer_voip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A951715639A00A0D168 /* libmediastreamer_voip.a */; }; - 154E1AAA171564CA00A0D168 /* libmediastreamer_voip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A951715639A00A0D168 /* libmediastreamer_voip.a */; }; - 154E1AAB171564CA00A0D168 /* libmediastreamer_voip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A951715639A00A0D168 /* libmediastreamer_voip.a */; }; - 154E1AB21715661100A0D168 /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A9B1715645F00A0D168 /* libswscale.a */; }; - 154E1AB31715661100A0D168 /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A9B1715645F00A0D168 /* libswscale.a */; }; - 154E1AB41715661200A0D168 /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154E1A9B1715645F00A0D168 /* libswscale.a */; }; - 15FC168517157478003FDB31 /* buddy_status.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FC167E17157478003FDB31 /* buddy_status.c */; }; - 15FC168817157478003FDB31 /* chatroom.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FC167F17157478003FDB31 /* chatroom.c */; }; - 15FC168A17157478003FDB31 /* helloworld.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FC168017157478003FDB31 /* helloworld.c */; }; - 15FC168F17157478003FDB31 /* registration.c in Sources */ = {isa = PBXBuildFile; fileRef = 15FC168117157478003FDB31 /* registration.c */; }; - 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; - 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - 2220D5D81278461C008F2C2E /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D71278461C008F2C2E /* CFNetwork.framework */; }; - 2220D5DA1278461C008F2C2E /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D91278461C008F2C2E /* CoreAudio.framework */; }; - 2220D5EA12784672008F2C2E /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5E912784672008F2C2E /* AudioToolbox.framework */; }; - 2294996912A53FEE00D6CF48 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; - 2294996A12A53FEE00D6CF48 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - 2294996B12A53FEE00D6CF48 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; - 2294997612A53FEE00D6CF48 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D71278461C008F2C2E /* CFNetwork.framework */; }; - 2294997712A53FEE00D6CF48 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D91278461C008F2C2E /* CoreAudio.framework */; }; - 2294997812A53FEE00D6CF48 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5E912784672008F2C2E /* AudioToolbox.framework */; }; - 2294997912A53FEE00D6CF48 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 22D1B6A012A3E159001AE361 /* libresolv.dylib */; }; - 229499A612A5417D00D6CF48 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; - 229499A712A5417D00D6CF48 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - 229499A812A5417D00D6CF48 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; - 229499B312A5417D00D6CF48 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D71278461C008F2C2E /* CFNetwork.framework */; }; - 229499B412A5417D00D6CF48 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D91278461C008F2C2E /* CoreAudio.framework */; }; - 229499B512A5417D00D6CF48 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5E912784672008F2C2E /* AudioToolbox.framework */; }; - 229499B612A5417D00D6CF48 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 22D1B6A012A3E159001AE361 /* libresolv.dylib */; }; - 229499EB12A5433F00D6CF48 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; - 229499EC12A5433F00D6CF48 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - 229499ED12A5433F00D6CF48 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; - 229499F812A5433F00D6CF48 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D71278461C008F2C2E /* CFNetwork.framework */; }; - 229499F912A5433F00D6CF48 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5D91278461C008F2C2E /* CoreAudio.framework */; }; - 229499FA12A5433F00D6CF48 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220D5E912784672008F2C2E /* AudioToolbox.framework */; }; - 229499FB12A5433F00D6CF48 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 22D1B6A012A3E159001AE361 /* libresolv.dylib */; }; - 22D1B6A112A3E159001AE361 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 22D1B6A012A3E159001AE361 /* libresolv.dylib */; }; - 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; - 34F9DFF614C41EBA00E1BC69 /* libgsm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFEC14C41EBA00E1BC69 /* libgsm.a */; }; - 34F9DFF714C41EBA00E1BC69 /* libilbc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFED14C41EBA00E1BC69 /* libilbc.a */; }; - 34F9DFF814C41EBA00E1BC69 /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFEE14C41EBA00E1BC69 /* liblinphone.a */; }; - 34F9DFFA14C41EBA00E1BC69 /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFF014C41EBA00E1BC69 /* libortp.a */; }; - 34F9DFFD14C41EBA00E1BC69 /* libspeex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFF314C41EBA00E1BC69 /* libspeex.a */; }; - 34F9DFFE14C41EBA00E1BC69 /* libspeexdsp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFF414C41EBA00E1BC69 /* libspeexdsp.a */; }; - 34F9E00314C41FB400E1BC69 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00214C41FB400E1BC69 /* OpenGLES.framework */; }; - 34F9E00614C41FCF00E1BC69 /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00414C41FCF00E1BC69 /* libsrtp.a */; }; - 34F9E00714C41FCF00E1BC69 /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00514C41FCF00E1BC69 /* libvpx.a */; }; - 34F9E00B14C4202100E1BC69 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00A14C4202100E1BC69 /* QuartzCore.framework */; }; - 34F9E00C14C4203900E1BC69 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00214C41FB400E1BC69 /* OpenGLES.framework */; }; - 34F9E00D14C4203900E1BC69 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00A14C4202100E1BC69 /* QuartzCore.framework */; }; - 34F9E00E14C4204600E1BC69 /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00414C41FCF00E1BC69 /* libsrtp.a */; }; - 34F9E00F14C4204600E1BC69 /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00514C41FCF00E1BC69 /* libvpx.a */; }; - 34F9E01014C4207700E1BC69 /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFEE14C41EBA00E1BC69 /* liblinphone.a */; }; - 34F9E01314C4208C00E1BC69 /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFF014C41EBA00E1BC69 /* libortp.a */; }; - 34F9E01614C420B800E1BC69 /* libgsm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFEC14C41EBA00E1BC69 /* libgsm.a */; }; - 34F9E01714C420B800E1BC69 /* libspeex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFF314C41EBA00E1BC69 /* libspeex.a */; }; - 34F9E01814C420B800E1BC69 /* libspeexdsp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFF414C41EBA00E1BC69 /* libspeexdsp.a */; }; - 34F9E01A14C420DD00E1BC69 /* libgsm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFEC14C41EBA00E1BC69 /* libgsm.a */; }; - 34F9E01B14C420DD00E1BC69 /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFEE14C41EBA00E1BC69 /* liblinphone.a */; }; - 34F9E01C14C420DD00E1BC69 /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFF014C41EBA00E1BC69 /* libortp.a */; }; - 34F9E01F14C420DD00E1BC69 /* libspeex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFF314C41EBA00E1BC69 /* libspeex.a */; }; - 34F9E02014C420DD00E1BC69 /* libspeexdsp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFF414C41EBA00E1BC69 /* libspeexdsp.a */; }; - 34F9E02214C420FA00E1BC69 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00A14C4202100E1BC69 /* QuartzCore.framework */; }; - 34F9E02314C4210100E1BC69 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00214C41FB400E1BC69 /* OpenGLES.framework */; }; - 34F9E02414C4211000E1BC69 /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00414C41FCF00E1BC69 /* libsrtp.a */; }; - 34F9E02514C4211000E1BC69 /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00514C41FCF00E1BC69 /* libvpx.a */; }; - 34F9E02614C4212F00E1BC69 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00214C41FB400E1BC69 /* OpenGLES.framework */; }; - 34F9E02714C4212F00E1BC69 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00A14C4202100E1BC69 /* QuartzCore.framework */; }; - 34F9E02914C4214500E1BC69 /* libgsm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFEC14C41EBA00E1BC69 /* libgsm.a */; }; - 34F9E02A14C4214500E1BC69 /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFEE14C41EBA00E1BC69 /* liblinphone.a */; }; - 34F9E02C14C4214500E1BC69 /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFF014C41EBA00E1BC69 /* libortp.a */; }; - 34F9E02F14C4214500E1BC69 /* libspeex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFF314C41EBA00E1BC69 /* libspeex.a */; }; - 34F9E03014C4214500E1BC69 /* libspeexdsp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9DFF414C41EBA00E1BC69 /* libspeexdsp.a */; }; - 34F9E03114C4214500E1BC69 /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00414C41FCF00E1BC69 /* libsrtp.a */; }; - 34F9E03214C4214500E1BC69 /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00514C41FCF00E1BC69 /* libvpx.a */; }; - 34F9E03414C4247A00E1BC69 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03314C4247A00E1BC69 /* AVFoundation.framework */; }; - 34F9E03514C4249600E1BC69 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00814C41FE900E1BC69 /* CoreVideo.framework */; }; - 34F9E03714C424AF00E1BC69 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03614C424AF00E1BC69 /* CoreMedia.framework */; }; - 34F9E03814C4250B00E1BC69 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03314C4247A00E1BC69 /* AVFoundation.framework */; }; - 34F9E03914C4250B00E1BC69 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03614C424AF00E1BC69 /* CoreMedia.framework */; }; - 34F9E03A14C4250B00E1BC69 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00814C41FE900E1BC69 /* CoreVideo.framework */; }; - 34F9E03B14C4251B00E1BC69 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03314C4247A00E1BC69 /* AVFoundation.framework */; }; - 34F9E03C14C4251B00E1BC69 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03614C424AF00E1BC69 /* CoreMedia.framework */; }; - 34F9E03D14C4251B00E1BC69 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00814C41FE900E1BC69 /* CoreVideo.framework */; }; - 34F9E03E14C4252600E1BC69 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03314C4247A00E1BC69 /* AVFoundation.framework */; }; - 34F9E03F14C4253300E1BC69 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E03614C424AF00E1BC69 /* CoreMedia.framework */; }; - 34F9E04014C4253300E1BC69 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F9E00814C41FE900E1BC69 /* CoreVideo.framework */; }; - F079D95D199A6864009C58AA /* libbellesip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D95C199A6864009C58AA /* libbellesip.a */; }; - F079D95E199A6864009C58AA /* libbellesip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D95C199A6864009C58AA /* libbellesip.a */; }; - F079D95F199A6864009C58AA /* libbellesip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D95C199A6864009C58AA /* libbellesip.a */; }; - F079D960199A6864009C58AA /* libbellesip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D95C199A6864009C58AA /* libbellesip.a */; }; - F079D962199A6871009C58AA /* libantlr3c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D961199A6871009C58AA /* libantlr3c.a */; }; - F079D963199A6871009C58AA /* libantlr3c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D961199A6871009C58AA /* libantlr3c.a */; }; - F079D964199A6871009C58AA /* libantlr3c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D961199A6871009C58AA /* libantlr3c.a */; }; - F079D965199A6871009C58AA /* libantlr3c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D961199A6871009C58AA /* libantlr3c.a */; }; - F079D968199A68A5009C58AA /* libpolarssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D966199A68A5009C58AA /* libpolarssl.a */; }; - F079D969199A68A5009C58AA /* libpolarssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D966199A68A5009C58AA /* libpolarssl.a */; }; - F079D96A199A68A5009C58AA /* libpolarssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D966199A68A5009C58AA /* libpolarssl.a */; }; - F079D96B199A68A5009C58AA /* libpolarssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D966199A68A5009C58AA /* libpolarssl.a */; }; - F079D96C199A68A5009C58AA /* libxml2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D967199A68A5009C58AA /* libxml2.a */; }; - F079D96D199A68A5009C58AA /* libxml2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D967199A68A5009C58AA /* libxml2.a */; }; - F079D96E199A68A5009C58AA /* libxml2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D967199A68A5009C58AA /* libxml2.a */; }; - F079D96F199A68A5009C58AA /* libxml2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D967199A68A5009C58AA /* libxml2.a */; }; - F079D972199A68BA009C58AA /* libbzrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D970199A68BA009C58AA /* libbzrtp.a */; }; - F079D973199A68BA009C58AA /* libbzrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D970199A68BA009C58AA /* libbzrtp.a */; }; - F079D974199A68BA009C58AA /* libbzrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D970199A68BA009C58AA /* libbzrtp.a */; }; - F079D975199A68BA009C58AA /* libbzrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D970199A68BA009C58AA /* libbzrtp.a */; }; - F079D976199A68BA009C58AA /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D971199A68BA009C58AA /* libopus.a */; }; - F079D977199A68BA009C58AA /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D971199A68BA009C58AA /* libopus.a */; }; - F079D978199A68BA009C58AA /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D971199A68BA009C58AA /* libopus.a */; }; - F079D979199A68BA009C58AA /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D971199A68BA009C58AA /* libopus.a */; }; - F079D97B199A6905009C58AA /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D97A199A6905009C58AA /* libsqlite3.dylib */; }; - F079D97C199A690C009C58AA /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D97A199A6905009C58AA /* libsqlite3.dylib */; }; - F079D97D199A6913009C58AA /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D97A199A6905009C58AA /* libsqlite3.dylib */; }; - F079D97E199A6919009C58AA /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F079D97A199A6905009C58AA /* libsqlite3.dylib */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 154E1A931715638900A0D168 /* libmediastreamer_base.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmediastreamer_base.a; path = "../../liblinphone-sdk/apple-darwin/lib/libmediastreamer_base.a"; sourceTree = ""; }; - 154E1A951715639A00A0D168 /* libmediastreamer_voip.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmediastreamer_voip.a; path = "../../liblinphone-sdk/apple-darwin/lib/libmediastreamer_voip.a"; sourceTree = ""; }; - 154E1A971715642E00A0D168 /* libavutil.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavutil.a; path = "../../liblinphone-sdk/apple-darwin/lib/libavutil.a"; sourceTree = ""; }; - 154E1A991715644400A0D168 /* libavcodec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavcodec.a; path = "../../liblinphone-sdk/apple-darwin/lib/libavcodec.a"; sourceTree = ""; }; - 154E1A9B1715645F00A0D168 /* libswscale.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libswscale.a; path = "../../liblinphone-sdk/apple-darwin/lib/libswscale.a"; sourceTree = ""; }; - 15FC167E17157478003FDB31 /* buddy_status.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = buddy_status.c; path = "../../liblinphone-sdk/apple-darwin/share/linphone/tutorials/buddy_status.c"; sourceTree = ""; }; - 15FC167F17157478003FDB31 /* chatroom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = chatroom.c; path = "../../liblinphone-sdk/apple-darwin/share/linphone/tutorials/chatroom.c"; sourceTree = ""; }; - 15FC168017157478003FDB31 /* helloworld.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = helloworld.c; path = "../../liblinphone-sdk/apple-darwin/share/linphone/tutorials/helloworld.c"; sourceTree = ""; }; - 15FC168117157478003FDB31 /* registration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = registration.c; path = "../../liblinphone-sdk/apple-darwin/share/linphone/tutorials/registration.c"; sourceTree = ""; }; - 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 1D6058910D05DD3D006BFB54 /* hello-world.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "hello-world.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - 2220D5D51278461C008F2C2E /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; - 2220D5D71278461C008F2C2E /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 2220D5D91278461C008F2C2E /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; - 2220D5E912784672008F2C2E /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; - 2294997D12A53FEE00D6CF48 /* hello-world.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "hello-world.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 229499BA12A5417D00D6CF48 /* hello-world.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "hello-world.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 229499FF12A5433F00D6CF48 /* hello-world.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "hello-world.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 22D1B6A012A3E159001AE361 /* libresolv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libresolv.dylib; path = usr/lib/libresolv.dylib; sourceTree = SDKROOT; }; - 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - 32CA4F630368D1EE00C91783 /* hello_world_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hello_world_Prefix.pch; sourceTree = ""; }; - 34F9DFEC14C41EBA00E1BC69 /* libgsm.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgsm.a; path = "../../liblinphone-sdk/apple-darwin/lib/libgsm.a"; sourceTree = ""; }; - 34F9DFED14C41EBA00E1BC69 /* libilbc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libilbc.a; path = "../../liblinphone-sdk/apple-darwin/lib/libilbc.a"; sourceTree = ""; }; - 34F9DFEE14C41EBA00E1BC69 /* liblinphone.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblinphone.a; path = "../../liblinphone-sdk/apple-darwin/lib/liblinphone.a"; sourceTree = ""; }; - 34F9DFF014C41EBA00E1BC69 /* libortp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libortp.a; path = "../../liblinphone-sdk/apple-darwin/lib/libortp.a"; sourceTree = ""; }; - 34F9DFF314C41EBA00E1BC69 /* libspeex.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libspeex.a; path = "../../liblinphone-sdk/apple-darwin/lib/libspeex.a"; sourceTree = ""; }; - 34F9DFF414C41EBA00E1BC69 /* libspeexdsp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libspeexdsp.a; path = "../../liblinphone-sdk/apple-darwin/lib/libspeexdsp.a"; sourceTree = ""; }; - 34F9E00214C41FB400E1BC69 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; - 34F9E00414C41FCF00E1BC69 /* libsrtp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsrtp.a; path = "../../liblinphone-sdk/apple-darwin/lib/libsrtp.a"; sourceTree = ""; }; - 34F9E00514C41FCF00E1BC69 /* libvpx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvpx.a; path = "../../liblinphone-sdk/apple-darwin/lib/libvpx.a"; sourceTree = ""; }; - 34F9E00814C41FE900E1BC69 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; - 34F9E00A14C4202100E1BC69 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; - 34F9E03314C4247A00E1BC69 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; - 34F9E03614C424AF00E1BC69 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; - 8D1107310486CEB800E47090 /* helloworld-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "helloworld-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; - F079D95C199A6864009C58AA /* libbellesip.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbellesip.a; path = "../../liblinphone-sdk/apple-darwin/lib/libbellesip.a"; sourceTree = ""; }; - F079D961199A6871009C58AA /* libantlr3c.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libantlr3c.a; path = "../../liblinphone-sdk/apple-darwin/lib/libantlr3c.a"; sourceTree = ""; }; - F079D966199A68A5009C58AA /* libpolarssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpolarssl.a; path = "../../liblinphone-sdk/apple-darwin/lib/libpolarssl.a"; sourceTree = ""; }; - F079D967199A68A5009C58AA /* libxml2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libxml2.a; path = "../../liblinphone-sdk/apple-darwin/lib/libxml2.a"; sourceTree = ""; }; - F079D970199A68BA009C58AA /* libbzrtp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbzrtp.a; path = "../../liblinphone-sdk/apple-darwin/lib/libbzrtp.a"; sourceTree = ""; }; - F079D971199A68BA009C58AA /* libopus.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopus.a; path = "../../liblinphone-sdk/apple-darwin/lib/libopus.a"; sourceTree = ""; }; - F079D97A199A6905009C58AA /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F079D97B199A6905009C58AA /* libsqlite3.dylib in Frameworks */, - 154E1A9C1715645F00A0D168 /* libswscale.a in Frameworks */, - F079D96C199A68A5009C58AA /* libxml2.a in Frameworks */, - 154E1A9A1715644400A0D168 /* libavcodec.a in Frameworks */, - 154E1A981715642E00A0D168 /* libavutil.a in Frameworks */, - F079D968199A68A5009C58AA /* libpolarssl.a in Frameworks */, - F079D95D199A6864009C58AA /* libbellesip.a in Frameworks */, - F079D972199A68BA009C58AA /* libbzrtp.a in Frameworks */, - 34F9E03714C424AF00E1BC69 /* CoreMedia.framework in Frameworks */, - 34F9E03514C4249600E1BC69 /* CoreVideo.framework in Frameworks */, - 34F9E03414C4247A00E1BC69 /* AVFoundation.framework in Frameworks */, - 34F9E00B14C4202100E1BC69 /* QuartzCore.framework in Frameworks */, - 34F9E00614C41FCF00E1BC69 /* libsrtp.a in Frameworks */, - 34F9E00714C41FCF00E1BC69 /* libvpx.a in Frameworks */, - 34F9E00314C41FB400E1BC69 /* OpenGLES.framework in Frameworks */, - 34F9DFF614C41EBA00E1BC69 /* libgsm.a in Frameworks */, - 34F9DFF714C41EBA00E1BC69 /* libilbc.a in Frameworks */, - 34F9DFF814C41EBA00E1BC69 /* liblinphone.a in Frameworks */, - F079D962199A6871009C58AA /* libantlr3c.a in Frameworks */, - 154E1A941715638900A0D168 /* libmediastreamer_base.a in Frameworks */, - F079D976199A68BA009C58AA /* libopus.a in Frameworks */, - 154E1A961715639A00A0D168 /* libmediastreamer_voip.a in Frameworks */, - 34F9DFFA14C41EBA00E1BC69 /* libortp.a in Frameworks */, - 34F9DFFD14C41EBA00E1BC69 /* libspeex.a in Frameworks */, - 34F9DFFE14C41EBA00E1BC69 /* libspeexdsp.a in Frameworks */, - 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, - 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, - 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, - 2220D5D81278461C008F2C2E /* CFNetwork.framework in Frameworks */, - 2220D5DA1278461C008F2C2E /* CoreAudio.framework in Frameworks */, - 2220D5EA12784672008F2C2E /* AudioToolbox.framework in Frameworks */, - 22D1B6A112A3E159001AE361 /* libresolv.dylib in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2294996812A53FEE00D6CF48 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F079D97C199A690C009C58AA /* libsqlite3.dylib in Frameworks */, - 34F9E03F14C4253300E1BC69 /* CoreMedia.framework in Frameworks */, - F079D96D199A68A5009C58AA /* libxml2.a in Frameworks */, - 34F9E04014C4253300E1BC69 /* CoreVideo.framework in Frameworks */, - 34F9E03E14C4252600E1BC69 /* AVFoundation.framework in Frameworks */, - F079D969199A68A5009C58AA /* libpolarssl.a in Frameworks */, - F079D95E199A6864009C58AA /* libbellesip.a in Frameworks */, - F079D973199A68BA009C58AA /* libbzrtp.a in Frameworks */, - 34F9E01614C420B800E1BC69 /* libgsm.a in Frameworks */, - 34F9E01714C420B800E1BC69 /* libspeex.a in Frameworks */, - 34F9E01814C420B800E1BC69 /* libspeexdsp.a in Frameworks */, - 34F9E01314C4208C00E1BC69 /* libortp.a in Frameworks */, - 34F9E01014C4207700E1BC69 /* liblinphone.a in Frameworks */, - 34F9E00E14C4204600E1BC69 /* libsrtp.a in Frameworks */, - 34F9E00F14C4204600E1BC69 /* libvpx.a in Frameworks */, - 34F9E00C14C4203900E1BC69 /* OpenGLES.framework in Frameworks */, - 34F9E00D14C4203900E1BC69 /* QuartzCore.framework in Frameworks */, - 2294996912A53FEE00D6CF48 /* Foundation.framework in Frameworks */, - F079D963199A6871009C58AA /* libantlr3c.a in Frameworks */, - 2294996A12A53FEE00D6CF48 /* UIKit.framework in Frameworks */, - F079D977199A68BA009C58AA /* libopus.a in Frameworks */, - 2294996B12A53FEE00D6CF48 /* CoreGraphics.framework in Frameworks */, - 2294997612A53FEE00D6CF48 /* CFNetwork.framework in Frameworks */, - 2294997712A53FEE00D6CF48 /* CoreAudio.framework in Frameworks */, - 2294997812A53FEE00D6CF48 /* AudioToolbox.framework in Frameworks */, - 2294997912A53FEE00D6CF48 /* libresolv.dylib in Frameworks */, - 154E1A9D171564B500A0D168 /* libavcodec.a in Frameworks */, - 154E1AA0171564BA00A0D168 /* libavutil.a in Frameworks */, - 154E1AA3171564C100A0D168 /* libilbc.a in Frameworks */, - 154E1AA6171564C600A0D168 /* libmediastreamer_base.a in Frameworks */, - 154E1AA9171564C900A0D168 /* libmediastreamer_voip.a in Frameworks */, - 154E1AB21715661100A0D168 /* libswscale.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 229499A512A5417D00D6CF48 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F079D97D199A6913009C58AA /* libsqlite3.dylib in Frameworks */, - 34F9E03B14C4251B00E1BC69 /* AVFoundation.framework in Frameworks */, - F079D96E199A68A5009C58AA /* libxml2.a in Frameworks */, - 34F9E03C14C4251B00E1BC69 /* CoreMedia.framework in Frameworks */, - 34F9E03D14C4251B00E1BC69 /* CoreVideo.framework in Frameworks */, - F079D96A199A68A5009C58AA /* libpolarssl.a in Frameworks */, - F079D95F199A6864009C58AA /* libbellesip.a in Frameworks */, - F079D974199A68BA009C58AA /* libbzrtp.a in Frameworks */, - 34F9E02414C4211000E1BC69 /* libsrtp.a in Frameworks */, - 34F9E02514C4211000E1BC69 /* libvpx.a in Frameworks */, - 34F9E02314C4210100E1BC69 /* OpenGLES.framework in Frameworks */, - 34F9E02214C420FA00E1BC69 /* QuartzCore.framework in Frameworks */, - 34F9E01A14C420DD00E1BC69 /* libgsm.a in Frameworks */, - 34F9E01B14C420DD00E1BC69 /* liblinphone.a in Frameworks */, - 34F9E01C14C420DD00E1BC69 /* libortp.a in Frameworks */, - 34F9E01F14C420DD00E1BC69 /* libspeex.a in Frameworks */, - 34F9E02014C420DD00E1BC69 /* libspeexdsp.a in Frameworks */, - 229499A612A5417D00D6CF48 /* Foundation.framework in Frameworks */, - F079D964199A6871009C58AA /* libantlr3c.a in Frameworks */, - 229499A712A5417D00D6CF48 /* UIKit.framework in Frameworks */, - F079D978199A68BA009C58AA /* libopus.a in Frameworks */, - 229499A812A5417D00D6CF48 /* CoreGraphics.framework in Frameworks */, - 229499B312A5417D00D6CF48 /* CFNetwork.framework in Frameworks */, - 229499B412A5417D00D6CF48 /* CoreAudio.framework in Frameworks */, - 229499B512A5417D00D6CF48 /* AudioToolbox.framework in Frameworks */, - 229499B612A5417D00D6CF48 /* libresolv.dylib in Frameworks */, - 154E1A9E171564B500A0D168 /* libavcodec.a in Frameworks */, - 154E1AA1171564BA00A0D168 /* libavutil.a in Frameworks */, - 154E1AA4171564C100A0D168 /* libilbc.a in Frameworks */, - 154E1AA7171564C600A0D168 /* libmediastreamer_base.a in Frameworks */, - 154E1AAA171564CA00A0D168 /* libmediastreamer_voip.a in Frameworks */, - 154E1AB31715661100A0D168 /* libswscale.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 229499EA12A5433F00D6CF48 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F079D97E199A6919009C58AA /* libsqlite3.dylib in Frameworks */, - 34F9E03814C4250B00E1BC69 /* AVFoundation.framework in Frameworks */, - F079D96F199A68A5009C58AA /* libxml2.a in Frameworks */, - 34F9E03914C4250B00E1BC69 /* CoreMedia.framework in Frameworks */, - 34F9E03A14C4250B00E1BC69 /* CoreVideo.framework in Frameworks */, - F079D96B199A68A5009C58AA /* libpolarssl.a in Frameworks */, - F079D960199A6864009C58AA /* libbellesip.a in Frameworks */, - F079D975199A68BA009C58AA /* libbzrtp.a in Frameworks */, - 34F9E02914C4214500E1BC69 /* libgsm.a in Frameworks */, - 34F9E02A14C4214500E1BC69 /* liblinphone.a in Frameworks */, - 34F9E02C14C4214500E1BC69 /* libortp.a in Frameworks */, - 34F9E02F14C4214500E1BC69 /* libspeex.a in Frameworks */, - 34F9E03014C4214500E1BC69 /* libspeexdsp.a in Frameworks */, - 34F9E03114C4214500E1BC69 /* libsrtp.a in Frameworks */, - 34F9E03214C4214500E1BC69 /* libvpx.a in Frameworks */, - 34F9E02614C4212F00E1BC69 /* OpenGLES.framework in Frameworks */, - 34F9E02714C4212F00E1BC69 /* QuartzCore.framework in Frameworks */, - 229499EB12A5433F00D6CF48 /* Foundation.framework in Frameworks */, - F079D965199A6871009C58AA /* libantlr3c.a in Frameworks */, - 229499EC12A5433F00D6CF48 /* UIKit.framework in Frameworks */, - F079D979199A68BA009C58AA /* libopus.a in Frameworks */, - 229499ED12A5433F00D6CF48 /* CoreGraphics.framework in Frameworks */, - 229499F812A5433F00D6CF48 /* CFNetwork.framework in Frameworks */, - 229499F912A5433F00D6CF48 /* CoreAudio.framework in Frameworks */, - 229499FA12A5433F00D6CF48 /* AudioToolbox.framework in Frameworks */, - 229499FB12A5433F00D6CF48 /* libresolv.dylib in Frameworks */, - 154E1A9F171564B600A0D168 /* libavcodec.a in Frameworks */, - 154E1AA2171564BA00A0D168 /* libavutil.a in Frameworks */, - 154E1AA5171564C200A0D168 /* libilbc.a in Frameworks */, - 154E1AA8171564C700A0D168 /* libmediastreamer_base.a in Frameworks */, - 154E1AAB171564CA00A0D168 /* libmediastreamer_voip.a in Frameworks */, - 154E1AB41715661200A0D168 /* libswscale.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 080E96DDFE201D6D7F000001 /* Classes */ = { - isa = PBXGroup; - children = ( - ); - path = Classes; - sourceTree = ""; - }; - 19C28FACFE9D520D11CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 1D6058910D05DD3D006BFB54 /* hello-world.app */, - 2294997D12A53FEE00D6CF48 /* hello-world.app */, - 229499BA12A5417D00D6CF48 /* hello-world.app */, - 229499FF12A5433F00D6CF48 /* hello-world.app */, - ); - name = Products; - sourceTree = ""; - }; - 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { - isa = PBXGroup; - children = ( - 080E96DDFE201D6D7F000001 /* Classes */, - 29B97315FDCFA39411CA2CEA /* Other Sources */, - 29B97317FDCFA39411CA2CEA /* Resources */, - 29B97323FDCFA39411CA2CEA /* Frameworks */, - 19C28FACFE9D520D11CA2CBB /* Products */, - 22D1B6A012A3E159001AE361 /* libresolv.dylib */, - ); - name = CustomTemplate; - sourceTree = ""; - }; - 29B97315FDCFA39411CA2CEA /* Other Sources */ = { - isa = PBXGroup; - children = ( - 15FC167E17157478003FDB31 /* buddy_status.c */, - 15FC167F17157478003FDB31 /* chatroom.c */, - 15FC168017157478003FDB31 /* helloworld.c */, - 15FC168117157478003FDB31 /* registration.c */, - 32CA4F630368D1EE00C91783 /* hello_world_Prefix.pch */, - ); - name = "Other Sources"; - sourceTree = ""; - }; - 29B97317FDCFA39411CA2CEA /* Resources */ = { - isa = PBXGroup; - children = ( - 8D1107310486CEB800E47090 /* helloworld-Info.plist */, - ); - name = Resources; - sourceTree = ""; - }; - 29B97323FDCFA39411CA2CEA /* Frameworks */ = { - isa = PBXGroup; - children = ( - F079D97A199A6905009C58AA /* libsqlite3.dylib */, - 154E1A991715644400A0D168 /* libavcodec.a */, - 154E1A971715642E00A0D168 /* libavutil.a */, - 34F9DFEC14C41EBA00E1BC69 /* libgsm.a */, - F079D961199A6871009C58AA /* libantlr3c.a */, - 34F9DFED14C41EBA00E1BC69 /* libilbc.a */, - 34F9DFEE14C41EBA00E1BC69 /* liblinphone.a */, - 154E1A931715638900A0D168 /* libmediastreamer_base.a */, - 154E1A951715639A00A0D168 /* libmediastreamer_voip.a */, - 34F9DFF014C41EBA00E1BC69 /* libortp.a */, - F079D966199A68A5009C58AA /* libpolarssl.a */, - F079D967199A68A5009C58AA /* libxml2.a */, - F079D970199A68BA009C58AA /* libbzrtp.a */, - F079D971199A68BA009C58AA /* libopus.a */, - F079D95C199A6864009C58AA /* libbellesip.a */, - 34F9DFF314C41EBA00E1BC69 /* libspeex.a */, - 34F9DFF414C41EBA00E1BC69 /* libspeexdsp.a */, - 34F9E00414C41FCF00E1BC69 /* libsrtp.a */, - 154E1A9B1715645F00A0D168 /* libswscale.a */, - 34F9E00514C41FCF00E1BC69 /* libvpx.a */, - 34F9E03614C424AF00E1BC69 /* CoreMedia.framework */, - 34F9E03314C4247A00E1BC69 /* AVFoundation.framework */, - 34F9E00A14C4202100E1BC69 /* QuartzCore.framework */, - 34F9E00814C41FE900E1BC69 /* CoreVideo.framework */, - 34F9E00214C41FB400E1BC69 /* OpenGLES.framework */, - 2220D5D51278461C008F2C2E /* AudioUnit.framework */, - 2220D5D71278461C008F2C2E /* CFNetwork.framework */, - 2220D5D91278461C008F2C2E /* CoreAudio.framework */, - 2220D5E912784672008F2C2E /* AudioToolbox.framework */, - 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, - 1D30AB110D05D00D00671497 /* Foundation.framework */, - 288765FC0DF74451002DB57D /* CoreGraphics.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 1D6058900D05DD3D006BFB54 /* helloworld */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "helloworld" */; - buildPhases = ( - 1D60588D0D05DD3D006BFB54 /* Resources */, - 1D60588E0D05DD3D006BFB54 /* Sources */, - 1D60588F0D05DD3D006BFB54 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = helloworld; - productName = "hello-world"; - productReference = 1D6058910D05DD3D006BFB54 /* hello-world.app */; - productType = "com.apple.product-type.application"; - }; - 2294996112A53FEE00D6CF48 /* registration */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2294997A12A53FEE00D6CF48 /* Build configuration list for PBXNativeTarget "registration" */; - buildPhases = ( - 2294996212A53FEE00D6CF48 /* Resources */, - 2294996312A53FEE00D6CF48 /* Sources */, - 2294996812A53FEE00D6CF48 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = registration; - productName = "hello-world"; - productReference = 2294997D12A53FEE00D6CF48 /* hello-world.app */; - productType = "com.apple.product-type.application"; - }; - 229499A112A5417D00D6CF48 /* chatroom */ = { - isa = PBXNativeTarget; - buildConfigurationList = 229499B712A5417D00D6CF48 /* Build configuration list for PBXNativeTarget "chatroom" */; - buildPhases = ( - 229499A212A5417D00D6CF48 /* Resources */, - 229499A312A5417D00D6CF48 /* Sources */, - 229499A512A5417D00D6CF48 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = chatroom; - productName = "hello-world"; - productReference = 229499BA12A5417D00D6CF48 /* hello-world.app */; - productType = "com.apple.product-type.application"; - }; - 229499E612A5433F00D6CF48 /* buddy_status */ = { - isa = PBXNativeTarget; - buildConfigurationList = 229499FC12A5433F00D6CF48 /* Build configuration list for PBXNativeTarget "buddy_status" */; - buildPhases = ( - 229499E712A5433F00D6CF48 /* Resources */, - 229499E812A5433F00D6CF48 /* Sources */, - 229499EA12A5433F00D6CF48 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = buddy_status; - productName = "hello-world"; - productReference = 229499FF12A5433F00D6CF48 /* hello-world.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 29B97313FDCFA39411CA2CEA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0510; - }; - buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "hello-world" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 1D6058900D05DD3D006BFB54 /* helloworld */, - 2294996112A53FEE00D6CF48 /* registration */, - 229499A112A5417D00D6CF48 /* chatroom */, - 229499E612A5433F00D6CF48 /* buddy_status */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 1D60588D0D05DD3D006BFB54 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2294996212A53FEE00D6CF48 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 229499A212A5417D00D6CF48 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 229499E712A5433F00D6CF48 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 1D60588E0D05DD3D006BFB54 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 15FC168A17157478003FDB31 /* helloworld.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2294996312A53FEE00D6CF48 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 15FC168F17157478003FDB31 /* registration.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 229499A312A5417D00D6CF48 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 15FC168817157478003FDB31 /* chatroom.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 229499E812A5433F00D6CF48 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 15FC168517157478003FDB31 /* buddy_status.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 1D6058940D05DD3E006BFB54 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = hello_world_Prefix.pch; - GCC_VERSION = ""; - INFOPLIST_FILE = "helloworld-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.1; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\"", - ); - PRODUCT_NAME = "hello-world"; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 1D6058950D05DD3E006BFB54 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = hello_world_Prefix.pch; - GCC_VERSION = ""; - INFOPLIST_FILE = "helloworld-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.1; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\"", - ); - PRODUCT_NAME = "hello-world"; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 2294997B12A53FEE00D6CF48 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = hello_world_Prefix.pch; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - INFOPLIST_FILE = "helloworld-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.1; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\\\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\\\"", - "\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\"", - ); - PRODUCT_NAME = "hello-world"; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 2294997C12A53FEE00D6CF48 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = hello_world_Prefix.pch; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - INFOPLIST_FILE = "helloworld-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.1; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\\\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\\\"", - "\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\"", - ); - PRODUCT_NAME = "hello-world"; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 229499B812A5417D00D6CF48 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = hello_world_Prefix.pch; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - INFOPLIST_FILE = "helloworld-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.1; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\\\\\\\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\\\\\\\"", - "\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\"", - ); - PRODUCT_NAME = "hello-world"; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 229499B912A5417D00D6CF48 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = hello_world_Prefix.pch; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - INFOPLIST_FILE = "helloworld-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.1; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\\\\\\\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\\\\\\\"", - "\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\"", - ); - PRODUCT_NAME = "hello-world"; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 229499FD12A5433F00D6CF48 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = hello_world_Prefix.pch; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - INFOPLIST_FILE = "helloworld-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.1; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\\\\\\\\\\\\\\\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\\\\\\\\\\\\\\\"", - "\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\"", - ); - PRODUCT_NAME = "hello-world"; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 229499FE12A5433F00D6CF48 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = hello_world_Prefix.pch; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - INFOPLIST_FILE = "helloworld-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.1; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\\\\\\\\\\\\\\\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\\\\\\\\\\\\\\\"", - "\"$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib\"", - ); - PRODUCT_NAME = "hello-world"; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - C01FCF4F08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - GCC_C_LANGUAGE_STANDARD = c99; - GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = "$(SRCROOT)/../../liblinphone-sdk/apple-darwin/include"; - LIBRARY_SEARCH_PATHS = "$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib"; - PREBINDING = NO; - SDKROOT = iphoneos; - }; - name = Debug; - }; - C01FCF5008A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - GCC_C_LANGUAGE_STANDARD = c99; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = "$(SRCROOT)/../../liblinphone-sdk/apple-darwin/include"; - LIBRARY_SEARCH_PATHS = "$(SRCROOT)/../../liblinphone-sdk/apple-darwin/lib"; - OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; - PREBINDING = NO; - SDKROOT = iphoneos; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "helloworld" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1D6058940D05DD3E006BFB54 /* Debug */, - 1D6058950D05DD3E006BFB54 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 2294997A12A53FEE00D6CF48 /* Build configuration list for PBXNativeTarget "registration" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2294997B12A53FEE00D6CF48 /* Debug */, - 2294997C12A53FEE00D6CF48 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 229499B712A5417D00D6CF48 /* Build configuration list for PBXNativeTarget "chatroom" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 229499B812A5417D00D6CF48 /* Debug */, - 229499B912A5417D00D6CF48 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 229499FC12A5433F00D6CF48 /* Build configuration list for PBXNativeTarget "buddy_status" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 229499FD12A5433F00D6CF48 /* Debug */, - 229499FE12A5433F00D6CF48 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C01FCF4E08A954540054247B /* Build configuration list for PBXProject "hello-world" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4F08A954540054247B /* Debug */, - C01FCF5008A954540054247B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; -} diff --git a/linphone-Info.plist b/linphone-Info.plist index 6068e586b..a929e264d 100644 --- a/linphone-Info.plist +++ b/linphone-Info.plist @@ -11,7 +11,7 @@ CFBundleIcons~ipad CFBundleIdentifier - org.linphone.phone + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleLocalizations @@ -24,7 +24,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 3.7.5 + 3.10.0 CFBundleURLTypes @@ -53,7 +53,7 @@ CFBundleVersion - 2.2.5 + 3 LSRequiresIPhoneOS UIApplicationExitsOnSuspend @@ -82,9 +82,9 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortraitUpsideDown UISupportedInterfaceOrientations~ipad diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 660142633..11359bd5b 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -7,322 +7,596 @@ objects = { /* Begin PBXBuildFile section */ - 045B5CB318D72E9A0088350C /* libbzrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 045B5CB218D72E9A0088350C /* libbzrtp.a */; }; - 15017E701773578400784ACB /* libxml2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 15017E6F1773578400784ACB /* libxml2.a */; }; - 1560821F18EEF26100765332 /* libmsopenh264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1560821E18EEF26100765332 /* libmsopenh264.a */; }; - 1599105316F746B2007BF52B /* route_bluetooth_off_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599104316F746B2007BF52B /* route_bluetooth_off_default_landscape.png */; }; - 1599105516F746B2007BF52B /* route_bluetooth_off_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599104416F746B2007BF52B /* route_bluetooth_off_disabled_landscape.png */; }; - 1599105716F746B2007BF52B /* route_bluetooth_off_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599104516F746B2007BF52B /* route_bluetooth_off_over_landscape.png */; }; - 1599105916F746B2007BF52B /* route_bluetooth_on_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599104616F746B2007BF52B /* route_bluetooth_on_default_landscape.png */; }; - 1599105B16F746B2007BF52B /* route_phone_off_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599104716F746B2007BF52B /* route_phone_off_default_landscape.png */; }; - 1599105D16F746B2007BF52B /* route_phone_off_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599104816F746B2007BF52B /* route_phone_off_disabled_landscape.png */; }; - 1599105F16F746B2007BF52B /* route_phone_off_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599104916F746B2007BF52B /* route_phone_off_over_landscape.png */; }; - 1599106116F746B2007BF52B /* route_phone_on_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599104A16F746B2007BF52B /* route_phone_on_default_landscape.png */; }; - 1599106316F746B2007BF52B /* route_speaker_off_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599104B16F746B2007BF52B /* route_speaker_off_default_landscape.png */; }; - 1599106516F746B2007BF52B /* route_speaker_off_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599104C16F746B2007BF52B /* route_speaker_off_disabled_landscape.png */; }; - 1599106716F746B2007BF52B /* route_speaker_off_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599104D16F746B2007BF52B /* route_speaker_off_over_landscape.png */; }; - 1599106916F746B2007BF52B /* route_speaker_on_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599104E16F746B2007BF52B /* route_speaker_on_default_landscape.png */; }; - 1599106B16F746B2007BF52B /* routes_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599104F16F746B2007BF52B /* routes_default_landscape.png */; }; - 1599106D16F746B2007BF52B /* routes_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599105016F746B2007BF52B /* routes_disabled_landscape.png */; }; - 1599106F16F746B2007BF52B /* routes_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599105116F746B2007BF52B /* routes_over_landscape.png */; }; - 1599107116F746B2007BF52B /* routes_selected_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 1599105216F746B2007BF52B /* routes_selected_landscape.png */; }; - 15AF3C5416F37A3E00FC52EC /* route_bluetooth_off_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C4C16F37A3E00FC52EC /* route_bluetooth_off_default.png */; }; - 15AF3C5616F37A3E00FC52EC /* route_bluetooth_off_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C4D16F37A3E00FC52EC /* route_bluetooth_off_disabled.png */; }; - 15AF3C5816F37A3E00FC52EC /* route_bluetooth_off_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C4E16F37A3E00FC52EC /* route_bluetooth_off_over.png */; }; - 15AF3C5C16F37A3E00FC52EC /* route_bluetooth_on_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C5016F37A3E00FC52EC /* route_bluetooth_on_default.png */; }; - 15AF3C6C16F37A4A00FC52EC /* route_phone_off_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C6416F37A4A00FC52EC /* route_phone_off_default.png */; }; - 15AF3C6E16F37A4A00FC52EC /* route_phone_off_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C6516F37A4A00FC52EC /* route_phone_off_disabled.png */; }; - 15AF3C7016F37A4A00FC52EC /* route_phone_off_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C6616F37A4A00FC52EC /* route_phone_off_over.png */; }; - 15AF3C7416F37A4A00FC52EC /* route_phone_on_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C6816F37A4A00FC52EC /* route_phone_on_default.png */; }; - 15AF3C8416F37A5500FC52EC /* route_speaker_off_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C7C16F37A5500FC52EC /* route_speaker_off_default.png */; }; - 15AF3C8616F37A5500FC52EC /* route_speaker_off_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C7D16F37A5500FC52EC /* route_speaker_off_disabled.png */; }; - 15AF3C8816F37A5500FC52EC /* route_speaker_off_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C7E16F37A5500FC52EC /* route_speaker_off_over.png */; }; - 15AF3C8C16F37A5500FC52EC /* route_speaker_on_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C8016F37A5500FC52EC /* route_speaker_on_default.png */; }; - 15AF3C9816F37A5D00FC52EC /* routes_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C9416F37A5D00FC52EC /* routes_default.png */; }; - 15AF3C9A16F37A5D00FC52EC /* routes_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C9516F37A5D00FC52EC /* routes_disabled.png */; }; - 15AF3C9C16F37A5D00FC52EC /* routes_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C9616F37A5D00FC52EC /* routes_over.png */; }; - 15AF3C9E16F37A5D00FC52EC /* routes_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 15AF3C9716F37A5D00FC52EC /* routes_selected.png */; }; + 152F22361B15E889008C0621 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 152F22351B15E889008C0621 /* libxml2.dylib */; }; + 15F728741B16FF9A00A1C901 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 152F22351B15E889008C0621 /* libxml2.dylib */; }; 1D3623260D0F684500981E51 /* LinphoneAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* LinphoneAppDelegate.m */; }; 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 220FAD3210765B400068D98F /* libgsm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD2910765B400068D98F /* libgsm.a */; }; - 220FAD3810765B400068D98F /* libspeex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD2F10765B400068D98F /* libspeex.a */; }; - 220FAD3910765B400068D98F /* libspeexdsp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD3010765B400068D98F /* libspeexdsp.a */; }; - 2214783D1386A2030020F8B8 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2214783B1386A2030020F8B8 /* Localizable.strings */; }; 2214EB7A12F846B1002A5394 /* UICallButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 2214EB7912F846B1002A5394 /* UICallButton.m */; }; 2214EB8912F84EBB002A5394 /* UIHangUpButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 2214EB8812F84EBB002A5394 /* UIHangUpButton.m */; }; 2214EBF312F86360002A5394 /* UIMicroButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 2214EBF212F86360002A5394 /* UIMicroButton.m */; }; - 2218A92512FBE1340088A667 /* FirstLoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2218A92312FBE1340088A667 /* FirstLoginViewController.m */; }; - 22276E8313C73D3100210156 /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22276E8013C73D3100210156 /* libavcodec.a */; }; - 22276E8413C73D3100210156 /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22276E8113C73D3100210156 /* libavutil.a */; }; - 22276E8513C73D3100210156 /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22276E8213C73D3100210156 /* libswscale.a */; }; 22276E8713C73D8A00210156 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22276E8613C73D8A00210156 /* CoreVideo.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 22276E8913C73DC000210156 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22276E8813C73DC000210156 /* CoreMedia.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 223148E41178A08200637D6A /* libilbc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 223148E31178A08200637D6A /* libilbc.a */; }; - 223148E61178A09900637D6A /* libmsilbc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 223148E51178A09900637D6A /* libmsilbc.a */; }; - 2234C8E915EE2F7F00E18E83 /* chat_message_delivered.png in Resources */ = {isa = PBXBuildFile; fileRef = 2234C8E715EE2F7F00E18E83 /* chat_message_delivered.png */; }; - 2234C8EB15EE2F7F00E18E83 /* chat_message_not_delivered.png in Resources */ = {isa = PBXBuildFile; fileRef = 2234C8E815EE2F7F00E18E83 /* chat_message_not_delivered.png */; }; - 2234C8EE15EE744200E18E83 /* chat_message_inprogress.png in Resources */ = {isa = PBXBuildFile; fileRef = 2234C8ED15EE744200E18E83 /* chat_message_inprogress.png */; }; - 2237D4091084D7A9001383EE /* ring.wav in Resources */ = {isa = PBXBuildFile; fileRef = 2237D4081084D7A9001383EE /* ring.wav */; }; - 223CA7E616D9255800EF1BEC /* libantlr3c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 223CA7E416D9255800EF1BEC /* libantlr3c.a */; }; - 223CA7E716D9255800EF1BEC /* libbellesip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 223CA7E516D9255800EF1BEC /* libbellesip.a */; }; 22405EEE1600B4E400B92522 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22405EED1600B4E400B92522 /* AssetsLibrary.framework */; }; - 22405F001601C19200B92522 /* ImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 22405EFE1601C19100B92522 /* ImageViewController.m */; }; - 2242E313125235120061DDCE /* ring.caf in Resources */ = {isa = PBXBuildFile; fileRef = 2242E312125235120061DDCE /* ring.caf */; }; + 22405F001601C19200B92522 /* ImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 22405EFE1601C19100B92522 /* ImageView.m */; }; 224567C2107B968500F10948 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 224567C1107B968500F10948 /* AVFoundation.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 2248E90E12F7E4CF00220D9C /* UIDigitButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 2248E90D12F7E4CF00220D9C /* UIDigitButton.m */; }; - 22509042196BD902007863F6 /* libopenh264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22509041196BD902007863F6 /* libopenh264.a */; }; - 225CB2FA11ABB76400628906 /* linphone-banner.png in Resources */ = {isa = PBXBuildFile; fileRef = 225CB2F911ABB76400628906 /* linphone-banner.png */; }; - 226183AD1472527D0037138E /* libSKP_SILK_SDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226183AA1472527D0037138E /* libSKP_SILK_SDK.a */; }; - 226183AE1472527D0037138E /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226183AB1472527D0037138E /* libsrtp.a */; }; - 226183B0147259670037138E /* libmssilk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226183AF147259670037138E /* libmssilk.a */; }; 2264B6D211200342002C2C53 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2264B6D111200342002C2C53 /* SystemConfiguration.framework */; }; - 226CDAE014E2D0B800513B67 /* libmsbcg729.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226CDADE14E2D0B800513B67 /* libmsbcg729.a */; }; 226EF06C15FA256B005865C7 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 226EF06B15FA256B005865C7 /* MobileCoreServices.framework */; }; - 226F2ED61344B0EF00F6EF27 /* libopencore-amrwb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226F2ED31344B0EF00F6EF27 /* libopencore-amrwb.a */; }; - 226F2ED71344B0EF00F6EF27 /* libopencore-amrnb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226F2ED41344B0EF00F6EF27 /* libopencore-amrnb.a */; }; - 226F2ED81344B0EF00F6EF27 /* libmsamr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226F2ED51344B0EF00F6EF27 /* libmsamr.a */; }; 2274401A106F31BD006EC466 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22744019106F31BD006EC466 /* CoreAudio.framework */; }; 2274402F106F335E006EC466 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2274402E106F335E006EC466 /* AudioToolbox.framework */; }; 228697C411AC29B800E9E0CA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 228697C311AC29B800E9E0CA /* CFNetwork.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 22968A5F12F875C600588287 /* UISpeakerButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 22968A5E12F875C600588287 /* UISpeakerButton.m */; }; - 22A10F3B11F8960300373793 /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD2C10765B400068D98F /* libortp.a */; }; - 22AA8AFD13D7125600B30535 /* libx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22AA8AFB13D7125500B30535 /* libx264.a */; }; - 22AA8AFE13D7125600B30535 /* libmsx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22AA8AFC13D7125500B30535 /* libmsx264.a */; }; 22AA8B0113D83F6300B30535 /* UICamSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = 22AA8B0013D83F6300B30535 /* UICamSwitch.m */; }; - 22AF73C21754C0D100BE8398 /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22AF73C11754C0D000BE8398 /* libopus.a */; }; 22B5EFA310CE50BD00777D97 /* AddressBookUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22B5EFA210CE50BD00777D97 /* AddressBookUI.framework */; }; 22B5F03510CE6B2F00777D97 /* AddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22B5F03410CE6B2F00777D97 /* AddressBook.framework */; }; - 22BB1A69132FF16A005CD7AA /* UIEraseButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 22BB1A68132FF16A005CD7AA /* UIEraseButton.m */; }; 22C755601317E59C007BC101 /* UIBluetoothButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 22C7555F1317E59C007BC101 /* UIBluetoothButton.m */; }; 22D1B68112A3E0BE001AE361 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 22D1B68012A3E0BE001AE361 /* libresolv.dylib */; }; - 22E0A822111C44E100B04932 /* AboutViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 22E0A81C111C44E100B04932 /* AboutViewController.m */; }; - 22F2508E107141E100AC9B3F /* DialerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 22F2508C107141E100AC9B3F /* DialerViewController.m */; }; - 22F254811073D99800AC9B3F /* ringback.wav in Resources */ = {isa = PBXBuildFile; fileRef = 22F254801073D99800AC9B3F /* ringback.wav */; }; + 22E0A822111C44E100B04932 /* AboutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 22E0A81C111C44E100B04932 /* AboutView.m */; }; + 22F2508E107141E100AC9B3F /* DialerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 22F2508C107141E100AC9B3F /* DialerView.m */; }; 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 340751971506459A00B89C47 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 340751961506459A00B89C47 /* CoreTelephony.framework */; }; 340751E7150F38FD00B89C47 /* UIVideoButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 340751E6150F38FD00B89C47 /* UIVideoButton.m */; }; 34216F401547EBCD00EA9777 /* VideoZoomHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */; }; 344ABDF114850AE9007420B6 /* libc++.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 344ABDEF14850AE9007420B6 /* libc++.1.dylib */; settings = {ATTRIBUTES = (Weak, ); }; }; 344ABDF214850AE9007420B6 /* libstdc++.6.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 344ABDF014850AE9007420B6 /* libstdc++.6.dylib */; settings = {ATTRIBUTES = (Weak, ); }; }; - 57B0E360173C010400A476B8 /* libpolarssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 57B0E35F173C010400A476B8 /* libpolarssl.a */; }; - 57F005C415EE2CCF00914747 /* linphonerc in Resources */ = {isa = PBXBuildFile; fileRef = 57F005C315EE2CCF00914747 /* linphonerc */; }; - 57F005C815EE2D9200914747 /* linphonerc-factory in Resources */ = {isa = PBXBuildFile; fileRef = 57F005C615EE2D9200914747 /* linphonerc-factory */; }; - 57F005CA15EE2D9200914747 /* linphonerc-factory~ipad in Resources */ = {isa = PBXBuildFile; fileRef = 57F005C715EE2D9200914747 /* linphonerc-factory~ipad */; }; - 631C4FB119D2A8F2004BFE77 /* UIDigitButtonLongPlus.m in Sources */ = {isa = PBXBuildFile; fileRef = 631C4FB019D2A8F2004BFE77 /* UIDigitButtonLongPlus.m */; }; - 631C4FB719D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m in Sources */ = {isa = PBXBuildFile; fileRef = 631C4FB619D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m */; }; - 636316D11A1DEBCB0009B839 /* AboutViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 636316D31A1DEBCB0009B839 /* AboutViewController.xib */; }; - 636316D41A1DEC650009B839 /* SettingsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 636316D61A1DEC650009B839 /* SettingsViewController.xib */; }; - 636316D91A1DECC90009B839 /* PhoneMainView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 636316D71A1DECC90009B839 /* PhoneMainView.xib */; }; - 636316DE1A1DEF2F0009B839 /* UIButtonShrinkable.m in Sources */ = {isa = PBXBuildFile; fileRef = 636316DD1A1DEF2F0009B839 /* UIButtonShrinkable.m */; }; - 639CEAFD1A1DF4D9004DE38F /* UIStateBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEAFF1A1DF4D9004DE38F /* UIStateBar.xib */; }; + 630589E71B4E810900EFAE36 /* ChatTester.m in Sources */ = {isa = PBXBuildFile; fileRef = 630589DF1B4E810900EFAE36 /* ChatTester.m */; }; + 630589E81B4E810900EFAE36 /* ContactsTester.m in Sources */ = {isa = PBXBuildFile; fileRef = 630589E11B4E810900EFAE36 /* ContactsTester.m */; }; + 630589EA1B4E810900EFAE36 /* LinphoneTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 630589E41B4E810900EFAE36 /* LinphoneTestCase.m */; }; + 630589EB1B4E810900EFAE36 /* AssistantTester.m in Sources */ = {isa = PBXBuildFile; fileRef = 630589E61B4E810900EFAE36 /* AssistantTester.m */; }; + 63058A241B4E821E00EFAE36 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 63058A0E1B4E821E00EFAE36 /* AppDelegate.m */; }; + 63058A251B4E821E00EFAE36 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 63058A0F1B4E821E00EFAE36 /* InfoPlist.strings */; }; + 63058A261B4E821E00EFAE36 /* Main_iPad.strings in Resources */ = {isa = PBXBuildFile; fileRef = 63058A111B4E821E00EFAE36 /* Main_iPad.strings */; }; + 63058A271B4E821E00EFAE36 /* Main_iPhone.strings in Resources */ = {isa = PBXBuildFile; fileRef = 63058A131B4E821E00EFAE36 /* Main_iPhone.strings */; }; + 63058A281B4E821E00EFAE36 /* Main_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63058A151B4E821E00EFAE36 /* Main_iPad.storyboard */; }; + 63058A291B4E821E00EFAE36 /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63058A171B4E821E00EFAE36 /* Main_iPhone.storyboard */; }; + 63058A2A1B4E821E00EFAE36 /* DetailView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63058A1A1B4E821E00EFAE36 /* DetailView.m */; }; + 63058A2C1B4E821E00EFAE36 /* LogsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63058A1F1B4E821E00EFAE36 /* LogsView.m */; }; + 63058A2D1B4E821E00EFAE36 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 63058A201B4E821E00EFAE36 /* main.m */; }; + 63058A2E1B4E821E00EFAE36 /* MasterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63058A221B4E821E00EFAE36 /* MasterView.m */; }; + 63058A2F1B4E821E00EFAE36 /* TesterImages.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 63058A231B4E821E00EFAE36 /* TesterImages.xcassets */; }; + 63058A3B1B4E822F00EFAE36 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 63058A311B4E822F00EFAE36 /* InfoPlist.strings */; }; + 63058A3C1B4E822F00EFAE36 /* DTObjectBlockExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 63058A341B4E822F00EFAE36 /* DTObjectBlockExecutor.m */; }; + 63058A3E1B4E822F00EFAE36 /* LinphoneTester_Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63058A381B4E822F00EFAE36 /* LinphoneTester_Tests.m */; }; + 63058A3F1B4E823000EFAE36 /* NSObject+DTRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = 63058A3A1B4E822F00EFAE36 /* NSObject+DTRuntime.m */; }; + 63058A4F1B4E835200EFAE36 /* libKIF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 630589FD1B4E816A00EFAE36 /* libKIF.a */; }; + 63058ACF1B4E922500EFAE36 /* certificates in Resources */ = {isa = PBXBuildFile; fileRef = 63058AC81B4E922500EFAE36 /* certificates */; }; + 63058AD01B4E922500EFAE36 /* flexisip in Resources */ = {isa = PBXBuildFile; fileRef = 63058AC91B4E922500EFAE36 /* flexisip */; }; + 63058AD11B4E922500EFAE36 /* images in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACA1B4E922500EFAE36 /* images */; }; + 63058AD21B4E922500EFAE36 /* marie_xml in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACB1B4E922500EFAE36 /* marie_xml */; }; + 63058AD31B4E922500EFAE36 /* messages.db in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACC1B4E922500EFAE36 /* messages.db */; }; + 63058AD41B4E922500EFAE36 /* rcfiles in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACD1B4E922500EFAE36 /* rcfiles */; }; + 63058AD51B4E922500EFAE36 /* sounds in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACE1B4E922500EFAE36 /* sounds */; }; + 63058AD61B4E92D400EFAE36 /* liblinphonetester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F0BB8C0F193623F200974404 /* liblinphonetester.a */; }; + 63058ADA1B4E937300EFAE36 /* certificates in Resources */ = {isa = PBXBuildFile; fileRef = 63058AC81B4E922500EFAE36 /* certificates */; }; + 63058ADB1B4E937300EFAE36 /* flexisip in Resources */ = {isa = PBXBuildFile; fileRef = 63058AC91B4E922500EFAE36 /* flexisip */; }; + 63058ADC1B4E937300EFAE36 /* images in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACA1B4E922500EFAE36 /* images */; }; + 63058ADD1B4E937300EFAE36 /* marie_xml in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACB1B4E922500EFAE36 /* marie_xml */; }; + 63058ADE1B4E937300EFAE36 /* messages.db in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACC1B4E922500EFAE36 /* messages.db */; }; + 63058ADF1B4E937300EFAE36 /* rcfiles in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACD1B4E922500EFAE36 /* rcfiles */; }; + 63058AE01B4E937300EFAE36 /* sounds in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACE1B4E922500EFAE36 /* sounds */; }; + 63058AE21B4E93A100EFAE36 /* tester_hosts in Resources */ = {isa = PBXBuildFile; fileRef = 63058AE11B4E93A100EFAE36 /* tester_hosts */; }; + 63058AE31B4E93B300EFAE36 /* tester_hosts in Resources */ = {isa = PBXBuildFile; fileRef = 63058AE11B4E93A100EFAE36 /* tester_hosts */; }; + 6306440E1BECB08500134C72 /* FirstLoginView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6306440C1BECB08500134C72 /* FirstLoginView.m */; }; + 6308F9C51BF0DD6600D1234B /* XMLRPCHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 6308F9C41BF0DD6600D1234B /* XMLRPCHelper.m */; }; + 630CF5571AF7CE1500539F7A /* UITextField+DoneButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 630CF5561AF7CE1500539F7A /* UITextField+DoneButton.m */; }; + 63130FB21C1ED06900371918 /* SideMenuView~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63130FB01C1ED06900371918 /* SideMenuView~ipad.xib */; }; + 631348301B6F7B6600C6BDCB /* UIRoundBorderedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 6313482F1B6F7B6600C6BDCB /* UIRoundBorderedButton.m */; }; + 631348321B6FA53300C6BDCB /* rootca.pem in Resources */ = {isa = PBXBuildFile; fileRef = 631348311B6FA53300C6BDCB /* rootca.pem */; }; + 6316FA6D1BE12A3E0050E441 /* UIRightImageButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 6316FA6C1BE12A3E0050E441 /* UIRightImageButton.m */; }; + 632DA24D1B43EE9400EB356A /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = D35860D515B549B500513429 /* Utils.m */; }; + 632DA24E1B43EEEF00EB356A /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = D35860D515B549B500513429 /* Utils.m */; }; + 6334DDFA1BBAC97C00631900 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D32B6E2E15A5C0AC0033019F /* libsqlite3.dylib */; }; + 6334DDFB1BBAC99400631900 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D32B6E2E15A5C0AC0033019F /* libsqlite3.dylib */; }; + 6334DDFC1BBAC99B00631900 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 152F22351B15E889008C0621 /* libxml2.dylib */; }; + 6334DDFD1BBAC9A200631900 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F0B026F21AA710AF00FF49F7 /* libiconv.dylib */; }; + 633671611BCBAAD200BFCBDE /* ChatConversationCreateView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6336715F1BCBAAD200BFCBDE /* ChatConversationCreateView.m */; }; + 633756391B67BAF400E21BAD /* SideMenuTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 633756381B67BAF400E21BAD /* SideMenuTableView.m */; }; + 633756451B67D2B200E21BAD /* SideMenuView.m in Sources */ = {isa = PBXBuildFile; fileRef = 633756431B67D2B100E21BAD /* SideMenuView.m */; }; + 633888451BFB2C49001D5E7B /* HPGrowingTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 633888421BFB2C49001D5E7B /* HPGrowingTextView.m */; }; + 633888461BFB2C49001D5E7B /* HPTextViewInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = 633888441BFB2C49001D5E7B /* HPTextViewInternal.m */; }; + 6341807C1BBC103100F71761 /* ChatConversationCreateTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6341807B1BBC103100F71761 /* ChatConversationCreateTableView.m */; }; + 634610061B61330300548952 /* UILabel+Boldify.m in Sources */ = {isa = PBXBuildFile; fileRef = 634610051B61330300548952 /* UILabel+Boldify.m */; }; + 6346100F1B61409800548952 /* CallOutgoingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6346100E1B61409800548952 /* CallOutgoingView.m */; }; + 634610121B6140A500548952 /* CallOutgoingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 634610101B6140A500548952 /* CallOutgoingView.xib */; }; + 635173F91BA082A40095EB0A /* UIChatBubblePhotoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 635173F81BA082A40095EB0A /* UIChatBubblePhotoCell.m */; }; + 6352A5751BE0D4B800594C1C /* CallSideMenuView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6352A5731BE0D4B800594C1C /* CallSideMenuView.m */; }; + 6352A5761BE0D4B800594C1C /* CallSideMenuView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6352A5741BE0D4B800594C1C /* CallSideMenuView.xib */; }; + 635775251B6673EC00C8B704 /* HistoryDetailsTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 635775241B6673EC00C8B704 /* HistoryDetailsTableView.m */; }; + 636316D11A1DEBCB0009B839 /* AboutView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 636316D31A1DEBCB0009B839 /* AboutView.xib */; }; + 636316D41A1DEC650009B839 /* SettingsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 636316D61A1DEC650009B839 /* SettingsView.xib */; }; + 636B97E41C298401003BA37C /* add_field_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B967D1C298400003BA37C /* add_field_default.png */; }; + 636B97E51C298401003BA37C /* add_field_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B967E1C298400003BA37C /* add_field_default@2x.png */; }; + 636B97E61C298401003BA37C /* add_field_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B967F1C298400003BA37C /* add_field_over.png */; }; + 636B97E71C298401003BA37C /* add_field_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96801C298400003BA37C /* add_field_over@2x.png */; }; + 636B97E81C298401003BA37C /* avatar.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96811C298400003BA37C /* avatar.png */; }; + 636B97E91C298401003BA37C /* avatar@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96821C298400003BA37C /* avatar@2x.png */; }; + 636B97EA1C298401003BA37C /* back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96831C298400003BA37C /* back_default.png */; }; + 636B97EB1C298401003BA37C /* back_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96841C298400003BA37C /* back_default@2x.png */; }; + 636B97EC1C298401003BA37C /* back_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96851C298400003BA37C /* back_disabled.png */; }; + 636B97ED1C298401003BA37C /* back_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96861C298400003BA37C /* back_disabled@2x.png */; }; + 636B97EE1C298401003BA37C /* backspace_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96871C298400003BA37C /* backspace_default.png */; }; + 636B97EF1C298401003BA37C /* backspace_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96881C298400003BA37C /* backspace_default@2x.png */; }; + 636B97F01C298401003BA37C /* backspace_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96891C298400003BA37C /* backspace_disabled.png */; }; + 636B97F11C298401003BA37C /* backspace_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B968A1C298400003BA37C /* backspace_disabled@2x.png */; }; + 636B97F21C298401003BA37C /* backspace_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B968B1C298400003BA37C /* backspace_over.png */; }; + 636B97F31C298401003BA37C /* backspace_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B968C1C298400003BA37C /* backspace_over@2x.png */; }; + 636B97F41C298401003BA37C /* call_add_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B968D1C298400003BA37C /* call_add_default.png */; }; + 636B97F51C298401003BA37C /* call_add_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B968E1C298400003BA37C /* call_add_default@2x.png */; }; + 636B97F61C298401003BA37C /* call_add_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B968F1C298400003BA37C /* call_add_disabled.png */; }; + 636B97F71C298401003BA37C /* call_add_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96901C298400003BA37C /* call_add_disabled@2x.png */; }; + 636B97F81C298401003BA37C /* call_alt_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96911C298400003BA37C /* call_alt_back_default.png */; }; + 636B97F91C298401003BA37C /* call_alt_back_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96921C298400003BA37C /* call_alt_back_default@2x.png */; }; + 636B97FA1C298401003BA37C /* call_alt_back_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96931C298400003BA37C /* call_alt_back_disabled.png */; }; + 636B97FB1C298401003BA37C /* call_alt_back_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96941C298400003BA37C /* call_alt_back_disabled@2x.png */; }; + 636B97FC1C298401003BA37C /* call_alt_start_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96951C298400003BA37C /* call_alt_start_default.png */; }; + 636B97FD1C298401003BA37C /* call_alt_start_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96961C298400003BA37C /* call_alt_start_default@2x.png */; }; + 636B97FE1C298401003BA37C /* call_alt_start_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96971C298400003BA37C /* call_alt_start_disabled.png */; }; + 636B97FF1C298401003BA37C /* call_alt_start_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96981C298400003BA37C /* call_alt_start_disabled@2x.png */; }; + 636B98001C298401003BA37C /* call_audio_start_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96991C298400003BA37C /* call_audio_start_default.png */; }; + 636B98011C298401003BA37C /* call_audio_start_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B969A1C298400003BA37C /* call_audio_start_default@2x.png */; }; + 636B98021C298401003BA37C /* call_audio_start_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B969B1C298400003BA37C /* call_audio_start_disabled.png */; }; + 636B98031C298401003BA37C /* call_audio_start_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B969C1C298400003BA37C /* call_audio_start_disabled@2x.png */; }; + 636B98041C298401003BA37C /* call_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B969D1C298400003BA37C /* call_back_default.png */; }; + 636B98051C298401003BA37C /* call_back_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B969E1C298400003BA37C /* call_back_default@2x.png */; }; + 636B98061C298401003BA37C /* call_back_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B969F1C298400003BA37C /* call_back_disabled.png */; }; + 636B98071C298401003BA37C /* call_back_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96A01C298400003BA37C /* call_back_disabled@2x.png */; }; + 636B98081C298401003BA37C /* call_hangup_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96A11C298400003BA37C /* call_hangup_default.png */; }; + 636B98091C298401003BA37C /* call_hangup_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96A21C298400003BA37C /* call_hangup_default@2x.png */; }; + 636B980A1C298401003BA37C /* call_hangup_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96A31C298400003BA37C /* call_hangup_disabled.png */; }; + 636B980B1C298401003BA37C /* call_hangup_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96A41C298400003BA37C /* call_hangup_disabled@2x.png */; }; + 636B980C1C298401003BA37C /* call_incoming.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96A51C298400003BA37C /* call_incoming.png */; }; + 636B980D1C298401003BA37C /* call_incoming@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96A61C298400003BA37C /* call_incoming@2x.png */; }; + 636B980E1C298401003BA37C /* call_missed.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96A71C298400003BA37C /* call_missed.png */; }; + 636B980F1C298401003BA37C /* call_missed@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96A81C298400003BA37C /* call_missed@2x.png */; }; + 636B98101C298401003BA37C /* call_outgoing.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96A91C298400003BA37C /* call_outgoing.png */; }; + 636B98111C298401003BA37C /* call_outgoing@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96AA1C298400003BA37C /* call_outgoing@2x.png */; }; + 636B98121C298401003BA37C /* call_quality_indicator_0.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96AB1C298400003BA37C /* call_quality_indicator_0.png */; }; + 636B98131C298401003BA37C /* call_quality_indicator_0@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96AC1C298400003BA37C /* call_quality_indicator_0@2x.png */; }; + 636B98141C298401003BA37C /* call_quality_indicator_1.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96AD1C298400003BA37C /* call_quality_indicator_1.png */; }; + 636B98151C298401003BA37C /* call_quality_indicator_1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96AE1C298400003BA37C /* call_quality_indicator_1@2x.png */; }; + 636B98161C298401003BA37C /* call_quality_indicator_2.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96AF1C298400003BA37C /* call_quality_indicator_2.png */; }; + 636B98171C298401003BA37C /* call_quality_indicator_2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96B01C298400003BA37C /* call_quality_indicator_2@2x.png */; }; + 636B98181C298401003BA37C /* call_quality_indicator_3.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96B11C298400003BA37C /* call_quality_indicator_3.png */; }; + 636B98191C298401003BA37C /* call_quality_indicator_3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96B21C298400003BA37C /* call_quality_indicator_3@2x.png */; }; + 636B981A1C298401003BA37C /* call_quality_indicator_4.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96B31C298400003BA37C /* call_quality_indicator_4.png */; }; + 636B981B1C298401003BA37C /* call_quality_indicator_4@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96B41C298400003BA37C /* call_quality_indicator_4@2x.png */; }; + 636B981C1C298401003BA37C /* call_start_body_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96B51C298400003BA37C /* call_start_body_default.png */; }; + 636B981D1C298401003BA37C /* call_start_body_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96B61C298400003BA37C /* call_start_body_default@2x.png */; }; + 636B981E1C298401003BA37C /* call_start_body_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96B71C298400003BA37C /* call_start_body_disabled.png */; }; + 636B981F1C298401003BA37C /* call_start_body_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96B81C298400003BA37C /* call_start_body_disabled@2x.png */; }; + 636B98201C298401003BA37C /* call_start_body_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96B91C298400003BA37C /* call_start_body_over.png */; }; + 636B98211C298401003BA37C /* call_start_body_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96BA1C298400003BA37C /* call_start_body_over@2x.png */; }; + 636B98221C298401003BA37C /* call_status_incoming.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96BB1C298400003BA37C /* call_status_incoming.png */; }; + 636B98231C298401003BA37C /* call_status_incoming@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96BC1C298400003BA37C /* call_status_incoming@2x.png */; }; + 636B98241C298401003BA37C /* call_status_missed.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96BD1C298400003BA37C /* call_status_missed.png */; }; + 636B98251C298401003BA37C /* call_status_missed@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96BE1C298400003BA37C /* call_status_missed@2x.png */; }; + 636B98261C298401003BA37C /* call_status_outgoing.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96BF1C298400003BA37C /* call_status_outgoing.png */; }; + 636B98271C298401003BA37C /* call_status_outgoing@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96C01C298400003BA37C /* call_status_outgoing@2x.png */; }; + 636B98281C298401003BA37C /* call_transfer_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96C11C298400003BA37C /* call_transfer_default.png */; }; + 636B98291C298401003BA37C /* call_transfer_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96C21C298400003BA37C /* call_transfer_default@2x.png */; }; + 636B982A1C298401003BA37C /* call_transfer_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96C31C298400003BA37C /* call_transfer_disabled.png */; }; + 636B982B1C298401003BA37C /* call_transfer_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96C41C298400003BA37C /* call_transfer_disabled@2x.png */; }; + 636B982C1C298401003BA37C /* call_video_start_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96C51C298400003BA37C /* call_video_start_default.png */; }; + 636B982D1C298401003BA37C /* call_video_start_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96C61C298400003BA37C /* call_video_start_default@2x.png */; }; + 636B982E1C298401003BA37C /* call_video_start_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96C71C298400003BA37C /* call_video_start_disabled.png */; }; + 636B982F1C298401003BA37C /* call_video_start_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96C81C298400003BA37C /* call_video_start_disabled@2x.png */; }; + 636B98301C298401003BA37C /* camera_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96C91C298400003BA37C /* camera_default.png */; }; + 636B98311C298401003BA37C /* camera_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96CA1C298400003BA37C /* camera_default@2x.png */; }; + 636B98321C298401003BA37C /* camera_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96CB1C298400003BA37C /* camera_disabled.png */; }; + 636B98331C298401003BA37C /* camera_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96CC1C298400003BA37C /* camera_disabled@2x.png */; }; + 636B98341C298401003BA37C /* camera_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96CD1C298400003BA37C /* camera_selected.png */; }; + 636B98351C298401003BA37C /* camera_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96CE1C298400003BA37C /* camera_selected@2x.png */; }; + 636B98361C298401003BA37C /* camera_switch_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96CF1C298400003BA37C /* camera_switch_default.png */; }; + 636B98371C298401003BA37C /* camera_switch_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96D01C298400003BA37C /* camera_switch_default@2x.png */; }; + 636B98381C298401003BA37C /* camera_switch_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96D11C298400003BA37C /* camera_switch_disabled.png */; }; + 636B98391C298401003BA37C /* camera_switch_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96D21C298400003BA37C /* camera_switch_disabled@2x.png */; }; + 636B983A1C298401003BA37C /* camera_switch_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96D31C298400003BA37C /* camera_switch_over.png */; }; + 636B983B1C298401003BA37C /* camera_switch_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96D41C298400003BA37C /* camera_switch_over@2x.png */; }; + 636B983C1C298401003BA37C /* cancel_edit_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96D51C298400003BA37C /* cancel_edit_default.png */; }; + 636B983D1C298401003BA37C /* cancel_edit_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96D61C298400003BA37C /* cancel_edit_default@2x.png */; }; + 636B983E1C298401003BA37C /* cancel_edit_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96D71C298400003BA37C /* cancel_edit_disabled.png */; }; + 636B983F1C298401003BA37C /* cancel_edit_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96D81C298400003BA37C /* cancel_edit_disabled@2x.png */; }; + 636B98401C298401003BA37C /* chat_add_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96D91C298400003BA37C /* chat_add_default.png */; }; + 636B98411C298401003BA37C /* chat_add_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96DA1C298400003BA37C /* chat_add_default@2x.png */; }; + 636B98421C298401003BA37C /* chat_add_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96DB1C298400003BA37C /* chat_add_disabled.png */; }; + 636B98431C298401003BA37C /* chat_add_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96DC1C298400003BA37C /* chat_add_disabled@2x.png */; }; + 636B98441C298401003BA37C /* chat_attachment_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96DD1C298400003BA37C /* chat_attachment_default.png */; }; + 636B98451C298401003BA37C /* chat_attachment_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96DE1C298400003BA37C /* chat_attachment_default@2x.png */; }; + 636B98461C298401003BA37C /* chat_attachment_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96DF1C298400003BA37C /* chat_attachment_disabled.png */; }; + 636B98471C298401003BA37C /* chat_attachment_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96E01C298400003BA37C /* chat_attachment_disabled@2x.png */; }; + 636B98481C298401003BA37C /* chat_attachment_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96E11C298400003BA37C /* chat_attachment_over.png */; }; + 636B98491C298401003BA37C /* chat_attachment_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96E21C298400003BA37C /* chat_attachment_over@2x.png */; }; + 636B984A1C298401003BA37C /* chat_message_not_delivered.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96E31C298400003BA37C /* chat_message_not_delivered.png */; }; + 636B984B1C298401003BA37C /* chat_message_not_delivered@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96E41C298400003BA37C /* chat_message_not_delivered@2x.png */; }; + 636B984C1C298401003BA37C /* chat_send_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96E51C298400003BA37C /* chat_send_default.png */; }; + 636B984D1C298401003BA37C /* chat_send_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96E61C298400003BA37C /* chat_send_default@2x.png */; }; + 636B984E1C298401003BA37C /* chat_send_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96E71C298400003BA37C /* chat_send_disabled.png */; }; + 636B984F1C298401003BA37C /* chat_send_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96E81C298400003BA37C /* chat_send_disabled@2x.png */; }; + 636B98501C298401003BA37C /* chat_send_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96E91C298400003BA37C /* chat_send_over.png */; }; + 636B98511C298401003BA37C /* chat_send_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96EA1C298400003BA37C /* chat_send_over@2x.png */; }; + 636B98521C298401003BA37C /* chat_start_body_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96EB1C298400003BA37C /* chat_start_body_default.png */; }; + 636B98531C298401003BA37C /* chat_start_body_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96EC1C298400003BA37C /* chat_start_body_default@2x.png */; }; + 636B98541C298401003BA37C /* chat_start_body_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96ED1C298400003BA37C /* chat_start_body_disabled.png */; }; + 636B98551C298401003BA37C /* chat_start_body_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96EE1C298400003BA37C /* chat_start_body_disabled@2x.png */; }; + 636B98561C298401003BA37C /* chat_start_body_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96EF1C298400003BA37C /* chat_start_body_over.png */; }; + 636B98571C298401003BA37C /* chat_start_body_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96F01C298400003BA37C /* chat_start_body_over@2x.png */; }; + 636B98581C298401003BA37C /* checkbox_checked.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96F11C298400003BA37C /* checkbox_checked.png */; }; + 636B98591C298401003BA37C /* checkbox_checked@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96F21C298400003BA37C /* checkbox_checked@2x.png */; }; + 636B985A1C298401003BA37C /* checkbox_unchecked.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96F31C298400003BA37C /* checkbox_unchecked.png */; }; + 636B985B1C298401003BA37C /* checkbox_unchecked@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96F41C298400003BA37C /* checkbox_unchecked@2x.png */; }; + 636B985C1C298401003BA37C /* color_A.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96F51C298400003BA37C /* color_A.png */; }; + 636B985D1C298401003BA37C /* color_C.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96F61C298400003BA37C /* color_C.png */; }; + 636B985E1C298401003BA37C /* color_D.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96F71C298400003BA37C /* color_D.png */; }; + 636B985F1C298401003BA37C /* color_E.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96F81C298400003BA37C /* color_E.png */; }; + 636B98601C298401003BA37C /* color_F.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96F91C298400003BA37C /* color_F.png */; }; + 636B98611C298401003BA37C /* color_G.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96FA1C298400003BA37C /* color_G.png */; }; + 636B98621C298401003BA37C /* color_H.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96FB1C298400003BA37C /* color_H.png */; }; + 636B98631C298401003BA37C /* color_I.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96FC1C298400003BA37C /* color_I.png */; }; + 636B98641C298401003BA37C /* color_L.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96FD1C298400003BA37C /* color_L.png */; }; + 636B98651C298401003BA37C /* color_M.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96FE1C298400003BA37C /* color_M.png */; }; + 636B98661C298401003BA37C /* conference_exit_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B96FF1C298400003BA37C /* conference_exit_default.png */; }; + 636B98671C298401003BA37C /* conference_exit_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97001C298400003BA37C /* conference_exit_default@2x.png */; }; + 636B98681C298401003BA37C /* conference_exit_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97011C298400003BA37C /* conference_exit_over.png */; }; + 636B98691C298401003BA37C /* conference_exit_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97021C298400003BA37C /* conference_exit_over@2x.png */; }; + 636B986A1C298401003BA37C /* contact_add_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97031C298400003BA37C /* contact_add_default.png */; }; + 636B986B1C298401003BA37C /* contact_add_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97041C298400003BA37C /* contact_add_default@2x.png */; }; + 636B986C1C298401003BA37C /* contact_add_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97051C298400003BA37C /* contact_add_disabled.png */; }; + 636B986D1C298401003BA37C /* contact_add_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97061C298400003BA37C /* contact_add_disabled@2x.png */; }; + 636B986E1C298401003BA37C /* contacts_all_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97071C298400003BA37C /* contacts_all_default.png */; }; + 636B986F1C298401003BA37C /* contacts_all_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97081C298400003BA37C /* contacts_all_default@2x.png */; }; + 636B98701C298401003BA37C /* contacts_all_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97091C298400003BA37C /* contacts_all_disabled.png */; }; + 636B98711C298401003BA37C /* contacts_all_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B970A1C298400003BA37C /* contacts_all_disabled@2x.png */; }; + 636B98721C298401003BA37C /* contacts_all_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B970B1C298400003BA37C /* contacts_all_selected.png */; }; + 636B98731C298401003BA37C /* contacts_all_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B970C1C298400003BA37C /* contacts_all_selected@2x.png */; }; + 636B98741C298401003BA37C /* contacts_sip_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B970D1C298400003BA37C /* contacts_sip_default.png */; }; + 636B98751C298401003BA37C /* contacts_sip_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B970E1C298400003BA37C /* contacts_sip_default@2x.png */; }; + 636B98761C298401003BA37C /* contacts_sip_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B970F1C298400003BA37C /* contacts_sip_disabled.png */; }; + 636B98771C298401003BA37C /* contacts_sip_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97101C298400003BA37C /* contacts_sip_disabled@2x.png */; }; + 636B98781C298401003BA37C /* contacts_sip_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97111C298400003BA37C /* contacts_sip_selected.png */; }; + 636B98791C298401003BA37C /* contacts_sip_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97121C298400003BA37C /* contacts_sip_selected@2x.png */; }; + 636B987A1C298401003BA37C /* delete_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97131C298400003BA37C /* delete_default.png */; }; + 636B987B1C298401003BA37C /* delete_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97141C298400003BA37C /* delete_default@2x.png */; }; + 636B987C1C298401003BA37C /* delete_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97151C298400003BA37C /* delete_disabled.png */; }; + 636B987D1C298401003BA37C /* delete_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97161C298400003BA37C /* delete_disabled@2x.png */; }; + 636B987E1C298401003BA37C /* delete_field_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97171C298400003BA37C /* delete_field_default.png */; }; + 636B987F1C298401003BA37C /* delete_field_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97181C298400003BA37C /* delete_field_default@2x.png */; }; + 636B98801C298401003BA37C /* delete_field_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97191C298400003BA37C /* delete_field_over.png */; }; + 636B98811C298401003BA37C /* delete_field_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B971A1C298400003BA37C /* delete_field_over@2x.png */; }; + 636B98821C298401003BA37C /* deselect_all.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B971B1C298400003BA37C /* deselect_all.png */; }; + 636B98831C298401003BA37C /* deselect_all@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B971C1C298400003BA37C /* deselect_all@2x.png */; }; + 636B98841C298401003BA37C /* dialer_alt_back.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B971D1C298400003BA37C /* dialer_alt_back.png */; }; + 636B98851C298401003BA37C /* dialer_alt_back@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B971E1C298400003BA37C /* dialer_alt_back@2x.png */; }; + 636B98861C298401003BA37C /* dialer_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B971F1C298400003BA37C /* dialer_back_default.png */; }; + 636B98871C298401003BA37C /* dialer_back_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97201C298400003BA37C /* dialer_back_default@2x.png */; }; + 636B98881C298401003BA37C /* dialer_back_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97211C298400003BA37C /* dialer_back_disabled.png */; }; + 636B98891C298401003BA37C /* dialer_back_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97221C298400003BA37C /* dialer_back_disabled@2x.png */; }; + 636B988A1C298401003BA37C /* dialer_background.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97231C298400003BA37C /* dialer_background.png */; }; + 636B988B1C298401003BA37C /* dialer_background@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97241C298400003BA37C /* dialer_background@2x.png */; }; + 636B988C1C298401003BA37C /* edit_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97251C298400003BA37C /* edit_default.png */; }; + 636B988D1C298401003BA37C /* edit_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97261C298400003BA37C /* edit_default@2x.png */; }; + 636B988E1C298401003BA37C /* edit_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97271C298400003BA37C /* edit_disabled.png */; }; + 636B988F1C298401003BA37C /* edit_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97281C298400003BA37C /* edit_disabled@2x.png */; }; + 636B98901C298401003BA37C /* edit_list_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97291C298400003BA37C /* edit_list_default.png */; }; + 636B98911C298401003BA37C /* edit_list_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B972A1C298400003BA37C /* edit_list_default@2x.png */; }; + 636B98921C298401003BA37C /* edit_list_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B972B1C298400003BA37C /* edit_list_disabled.png */; }; + 636B98931C298401003BA37C /* edit_list_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B972C1C298400003BA37C /* edit_list_disabled@2x.png */; }; + 636B98941C298401003BA37C /* footer_chat_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B972D1C298400003BA37C /* footer_chat_default.png */; }; + 636B98951C298401003BA37C /* footer_chat_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B972E1C298400003BA37C /* footer_chat_default@2x.png */; }; + 636B98961C298401003BA37C /* footer_chat_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B972F1C298400003BA37C /* footer_chat_disabled.png */; }; + 636B98971C298401003BA37C /* footer_chat_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97301C298400003BA37C /* footer_chat_disabled@2x.png */; }; + 636B98981C298401003BA37C /* footer_contacts_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97311C298400003BA37C /* footer_contacts_default.png */; }; + 636B98991C298401003BA37C /* footer_contacts_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97321C298400003BA37C /* footer_contacts_default@2x.png */; }; + 636B989A1C298401003BA37C /* footer_contacts_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97331C298400003BA37C /* footer_contacts_disabled.png */; }; + 636B989B1C298401003BA37C /* footer_contacts_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97341C298400003BA37C /* footer_contacts_disabled@2x.png */; }; + 636B989C1C298401003BA37C /* footer_dialer_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97351C298400003BA37C /* footer_dialer_default.png */; }; + 636B989D1C298401003BA37C /* footer_dialer_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97361C298400003BA37C /* footer_dialer_default@2x.png */; }; + 636B989E1C298401003BA37C /* footer_dialer_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97371C298400003BA37C /* footer_dialer_disabled.png */; }; + 636B989F1C298401003BA37C /* footer_dialer_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97381C298400003BA37C /* footer_dialer_disabled@2x.png */; }; + 636B98A01C298401003BA37C /* footer_history_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97391C298400003BA37C /* footer_history_default.png */; }; + 636B98A11C298401003BA37C /* footer_history_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B973A1C298400003BA37C /* footer_history_default@2x.png */; }; + 636B98A21C298401003BA37C /* footer_history_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B973B1C298400003BA37C /* footer_history_disabled.png */; }; + 636B98A31C298401003BA37C /* footer_history_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B973C1C298400003BA37C /* footer_history_disabled@2x.png */; }; + 636B98A41C298401003BA37C /* history_all_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B973D1C298400003BA37C /* history_all_default.png */; }; + 636B98A51C298401003BA37C /* history_all_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B973E1C298400003BA37C /* history_all_default@2x.png */; }; + 636B98A61C298401003BA37C /* history_all_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B973F1C298400003BA37C /* history_all_disabled.png */; }; + 636B98A71C298401003BA37C /* history_all_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97401C298400003BA37C /* history_all_disabled@2x.png */; }; + 636B98A81C298401003BA37C /* history_all_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97411C298400003BA37C /* history_all_selected.png */; }; + 636B98A91C298401003BA37C /* history_all_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97421C298400003BA37C /* history_all_selected@2x.png */; }; + 636B98AA1C298401003BA37C /* history_chat_indicator.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97431C298400003BA37C /* history_chat_indicator.png */; }; + 636B98AB1C298401003BA37C /* history_chat_indicator@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97441C298400003BA37C /* history_chat_indicator@2x.png */; }; + 636B98AC1C298401003BA37C /* history_missed_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97451C298400003BA37C /* history_missed_default.png */; }; + 636B98AD1C298401003BA37C /* history_missed_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97461C298400003BA37C /* history_missed_default@2x.png */; }; + 636B98AE1C298401003BA37C /* history_missed_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97471C298400003BA37C /* history_missed_disabled.png */; }; + 636B98AF1C298401003BA37C /* history_missed_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97481C298400003BA37C /* history_missed_disabled@2x.png */; }; + 636B98B01C298401003BA37C /* history_missed_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97491C298400003BA37C /* history_missed_selected.png */; }; + 636B98B11C298401003BA37C /* history_missed_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B974A1C298400003BA37C /* history_missed_selected@2x.png */; }; + 636B98B21C298401003BA37C /* led_connected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B974B1C298400003BA37C /* led_connected.png */; }; + 636B98B31C298401003BA37C /* led_connected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B974C1C298400003BA37C /* led_connected@2x.png */; }; + 636B98B41C298401003BA37C /* led_disconnected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B974D1C298400003BA37C /* led_disconnected.png */; }; + 636B98B51C298401003BA37C /* led_disconnected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B974E1C298400003BA37C /* led_disconnected@2x.png */; }; + 636B98B61C298401003BA37C /* led_error.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B974F1C298400003BA37C /* led_error.png */; }; + 636B98B71C298401003BA37C /* led_error@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97501C298400003BA37C /* led_error@2x.png */; }; + 636B98B81C298401003BA37C /* led_inprogress.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97511C298400003BA37C /* led_inprogress.png */; }; + 636B98B91C298401003BA37C /* led_inprogress@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97521C298400003BA37C /* led_inprogress@2x.png */; }; + 636B98BA1C298401003BA37C /* linphone_logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97531C298400003BA37C /* linphone_logo.png */; }; + 636B98BB1C298401003BA37C /* linphone_logo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97541C298400003BA37C /* linphone_logo@2x.png */; }; + 636B98BC1C298401003BA37C /* linphone_user.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97551C298400003BA37C /* linphone_user.png */; }; + 636B98BD1C298401003BA37C /* linphone_user@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97561C298400003BA37C /* linphone_user@2x.png */; }; + 636B98BE1C298401003BA37C /* list_details_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97571C298401003BA37C /* list_details_default.png */; }; + 636B98BF1C298401003BA37C /* list_details_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97581C298401003BA37C /* list_details_default@2x.png */; }; + 636B98C01C298401003BA37C /* list_details_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97591C298401003BA37C /* list_details_over.png */; }; + 636B98C11C298401003BA37C /* list_details_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B975A1C298401003BA37C /* list_details_over@2x.png */; }; + 636B98C21C298401003BA37C /* menu.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B975B1C298401003BA37C /* menu.png */; }; + 636B98C31C298401003BA37C /* menu@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B975C1C298401003BA37C /* menu@2x.png */; }; + 636B98C41C298401003BA37C /* micro_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B975D1C298401003BA37C /* micro_default.png */; }; + 636B98C51C298401003BA37C /* micro_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B975E1C298401003BA37C /* micro_default@2x.png */; }; + 636B98C61C298401003BA37C /* micro_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B975F1C298401003BA37C /* micro_disabled.png */; }; + 636B98C71C298401003BA37C /* micro_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97601C298401003BA37C /* micro_disabled@2x.png */; }; + 636B98C81C298401003BA37C /* micro_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97611C298401003BA37C /* micro_selected.png */; }; + 636B98C91C298401003BA37C /* micro_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97621C298401003BA37C /* micro_selected@2x.png */; }; + 636B98CA1C298401003BA37C /* numpad_0_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97631C298401003BA37C /* numpad_0_default.png */; }; + 636B98CB1C298401003BA37C /* numpad_0_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97641C298401003BA37C /* numpad_0_default@2x.png */; }; + 636B98CC1C298401003BA37C /* numpad_0_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97651C298401003BA37C /* numpad_0_over.png */; }; + 636B98CD1C298401003BA37C /* numpad_0_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97661C298401003BA37C /* numpad_0_over@2x.png */; }; + 636B98CE1C298401003BA37C /* numpad_1_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97671C298401003BA37C /* numpad_1_default.png */; }; + 636B98CF1C298401003BA37C /* numpad_1_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97681C298401003BA37C /* numpad_1_default@2x.png */; }; + 636B98D01C298401003BA37C /* numpad_1_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97691C298401003BA37C /* numpad_1_over.png */; }; + 636B98D11C298401003BA37C /* numpad_1_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B976A1C298401003BA37C /* numpad_1_over@2x.png */; }; + 636B98D21C298401003BA37C /* numpad_2_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B976B1C298401003BA37C /* numpad_2_default.png */; }; + 636B98D31C298401003BA37C /* numpad_2_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B976C1C298401003BA37C /* numpad_2_default@2x.png */; }; + 636B98D41C298401003BA37C /* numpad_2_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B976D1C298401003BA37C /* numpad_2_over.png */; }; + 636B98D51C298401003BA37C /* numpad_2_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B976E1C298401003BA37C /* numpad_2_over@2x.png */; }; + 636B98D61C298401003BA37C /* numpad_3_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B976F1C298401003BA37C /* numpad_3_default.png */; }; + 636B98D71C298401003BA37C /* numpad_3_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97701C298401003BA37C /* numpad_3_default@2x.png */; }; + 636B98D81C298401003BA37C /* numpad_3_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97711C298401003BA37C /* numpad_3_over.png */; }; + 636B98D91C298401003BA37C /* numpad_3_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97721C298401003BA37C /* numpad_3_over@2x.png */; }; + 636B98DA1C298401003BA37C /* numpad_4_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97731C298401003BA37C /* numpad_4_default.png */; }; + 636B98DB1C298401003BA37C /* numpad_4_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97741C298401003BA37C /* numpad_4_default@2x.png */; }; + 636B98DC1C298401003BA37C /* numpad_4_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97751C298401003BA37C /* numpad_4_over.png */; }; + 636B98DD1C298401003BA37C /* numpad_4_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97761C298401003BA37C /* numpad_4_over@2x.png */; }; + 636B98DE1C298401003BA37C /* numpad_5_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97771C298401003BA37C /* numpad_5_default.png */; }; + 636B98DF1C298401003BA37C /* numpad_5_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97781C298401003BA37C /* numpad_5_default@2x.png */; }; + 636B98E01C298401003BA37C /* numpad_5_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97791C298401003BA37C /* numpad_5_over.png */; }; + 636B98E11C298401003BA37C /* numpad_5_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B977A1C298401003BA37C /* numpad_5_over@2x.png */; }; + 636B98E21C298401003BA37C /* numpad_6_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B977B1C298401003BA37C /* numpad_6_default.png */; }; + 636B98E31C298401003BA37C /* numpad_6_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B977C1C298401003BA37C /* numpad_6_default@2x.png */; }; + 636B98E41C298401003BA37C /* numpad_6_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B977D1C298401003BA37C /* numpad_6_over.png */; }; + 636B98E51C298401003BA37C /* numpad_6_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B977E1C298401003BA37C /* numpad_6_over@2x.png */; }; + 636B98E61C298401003BA37C /* numpad_7_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B977F1C298401003BA37C /* numpad_7_default.png */; }; + 636B98E71C298401003BA37C /* numpad_7_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97801C298401003BA37C /* numpad_7_default@2x.png */; }; + 636B98E81C298401003BA37C /* numpad_7_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97811C298401003BA37C /* numpad_7_over.png */; }; + 636B98E91C298401003BA37C /* numpad_7_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97821C298401003BA37C /* numpad_7_over@2x.png */; }; + 636B98EA1C298401003BA37C /* numpad_8_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97831C298401003BA37C /* numpad_8_default.png */; }; + 636B98EB1C298401003BA37C /* numpad_8_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97841C298401003BA37C /* numpad_8_default@2x.png */; }; + 636B98EC1C298401003BA37C /* numpad_8_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97851C298401003BA37C /* numpad_8_over.png */; }; + 636B98ED1C298401003BA37C /* numpad_8_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97861C298401003BA37C /* numpad_8_over@2x.png */; }; + 636B98EE1C298401003BA37C /* numpad_9_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97871C298401003BA37C /* numpad_9_default.png */; }; + 636B98EF1C298401003BA37C /* numpad_9_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97881C298401003BA37C /* numpad_9_default@2x.png */; }; + 636B98F01C298401003BA37C /* numpad_9_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97891C298401003BA37C /* numpad_9_over.png */; }; + 636B98F11C298401003BA37C /* numpad_9_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B978A1C298401003BA37C /* numpad_9_over@2x.png */; }; + 636B98F21C298401003BA37C /* numpad_hash_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B978B1C298401003BA37C /* numpad_hash_default.png */; }; + 636B98F31C298401003BA37C /* numpad_hash_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B978C1C298401003BA37C /* numpad_hash_default@2x.png */; }; + 636B98F41C298401003BA37C /* numpad_hash_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B978D1C298401003BA37C /* numpad_hash_over.png */; }; + 636B98F51C298401003BA37C /* numpad_hash_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B978E1C298401003BA37C /* numpad_hash_over@2x.png */; }; + 636B98F61C298401003BA37C /* numpad_over_background.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B978F1C298401003BA37C /* numpad_over_background.png */; }; + 636B98F71C298401003BA37C /* numpad_star_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97901C298401003BA37C /* numpad_star_default.png */; }; + 636B98F81C298401003BA37C /* numpad_star_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97911C298401003BA37C /* numpad_star_default@2x.png */; }; + 636B98F91C298401003BA37C /* numpad_star_over.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97921C298401003BA37C /* numpad_star_over.png */; }; + 636B98FA1C298401003BA37C /* numpad_star_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97931C298401003BA37C /* numpad_star_over@2x.png */; }; + 636B98FB1C298401003BA37C /* options_add_call_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97941C298401003BA37C /* options_add_call_default.png */; }; + 636B98FC1C298401003BA37C /* options_add_call_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97951C298401003BA37C /* options_add_call_default@2x.png */; }; + 636B98FD1C298401003BA37C /* options_add_call_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97961C298401003BA37C /* options_add_call_disabled.png */; }; + 636B98FE1C298401003BA37C /* options_add_call_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97971C298401003BA37C /* options_add_call_disabled@2x.png */; }; + 636B98FF1C298401003BA37C /* options_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97981C298401003BA37C /* options_default.png */; }; + 636B99001C298401003BA37C /* options_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97991C298401003BA37C /* options_default@2x.png */; }; + 636B99011C298401003BA37C /* options_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B979A1C298401003BA37C /* options_disabled.png */; }; + 636B99021C298401003BA37C /* options_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B979B1C298401003BA37C /* options_disabled@2x.png */; }; + 636B99031C298401003BA37C /* options_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B979C1C298401003BA37C /* options_selected.png */; }; + 636B99041C298401003BA37C /* options_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B979D1C298401003BA37C /* options_selected@2x.png */; }; + 636B99051C298401003BA37C /* options_start_conference_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B979E1C298401003BA37C /* options_start_conference_default.png */; }; + 636B99061C298401003BA37C /* options_start_conference_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B979F1C298401003BA37C /* options_start_conference_default@2x.png */; }; + 636B99071C298401003BA37C /* options_start_conference_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97A01C298401003BA37C /* options_start_conference_disabled.png */; }; + 636B99081C298401003BA37C /* options_start_conference_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97A11C298401003BA37C /* options_start_conference_disabled@2x.png */; }; + 636B99091C298401003BA37C /* options_transfer_call_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97A21C298401003BA37C /* options_transfer_call_default.png */; }; + 636B990A1C298401003BA37C /* options_transfer_call_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97A31C298401003BA37C /* options_transfer_call_default@2x.png */; }; + 636B990B1C298401003BA37C /* options_transfer_call_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97A41C298401003BA37C /* options_transfer_call_disabled.png */; }; + 636B990C1C298401003BA37C /* options_transfer_call_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97A51C298401003BA37C /* options_transfer_call_disabled@2x.png */; }; + 636B990D1C298401003BA37C /* pause_big_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97A61C298401003BA37C /* pause_big_default.png */; }; + 636B990E1C298401003BA37C /* pause_big_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97A71C298401003BA37C /* pause_big_default@2x.png */; }; + 636B990F1C298401003BA37C /* pause_big_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97A81C298401003BA37C /* pause_big_disabled.png */; }; + 636B99101C298401003BA37C /* pause_big_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97A91C298401003BA37C /* pause_big_disabled@2x.png */; }; + 636B99111C298401003BA37C /* pause_big_over_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97AA1C298401003BA37C /* pause_big_over_selected.png */; }; + 636B99121C298401003BA37C /* pause_big_over_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97AB1C298401003BA37C /* pause_big_over_selected@2x.png */; }; + 636B99131C298401003BA37C /* pause_small_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97AC1C298401003BA37C /* pause_small_default.png */; }; + 636B99141C298401003BA37C /* pause_small_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97AD1C298401003BA37C /* pause_small_default@2x.png */; }; + 636B99151C298401003BA37C /* pause_small_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97AE1C298401003BA37C /* pause_small_disabled.png */; }; + 636B99161C298401003BA37C /* pause_small_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97AF1C298401003BA37C /* pause_small_disabled@2x.png */; }; + 636B99171C298401003BA37C /* pause_small_over_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97B01C298401003BA37C /* pause_small_over_selected.png */; }; + 636B99181C298401003BA37C /* pause_small_over_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97B11C298401003BA37C /* pause_small_over_selected@2x.png */; }; + 636B99191C298401003BA37C /* route_bluetooth_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97B21C298401003BA37C /* route_bluetooth_default.png */; }; + 636B991A1C298401003BA37C /* route_bluetooth_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97B31C298401003BA37C /* route_bluetooth_default@2x.png */; }; + 636B991B1C298401003BA37C /* route_bluetooth_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97B41C298401003BA37C /* route_bluetooth_disabled.png */; }; + 636B991C1C298401003BA37C /* route_bluetooth_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97B51C298401003BA37C /* route_bluetooth_disabled@2x.png */; }; + 636B991D1C298401003BA37C /* route_bluetooth_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97B61C298401003BA37C /* route_bluetooth_selected.png */; }; + 636B991E1C298401003BA37C /* route_bluetooth_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97B71C298401003BA37C /* route_bluetooth_selected@2x.png */; }; + 636B991F1C298401003BA37C /* route_earpiece_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97B81C298401003BA37C /* route_earpiece_default.png */; }; + 636B99201C298401003BA37C /* route_earpiece_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97B91C298401003BA37C /* route_earpiece_default@2x.png */; }; + 636B99211C298401003BA37C /* route_earpiece_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97BA1C298401003BA37C /* route_earpiece_disabled.png */; }; + 636B99221C298401003BA37C /* route_earpiece_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97BB1C298401003BA37C /* route_earpiece_disabled@2x.png */; }; + 636B99231C298401003BA37C /* route_earpiece_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97BC1C298401003BA37C /* route_earpiece_selected.png */; }; + 636B99241C298401003BA37C /* route_earpiece_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97BD1C298401003BA37C /* route_earpiece_selected@2x.png */; }; + 636B99251C298401003BA37C /* route_speaker_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97BE1C298401003BA37C /* route_speaker_default.png */; }; + 636B99261C298401003BA37C /* route_speaker_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97BF1C298401003BA37C /* route_speaker_default@2x.png */; }; + 636B99271C298401003BA37C /* route_speaker_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97C01C298401003BA37C /* route_speaker_disabled.png */; }; + 636B99281C298401003BA37C /* route_speaker_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97C11C298401003BA37C /* route_speaker_disabled@2x.png */; }; + 636B99291C298401003BA37C /* route_speaker_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97C21C298401003BA37C /* route_speaker_selected.png */; }; + 636B992A1C298401003BA37C /* route_speaker_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97C31C298401003BA37C /* route_speaker_selected@2x.png */; }; + 636B992B1C298401003BA37C /* routes_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97C41C298401003BA37C /* routes_default.png */; }; + 636B992C1C298401003BA37C /* routes_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97C51C298401003BA37C /* routes_default@2x.png */; }; + 636B992D1C298401003BA37C /* routes_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97C61C298401003BA37C /* routes_disabled.png */; }; + 636B992E1C298401003BA37C /* routes_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97C71C298401003BA37C /* routes_disabled@2x.png */; }; + 636B992F1C298401003BA37C /* routes_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97C81C298401003BA37C /* routes_selected.png */; }; + 636B99301C298401003BA37C /* routes_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97C91C298401003BA37C /* routes_selected@2x.png */; }; + 636B99311C298401003BA37C /* security_ko.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97CA1C298401003BA37C /* security_ko.png */; }; + 636B99321C298401003BA37C /* security_ko@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97CB1C298401003BA37C /* security_ko@2x.png */; }; + 636B99331C298401003BA37C /* security_ok.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97CC1C298401003BA37C /* security_ok.png */; }; + 636B99341C298401003BA37C /* security_ok@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97CD1C298401003BA37C /* security_ok@2x.png */; }; + 636B99351C298401003BA37C /* security_pending.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97CE1C298401003BA37C /* security_pending.png */; }; + 636B99361C298401003BA37C /* security_pending@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97CF1C298401003BA37C /* security_pending@2x.png */; }; + 636B99371C298401003BA37C /* select_all_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97D01C298401003BA37C /* select_all_default.png */; }; + 636B99381C298401003BA37C /* select_all_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97D11C298401003BA37C /* select_all_default@2x.png */; }; + 636B99391C298401003BA37C /* select_all_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97D21C298401003BA37C /* select_all_disabled.png */; }; + 636B993A1C298401003BA37C /* select_all_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97D31C298401003BA37C /* select_all_disabled@2x.png */; }; + 636B993B1C298401003BA37C /* speaker_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97D41C298401003BA37C /* speaker_default.png */; }; + 636B993C1C298401003BA37C /* speaker_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97D51C298401003BA37C /* speaker_default@2x.png */; }; + 636B993D1C298401003BA37C /* speaker_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97D61C298401003BA37C /* speaker_disabled.png */; }; + 636B993E1C298401003BA37C /* speaker_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97D71C298401003BA37C /* speaker_disabled@2x.png */; }; + 636B993F1C298401003BA37C /* speaker_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97D81C298401003BA37C /* speaker_selected.png */; }; + 636B99401C298401003BA37C /* speaker_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97D91C298401003BA37C /* speaker_selected@2x.png */; }; + 636B99411C298401003BA37C /* splashscreen.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97DA1C298401003BA37C /* splashscreen.png */; }; + 636B99421C298401003BA37C /* splashscreen@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97DB1C298401003BA37C /* splashscreen@2x.png */; }; + 636B99431C298401003BA37C /* valid_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97DC1C298401003BA37C /* valid_default.png */; }; + 636B99441C298401003BA37C /* valid_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97DD1C298401003BA37C /* valid_default@2x.png */; }; + 636B99451C298401003BA37C /* valid_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97DE1C298401003BA37C /* valid_disabled.png */; }; + 636B99461C298401003BA37C /* valid_disabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97DF1C298401003BA37C /* valid_disabled@2x.png */; }; + 636B99471C298401003BA37C /* voicemail.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97E01C298401003BA37C /* voicemail.png */; }; + 636B99481C298401003BA37C /* voicemail@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97E11C298401003BA37C /* voicemail@2x.png */; }; + 636B99491C298401003BA37C /* waiting_time.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97E21C298401003BA37C /* waiting_time.png */; }; + 636B994A1C298401003BA37C /* waiting_time@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 636B97E31C298401003BA37C /* waiting_time@2x.png */; }; + 636BC9971B5F921B00C754CE /* UIIconButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 636BC9961B5F921B00C754CE /* UIIconButton.m */; }; + 63701DDF1BA32039006A9AE3 /* UIConfirmationDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = 63701DDE1BA32039006A9AE3 /* UIConfirmationDialog.m */; }; + 637157A11B283FE200C91677 /* FileTransferDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 637157A01B283FE200C91677 /* FileTransferDelegate.m */; }; + 6377AC801BDE4069007F7625 /* UIBackToCallButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 6377AC7F1BDE4069007F7625 /* UIBackToCallButton.m */; }; + 6381DA7D1C1AD5EA00DF3BBD /* UIBouncingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6381DA7C1C1AD5EA00DF3BBD /* UIBouncingView.m */; }; + 638F1A621C2021B2004B8E02 /* DialerView~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 638F1A601C2021B2004B8E02 /* DialerView~ipad.xib */; }; + 638F1A881C2167C2004B8E02 /* CallView~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 638F1A861C2167C2004B8E02 /* CallView~ipad.xib */; }; + 638F1A911C21993D004B8E02 /* UICompositeView~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 638F1A8F1C21993D004B8E02 /* UICompositeView~ipad.xib */; }; + 639CEAFD1A1DF4D9004DE38F /* StatusBarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEAFF1A1DF4D9004DE38F /* StatusBarView.xib */; }; 639CEB001A1DF4E4004DE38F /* UIHistoryCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEB021A1DF4E4004DE38F /* UIHistoryCell.xib */; }; - 639CEB031A1DF4EB004DE38F /* UICompositeViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEB051A1DF4EB004DE38F /* UICompositeViewController.xib */; }; - 639CEB061A1DF4F1004DE38F /* UIChatRoomCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEB081A1DF4F1004DE38F /* UIChatRoomCell.xib */; }; + 639CEB031A1DF4EB004DE38F /* UICompositeView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEB051A1DF4EB004DE38F /* UICompositeView.xib */; }; 639CEB091A1DF4FA004DE38F /* UIChatCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEB0B1A1DF4FA004DE38F /* UIChatCell.xib */; }; + 639E9C801C0DB13D00019A75 /* UICheckBoxTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 639E9C7F1C0DB13D00019A75 /* UICheckBoxTableView.m */; }; + 639E9C931C0DB7BE00019A75 /* FirstLoginView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639E9C951C0DB7BE00019A75 /* FirstLoginView.xib */; }; + 639E9C9A1C0DB7D300019A75 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639E9C9C1C0DB7D300019A75 /* LaunchScreen.xib */; }; + 639E9C9D1C0DB7DF00019A75 /* UICallPausedCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639E9C9F1C0DB7DF00019A75 /* UICallPausedCell.xib */; }; + 639E9CA01C0DB7E500019A75 /* UIChatBubblePhotoCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639E9CA21C0DB7E500019A75 /* UIChatBubblePhotoCell.xib */; }; + 639E9CA31C0DB7EA00019A75 /* UIChatBubbleTextCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639E9CA51C0DB7EA00019A75 /* UIChatBubbleTextCell.xib */; }; + 639E9CA61C0DB7F200019A75 /* UIChatCreateCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639E9CA81C0DB7F200019A75 /* UIChatCreateCell.xib */; }; + 639E9CA91C0DB7FB00019A75 /* UIConfirmationDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639E9CAB1C0DB7FB00019A75 /* UIConfirmationDialog.xib */; }; + 639E9CAC1C0DB80300019A75 /* UIContactDetailsCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639E9CAE1C0DB80300019A75 /* UIContactDetailsCell.xib */; }; + 639E9CB01C0DB83000019A75 /* SideMenuView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639E9CB21C0DB83000019A75 /* SideMenuView.xib */; }; + 639E9CB51C0DB88200019A75 /* PhoneMainView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639E9CB31C0DB88200019A75 /* PhoneMainView.xib */; }; + 63AADBE81B6A0FF200AA16FD /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 63AADBC41B6A0FF200AA16FD /* Localizable.strings */; }; + 63AADBE91B6A0FF200AA16FD /* hold.wav in Resources */ = {isa = PBXBuildFile; fileRef = 63AADBC91B6A0FF200AA16FD /* hold.wav */; }; + 63AADBEA1B6A0FF200AA16FD /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 63AADBCA1B6A0FF200AA16FD /* Images.xcassets */; }; + 63AADBF31B6A0FF200AA16FD /* licenses.html in Resources */ = {isa = PBXBuildFile; fileRef = 63AADBD51B6A0FF200AA16FD /* licenses.html */; }; + 63AADBF51B6A0FF200AA16FD /* linphonerc in Resources */ = {isa = PBXBuildFile; fileRef = 63AADBD71B6A0FF200AA16FD /* linphonerc */; }; + 63AADBF61B6A0FF200AA16FD /* linphonerc-factory in Resources */ = {isa = PBXBuildFile; fileRef = 63AADBD81B6A0FF200AA16FD /* linphonerc-factory */; }; + 63AADBF81B6A0FF200AA16FD /* linphonerc~ipad in Resources */ = {isa = PBXBuildFile; fileRef = 63AADBDA1B6A0FF200AA16FD /* linphonerc~ipad */; }; + 63AADBFF1B6A0FF200AA16FD /* assistant_external_sip.rc in Resources */ = {isa = PBXBuildFile; fileRef = 63AADBE31B6A0FF200AA16FD /* assistant_external_sip.rc */; }; + 63AADC001B6A0FF200AA16FD /* assistant_linphone_create.rc in Resources */ = {isa = PBXBuildFile; fileRef = 63AADBE41B6A0FF200AA16FD /* assistant_linphone_create.rc */; }; + 63AADC011B6A0FF200AA16FD /* assistant_linphone_existing.rc in Resources */ = {isa = PBXBuildFile; fileRef = 63AADBE51B6A0FF200AA16FD /* assistant_linphone_existing.rc */; }; + 63AADC021B6A0FF200AA16FD /* assistant_remote.rc in Resources */ = {isa = PBXBuildFile; fileRef = 63AADBE61B6A0FF200AA16FD /* assistant_remote.rc */; }; + 63B81A0C1B57DA33009604A6 /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = 63B81A031B57DA33009604A6 /* LICENSE.txt */; }; + 63B81A0D1B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B81A051B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.m */; }; + 63B81A0E1B57DA33009604A6 /* TPKeyboardAvoidingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B81A071B57DA33009604A6 /* TPKeyboardAvoidingScrollView.m */; }; + 63B81A0F1B57DA33009604A6 /* TPKeyboardAvoidingTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B81A091B57DA33009604A6 /* TPKeyboardAvoidingTableView.m */; }; + 63B81A101B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B81A0B1B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.m */; }; + 63B8D68C1BCBE65600C12B09 /* ChatConversationCreateView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63B8D68E1BCBE65600C12B09 /* ChatConversationCreateView.xib */; }; + 63B8D6A21BCBF43100C12B09 /* UIChatCreateCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 63B8D6A01BCBF43100C12B09 /* UIChatCreateCell.m */; }; + 63BC49E21BA2CDFC004EC273 /* UICallPausedCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 63BC49E11BA2CDFC004EC273 /* UICallPausedCell.m */; }; + 63C441C31BBC23ED0053DC5E /* UIAssistantTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 63C441C21BBC23ED0053DC5E /* UIAssistantTextField.m */; }; 63CD4B4F1A5AAC8C00B84282 /* DTAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63CD4B4E1A5AAC8C00B84282 /* DTAlertView.m */; }; + 63CDC45D1C3BDE370085F529 /* hold.caf in Resources */ = {isa = PBXBuildFile; fileRef = 63CDC4521C3BDE370085F529 /* hold.caf */; }; + 63CDC45E1C3BDE370085F529 /* msg.caf in Resources */ = {isa = PBXBuildFile; fileRef = 63CDC4531C3BDE370085F529 /* msg.caf */; }; + 63CDC45F1C3BDE370085F529 /* ringback.wav in Resources */ = {isa = PBXBuildFile; fileRef = 63CDC4541C3BDE370085F529 /* ringback.wav */; }; + 63CDC4601C3BDE370085F529 /* four_hands_together.caf in Resources */ = {isa = PBXBuildFile; fileRef = 63CDC4561C3BDE370085F529 /* four_hands_together.caf */; }; + 63CDC4611C3BDE370085F529 /* house_keeping.caf in Resources */ = {isa = PBXBuildFile; fileRef = 63CDC4571C3BDE370085F529 /* house_keeping.caf */; }; + 63CDC4621C3BDE370085F529 /* it_s_a_game.caf in Resources */ = {isa = PBXBuildFile; fileRef = 63CDC4581C3BDE370085F529 /* it_s_a_game.caf */; }; + 63CDC4631C3BDE370085F529 /* leaving_a_dream.caf in Resources */ = {isa = PBXBuildFile; fileRef = 63CDC4591C3BDE370085F529 /* leaving_a_dream.caf */; }; + 63CDC4641C3BDE370085F529 /* notes_of_the_optimistic.caf in Resources */ = {isa = PBXBuildFile; fileRef = 63CDC45A1C3BDE370085F529 /* notes_of_the_optimistic.caf */; }; + 63CDC4651C3BDE370085F529 /* soft_as_snow.caf in Resources */ = {isa = PBXBuildFile; fileRef = 63CDC45B1C3BDE370085F529 /* soft_as_snow.caf */; }; + 63CDC4661C3BDE370085F529 /* shortring.caf in Resources */ = {isa = PBXBuildFile; fileRef = 63CDC45C1C3BDE370085F529 /* shortring.caf */; }; + 63CFEDE81B9EDD74007EA5BD /* libantlr3c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 223CA7E416D9255800EF1BEC /* libantlr3c.a */; }; + 63CFEDE91B9EDD74007EA5BD /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22276E8013C73D3100210156 /* libavcodec.a */; }; + 63CFEDEA1B9EDD74007EA5BD /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22276E8113C73D3100210156 /* libavutil.a */; }; + 63CFEDEB1B9EDD74007EA5BD /* libbcg729.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63CFEDE41B9EDD36007EA5BD /* libbcg729.a */; }; + 63CFEDEC1B9EDD74007EA5BD /* libbellesip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 223CA7E516D9255800EF1BEC /* libbellesip.a */; }; + 63CFEDED1B9EDD74007EA5BD /* libbzrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 045B5CB218D72E9A0088350C /* libbzrtp.a */; }; + 63CFEDEF1B9EDD74007EA5BD /* libgsm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD2910765B400068D98F /* libgsm.a */; }; + 63CFEDF21B9EDD74007EA5BD /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2211DB911475562600DEE054 /* liblinphone.a */; }; + 63CFEDF41B9EDD74007EA5BD /* libmediastreamer_base.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22405EE916006F0700B92522 /* libmediastreamer_base.a */; }; + 63CFEDF51B9EDD74007EA5BD /* libmediastreamer_voip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22405EEA16006F0700B92522 /* libmediastreamer_voip.a */; }; + 63CFEDF61B9EDD74007EA5BD /* libopencore-amrnb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226F2ED41344B0EF00F6EF27 /* libopencore-amrnb.a */; }; + 63CFEDF71B9EDD74007EA5BD /* libopencore-amrwb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226F2ED31344B0EF00F6EF27 /* libopencore-amrwb.a */; }; + 63CFEDF81B9EDD74007EA5BD /* libopenh264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22509041196BD902007863F6 /* libopenh264.a */; }; + 63CFEDF91B9EDD74007EA5BD /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22AF73C11754C0D000BE8398 /* libopus.a */; }; + 63CFEDFA1B9EDD74007EA5BD /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD2C10765B400068D98F /* libortp.a */; }; + 63CFEDFB1B9EDD74007EA5BD /* libpolarssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 57B0E35F173C010400A476B8 /* libpolarssl.a */; }; + 63CFEDFD1B9EDD74007EA5BD /* libspeex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD2F10765B400068D98F /* libspeex.a */; }; + 63CFEDFE1B9EDD74007EA5BD /* libspeexdsp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD3010765B400068D98F /* libspeexdsp.a */; }; + 63CFEDFF1B9EDD74007EA5BD /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226183AB1472527D0037138E /* libsrtp.a */; }; + 63CFEE011B9EDD74007EA5BD /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22276E8213C73D3100210156 /* libswscale.a */; }; + 63CFEE021B9EDD74007EA5BD /* libtunnel.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D30BF33216A427BC00AF0026 /* libtunnel.a */; }; + 63CFEE041B9EDD74007EA5BD /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7066FC0B13E830E400EFC6DC /* libvpx.a */; }; + 63CFEE051B9EDD74007EA5BD /* libx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22AA8AFB13D7125500B30535 /* libx264.a */; }; + 63CFEE061B9EDD88007EA5BD /* libmsamr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226F2ED51344B0EF00F6EF27 /* libmsamr.a */; }; + 63CFEE071B9EDD88007EA5BD /* libmsbcg729.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226CDADE14E2D0B800513B67 /* libmsbcg729.a */; }; + 63CFEE091B9EDD88007EA5BD /* libmsopenh264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1560821E18EEF26100765332 /* libmsopenh264.a */; }; + 63CFEE0A1B9EDD88007EA5BD /* libmssilk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226183AF147259670037138E /* libmssilk.a */; }; + 63CFEE0B1B9EDD88007EA5BD /* libmswebrtc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63EA4C941B50189D00922857 /* libmswebrtc.a */; }; + 63CFEE0C1B9EDD88007EA5BD /* libmsx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22AA8AFC13D7125500B30535 /* libmsx264.a */; }; + 63CFEE131B9EDF65007EA5BD /* libvo-amrwbenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63CFEDE31B9EDD36007EA5BD /* libvo-amrwbenc.a */; }; + 63E59A3F1ADE70D900646FB3 /* InAppProductsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E59A3E1ADE70D900646FB3 /* InAppProductsManager.m */; }; + 63EEE3FF1BBA9AC00087D3AF /* libcunit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A9B7E18C0D9C900C4D7FE /* libcunit.a */; }; + 63EEE4001BBA9AC00087D3AF /* liblinphonetester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F0BB8C0F193623F200974404 /* liblinphonetester.a */; }; + 63EEE4041BBA9B010087D3AF /* libbellesip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 223CA7E516D9255800EF1BEC /* libbellesip.a */; }; + 63EEE4051BBA9B010087D3AF /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2211DB911475562600DEE054 /* liblinphone.a */; }; + 63EEE4061BBA9B010087D3AF /* libmediastreamer_base.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22405EE916006F0700B92522 /* libmediastreamer_base.a */; }; + 63EEE4071BBA9B010087D3AF /* libmediastreamer_voip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22405EEA16006F0700B92522 /* libmediastreamer_voip.a */; }; + 63EEE4081BBA9B010087D3AF /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD2C10765B400068D98F /* libortp.a */; }; + 63F1DF441BCE618E00EDED90 /* UIAddressTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F1DF431BCE618E00EDED90 /* UIAddressTextField.m */; }; + 63F1DF4B1BCE983200EDED90 /* CallConferenceTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F1DF4A1BCE983200EDED90 /* CallConferenceTableView.m */; }; + 63F1DF4F1BCE985F00EDED90 /* UICallConferenceCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F1DF4D1BCE985F00EDED90 /* UICallConferenceCell.m */; }; + 63F1DF511BCE986A00EDED90 /* UICallConferenceCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63F1DF531BCE986A00EDED90 /* UICallConferenceCell.xib */; }; 63FB30351A680E73008CA393 /* UIRoundedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63FB30341A680E73008CA393 /* UIRoundedImageView.m */; }; - 70571E1A13FABCB000CDD3C2 /* rootca.pem in Resources */ = {isa = PBXBuildFile; fileRef = 70571E1913FABCB000CDD3C2 /* rootca.pem */; }; - 7066FC0C13E830E400EFC6DC /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7066FC0B13E830E400EFC6DC /* libvpx.a */; }; 70E542F313E147E3002BA2C0 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542F213E147E3002BA2C0 /* OpenGLES.framework */; }; 70E542F513E147EB002BA2C0 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542F413E147EB002BA2C0 /* QuartzCore.framework */; }; - C90FAA7915AF54E6002091CB /* HistoryDetailsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C90FAA7715AF54E6002091CB /* HistoryDetailsViewController.m */; }; - C9C8254315AE204D00D493FA /* options_add_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = C9C8253F15AE204D00D493FA /* options_add_disabled.png */; }; - C9C8254515AE204D00D493FA /* options_transfer_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = C9C8254015AE204D00D493FA /* options_transfer_disabled.png */; }; - C9C8254715AE204D00D493FA /* transfer_call_default.png in Resources */ = {isa = PBXBuildFile; fileRef = C9C8254115AE204D00D493FA /* transfer_call_default.png */; }; - C9C8254915AE204D00D493FA /* transfer_call_over.png in Resources */ = {isa = PBXBuildFile; fileRef = C9C8254215AE204D00D493FA /* transfer_call_over.png */; }; - C9C8254C15AE207B00D493FA /* options_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = C9C8254B15AE207B00D493FA /* options_selected.png */; }; - C9C8254F15AE256100D493FA /* transfer_call_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = C9C8254E15AE256100D493FA /* transfer_call_disabled.png */; }; - D3012CC41610467D007CD926 /* linphone_logo.png in Resources */ = {isa = PBXBuildFile; fileRef = D3012CC31610467D007CD926 /* linphone_logo.png */; }; - D3012CC616105ECF007CD926 /* bubble.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8D91609A86700D3DA1A /* bubble.png */; }; - D30562151671DC4900C97967 /* libNinePatch.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3B90E1915C2CB5800F64F8C /* libNinePatch.a */; }; + C90FAA7915AF54E6002091CB /* HistoryDetailsView.m in Sources */ = {isa = PBXBuildFile; fileRef = C90FAA7715AF54E6002091CB /* HistoryDetailsView.m */; }; D30562161671DC4900C97967 /* libXMLRPC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3554ED115CA79AA00478841 /* libXMLRPC.a */; }; D306459E1611EC2A00BB571E /* UILoadingImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = D306459D1611EC2900BB571E /* UILoadingImageView.m */; }; - D30BBD1815D402A7000F93DD /* contact_ok_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D30BBD1715D402A7000F93DD /* contact_ok_disabled.png */; }; - D3119E7215B6A4710005D4A4 /* contacts_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3119E7015B6A4710005D4A4 /* contacts_back_default.png */; }; - D3119E7415B6A4710005D4A4 /* contacts_back_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3119E7115B6A4710005D4A4 /* contacts_back_over.png */; }; - D3128FE115AABC7E00A2147A /* ContactDetailsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3128FDF15AABC7E00A2147A /* ContactDetailsViewController.m */; }; - D3128FEF15AABE4E00A2147A /* contact_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3128FE715AABE4E00A2147A /* contact_back_default.png */; }; - D3128FF115AABE4E00A2147A /* contact_back_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3128FE815AABE4E00A2147A /* contact_back_over.png */; }; - D3128FF315AABE4E00A2147A /* contact_edit_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3128FE915AABE4E00A2147A /* contact_edit_default.png */; }; - D3128FF515AABE4E00A2147A /* contact_edit_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3128FEA15AABE4E00A2147A /* contact_edit_over.png */; }; - D3157A8A15B4466F00DD8C4C /* history_details_add_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3157A8815B4466F00DD8C4C /* history_details_add_default.png */; }; - D3157A8C15B4466F00DD8C4C /* history_details_add_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3157A8915B4466F00DD8C4C /* history_details_add_over.png */; }; - D3157A9015B446CB00DD8C4C /* history_details_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3157A8E15B446CB00DD8C4C /* history_details_back_default.png */; }; - D3157A9215B446CB00DD8C4C /* history_details_back_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3157A8F15B446CB00DD8C4C /* history_details_back_over.png */; }; - D3196D3415A321E3007FEEBA /* options_add_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3196D3015A321E2007FEEBA /* options_add_default.png */; }; - D3196D3615A321E3007FEEBA /* options_add_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3196D3115A321E2007FEEBA /* options_add_over.png */; }; - D3196D3815A321E3007FEEBA /* options_transfer_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3196D3215A321E3007FEEBA /* options_transfer_default.png */; }; - D3196D3A15A321E3007FEEBA /* options_transfer_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3196D3315A321E3007FEEBA /* options_transfer_over.png */; }; + D3128FE115AABC7E00A2147A /* ContactDetailsView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3128FDF15AABC7E00A2147A /* ContactDetailsView.m */; }; D3196D3E15A32BD8007FEEBA /* UITransferButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D3196D3D15A32BD8007FEEBA /* UITransferButton.m */; }; - D31AAF5E159B3919002C6B02 /* InCallTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D31AAF5D159B3919002C6B02 /* InCallTableViewController.m */; }; - D31AAF63159B5B6F002C6B02 /* conference_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D31AAF61159B5B6E002C6B02 /* conference_default.png */; }; - D31AAF65159B5B6F002C6B02 /* conference_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D31AAF62159B5B6E002C6B02 /* conference_over.png */; }; - D31AAF6E159B65E1002C6B02 /* call_state_ringing_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D31AAF6D159B65E1002C6B02 /* call_state_ringing_default.png */; }; - D31B4B21159876C0002E6C72 /* UICompositeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D31B4B1F159876C0002E6C72 /* UICompositeViewController.m */; }; - D31B4B281598A390002E6C72 /* avatar_unknown.png in Resources */ = {isa = PBXBuildFile; fileRef = D31B4B261598A390002E6C72 /* avatar_unknown.png */; }; - D31B4B2A1598A390002E6C72 /* avatar_unknown_small.png in Resources */ = {isa = PBXBuildFile; fileRef = D31B4B271598A390002E6C72 /* avatar_unknown_small.png */; }; - D31C9C90158A1C1000756B45 /* call_status_incoming.png in Resources */ = {isa = PBXBuildFile; fileRef = D31C9C8D158A1C1000756B45 /* call_status_incoming.png */; }; - D31C9C92158A1C1000756B45 /* call_status_missed.png in Resources */ = {isa = PBXBuildFile; fileRef = D31C9C8E158A1C1000756B45 /* call_status_missed.png */; }; - D31C9C94158A1C1000756B45 /* call_status_outgoing.png in Resources */ = {isa = PBXBuildFile; fileRef = D31C9C8F158A1C1000756B45 /* call_status_outgoing.png */; }; + D31AAF5E159B3919002C6B02 /* CallPausedTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = D31AAF5D159B3919002C6B02 /* CallPausedTableView.m */; }; + D31B4B21159876C0002E6C72 /* UICompositeView.m in Sources */ = {isa = PBXBuildFile; fileRef = D31B4B1F159876C0002E6C72 /* UICompositeView.m */; }; D31C9C98158A1CDF00756B45 /* UIHistoryCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D31C9C97158A1CDE00756B45 /* UIHistoryCell.m */; }; - D3211BA6159C3D410098460B /* call_state_outgoing_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3211BA5159C3D410098460B /* call_state_outgoing_default.png */; }; - D3211BB0159C4EF10098460B /* UIConferenceHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = D3211BAE159C4EF00098460B /* UIConferenceHeader.m */; }; - D3211BB9159C8A820098460B /* cell_call_first.png in Resources */ = {isa = PBXBuildFile; fileRef = D3211BB8159C8A820098460B /* cell_call_first.png */; }; - D3211BBE159CBFD60098460B /* back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3211BBB159CBFD60098460B /* back_default.png */; }; - D3211BC0159CBFD70098460B /* back_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D3211BBC159CBFD60098460B /* back_disabled.png */; }; - D3211BC2159CBFD70098460B /* back_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3211BBD159CBFD60098460B /* back_over.png */; }; - D321FF9915E628CB0098B5F4 /* linphonerc~ipad in Resources */ = {isa = PBXBuildFile; fileRef = D321FF9815E628CB0098B5F4 /* linphonerc~ipad */; }; - D32409C3158B49A600C8C119 /* UILongTouchButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D32409C2158B49A600C8C119 /* UILongTouchButton.m */; }; - D32460E6159D9AAD00BA7F3A /* UITransparentView.m in Sources */ = {isa = PBXBuildFile; fileRef = D32460E5159D9AAD00BA7F3A /* UITransparentView.m */; }; D326483815887D5200930C67 /* OrderedDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = D326483715887D5200930C67 /* OrderedDictionary.m */; }; - D326483E1588950F00930C67 /* UICallBar.m in Sources */ = {isa = PBXBuildFile; fileRef = D326483C1588950F00930C67 /* UICallBar.m */; }; D32648441588F6FC00930C67 /* UIToggleButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D32648431588F6FB00930C67 /* UIToggleButton.m */; }; - D32B6E2415A5B2020033019F /* chat_send_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D32B6E2315A5B2020033019F /* chat_send_disabled.png */; }; - D32B6E2915A5BC440033019F /* ChatRoomTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D32B6E2815A5BC430033019F /* ChatRoomTableViewController.m */; }; - D32B6E2F15A5C0AC0033019F /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D32B6E2E15A5C0AC0033019F /* libsqlite3.dylib */; }; + D32B6E2915A5BC440033019F /* ChatConversationTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = D32B6E2815A5BC430033019F /* ChatConversationTableView.m */; }; D32B9DFC15A2F131000B6DEC /* FastAddressBook.m in Sources */ = {isa = PBXBuildFile; fileRef = D32B9DFB15A2F131000B6DEC /* FastAddressBook.m */; }; - D32D5AA715ADE5D9008593F3 /* button_alert_background_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D32D5AA515ADE5D9008593F3 /* button_alert_background_default.png */; }; - D32D5AA915ADE5D9008593F3 /* button_alert_background_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D32D5AA615ADE5D9008593F3 /* button_alert_background_over.png */; }; - D3328646160B5BC300E6435D /* dialer_alt_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3328642160B5BC300E6435D /* dialer_alt_disabled_landscape.png */; }; - D3328648160B5BC300E6435D /* dialer_alt_disabled_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3328643160B5BC300E6435D /* dialer_alt_disabled_landscape~ipad.png */; }; - D332864A160B5BC300E6435D /* dialer_alt_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D3328644160B5BC300E6435D /* dialer_alt_disabled.png */; }; - D332864C160B5BC300E6435D /* dialer_alt_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3328645160B5BC300E6435D /* dialer_alt_disabled~ipad.png */; }; - D33988B415C6DD1600CAF1E4 /* conference_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339888C15C6DD1600CAF1E4 /* conference_default_landscape~ipad.png */; }; - D33988B615C6DD1600CAF1E4 /* conference_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339888D15C6DD1600CAF1E4 /* conference_over_landscape~ipad.png */; }; - D33988B815C6DD1600CAF1E4 /* dialer_alt_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339888E15C6DD1600CAF1E4 /* dialer_alt_default_landscape~ipad.png */; }; - D33988BA15C6DD1600CAF1E4 /* dialer_alt_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339888F15C6DD1600CAF1E4 /* dialer_alt_over_landscape~ipad.png */; }; - D33988BC15C6DD1600CAF1E4 /* hangup_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889015C6DD1600CAF1E4 /* hangup_default_landscape~ipad.png */; }; - D33988BE15C6DD1600CAF1E4 /* hangup_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889115C6DD1600CAF1E4 /* hangup_over_landscape~ipad.png */; }; - D33988C015C6DD1600CAF1E4 /* micro_off_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889215C6DD1600CAF1E4 /* micro_off_default_landscape~ipad.png */; }; - D33988C215C6DD1600CAF1E4 /* micro_off_disabled_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889315C6DD1600CAF1E4 /* micro_off_disabled_landscape~ipad.png */; }; - D33988C415C6DD1600CAF1E4 /* micro_off_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889415C6DD1600CAF1E4 /* micro_off_over_landscape~ipad.png */; }; - D33988C615C6DD1600CAF1E4 /* micro_on_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889515C6DD1600CAF1E4 /* micro_on_default_landscape~ipad.png */; }; - D33988C815C6DD1600CAF1E4 /* micro_on_disabled_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889615C6DD1600CAF1E4 /* micro_on_disabled_landscape~ipad.png */; }; - D33988CA15C6DD1600CAF1E4 /* micro_on_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889715C6DD1600CAF1E4 /* micro_on_over_landscape~ipad.png */; }; - D33988CC15C6DD1600CAF1E4 /* options_add_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889815C6DD1600CAF1E4 /* options_add_default_landscape~ipad.png */; }; - D33988CE15C6DD1600CAF1E4 /* options_add_disabled_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889915C6DD1600CAF1E4 /* options_add_disabled_landscape~ipad.png */; }; - D33988D015C6DD1600CAF1E4 /* options_add_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889A15C6DD1600CAF1E4 /* options_add_over_landscape~ipad.png */; }; - D33988D215C6DD1600CAF1E4 /* options_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889B15C6DD1600CAF1E4 /* options_default_landscape~ipad.png */; }; - D33988D415C6DD1600CAF1E4 /* options_disabled_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889C15C6DD1600CAF1E4 /* options_disabled_landscape~ipad.png */; }; - D33988D615C6DD1600CAF1E4 /* options_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889D15C6DD1600CAF1E4 /* options_over_landscape~ipad.png */; }; - D33988D815C6DD1600CAF1E4 /* options_selected_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889E15C6DD1600CAF1E4 /* options_selected_landscape~ipad.png */; }; - D33988DA15C6DD1600CAF1E4 /* options_transfer_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339889F15C6DD1600CAF1E4 /* options_transfer_default_landscape~ipad.png */; }; - D33988DC15C6DD1600CAF1E4 /* options_transfer_disabled_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988A015C6DD1600CAF1E4 /* options_transfer_disabled_landscape~ipad.png */; }; - D33988DE15C6DD1600CAF1E4 /* options_transfer_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988A115C6DD1600CAF1E4 /* options_transfer_over_landscape~ipad.png */; }; - D33988E015C6DD1600CAF1E4 /* pause_off_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988A215C6DD1600CAF1E4 /* pause_off_default_landscape~ipad.png */; }; - D33988E215C6DD1600CAF1E4 /* pause_off_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988A315C6DD1600CAF1E4 /* pause_off_over_landscape~ipad.png */; }; - D33988E415C6DD1600CAF1E4 /* pause_on_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988A415C6DD1600CAF1E4 /* pause_on_default_landscape~ipad.png */; }; - D33988E615C6DD1600CAF1E4 /* pause_on_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988A515C6DD1600CAF1E4 /* pause_on_over_landscape~ipad.png */; }; - D33988E815C6DD1600CAF1E4 /* speaker_off_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988A615C6DD1600CAF1E4 /* speaker_off_default_landscape~ipad.png */; }; - D33988EA15C6DD1600CAF1E4 /* speaker_off_disabled_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988A715C6DD1600CAF1E4 /* speaker_off_disabled_landscape~ipad.png */; }; - D33988EC15C6DD1600CAF1E4 /* speaker_off_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988A815C6DD1600CAF1E4 /* speaker_off_over_landscape~ipad.png */; }; - D33988EE15C6DD1600CAF1E4 /* speaker_on_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988A915C6DD1600CAF1E4 /* speaker_on_default_landscape~ipad.png */; }; - D33988F015C6DD1600CAF1E4 /* speaker_on_disabled_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988AA15C6DD1600CAF1E4 /* speaker_on_disabled_landscape~ipad.png */; }; - D33988F215C6DD1600CAF1E4 /* speaker_on_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988AB15C6DD1600CAF1E4 /* speaker_on_over_landscape~ipad.png */; }; - D33988F815C6DD1600CAF1E4 /* video_off_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988AE15C6DD1600CAF1E4 /* video_off_default_landscape~ipad.png */; }; - D33988FA15C6DD1600CAF1E4 /* video_off_disabled_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988AF15C6DD1600CAF1E4 /* video_off_disabled_landscape~ipad.png */; }; - D33988FC15C6DD1600CAF1E4 /* video_off_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988B015C6DD1600CAF1E4 /* video_off_over_landscape~ipad.png */; }; - D33988FE15C6DD1600CAF1E4 /* video_on_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988B115C6DD1600CAF1E4 /* video_on_default_landscape~ipad.png */; }; - D339890015C6DD1600CAF1E4 /* video_on_disabled_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988B215C6DD1600CAF1E4 /* video_on_disabled_landscape~ipad.png */; }; - D339890215C6DD1600CAF1E4 /* video_on_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D33988B315C6DD1600CAF1E4 /* video_on_over_landscape~ipad.png */; }; - D339890615C6E16F00CAF1E4 /* dialer_alt_back_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339890415C6E16F00CAF1E4 /* dialer_alt_back_default_landscape~ipad.png */; }; - D339890815C6E16F00CAF1E4 /* dialer_alt_back_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D339890515C6E16F00CAF1E4 /* dialer_alt_back_over_landscape~ipad.png */; }; - D33E1F08164CF35100CFA363 /* callbar_left_padding.png in Resources */ = {isa = PBXBuildFile; fileRef = D33E1F06164CF35100CFA363 /* callbar_left_padding.png */; }; - D33E1F0A164CF35100CFA363 /* callbar_right_padding.png in Resources */ = {isa = PBXBuildFile; fileRef = D33E1F07164CF35100CFA363 /* callbar_right_padding.png */; }; - D3432A62158A4446001C6B0B /* led_connected.png in Resources */ = {isa = PBXBuildFile; fileRef = D3432A5C158A4446001C6B0B /* led_connected.png */; }; - D3432A64158A4446001C6B0B /* led_error.png in Resources */ = {isa = PBXBuildFile; fileRef = D3432A5D158A4446001C6B0B /* led_error.png */; }; - D3432A66158A4446001C6B0B /* call_quality_indicator_0.png in Resources */ = {isa = PBXBuildFile; fileRef = D3432A5E158A4446001C6B0B /* call_quality_indicator_0.png */; }; - D3432A68158A4446001C6B0B /* call_quality_indicator_1.png in Resources */ = {isa = PBXBuildFile; fileRef = D3432A5F158A4446001C6B0B /* call_quality_indicator_1.png */; }; - D3432A6A158A4446001C6B0B /* call_quality_indicator_2.png in Resources */ = {isa = PBXBuildFile; fileRef = D3432A60158A4446001C6B0B /* call_quality_indicator_2.png */; }; - D3432A6C158A4446001C6B0B /* call_quality_indicator_3.png in Resources */ = {isa = PBXBuildFile; fileRef = D3432A61158A4446001C6B0B /* call_quality_indicator_3.png */; }; - D3432A71158A45AF001C6B0B /* led_inprogress.png in Resources */ = {isa = PBXBuildFile; fileRef = D3432A6F158A45AF001C6B0B /* led_inprogress.png */; }; - D3432A73158A45AF001C6B0B /* led_disconnected.png in Resources */ = {isa = PBXBuildFile; fileRef = D3432A70158A45AF001C6B0B /* led_disconnected.png */; }; - D347347E1580E5F8003C7B8C /* history_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D347347C1580E5F8003C7B8C /* history_default.png */; }; - D347347F1580E5F8003C7B8C /* history_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = D347347D1580E5F8003C7B8C /* history_selected.png */; }; D34F6F9E1594D3FB0095705B /* InAppSettings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D34F6F9D1594D3FB0095705B /* InAppSettings.bundle */; }; - D350F20E15A43BB100149E54 /* WizardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D350F20C15A43BB100149E54 /* WizardViewController.m */; }; - D350F21C15A43D3400149E54 /* setup_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D350F21315A43D3400149E54 /* setup_back_default.png */; }; - D350F21E15A43D3400149E54 /* setup_back_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D350F21415A43D3400149E54 /* setup_back_over.png */; }; - D350F22015A43D3400149E54 /* setup_cancel_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D350F21515A43D3400149E54 /* setup_cancel_default.png */; }; - D350F22215A43D3400149E54 /* setup_cancel_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D350F21615A43D3400149E54 /* setup_cancel_over.png */; }; - D350F22415A43D3400149E54 /* field_background.png in Resources */ = {isa = PBXBuildFile; fileRef = D350F21715A43D3400149E54 /* field_background.png */; }; - D350F22615A43D3400149E54 /* setup_start_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D350F21815A43D3400149E54 /* setup_start_default.png */; }; - D350F22815A43D3400149E54 /* setup_start_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D350F21915A43D3400149E54 /* setup_start_over.png */; }; - D350F22C15A43D3400149E54 /* setup_welcome_logo.png in Resources */ = {isa = PBXBuildFile; fileRef = D350F21B15A43D3400149E54 /* setup_welcome_logo.png */; }; - D35406F715A47E9E007E7E81 /* button_background_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D35406F515A47E9E007E7E81 /* button_background_default.png */; }; - D35406F915A47E9E007E7E81 /* button_background_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D35406F615A47E9E007E7E81 /* button_background_over.png */; }; - D35497FE15875372000081D8 /* ContactsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D35497FC15875372000081D8 /* ContactsViewController.m */; }; - D354980615875534000081D8 /* contacts_all_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = D354980215875534000081D8 /* contacts_all_selected.png */; }; - D354980815875534000081D8 /* contacts_all_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D354980315875534000081D8 /* contacts_all_default.png */; }; - D354980A15875534000081D8 /* contacts_linphone_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = D354980415875534000081D8 /* contacts_linphone_selected.png */; }; - D354980C15875534000081D8 /* contacts_linphone_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D354980515875534000081D8 /* contacts_linphone_default.png */; }; - D354981015875608000081D8 /* contacts_add_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D354980E15875608000081D8 /* contacts_add_default.png */; }; - D354981215875608000081D8 /* contacts_add_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D354980F15875608000081D8 /* contacts_add_over.png */; }; - D3549816158761D0000081D8 /* ContactsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3549815158761D0000081D8 /* ContactsTableViewController.m */; }; - D354981A15876FE7000081D8 /* list_details_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D354981815876FE7000081D8 /* list_details_default.png */; }; - D354981C15876FE7000081D8 /* list_details_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D354981915876FE7000081D8 /* list_details_over.png */; }; - D35498211587716B000081D8 /* UIStateBar.m in Sources */ = {isa = PBXBuildFile; fileRef = D354981F1587716B000081D8 /* UIStateBar.m */; }; + D350F20E15A43BB100149E54 /* AssistantView.m in Sources */ = {isa = PBXBuildFile; fileRef = D350F20C15A43BB100149E54 /* AssistantView.m */; }; + D35497FE15875372000081D8 /* ContactsListView.m in Sources */ = {isa = PBXBuildFile; fileRef = D35497FC15875372000081D8 /* ContactsListView.m */; }; + D3549816158761D0000081D8 /* ContactsListTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3549815158761D0000081D8 /* ContactsListTableView.m */; }; + D35498211587716B000081D8 /* StatusBarView.m in Sources */ = {isa = PBXBuildFile; fileRef = D354981F1587716B000081D8 /* StatusBarView.m */; }; D35860D615B549B500513429 /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = D35860D515B549B500513429 /* Utils.m */; }; - D35E757815931E5D0066B1C1 /* switch_camera_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D35E757515931E5D0066B1C1 /* switch_camera_default.png */; }; - D35E757A15931E5D0066B1C1 /* switch_camera_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D35E757615931E5D0066B1C1 /* switch_camera_over.png */; }; - D35E7581159328EB0066B1C1 /* UIAddressTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = D35E7580159328EB0066B1C1 /* UIAddressTextField.m */; }; - D35E758915932DE60066B1C1 /* backspace_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D35E758815932DE60066B1C1 /* backspace_disabled.png */; }; - D35E758D15934F360066B1C1 /* call_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D35E758C15934F360066B1C1 /* call_disabled.png */; }; - D35E7597159460580066B1C1 /* ChatViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D35E7595159460560066B1C1 /* ChatViewController.m */; }; - D35E759F159460B70066B1C1 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D35E759D159460B50066B1C1 /* SettingsViewController.m */; }; - D35E91EA160CA0BD0023116B /* field_background.9@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D35E91E9160CA0BD0023116B /* field_background.9@2x.png */; }; - D35E91EE160CA0C70023116B /* button_background_default.9@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D35E91EC160CA0C70023116B /* button_background_default.9@2x.png */; }; - D35E91F0160CA0C70023116B /* button_background_over.9@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D35E91ED160CA0C70023116B /* button_background_over.9@2x.png */; }; - D35E91F4160CA10B0023116B /* UILinphoneTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = D35E91F3160CA10B0023116B /* UILinphoneTextField.m */; }; - D35E91F8160CA4FF0023116B /* UILinphoneButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D35E91F7160CA4FF0023116B /* UILinphoneButton.m */; }; - D35E9209160CAA1F0023116B /* field_background.9.png in Resources */ = {isa = PBXBuildFile; fileRef = D35E9208160CAA1F0023116B /* field_background.9.png */; }; - D35E920D160CABD70023116B /* button_background_default.9.png in Resources */ = {isa = PBXBuildFile; fileRef = D35E920B160CABD70023116B /* button_background_default.9.png */; }; - D35E920F160CABD70023116B /* button_background_over.9.png in Resources */ = {isa = PBXBuildFile; fileRef = D35E920C160CABD70023116B /* button_background_over.9.png */; }; - D35EA76315A2DF8D003E025D /* micro_off_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D35EA76115A2DF8D003E025D /* micro_off_disabled.png */; }; - D35EA76515A2DF8D003E025D /* micro_on_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D35EA76215A2DF8D003E025D /* micro_on_disabled.png */; }; - D365AA7B15A2DE7500CAFE3F /* speaker_off_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D365AA7915A2DE7500CAFE3F /* speaker_off_disabled.png */; }; - D365AA7D15A2DE7500CAFE3F /* speaker_on_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D365AA7A15A2DE7500CAFE3F /* speaker_on_disabled.png */; }; - D36C43C6158F2E5A0048BA40 /* UICallCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D36C43C5158F2E5A0048BA40 /* UICallCell.m */; }; - D36C43D1158F2F370048BA40 /* cell_call.png in Resources */ = {isa = PBXBuildFile; fileRef = D36C43CC158F2F370048BA40 /* cell_call.png */; }; - D36C43D3158F2F370048BA40 /* cell_conference.png in Resources */ = {isa = PBXBuildFile; fileRef = D36C43CD158F2F370048BA40 /* cell_conference.png */; }; - D36C43D5158F2F370048BA40 /* header_conference.png in Resources */ = {isa = PBXBuildFile; fileRef = D36C43CE158F2F370048BA40 /* header_conference.png */; }; - D36C43D7158F2F370048BA40 /* dialer_alt_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D36C43CF158F2F370048BA40 /* dialer_alt_default.png */; }; - D36C43D9158F2F370048BA40 /* dialer_alt_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D36C43D0158F2F370048BA40 /* dialer_alt_over.png */; }; - D36C43E9158F3F7E0048BA40 /* pause_on_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D36C43E7158F3F7E0048BA40 /* pause_on_default.png */; }; - D36C43EB158F3F7E0048BA40 /* pause_on_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D36C43E8158F3F7E0048BA40 /* pause_on_over.png */; }; - D36C43F1158F61EA0048BA40 /* call_state_pause_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D36C43ED158F61EA0048BA40 /* call_state_pause_default.png */; }; - D36C43F3158F61EA0048BA40 /* call_state_pause_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D36C43EE158F61EA0048BA40 /* call_state_pause_over.png */; }; - D36C43F5158F61EA0048BA40 /* call_state_play_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D36C43EF158F61EA0048BA40 /* call_state_play_default.png */; }; - D36C43F7158F61EA0048BA40 /* call_state_play_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D36C43F0158F61EA0048BA40 /* call_state_play_over.png */; }; + D35E7597159460580066B1C1 /* ChatsListView.m in Sources */ = {isa = PBXBuildFile; fileRef = D35E7595159460560066B1C1 /* ChatsListView.m */; }; + D35E759F159460B70066B1C1 /* SettingsView.m in Sources */ = {isa = PBXBuildFile; fileRef = D35E759D159460B50066B1C1 /* SettingsView.m */; }; D36FB2D51589EF7C0036F6F2 /* UIPauseButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D36FB2D41589EF7C0036F6F2 /* UIPauseButton.m */; }; - D37295DB158B3C9600D2C0C7 /* video_off_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D37295DA158B3C9600D2C0C7 /* video_off_disabled.png */; }; - D374D3FD16071762003D25FF /* ImageSharing.m in Sources */ = {isa = PBXBuildFile; fileRef = D374D3FC16071762003D25FF /* ImageSharing.m */; }; - D377BBFA15A19DA6002B696B /* video_on_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D377BBF915A19DA6002B696B /* video_on_disabled.png */; }; - D378906515AC373B00BD776C /* ContactDetailsLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D378906315AC373B00BD776C /* ContactDetailsLabelViewController.m */; }; - D378AB2A15DCDB4A0098505D /* ImagePickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D378AB2915DCDB490098505D /* ImagePickerViewController.m */; }; - D37B96B715A1A6F20005CCD2 /* call_state_delete_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D37B96B515A1A6F20005CCD2 /* call_state_delete_default.png */; }; - D37B96B915A1A6F20005CCD2 /* call_state_delete_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D37B96B615A1A6F20005CCD2 /* call_state_delete_over.png */; }; - D37C638E15AAD251009D0BAC /* contact_number_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D37C638C15AAD251009D0BAC /* contact_number_over.png */; }; - D37C639015AAD251009D0BAC /* contact_number.png in Resources */ = {isa = PBXBuildFile; fileRef = D37C638D15AAD251009D0BAC /* contact_number.png */; }; - D37C639515AADDAF009D0BAC /* UIContactDetailsHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = D37C639315AADDAE009D0BAC /* UIContactDetailsHeader.m */; }; - D37C639B15AADEF6009D0BAC /* ContactDetailsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D37C639A15AADEF5009D0BAC /* ContactDetailsTableViewController.m */; }; + D378AB2A15DCDB4A0098505D /* ImagePickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = D378AB2915DCDB490098505D /* ImagePickerView.m */; }; + D37C639B15AADEF6009D0BAC /* ContactDetailsTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = D37C639A15AADEF5009D0BAC /* ContactDetailsTableView.m */; }; D37DC6C11594AE1800B2A5EB /* LinphoneCoreSettingsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6C01594AE1800B2A5EB /* LinphoneCoreSettingsStore.m */; }; D37DC7181594AF3400B2A5EB /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D37DC7171594AF3400B2A5EB /* MessageUI.framework */; }; D37E3ECD1619C27A0087659A /* CAAnimation+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = D37E3ECC1619C27A0087659A /* CAAnimation+Blocks.m */; }; - D37E3ED01619DCC50087659A /* licenses.html in Resources */ = {isa = PBXBuildFile; fileRef = D37E3ECF1619DCC50087659A /* licenses.html */; }; - D37EE10916032DA4003608A6 /* libmediastreamer_base.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22405EE916006F0700B92522 /* libmediastreamer_base.a */; }; - D37EE10A16032DA4003608A6 /* libmediastreamer_voip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22405EEA16006F0700B92522 /* libmediastreamer_voip.a */; }; - D37EE10D16035793003608A6 /* ImageViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37EE11016035793003608A6 /* ImageViewController.xib */; }; + D37EE10D16035793003608A6 /* ImageView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37EE11016035793003608A6 /* ImageView.xib */; }; D37EE162160377D7003608A6 /* DTActionSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = D37EE161160377D7003608A6 /* DTActionSheet.m */; }; - D3804E6015D92A57008072A5 /* msg.caf in Resources */ = {isa = PBXBuildFile; fileRef = D3804E5E15D92A57008072A5 /* msg.caf */; }; - D3804E6215D92A57008072A5 /* msg.wav in Resources */ = {isa = PBXBuildFile; fileRef = D3804E5F15D92A57008072A5 /* msg.wav */; }; D3807FBF15C28940005BE9BC /* DCRoundSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = D3807FB815C28940005BE9BC /* DCRoundSwitch.m */; }; D3807FC115C28940005BE9BC /* DCRoundSwitchKnobLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = D3807FBA15C28940005BE9BC /* DCRoundSwitchKnobLayer.m */; }; D3807FC315C28940005BE9BC /* DCRoundSwitchOutlineLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = D3807FBC15C28940005BE9BC /* DCRoundSwitchOutlineLayer.m */; }; D3807FC515C28940005BE9BC /* DCRoundSwitchToggleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = D3807FBE15C28940005BE9BC /* DCRoundSwitchToggleLayer.m */; }; - D3807FE815C2894A005BE9BC /* IASKAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3807FCA15C2894A005BE9BC /* IASKAppSettingsViewController.m */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; }; + D3807FE815C2894A005BE9BC /* IASKAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3807FCA15C2894A005BE9BC /* IASKAppSettingsViewController.m */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations -Wno-objc-designated-initializers"; }; }; D3807FEA15C2894A005BE9BC /* IASKAppSettingsWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3807FCC15C2894A005BE9BC /* IASKAppSettingsWebViewController.m */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; }; D3807FEC15C2894A005BE9BC /* IASKSpecifierValuesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3807FCE15C2894A005BE9BC /* IASKSpecifierValuesViewController.m */; }; D3807FEE15C2894A005BE9BC /* IASKSettingsReader.m in Sources */ = {isa = PBXBuildFile; fileRef = D3807FD215C2894A005BE9BC /* IASKSettingsReader.m */; }; @@ -336,384 +610,49 @@ D3807FFE15C2894A005BE9BC /* IASKSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = D3807FE315C2894A005BE9BC /* IASKSlider.m */; }; D380800015C2894A005BE9BC /* IASKSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = D3807FE515C2894A005BE9BC /* IASKSwitch.m */; }; D380800215C2894A005BE9BC /* IASKTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = D3807FE715C2894A005BE9BC /* IASKTextField.m */; }; - D380800515C28A7A005BE9BC /* UILinphone.m in Sources */ = {isa = PBXBuildFile; fileRef = D380800415C28A7A005BE9BC /* UILinphone.m */; }; D380801315C299D0005BE9BC /* ColorSpaceUtilites.m in Sources */ = {isa = PBXBuildFile; fileRef = D380801215C299D0005BE9BC /* ColorSpaceUtilites.m */; }; - D38187AD15FE340100C3EDCA /* ChatRoomViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187B015FE340100C3EDCA /* ChatRoomViewController.xib */; }; - D38187B115FE340500C3EDCA /* ChatViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187B415FE340500C3EDCA /* ChatViewController.xib */; }; - D38187B515FE341B00C3EDCA /* ContactDetailsLabelViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187B815FE341B00C3EDCA /* ContactDetailsLabelViewController.xib */; }; - D38187B915FE342200C3EDCA /* ContactDetailsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187BC15FE342200C3EDCA /* ContactDetailsViewController.xib */; }; - D38187BD15FE342800C3EDCA /* ContactsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187C015FE342800C3EDCA /* ContactsViewController.xib */; }; - D38187C115FE345B00C3EDCA /* DialerViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187C415FE345B00C3EDCA /* DialerViewController.xib */; }; - D38187C515FE345F00C3EDCA /* DialerViewController~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187C815FE345F00C3EDCA /* DialerViewController~ipad.xib */; }; - D38187C915FE346400C3EDCA /* FirstLoginViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187CC15FE346400C3EDCA /* FirstLoginViewController.xib */; }; - D38187CD15FE346700C3EDCA /* HistoryDetailsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187D015FE346700C3EDCA /* HistoryDetailsViewController.xib */; }; - D38187D115FE346B00C3EDCA /* HistoryViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187D415FE346B00C3EDCA /* HistoryViewController.xib */; }; - D38187D915FE347700C3EDCA /* IncomingCallViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187DC15FE347700C3EDCA /* IncomingCallViewController.xib */; }; - D38187DD15FE348A00C3EDCA /* WizardViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187E015FE348A00C3EDCA /* WizardViewController.xib */; }; - D38187E115FE349700C3EDCA /* UICallBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187E415FE349700C3EDCA /* UICallBar.xib */; }; - D38187E515FE349D00C3EDCA /* UICallBar~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187E815FE349D00C3EDCA /* UICallBar~ipad.xib */; }; - D38187F015FE354000C3EDCA /* UIConferenceHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187F315FE354000C3EDCA /* UIConferenceHeader.xib */; }; - D38187F415FE354700C3EDCA /* UIContactDetailsFooter.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187F715FE354700C3EDCA /* UIContactDetailsFooter.xib */; }; - D38187F815FE355D00C3EDCA /* UIMainBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187FB15FE355D00C3EDCA /* UIMainBar.xib */; }; - D38187FC15FE356100C3EDCA /* UIMainBar~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187FF15FE356100C3EDCA /* UIMainBar~ipad.xib */; }; - D381881115FE3F0B00C3EDCA /* UICallCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D381881415FE3F0B00C3EDCA /* UICallCell.xib */; }; - D381881515FE3F7F00C3EDCA /* UIContactDetailsHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = D381881815FE3F7F00C3EDCA /* UIContactDetailsHeader.xib */; }; - D381881915FE3FCA00C3EDCA /* InCallViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D381881C15FE3FCA00C3EDCA /* InCallViewController.xib */; }; - D38327F31580FE3A00FA0D23 /* contacts_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327EB1580FE3A00FA0D23 /* contacts_default.png */; }; - D38327F41580FE3A00FA0D23 /* contacts_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327EC1580FE3A00FA0D23 /* contacts_selected.png */; }; - D38327F51580FE3A00FA0D23 /* dialer_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327ED1580FE3A00FA0D23 /* dialer_default.png */; }; - D38327F61580FE3A00FA0D23 /* dialer_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327EE1580FE3A00FA0D23 /* dialer_over.png */; }; - D38327F71580FE3A00FA0D23 /* settings_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327EF1580FE3A00FA0D23 /* settings_default.png */; }; - D38327F81580FE3A00FA0D23 /* settings_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327F01580FE3A00FA0D23 /* settings_selected.png */; }; - D38327F91580FE3A00FA0D23 /* chat_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327F11580FE3A00FA0D23 /* chat_default.png */; }; - D38327FA1580FE3A00FA0D23 /* chat_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327F21580FE3A00FA0D23 /* chat_selected.png */; }; - D3832800158100E400FA0D23 /* contacts_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327FC158100E400FA0D23 /* contacts_over.png */; }; - D3832801158100E400FA0D23 /* history_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327FD158100E400FA0D23 /* history_over.png */; }; - D3832802158100E400FA0D23 /* settings_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327FE158100E400FA0D23 /* settings_over.png */; }; - D3832803158100E400FA0D23 /* chat_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327FF158100E400FA0D23 /* chat_over.png */; }; - D3866C281608CA1600830F95 /* image_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3866C261608CA1600830F95 /* image_back_default.png */; }; - D3866C2A1608CA1600830F95 /* image_back_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3866C271608CA1600830F95 /* image_back_over.png */; }; - D389363915A6D53200A3A3AA /* chat_bubble_incoming.9.png in Resources */ = {isa = PBXBuildFile; fileRef = D389363715A6D53200A3A3AA /* chat_bubble_incoming.9.png */; }; - D389363B15A6D53200A3A3AA /* chat_bubble_outgoing.9.png in Resources */ = {isa = PBXBuildFile; fileRef = D389363815A6D53200A3A3AA /* chat_bubble_outgoing.9.png */; }; - D38D14AF15A30B3D008497E8 /* cell_call_first_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = D38D14AD15A30B3D008497E8 /* cell_call_first_highlight.png */; }; - D38D14B115A30B3D008497E8 /* cell_call_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = D38D14AE15A30B3D008497E8 /* cell_call_highlight.png */; }; - D3998D0416031937009DD22C /* background_alt.png in Resources */ = {isa = PBXBuildFile; fileRef = D3998D0316031937009DD22C /* background_alt.png */; }; + D38187AD15FE340100C3EDCA /* ChatConversationView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187B015FE340100C3EDCA /* ChatConversationView.xib */; }; + D38187B115FE340500C3EDCA /* ChatsListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187B415FE340500C3EDCA /* ChatsListView.xib */; }; + D38187B915FE342200C3EDCA /* ContactDetailsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187BC15FE342200C3EDCA /* ContactDetailsView.xib */; }; + D38187BD15FE342800C3EDCA /* ContactsListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187C015FE342800C3EDCA /* ContactsListView.xib */; }; + D38187C115FE345B00C3EDCA /* DialerView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187C415FE345B00C3EDCA /* DialerView.xib */; }; + D38187CD15FE346700C3EDCA /* HistoryDetailsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187D015FE346700C3EDCA /* HistoryDetailsView.xib */; }; + D38187D115FE346B00C3EDCA /* HistoryListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187D415FE346B00C3EDCA /* HistoryListView.xib */; }; + D38187D915FE347700C3EDCA /* CallIncomingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187DC15FE347700C3EDCA /* CallIncomingView.xib */; }; + D38187DD15FE348A00C3EDCA /* AssistantView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187E015FE348A00C3EDCA /* AssistantView.xib */; }; + D38187F815FE355D00C3EDCA /* TabBarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D38187FB15FE355D00C3EDCA /* TabBarView.xib */; }; + D381881915FE3FCA00C3EDCA /* CallView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D381881C15FE3FCA00C3EDCA /* CallView.xib */; }; D3A55FBC15877E5E003FD403 /* UIContactCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D3A55FBB15877E5E003FD403 /* UIContactCell.m */; }; - D3A74E5915C68162001500B9 /* toolsbar_background.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E5815C68162001500B9 /* toolsbar_background.png */; }; - D3A74EB215C69392001500B9 /* add_call_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E5E15C69391001500B9 /* add_call_default~ipad.png */; }; - D3A74EB415C69392001500B9 /* add_call_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E5F15C69391001500B9 /* add_call_disabled~ipad.png */; }; - D3A74EB615C69392001500B9 /* add_call_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6015C69391001500B9 /* add_call_over~ipad.png */; }; - D3A74EB815C69392001500B9 /* add_contact_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6115C69391001500B9 /* add_contact_default~ipad.png */; }; - D3A74EBA15C69392001500B9 /* add_contact_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6215C69392001500B9 /* add_contact_disabled~ipad.png */; }; - D3A74EBC15C69392001500B9 /* add_contact_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6315C69392001500B9 /* add_contact_over~ipad.png */; }; - D3A74EBE15C69392001500B9 /* back_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6415C69392001500B9 /* back_default~ipad.png */; }; - D3A74EC015C69392001500B9 /* back_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6515C69392001500B9 /* back_disabled~ipad.png */; }; - D3A74EC215C69392001500B9 /* back_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6615C69392001500B9 /* back_over~ipad.png */; }; - D3A74EC415C69392001500B9 /* background_top~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6715C69392001500B9 /* background_top~ipad.png */; }; - D3A74EC615C69392001500B9 /* backspace_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6815C69392001500B9 /* backspace_default~ipad.png */; }; - D3A74EC815C69392001500B9 /* backspace_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6915C69392001500B9 /* backspace_disabled~ipad.png */; }; - D3A74ECA15C69392001500B9 /* backspace_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6A15C69392001500B9 /* backspace_over~ipad.png */; }; - D3A74ECC15C69392001500B9 /* call_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6B15C69392001500B9 /* call_default~ipad.png */; }; - D3A74ECE15C69392001500B9 /* call_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6C15C69392001500B9 /* call_disabled~ipad.png */; }; - D3A74ED015C69392001500B9 /* call_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6D15C69392001500B9 /* call_over~ipad.png */; }; - D3A74ED215C69392001500B9 /* chat_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6E15C69392001500B9 /* chat_default_landscape~ipad.png */; }; - D3A74ED415C69392001500B9 /* chat_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E6F15C69392001500B9 /* chat_default~ipad.png */; }; - D3A74ED615C69392001500B9 /* chat_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7015C69392001500B9 /* chat_over_landscape~ipad.png */; }; - D3A74ED815C69392001500B9 /* chat_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7115C69392001500B9 /* chat_over~ipad.png */; }; - D3A74EDA15C69392001500B9 /* chat_selected_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7215C69392001500B9 /* chat_selected_landscape~ipad.png */; }; - D3A74EDC15C69392001500B9 /* chat_selected~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7315C69392001500B9 /* chat_selected~ipad.png */; }; - D3A74EDE15C69392001500B9 /* conference_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7415C69392001500B9 /* conference_default~ipad.png */; }; - D3A74EE015C69392001500B9 /* conference_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7515C69392001500B9 /* conference_over~ipad.png */; }; - D3A74EE215C69392001500B9 /* contacts_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7615C69392001500B9 /* contacts_default_landscape~ipad.png */; }; - D3A74EE415C69392001500B9 /* contacts_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7715C69392001500B9 /* contacts_default~ipad.png */; }; - D3A74EE615C69392001500B9 /* contacts_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7815C69392001500B9 /* contacts_over_landscape~ipad.png */; }; - D3A74EE815C69392001500B9 /* contacts_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7915C69392001500B9 /* contacts_over~ipad.png */; }; - D3A74EEA15C69392001500B9 /* contacts_selected_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7A15C69392001500B9 /* contacts_selected_landscape~ipad.png */; }; - D3A74EEC15C69392001500B9 /* contacts_selected~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7B15C69392001500B9 /* contacts_selected~ipad.png */; }; - D3A74EEE15C69392001500B9 /* dialer_address_background_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7C15C69392001500B9 /* dialer_address_background_landscape~ipad.png */; }; - D3A74EF015C69392001500B9 /* dialer_address_background~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7D15C69392001500B9 /* dialer_address_background~ipad.png */; }; - D3A74EF215C69392001500B9 /* dialer_alt_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7E15C69392001500B9 /* dialer_alt_default~ipad.png */; }; - D3A74EF415C69392001500B9 /* dialer_alt_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E7F15C69392001500B9 /* dialer_alt_over~ipad.png */; }; - D3A74EF615C69392001500B9 /* hangup_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8015C69392001500B9 /* hangup_default~ipad.png */; }; - D3A74EF815C69392001500B9 /* hangup_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8115C69392001500B9 /* hangup_over~ipad.png */; }; - D3A74EFA15C69392001500B9 /* history_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8215C69392001500B9 /* history_default_landscape~ipad.png */; }; - D3A74EFC15C69392001500B9 /* history_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8315C69392001500B9 /* history_default~ipad.png */; }; - D3A74EFE15C69392001500B9 /* history_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8415C69392001500B9 /* history_over_landscape~ipad.png */; }; - D3A74F0015C69392001500B9 /* history_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8515C69392001500B9 /* history_over~ipad.png */; }; - D3A74F0215C69392001500B9 /* history_selected_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8615C69392001500B9 /* history_selected_landscape~ipad.png */; }; - D3A74F0415C69392001500B9 /* history_selected~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8715C69392001500B9 /* history_selected~ipad.png */; }; - D3A74F0615C69392001500B9 /* micro_off_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8815C69392001500B9 /* micro_off_default~ipad.png */; }; - D3A74F0815C69392001500B9 /* micro_off_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8915C69392001500B9 /* micro_off_disabled~ipad.png */; }; - D3A74F0A15C69392001500B9 /* micro_off_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8A15C69392001500B9 /* micro_off_over~ipad.png */; }; - D3A74F0C15C69392001500B9 /* micro_on_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8B15C69392001500B9 /* micro_on_default~ipad.png */; }; - D3A74F0E15C69392001500B9 /* micro_on_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8C15C69392001500B9 /* micro_on_disabled~ipad.png */; }; - D3A74F1015C69392001500B9 /* micro_on_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8D15C69392001500B9 /* micro_on_over~ipad.png */; }; - D3A74F1215C69392001500B9 /* options_add_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8E15C69392001500B9 /* options_add_default~ipad.png */; }; - D3A74F1415C69392001500B9 /* options_add_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E8F15C69392001500B9 /* options_add_disabled~ipad.png */; }; - D3A74F1615C69392001500B9 /* options_add_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9015C69392001500B9 /* options_add_over~ipad.png */; }; - D3A74F1815C69392001500B9 /* options_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9115C69392001500B9 /* options_default~ipad.png */; }; - D3A74F1A15C69392001500B9 /* options_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9215C69392001500B9 /* options_disabled~ipad.png */; }; - D3A74F1C15C69392001500B9 /* options_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9315C69392001500B9 /* options_over~ipad.png */; }; - D3A74F1E15C69392001500B9 /* options_selected~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9415C69392001500B9 /* options_selected~ipad.png */; }; - D3A74F2015C69392001500B9 /* options_transfer_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9515C69392001500B9 /* options_transfer_default~ipad.png */; }; - D3A74F2215C69392001500B9 /* options_transfer_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9615C69392001500B9 /* options_transfer_disabled~ipad.png */; }; - D3A74F2415C69392001500B9 /* options_transfer_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9715C69392001500B9 /* options_transfer_over~ipad.png */; }; - D3A74F2615C69392001500B9 /* pause_off_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9815C69392001500B9 /* pause_off_default~ipad.png */; }; - D3A74F2815C69392001500B9 /* pause_off_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9915C69392001500B9 /* pause_off_over~ipad.png */; }; - D3A74F2A15C69392001500B9 /* pause_on_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9A15C69392001500B9 /* pause_on_default~ipad.png */; }; - D3A74F2C15C69392001500B9 /* pause_on_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9B15C69392001500B9 /* pause_on_over~ipad.png */; }; - D3A74F2E15C69392001500B9 /* settings_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9C15C69392001500B9 /* settings_default_landscape~ipad.png */; }; - D3A74F3015C69392001500B9 /* settings_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9D15C69392001500B9 /* settings_default~ipad.png */; }; - D3A74F3215C69392001500B9 /* settings_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9E15C69392001500B9 /* settings_over_landscape~ipad.png */; }; - D3A74F3415C69392001500B9 /* settings_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74E9F15C69392001500B9 /* settings_over~ipad.png */; }; - D3A74F3615C69392001500B9 /* settings_selected_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EA015C69392001500B9 /* settings_selected_landscape~ipad.png */; }; - D3A74F3815C69392001500B9 /* settings_selected~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EA115C69392001500B9 /* settings_selected~ipad.png */; }; - D3A74F3A15C69392001500B9 /* speaker_off_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EA215C69392001500B9 /* speaker_off_default~ipad.png */; }; - D3A74F3C15C69392001500B9 /* speaker_off_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EA315C69392001500B9 /* speaker_off_disabled~ipad.png */; }; - D3A74F3E15C69392001500B9 /* speaker_off_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EA415C69392001500B9 /* speaker_off_over~ipad.png */; }; - D3A74F4015C69392001500B9 /* speaker_on_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EA515C69392001500B9 /* speaker_on_default~ipad.png */; }; - D3A74F4215C69392001500B9 /* speaker_on_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EA615C69392001500B9 /* speaker_on_disabled~ipad.png */; }; - D3A74F4415C69392001500B9 /* speaker_on_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EA715C69392001500B9 /* speaker_on_over~ipad.png */; }; - D3A74F4615C69392001500B9 /* statebar_background_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EA815C69392001500B9 /* statebar_background_landscape~ipad.png */; }; - D3A74F4815C69392001500B9 /* statebar_background~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EA915C69392001500B9 /* statebar_background~ipad.png */; }; - D3A74F4A15C69392001500B9 /* transfer_call_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EAA15C69392001500B9 /* transfer_call_default~ipad.png */; }; - D3A74F4C15C69392001500B9 /* transfer_call_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EAB15C69392001500B9 /* transfer_call_over~ipad.png */; }; - D3A74F4E15C69392001500B9 /* video_off_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EAC15C69392001500B9 /* video_off_default~ipad.png */; }; - D3A74F5015C69392001500B9 /* video_off_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EAD15C69392001500B9 /* video_off_disabled~ipad.png */; }; - D3A74F5215C69392001500B9 /* video_off_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EAE15C69392001500B9 /* video_off_over~ipad.png */; }; - D3A74F5415C69392001500B9 /* video_on_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EAF15C69392001500B9 /* video_on_default~ipad.png */; }; - D3A74F5615C69392001500B9 /* video_on_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EB015C69392001500B9 /* video_on_disabled~ipad.png */; }; - D3A74F5815C69392001500B9 /* video_on_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A74EB115C69392001500B9 /* video_on_over~ipad.png */; }; - D3A8BB7015A6C7D500F96BE5 /* UIChatRoomCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D3A8BB6F15A6C7D500F96BE5 /* UIChatRoomCell.m */; }; - D3A8BB7B15A6CC3200F96BE5 /* chat_bubble_outgoing.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A8BB7615A6CC3200F96BE5 /* chat_bubble_outgoing.png */; }; - D3A8BB7D15A6CC3200F96BE5 /* chat_bubble_incoming.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A8BB7715A6CC3200F96BE5 /* chat_bubble_incoming.png */; }; - D3A8BB7F15A6CC3200F96BE5 /* setup_back_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A8BB7815A6CC3200F96BE5 /* setup_back_disabled.png */; }; - D3A8BB8115A6CC3200F96BE5 /* setup_cancel_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A8BB7915A6CC3200F96BE5 /* setup_cancel_disabled.png */; }; - D3A8BB8315A6CC3200F96BE5 /* setup_start_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D3A8BB7A15A6CC3200F96BE5 /* setup_start_disabled.png */; }; - D3ACB09B15C6D59500E15894 /* dialer_alt_back_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ACB09915C6D59500E15894 /* dialer_alt_back_default~ipad.png */; }; - D3ACB09D15C6D59500E15894 /* dialer_alt_back_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ACB09A15C6D59500E15894 /* dialer_alt_back_over~ipad.png */; }; - D3B9A3E115A58C450096EA4E /* chat_ok_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DB15A58C440096EA4E /* chat_ok_default.png */; }; - D3B9A3E315A58C450096EA4E /* chat_ok_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DC15A58C440096EA4E /* chat_ok_over.png */; }; - D3B9A3E515A58C450096EA4E /* chat_send_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DD15A58C440096EA4E /* chat_send_default.png */; }; - D3B9A3E715A58C450096EA4E /* chat_send_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3B9A3DE15A58C450096EA4E /* chat_send_over.png */; }; - D3BDB9B915C6B5B1007BEAC1 /* transfer_call_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3BDB9B815C6B5B1007BEAC1 /* transfer_call_disabled~ipad.png */; }; - D3C2814B15A2D38D0098AA42 /* dialer_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C2814A15A2D38D0098AA42 /* dialer_selected.png */; }; - D3C2815215A2D64A0098AA42 /* numpad_star_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C2815115A2D64A0098AA42 /* numpad_star_over.png */; }; - D3C31A3215BD8DED008ED271 /* conference_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A0715BD8DED008ED271 /* conference_default_landscape.png */; }; - D3C31A3415BD8DED008ED271 /* conference_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A0815BD8DED008ED271 /* conference_over_landscape.png */; }; - D3C31A3615BD8DED008ED271 /* dialer_alt_back_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A0915BD8DED008ED271 /* dialer_alt_back_default_landscape.png */; }; - D3C31A3815BD8DED008ED271 /* dialer_alt_back_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A0A15BD8DED008ED271 /* dialer_alt_back_over_landscape.png */; }; - D3C31A3A15BD8DED008ED271 /* dialer_alt_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A0B15BD8DED008ED271 /* dialer_alt_default_landscape.png */; }; - D3C31A3C15BD8DED008ED271 /* dialer_alt_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A0C15BD8DED008ED271 /* dialer_alt_over_landscape.png */; }; - D3C31A3E15BD8DED008ED271 /* hangup_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A0D15BD8DED008ED271 /* hangup_default_landscape.png */; }; - D3C31A4015BD8DED008ED271 /* hangup_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A0E15BD8DED008ED271 /* hangup_over_landscape.png */; }; - D3C31A4215BD8DED008ED271 /* micro_off_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A0F15BD8DED008ED271 /* micro_off_default_landscape.png */; }; - D3C31A4415BD8DED008ED271 /* micro_off_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1015BD8DED008ED271 /* micro_off_disabled_landscape.png */; }; - D3C31A4615BD8DED008ED271 /* micro_off_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1115BD8DED008ED271 /* micro_off_over_landscape.png */; }; - D3C31A4815BD8DED008ED271 /* micro_on_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1215BD8DED008ED271 /* micro_on_default_landscape.png */; }; - D3C31A4A15BD8DED008ED271 /* micro_on_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1315BD8DED008ED271 /* micro_on_disabled_landscape.png */; }; - D3C31A4C15BD8DED008ED271 /* micro_on_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1415BD8DED008ED271 /* micro_on_over_landscape.png */; }; - D3C31A4E15BD8DED008ED271 /* options_add_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1515BD8DED008ED271 /* options_add_default_landscape.png */; }; - D3C31A5015BD8DED008ED271 /* options_add_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1615BD8DED008ED271 /* options_add_disabled_landscape.png */; }; - D3C31A5215BD8DED008ED271 /* options_add_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1715BD8DED008ED271 /* options_add_over_landscape.png */; }; - D3C31A5415BD8DED008ED271 /* options_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1815BD8DED008ED271 /* options_default_landscape.png */; }; - D3C31A5615BD8DED008ED271 /* options_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1915BD8DED008ED271 /* options_disabled_landscape.png */; }; - D3C31A5815BD8DED008ED271 /* options_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1A15BD8DED008ED271 /* options_over_landscape.png */; }; - D3C31A5A15BD8DED008ED271 /* options_selected_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1B15BD8DED008ED271 /* options_selected_landscape.png */; }; - D3C31A5C15BD8DED008ED271 /* options_transfer_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1C15BD8DED008ED271 /* options_transfer_default_landscape.png */; }; - D3C31A5E15BD8DED008ED271 /* options_transfer_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1D15BD8DED008ED271 /* options_transfer_disabled_landscape.png */; }; - D3C31A6015BD8DED008ED271 /* options_transfer_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1E15BD8DED008ED271 /* options_transfer_over_landscape.png */; }; - D3C31A6215BD8DED008ED271 /* pause_off_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A1F15BD8DED008ED271 /* pause_off_default_landscape.png */; }; - D3C31A6415BD8DED008ED271 /* pause_off_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2015BD8DED008ED271 /* pause_off_over_landscape.png */; }; - D3C31A6615BD8DED008ED271 /* pause_on_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2115BD8DED008ED271 /* pause_on_default_landscape.png */; }; - D3C31A6815BD8DED008ED271 /* pause_on_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2215BD8DED008ED271 /* pause_on_over_landscape.png */; }; - D3C31A6A15BD8DED008ED271 /* speaker_off_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2315BD8DED008ED271 /* speaker_off_default_landscape.png */; }; - D3C31A6C15BD8DED008ED271 /* speaker_off_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2415BD8DED008ED271 /* speaker_off_disabled_landscape.png */; }; - D3C31A6E15BD8DED008ED271 /* speaker_off_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2515BD8DED008ED271 /* speaker_off_over_landscape.png */; }; - D3C31A7015BD8DED008ED271 /* speaker_on_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2615BD8DED008ED271 /* speaker_on_default_landscape.png */; }; - D3C31A7215BD8DED008ED271 /* speaker_on_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2715BD8DED008ED271 /* speaker_on_disabled_landscape.png */; }; - D3C31A7415BD8DED008ED271 /* speaker_on_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2815BD8DED008ED271 /* speaker_on_over_landscape.png */; }; - D3C31A7615BD8DED008ED271 /* statebar_background_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2915BD8DED008ED271 /* statebar_background_landscape.png */; }; - D3C31A7C15BD8DED008ED271 /* video_off_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2C15BD8DED008ED271 /* video_off_default_landscape.png */; }; - D3C31A7E15BD8DED008ED271 /* video_off_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2D15BD8DED008ED271 /* video_off_disabled_landscape.png */; }; - D3C31A8015BD8DED008ED271 /* video_off_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2E15BD8DED008ED271 /* video_off_over_landscape.png */; }; - D3C31A8215BD8DED008ED271 /* video_on_default_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A2F15BD8DED008ED271 /* video_on_default_landscape.png */; }; - D3C31A8415BD8DED008ED271 /* video_on_disabled_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A3015BD8DED008ED271 /* video_on_disabled_landscape.png */; }; - D3C31A8615BD8DED008ED271 /* video_on_over_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C31A3115BD8DED008ED271 /* video_on_over_landscape.png */; }; - D3C6526715AC1A8F0092A874 /* UIEditableTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D3C6526615AC1A8F0092A874 /* UIEditableTableViewCell.m */; }; - D3C6526B15AC228A0092A874 /* contact_ok_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C6526915AC228A0092A874 /* contact_ok_default.png */; }; - D3C6526D15AC228A0092A874 /* contact_ok_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C6526A15AC228A0092A874 /* contact_ok_over.png */; }; - D3C714B3159DB84400705B8E /* hold.wav in Resources */ = {isa = PBXBuildFile; fileRef = D3C714B2159DB84400705B8E /* hold.wav */; }; - D3D14E7C15A711700074A527 /* avatar_shadow_small.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D14E7B15A711700074A527 /* avatar_shadow_small.png */; }; - D3D5124E160B213900946DF8 /* setup_cancel_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D5124C160B213900946DF8 /* setup_cancel_default~ipad.png */; }; - D3D51250160B213900946DF8 /* setup_cancel_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D5124D160B213900946DF8 /* setup_cancel_over~ipad.png */; }; - D3D51255160B35CB00946DF8 /* chat_message_background.9.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D51252160B35CB00946DF8 /* chat_message_background.9.png */; }; - D3D51257160B35CB00946DF8 /* chat_message_background.9@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D51253160B35CB00946DF8 /* chat_message_background.9@2x.png */; }; - D3D5126C160B3A8E00946DF8 /* WizardViews.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3D5126A160B3A8E00946DF8 /* WizardViews.xib */; }; - D3D51270160B3AD400946DF8 /* WizardViewController~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3D5126E160B3AD400946DF8 /* WizardViewController~ipad.xib */; }; - D3D52A731614480700DEB00A /* IncomingCallViewController~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3D52A711614480700DEB00A /* IncomingCallViewController~ipad.xib */; }; - D3D52A7D1614495300DEB00A /* accept_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D52A751614495300DEB00A /* accept_default_landscape~ipad.png */; }; - D3D52A7F1614495300DEB00A /* accept_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D52A761614495300DEB00A /* accept_default~ipad.png */; }; - D3D52A811614495300DEB00A /* accept_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D52A771614495300DEB00A /* accept_over_landscape~ipad.png */; }; - D3D52A831614495300DEB00A /* accept_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D52A781614495300DEB00A /* accept_over~ipad.png */; }; - D3D52A851614495300DEB00A /* decline_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D52A791614495300DEB00A /* decline_default_landscape~ipad.png */; }; - D3D52A871614495300DEB00A /* decline_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D52A7A1614495300DEB00A /* decline_default~ipad.png */; }; - D3D52A891614495300DEB00A /* decline_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D52A7B1614495300DEB00A /* decline_over_landscape~ipad.png */; }; - D3D52A8B1614495300DEB00A /* decline_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D52A7C1614495300DEB00A /* decline_over~ipad.png */; }; - D3D6A39E159B0EEF005F692C /* add_call_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D6A39B159B0EEF005F692C /* add_call_default.png */; }; - D3D6A3A0159B0EEF005F692C /* add_call_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D6A39C159B0EEF005F692C /* add_call_disabled.png */; }; - D3D6A3A2159B0EEF005F692C /* add_call_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D6A39D159B0EEF005F692C /* add_call_over.png */; }; - D3D6A3AB159B0EFE005F692C /* security_ko.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D6A3A5159B0EFE005F692C /* security_ko.png */; }; - D3D6A3AD159B0EFE005F692C /* security_pending.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D6A3A6159B0EFE005F692C /* security_pending.png */; }; - D3D6A3AF159B0EFE005F692C /* security_ok.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D6A3A7159B0EFE005F692C /* security_ok.png */; }; - D3D6A3B1159B0EFE005F692C /* options_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D6A3A8159B0EFE005F692C /* options_default.png */; }; - D3D6A3B3159B0EFE005F692C /* options_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D6A3A9159B0EFE005F692C /* options_disabled.png */; }; - D3D6A3B5159B0EFE005F692C /* options_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D6A3AA159B0EFE005F692C /* options_over.png */; }; - D3E84F1E15B00F4100420DAC /* cancel_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3E84F1715B00F4100420DAC /* cancel_default.png */; }; - D3E84F2015B00F4100420DAC /* cancel_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3E84F1815B00F4100420DAC /* cancel_over.png */; }; - D3E84F2615B00F4100420DAC /* dialer_alt_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3E84F1B15B00F4100420DAC /* dialer_alt_back_default.png */; }; - D3E84F2815B00F4100420DAC /* dialer_alt_back_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3E84F1C15B00F4100420DAC /* dialer_alt_back_over.png */; }; - D3E84F2A15B00F4100420DAC /* dialer_alt_background.png in Resources */ = {isa = PBXBuildFile; fileRef = D3E84F1D15B00F4100420DAC /* dialer_alt_background.png */; }; - D3E84F3815B011AF00420DAC /* contact_cancel_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3E84F3615B011AF00420DAC /* contact_cancel_default.png */; }; - D3E84F3A15B011AF00420DAC /* contact_cancel_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3E84F3715B011AF00420DAC /* contact_cancel_over.png */; }; - D3E8F68615ADE05B0065A226 /* UIContactDetailsFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = D3E8F68415ADE0580065A226 /* UIContactDetailsFooter.m */; }; + D3A8BB7015A6C7D500F96BE5 /* UIChatBubbleTextCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D3A8BB6F15A6C7D500F96BE5 /* UIChatBubbleTextCell.m */; }; + D3C6526715AC1A8F0092A874 /* UIContactDetailsCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D3C6526615AC1A8F0092A874 /* UIContactDetailsCell.m */; }; + D3D5126C160B3A8E00946DF8 /* AssistantViewScreens.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3D5126A160B3A8E00946DF8 /* AssistantViewScreens.xib */; }; D3EA53FD159850E80037DC6B /* LinphoneManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D3EA53FC159850E80037DC6B /* LinphoneManager.m */; }; - D3EA5403159852080037DC6B /* chat_edit_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3EA53FF159852080037DC6B /* chat_edit_default.png */; }; - D3EA5405159852080037DC6B /* chat_edit_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3EA5400159852080037DC6B /* chat_edit_over.png */; }; - D3EA5407159852080037DC6B /* chat_add_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3EA5401159852080037DC6B /* chat_add_default.png */; }; - D3EA5409159852080037DC6B /* chat_add_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3EA5402159852080037DC6B /* chat_add_over.png */; }; - D3EA540D1598528B0037DC6B /* ChatTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3EA540C1598528B0037DC6B /* ChatTableViewController.m */; }; + D3EA540D1598528B0037DC6B /* ChatsListTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3EA540C1598528B0037DC6B /* ChatsListTableView.m */; }; D3EA5411159853750037DC6B /* UIChatCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D3EA5410159853750037DC6B /* UIChatCell.m */; }; - D3EA5418159858A80037DC6B /* list_delete_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3EA5416159858A80037DC6B /* list_delete_default.png */; }; - D3EA541A159858A80037DC6B /* list_delete_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3EA5417159858A80037DC6B /* list_delete_over.png */; }; - D3ED3E411585FB4A006C0DE4 /* background.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E401585FB4A006C0DE4 /* background.png */; }; - D3ED3E451585FB8C006C0DE4 /* dialer_address_background.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E441585FB8C006C0DE4 /* dialer_address_background.png */; }; - D3ED3E521585FFFD006C0DE4 /* statebar_background.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E511585FFFD006C0DE4 /* statebar_background.png */; }; - D3ED3E6A15861A53006C0DE4 /* add_contact_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E6715861A53006C0DE4 /* add_contact_default.png */; }; - D3ED3E6C15861A53006C0DE4 /* add_contact_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E6815861A53006C0DE4 /* add_contact_disabled.png */; }; - D3ED3E6E15861A53006C0DE4 /* add_contact_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E6915861A53006C0DE4 /* add_contact_over.png */; }; - D3ED3E7215861ABD006C0DE4 /* call_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E7015861ABD006C0DE4 /* call_default.png */; }; - D3ED3E7415861ABD006C0DE4 /* call_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E7115861ABD006C0DE4 /* call_over.png */; }; - D3ED3E7815861B1B006C0DE4 /* backspace_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E7615861B1B006C0DE4 /* backspace_default.png */; }; - D3ED3E7A15861B1B006C0DE4 /* backspace_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E7715861B1B006C0DE4 /* backspace_over.png */; }; - D3ED3E871586291E006C0DE4 /* UIMainBar.m in Sources */ = {isa = PBXBuildFile; fileRef = D3ED3E851586291B006C0DE4 /* UIMainBar.m */; }; - D3ED3E9815872EF1006C0DE4 /* history_all_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E9215872EF1006C0DE4 /* history_all_selected.png */; }; - D3ED3E9A15872EF1006C0DE4 /* history_all_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E9315872EF1006C0DE4 /* history_all_default.png */; }; - D3ED3E9C15872EF1006C0DE4 /* history_edit_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E9415872EF1006C0DE4 /* history_edit_default.png */; }; - D3ED3E9E15872EF1006C0DE4 /* history_edit_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E9515872EF1006C0DE4 /* history_edit_over.png */; }; - D3ED3EA015872EF1006C0DE4 /* history_missed_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E9615872EF1006C0DE4 /* history_missed_selected.png */; }; - D3ED3EA215872EF1006C0DE4 /* history_missed_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3ED3E9715872EF1006C0DE4 /* history_missed_default.png */; }; - D3ED3EA71587334E006C0DE4 /* HistoryTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3ED3EA51587334C006C0DE4 /* HistoryTableViewController.m */; }; - D3ED3EB81587392C006C0DE4 /* HistoryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3ED3EB615873929006C0DE4 /* HistoryViewController.m */; }; - D3ED40191602172200BF332B /* HPGrowingTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3ED40161602172200BF332B /* HPGrowingTextView.m */; }; - D3ED401B1602172200BF332B /* HPTextViewInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = D3ED40181602172200BF332B /* HPTextViewInternal.m */; }; - D3F26BF115986B73005F9CAB /* IncomingCallViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F26BEF15986B71005F9CAB /* IncomingCallViewController.m */; }; - D3F26BF715986DAD005F9CAB /* history_ok_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F26BF515986DAD005F9CAB /* history_ok_default.png */; }; - D3F26BF915986DAD005F9CAB /* history_ok_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F26BF615986DAD005F9CAB /* history_ok_over.png */; }; - D3F26BFC15987083005F9CAB /* header_incoming.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F26BFB15987083005F9CAB /* header_incoming.png */; }; - D3F34F301599B008005BE94F /* avatar_shadow.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F34F2F1599B008005BE94F /* avatar_shadow.png */; }; - D3F5F8F71609A86700D3DA1A /* chat_cancel_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8DA1609A86700D3DA1A /* chat_cancel_default.png */; }; - D3F5F8F91609A86700D3DA1A /* chat_cancel_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8DB1609A86700D3DA1A /* chat_cancel_over.png */; }; - D3F5F8FB1609A86700D3DA1A /* chat_photo_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8DC1609A86700D3DA1A /* chat_photo_default.png */; }; - D3F5F8FD1609A86700D3DA1A /* chat_photo_disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8DD1609A86700D3DA1A /* chat_photo_disabled.png */; }; - D3F5F8FF1609A86700D3DA1A /* chat_photo_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8DE1609A86700D3DA1A /* chat_photo_over.png */; }; - D3F5F9071609A86700D3DA1A /* history_delete_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8E21609A86700D3DA1A /* history_delete_default.png */; }; - D3F5F9091609A86700D3DA1A /* history_delete_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8E31609A86700D3DA1A /* history_delete_over.png */; }; - D3F5F90B1609A86700D3DA1A /* logo_linphone_trame_background.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8E41609A86700D3DA1A /* logo_linphone_trame_background.png */; }; - D3F5F90D1609A86700D3DA1A /* setup_back_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8E51609A86700D3DA1A /* setup_back_disabled~ipad.png */; }; - D3F5F90F1609A86700D3DA1A /* setup_back_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8E61609A86700D3DA1A /* setup_back_over_landscape~ipad.png */; }; - D3F5F9111609A86700D3DA1A /* setup_back_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8E71609A86700D3DA1A /* setup_back_over~ipad.png */; }; - D3F5F9131609A86700D3DA1A /* setup_cancel_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8E81609A86700D3DA1A /* setup_cancel_default_landscape~ipad.png */; }; - D3F5F9171609A86700D3DA1A /* setup_cancel_disabled_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8EA1609A86700D3DA1A /* setup_cancel_disabled_landscape~ipad.png */; }; - D3F5F9191609A86700D3DA1A /* setup_cancel_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8EB1609A86700D3DA1A /* setup_cancel_disabled~ipad.png */; }; - D3F5F91B1609A86700D3DA1A /* setup_cancel_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8EC1609A86700D3DA1A /* setup_cancel_over_landscape~ipad.png */; }; - D3F5F91F1609A86700D3DA1A /* setup_start_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8EE1609A86700D3DA1A /* setup_start_default_landscape~ipad.png */; }; - D3F5F9211609A86700D3DA1A /* setup_start_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8EF1609A86700D3DA1A /* setup_start_default~ipad.png */; }; - D3F5F9231609A86700D3DA1A /* setup_start_disabled_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8F01609A86700D3DA1A /* setup_start_disabled_landscape~ipad.png */; }; - D3F5F9251609A86700D3DA1A /* setup_start_disabled~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8F11609A86700D3DA1A /* setup_start_disabled~ipad.png */; }; - D3F5F9271609A86700D3DA1A /* setup_start_over_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8F21609A86700D3DA1A /* setup_start_over_landscape~ipad.png */; }; - D3F5F9291609A86700D3DA1A /* setup_start_over~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8F31609A86700D3DA1A /* setup_start_over~ipad.png */; }; - D3F5F92B1609A86700D3DA1A /* setup_welcome_logo~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F8F41609A86700D3DA1A /* setup_welcome_logo~ipad.png */; }; - D3F5F987160B1A0900D3DA1A /* chat_progressbar_background.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F983160B1A0800D3DA1A /* chat_progressbar_background.png */; }; - D3F5F989160B1A0900D3DA1A /* setup_back_default_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F984160B1A0800D3DA1A /* setup_back_default_landscape~ipad.png */; }; - D3F5F98B160B1A0900D3DA1A /* setup_back_default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F985160B1A0800D3DA1A /* setup_back_default~ipad.png */; }; - D3F5F98D160B1A0900D3DA1A /* setup_back_disabled_landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F5F986160B1A0900D3DA1A /* setup_back_disabled_landscape~ipad.png */; }; - D3F795D615A582810077328B /* ChatRoomViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F795D415A582800077328B /* ChatRoomViewController.m */; }; - D3F795DD15A5831C0077328B /* chat_back_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F795DB15A5831C0077328B /* chat_back_default.png */; }; - D3F795DF15A5831C0077328B /* chat_back_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F795DC15A5831C0077328B /* chat_back_over.png */; }; + D3ED3E871586291E006C0DE4 /* TabBarView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3ED3E851586291B006C0DE4 /* TabBarView.m */; }; + D3ED3EA71587334E006C0DE4 /* HistoryListTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3ED3EA51587334C006C0DE4 /* HistoryListTableView.m */; }; + D3ED3EB81587392C006C0DE4 /* HistoryListView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3ED3EB615873929006C0DE4 /* HistoryListView.m */; }; + D3F26BF115986B73005F9CAB /* CallIncomingView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F26BEF15986B71005F9CAB /* CallIncomingView.m */; }; + D3F795D615A582810077328B /* ChatConversationView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F795D415A582800077328B /* ChatConversationView.m */; }; D3F7998115BD32370018C273 /* TPMultiLayoutViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F7998015BD32370018C273 /* TPMultiLayoutViewController.m */; }; - D3F83EEC1582021700336684 /* InCallViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F83EEA1582021700336684 /* InCallViewController.m */; }; - D3F83F0C158205A100336684 /* micro_off_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83EF4158205A100336684 /* micro_off_default.png */; }; - D3F83F0E158205A100336684 /* micro_off_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83EF5158205A100336684 /* micro_off_over.png */; }; - D3F83F10158205A100336684 /* micro_on_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83EF6158205A100336684 /* micro_on_default.png */; }; - D3F83F12158205A100336684 /* micro_on_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83EF7158205A100336684 /* micro_on_over.png */; }; - D3F83F14158205A100336684 /* pause_off_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83EF8158205A100336684 /* pause_off_default.png */; }; - D3F83F16158205A100336684 /* pause_off_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83EF9158205A100336684 /* pause_off_over.png */; }; - D3F83F18158205A100336684 /* hangup_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83EFA158205A100336684 /* hangup_default.png */; }; - D3F83F1A158205A100336684 /* hangup_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83EFB158205A100336684 /* hangup_over.png */; }; - D3F83F1C158205A100336684 /* speaker_off_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83EFC158205A100336684 /* speaker_off_default.png */; }; - D3F83F1E158205A100336684 /* speaker_off_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83EFD158205A100336684 /* speaker_off_over.png */; }; - D3F83F20158205A100336684 /* speaker_on_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83EFE158205A100336684 /* speaker_on_default.png */; }; - D3F83F22158205A100336684 /* speaker_on_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83EFF158205A100336684 /* speaker_on_over.png */; }; - D3F83F24158205A100336684 /* video_off_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F00158205A100336684 /* video_off_default.png */; }; - D3F83F26158205A100336684 /* video_off_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F01158205A100336684 /* video_off_over.png */; }; - D3F83F28158205A100336684 /* video_on_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F02158205A100336684 /* video_on_default.png */; }; - D3F83F2A158205A100336684 /* video_on_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F03158205A100336684 /* video_on_over.png */; }; - D3F83F441582223B00336684 /* numpad_zero_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F2C1582223B00336684 /* numpad_zero_default.png */; }; - D3F83F461582223B00336684 /* numpad_zero_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F2D1582223B00336684 /* numpad_zero_over.png */; }; - D3F83F481582223B00336684 /* numpad_one_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F2E1582223B00336684 /* numpad_one_default.png */; }; - D3F83F4A1582223B00336684 /* numpad_one_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F2F1582223B00336684 /* numpad_one_over.png */; }; - D3F83F4C1582223B00336684 /* numpad_two_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F301582223B00336684 /* numpad_two_default.png */; }; - D3F83F4E1582223B00336684 /* numpad_two_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F311582223B00336684 /* numpad_two_over.png */; }; - D3F83F501582223B00336684 /* numpad_three_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F321582223B00336684 /* numpad_three_default.png */; }; - D3F83F521582223B00336684 /* numpad_three_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F331582223B00336684 /* numpad_three_over.png */; }; - D3F83F541582223B00336684 /* numpad_four_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F341582223B00336684 /* numpad_four_default.png */; }; - D3F83F561582223B00336684 /* numpad_four_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F351582223B00336684 /* numpad_four_over.png */; }; - D3F83F581582223B00336684 /* numpad_five_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F361582223B00336684 /* numpad_five_default.png */; }; - D3F83F5A1582223B00336684 /* numpad_five_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F371582223B00336684 /* numpad_five_over.png */; }; - D3F83F5C1582223B00336684 /* numpad_six_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F381582223B00336684 /* numpad_six_default.png */; }; - D3F83F5E1582223B00336684 /* numpad_six_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F391582223B00336684 /* numpad_six_over.png */; }; - D3F83F601582223B00336684 /* numpad_seven_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F3A1582223B00336684 /* numpad_seven_default.png */; }; - D3F83F621582223B00336684 /* numpad_seven_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F3B1582223B00336684 /* numpad_seven_over.png */; }; - D3F83F641582223B00336684 /* numpad_eight_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F3C1582223B00336684 /* numpad_eight_default.png */; }; - D3F83F661582223B00336684 /* numpad_eight_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F3D1582223B00336684 /* numpad_eight_over.png */; }; - D3F83F681582223B00336684 /* numpad_nine_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F3E1582223B00336684 /* numpad_nine_default.png */; }; - D3F83F6A1582223B00336684 /* numpad_nine_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F3F1582223B00336684 /* numpad_nine_over.png */; }; - D3F83F6C1582223B00336684 /* numpad_sharp_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F401582223B00336684 /* numpad_sharp_default.png */; }; - D3F83F6E1582223B00336684 /* numpad_sharp_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F411582223B00336684 /* numpad_sharp_over.png */; }; - D3F83F721582223B00336684 /* numpad_star_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F431582223B00336684 /* numpad_star_default.png */; }; - D3F83F781582253100336684 /* accept_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F741582253100336684 /* accept_default.png */; }; - D3F83F7A1582253100336684 /* accept_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F751582253100336684 /* accept_over.png */; }; - D3F83F7C1582253100336684 /* decline_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F761582253100336684 /* decline_default.png */; }; - D3F83F7E1582253100336684 /* decline_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F83F771582253100336684 /* decline_over.png */; }; + D3F83EEC1582021700336684 /* CallView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F83EEA1582021700336684 /* CallView.m */; }; D3F83F8E15822ABE00336684 /* PhoneMainView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F83F8D15822ABD00336684 /* PhoneMainView.m */; }; - D3F9A9DB15AEEB940045320F /* history_notification.png in Resources */ = {isa = PBXBuildFile; fileRef = D3F9A9DA15AEEB940045320F /* history_notification.png */; }; - D3F9A9EE15AF277E0045320F /* UACellBackgroundView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3F9A9ED15AF277D0045320F /* UACellBackgroundView.m */; }; - F0022B091A370915009B51FD /* messages.db in Resources */ = {isa = PBXBuildFile; fileRef = F0022B081A370915009B51FD /* messages.db */; }; - F0022B0A1A370915009B51FD /* messages.db in Resources */ = {isa = PBXBuildFile; fileRef = F0022B081A370915009B51FD /* messages.db */; }; - F01A77EB18ED989B00E287CA /* shortring.caf in Resources */ = {isa = PBXBuildFile; fileRef = F01A77EA18ED989B00E287CA /* shortring.caf */; }; F03CA84318C72F1A0008889D /* UITextViewNoDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = F03CA84218C72F1A0008889D /* UITextViewNoDefine.m */; }; - F04892FF180C3296002FED35 /* ImageOptim.sh in Resources */ = {isa = PBXBuildFile; fileRef = F04892FE180C3296002FED35 /* ImageOptim.sh */; }; F05BAA621A5D594E00411815 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F05BAA611A5D594E00411815 /* libz.dylib */; }; F05BAA631A5D75BC00411815 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F05BAA611A5D594E00411815 /* libz.dylib */; }; F0642EF119DAC891009DB336 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F0642EF019DAC891009DB336 /* MainStoryboard.storyboard */; }; - F066515517F9A02E0064280C /* UITransparentTVCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F066515417F9A02E0064280C /* UITransparentTVCell.m */; }; - F070E6331A2622EC00E17AFD /* dialer_padding_left.png in Resources */ = {isa = PBXBuildFile; fileRef = F070E62D1A2622EC00E17AFD /* dialer_padding_left.png */; }; - F070E6341A2622EC00E17AFD /* dialer_padding_right.png in Resources */ = {isa = PBXBuildFile; fileRef = F070E62E1A2622EC00E17AFD /* dialer_padding_right.png */; }; - F070E6351A2622EC00E17AFD /* incall_padding_left_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = F070E62F1A2622EC00E17AFD /* incall_padding_left_landscape.png */; }; - F070E6361A2622EC00E17AFD /* incall_padding_left.png in Resources */ = {isa = PBXBuildFile; fileRef = F070E6301A2622EC00E17AFD /* incall_padding_left.png */; }; - F070E6371A2622EC00E17AFD /* incall_padding_right_landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = F070E6311A2622EC00E17AFD /* incall_padding_right_landscape.png */; }; - F070E6381A2622EC00E17AFD /* incall_padding_right.png in Resources */ = {isa = PBXBuildFile; fileRef = F070E6321A2622EC00E17AFD /* incall_padding_right.png */; }; F088488A19FF8C41007FFCF3 /* UIContactCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F088488D19FF8C41007FFCF3 /* UIContactCell.xib */; }; - F08BDC3D1A35E60F006210C9 /* liblinphonetester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F0BB8C0F193623F200974404 /* liblinphonetester.a */; }; - F08F118519C09C6B007D70C2 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A9B3318C0CF7000C4D7FE /* XCTest.framework */; }; + F08D468D1AA86849001E8CB5 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F0B026F21AA710AF00FF49F7 /* libiconv.dylib */; }; F08F118619C09C6B007D70C2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; F08F118719C09C6B007D70C2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - F08F118D19C09C6B007D70C2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F08F118B19C09C6B007D70C2 /* InfoPlist.strings */; }; - F08F118F19C09C6B007D70C2 /* LinphoneTester_Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = F08F118E19C09C6B007D70C2 /* LinphoneTester_Tests.m */; }; - F08F119919C09D88007D70C2 /* flexisip in Resources */ = {isa = PBXBuildFile; fileRef = F08F119819C09D88007D70C2 /* flexisip */; }; - F08F119A19C09D88007D70C2 /* flexisip in Resources */ = {isa = PBXBuildFile; fileRef = F08F119819C09D88007D70C2 /* flexisip */; }; - F08F119D19C0A65B007D70C2 /* NSObject+DTRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = F08F119C19C0A65B007D70C2 /* NSObject+DTRuntime.m */; }; - F08F11A019C0A6CB007D70C2 /* DTObjectBlockExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = F08F119F19C0A6CB007D70C2 /* DTObjectBlockExecutor.m */; }; F0938159188E629800A55DFA /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = F0938158188E629800A55DFA /* iTunesArtwork */; }; - F0A1CE081A6B056E001CA2BE /* ChatTester.m in Sources */ = {isa = PBXBuildFile; fileRef = F0A1CE071A6B056E001CA2BE /* ChatTester.m */; }; - F0B4FB5D1A65550B00637027 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F0B4FB5C1A65550B00637027 /* Images.xcassets */; }; + F0A54B0C1AD56F4600C22733 /* libc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A9B9718C0DB6F00C4D7FE /* libc++.dylib */; }; + F0A54B0D1AD56F4600C22733 /* libstdc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A9B9418C0DAE100C4D7FE /* libstdc++.dylib */; }; + F0B026F31AA710AF00FF49F7 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F0B026F21AA710AF00FF49F7 /* libiconv.dylib */; }; F0B89C2218DC89E30050B60E /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F0B89C2118DC89E30050B60E /* MediaPlayer.framework */; }; - F0B89C2818DC973E0050B60E /* wizard_external_sip.rc in Resources */ = {isa = PBXBuildFile; fileRef = F0B89C2418DC973E0050B60E /* wizard_external_sip.rc */; }; - F0B89C2A18DC973E0050B60E /* wizard_linphone_create.rc in Resources */ = {isa = PBXBuildFile; fileRef = F0B89C2518DC973E0050B60E /* wizard_linphone_create.rc */; }; - F0B89C2C18DC973E0050B60E /* wizard_linphone_existing.rc in Resources */ = {isa = PBXBuildFile; fileRef = F0B89C2618DC973E0050B60E /* wizard_linphone_existing.rc */; }; - F0B89C2E18DC973E0050B60E /* wizard_remote.rc in Resources */ = {isa = PBXBuildFile; fileRef = F0B89C2718DC973E0050B60E /* wizard_remote.rc */; }; F0BB8BD61936208100974404 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; F0BB8BD71936208100974404 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; F0BB8BD81936208100974404 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - F0BB8BDE1936208100974404 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8BDC1936208100974404 /* InfoPlist.strings */; }; - F0BB8BE01936208100974404 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F0BB8BDF1936208100974404 /* main.m */; }; - F0BB8BE41936208100974404 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F0BB8BE31936208100974404 /* AppDelegate.m */; }; - F0BB8BE71936208200974404 /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8BE51936208100974404 /* Main_iPhone.storyboard */; }; - F0BB8BEA1936208200974404 /* Main_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8BE81936208200974404 /* Main_iPad.storyboard */; }; - F0BB8BED1936208200974404 /* MasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F0BB8BEC1936208200974404 /* MasterViewController.m */; }; - F0BB8BF01936208200974404 /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F0BB8BEF1936208200974404 /* DetailViewController.m */; }; - F0BB8BF21936208200974404 /* TesterImages.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8BF11936208200974404 /* TesterImages.xcassets */; }; F0BB8C10193623F300974404 /* liblinphonetester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F0BB8C0F193623F200974404 /* liblinphonetester.a */; }; F0BB8C121936240300974404 /* libcunit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F0BB8C111936240300974404 /* libcunit.a */; }; F0BB8C131936242400974404 /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2211DB911475562600DEE054 /* liblinphone.a */; }; @@ -725,66 +664,64 @@ F0BB8C191936245300974404 /* libbellesip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 223CA7E516D9255800EF1BEC /* libbellesip.a */; }; F0BB8C1A1936245300974404 /* libbzrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 045B5CB218D72E9A0088350C /* libbzrtp.a */; }; F0BB8C1B1936245300974404 /* libgsm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD2910765B400068D98F /* libgsm.a */; }; - F0BB8C1C1936245300974404 /* libilbc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 223148E31178A08200637D6A /* libilbc.a */; }; F0BB8C1D1936245300974404 /* libmsamr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226F2ED51344B0EF00F6EF27 /* libmsamr.a */; }; F0BB8C1E1936245300974404 /* libmsbcg729.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226CDADE14E2D0B800513B67 /* libmsbcg729.a */; }; - F0BB8C1F1936245300974404 /* libmsilbc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 223148E51178A09900637D6A /* libmsilbc.a */; }; F0BB8C201936245300974404 /* libmssilk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226183AF147259670037138E /* libmssilk.a */; }; - F0BB8C211936245300974404 /* libmsx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22AA8AFC13D7125500B30535 /* libmsx264.a */; }; F0BB8C221936245300974404 /* libopencore-amrnb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226F2ED41344B0EF00F6EF27 /* libopencore-amrnb.a */; }; F0BB8C231936245300974404 /* libopencore-amrwb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226F2ED31344B0EF00F6EF27 /* libopencore-amrwb.a */; }; F0BB8C241936245300974404 /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22AF73C11754C0D000BE8398 /* libopus.a */; }; F0BB8C251936245300974404 /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD2C10765B400068D98F /* libortp.a */; }; F0BB8C261936245300974404 /* libpolarssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 57B0E35F173C010400A476B8 /* libpolarssl.a */; }; - F0BB8C271936245300974404 /* libSKP_SILK_SDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226183AA1472527D0037138E /* libSKP_SILK_SDK.a */; }; F0BB8C281936245300974404 /* libspeex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD2F10765B400068D98F /* libspeex.a */; }; F0BB8C291936245300974404 /* libspeexdsp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD3010765B400068D98F /* libspeexdsp.a */; }; F0BB8C2A1936245300974404 /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226183AB1472527D0037138E /* libsrtp.a */; }; F0BB8C2B1936245300974404 /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22276E8213C73D3100210156 /* libswscale.a */; }; F0BB8C2C1936245300974404 /* libtunnel.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D30BF33216A427BC00AF0026 /* libtunnel.a */; }; F0BB8C2D1936245300974404 /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7066FC0B13E830E400EFC6DC /* libvpx.a */; }; - F0BB8C2E1936245300974404 /* libx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22AA8AFB13D7125500B30535 /* libx264.a */; }; - F0BB8C2F1936245300974404 /* libxml2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 15017E6F1773578400784ACB /* libxml2.a */; }; F0BB8C301936246600974404 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2274402E106F335E006EC466 /* AudioToolbox.framework */; }; F0BB8C331936247C00974404 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D32B6E2E15A5C0AC0033019F /* libsqlite3.dylib */; }; F0BB8C35193624C800974404 /* libresolv.9.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F0BB8C34193624C800974404 /* libresolv.9.dylib */; }; - F0BB8C3819362C1500974404 /* rcfiles in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C3719362C1500974404 /* rcfiles */; }; - F0BB8C3C19362C2200974404 /* certificates in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C3919362C2200974404 /* certificates */; }; - F0BB8C3D19362C2200974404 /* images in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C3A19362C2200974404 /* images */; }; - F0BB8C3E19362C2200974404 /* sounds in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C3B19362C2200974404 /* sounds */; }; - F0BB8C45193630CA00974404 /* local_tester_hosts in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C40193630CA00974404 /* local_tester_hosts */; }; - F0BB8C46193630CA00974404 /* marie_xml in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C41193630CA00974404 /* marie_xml */; }; - F0BB8C47193630CA00974404 /* tester_hosts in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C42193630CA00974404 /* tester_hosts */; }; F0BB8C4C193631D200974404 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22276E8813C73DC000210156 /* CoreMedia.framework */; }; F0BB8C4D193631DF00974404 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 224567C1107B968500F10948 /* AVFoundation.framework */; }; - F0C1F8EB1A277ADA009402C9 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = F0C1F8EA1A277ADA009402C9 /* LaunchScreen.xib */; }; - F0C1F90E1A28781F009402C9 /* background-launch.png in Resources */ = {isa = PBXBuildFile; fileRef = F0C1F9041A28781F009402C9 /* background-launch.png */; }; - F0C1F9101A28781F009402C9 /* corner-left-bottom.png in Resources */ = {isa = PBXBuildFile; fileRef = F0C1F9061A28781F009402C9 /* corner-left-bottom.png */; }; - F0C1F9111A28781F009402C9 /* corner-left-top.png in Resources */ = {isa = PBXBuildFile; fileRef = F0C1F9071A28781F009402C9 /* corner-left-top.png */; }; - F0C1F9121A28781F009402C9 /* corner-right-bottom.png in Resources */ = {isa = PBXBuildFile; fileRef = F0C1F9081A28781F009402C9 /* corner-right-bottom.png */; }; - F0C1F9131A28781F009402C9 /* corner-right-top.png in Resources */ = {isa = PBXBuildFile; fileRef = F0C1F9091A28781F009402C9 /* corner-right-top.png */; }; - F0C1F9141A28781F009402C9 /* logo.png in Resources */ = {isa = PBXBuildFile; fileRef = F0C1F90A1A28781F009402C9 /* logo.png */; }; - F0C1F9151A28781F009402C9 /* strech-bottom.png in Resources */ = {isa = PBXBuildFile; fileRef = F0C1F90B1A28781F009402C9 /* strech-bottom.png */; }; - F0C1F9161A28781F009402C9 /* strech-top.png in Resources */ = {isa = PBXBuildFile; fileRef = F0C1F90C1A28781F009402C9 /* strech-top.png */; }; - F0C1F91D1A2CA345009402C9 /* local_tester_hosts in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C40193630CA00974404 /* local_tester_hosts */; }; - F0C1F91E1A2CA352009402C9 /* marie_xml in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C41193630CA00974404 /* marie_xml */; }; - F0C1F91F1A2CA354009402C9 /* tester_hosts in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C42193630CA00974404 /* tester_hosts */; }; - F0C1F9201A2CA358009402C9 /* rcfiles in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C3719362C1500974404 /* rcfiles */; }; - F0C1F9211A2CA35A009402C9 /* sounds in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C3B19362C2200974404 /* sounds */; }; - F0C1F9221A2CA35C009402C9 /* images in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C3A19362C2200974404 /* images */; }; - F0C1F9231A2CA35E009402C9 /* certificates in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C3919362C2200974404 /* certificates */; }; - F0C773921A94828900E0C486 /* libKIF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F0C773871A94822700E0C486 /* libKIF.a */; }; - F0F952121A6AECD300254160 /* WizardTester.m in Sources */ = {isa = PBXBuildFile; fileRef = F0F952111A6AECD300254160 /* WizardTester.m */; }; - F476004B147AAF2800FFF19B /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2211DB911475562600DEE054 /* liblinphone.a */; }; - F84015BF1939FE37006ABAB5 /* test_failed.png in Resources */ = {isa = PBXBuildFile; fileRef = F84015BC1939FE37006ABAB5 /* test_failed.png */; }; - F84015C01939FE37006ABAB5 /* test_inprogress.png in Resources */ = {isa = PBXBuildFile; fileRef = F84015BD1939FE37006ABAB5 /* test_inprogress.png */; }; - F84015C11939FE37006ABAB5 /* test_passed.png in Resources */ = {isa = PBXBuildFile; fileRef = F84015BE1939FE37006ABAB5 /* test_passed.png */; }; - F84015C7193B4E34006ABAB5 /* LogsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F84015C6193B4E34006ABAB5 /* LogsViewController.m */; }; - F844AB141A93E3A200428306 /* ContactsTester.m in Sources */ = {isa = PBXBuildFile; fileRef = F844AB131A93E3A200428306 /* ContactsTester.m */; }; - F85554481A6DA2F400A9F915 /* LinphoneTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = F85554471A6DA2F400A9F915 /* LinphoneTestCase.m */; }; + F0FF66AC1ACAEF4F008A4486 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F0FF66AA1ACAEEB0008A4486 /* IOKit.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 630589FC1B4E816A00EFAE36 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 630589F21B4E816900EFAE36 /* KIF.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EABD46AA1857A0C700A5F081; + remoteInfo = KIF; + }; + 63058A001B4E816A00EFAE36 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 630589F21B4E816900EFAE36 /* KIF.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EB60ECC1177F8C83005A041A; + remoteInfo = "Test Host"; + }; + 63058A021B4E816A00EFAE36 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 630589F21B4E816900EFAE36 /* KIF.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EABD46CD1857A0F300A5F081; + remoteInfo = "KIF Tests"; + }; + 63058A061B4E816A00EFAE36 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 630589F21B4E816900EFAE36 /* KIF.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 9CC9673B1AD4B1B600576D13; + remoteInfo = KIFFramework; + }; + 63058A4D1B4E832500EFAE36 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 630589F21B4E816900EFAE36 /* KIF.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = EABD46791857A0C700A5F081; + remoteInfo = KIF; + }; D3554ED015CA79AA00478841 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D3554EC515CA79A900478841 /* XMLRPC.xcodeproj */; @@ -799,20 +736,6 @@ remoteGlobalIDString = 903B0DB512F7574800BD6E09; remoteInfo = libXMLRPC; }; - D3B90E1815C2CB5800F64F8C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D3B90E1115C2CB5700F64F8C /* NinePatch.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = D2AAC07E0554694100DB518D; - remoteInfo = NinePatch; - }; - D3B90E1A15C2CBC800F64F8C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D3B90E1115C2CB5700F64F8C /* NinePatch.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = D2AAC07D0554694100DB518D; - remoteInfo = NinePatch; - }; F08F119119C09C6B007D70C2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; @@ -820,48 +743,6 @@ remoteGlobalIDString = F0BB8BD41936208100974404; remoteInfo = LinphoneTester; }; - F0C773861A94822700E0C486 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F0C7737D1A94822600E0C486 /* KIF.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = EABD46AA1857A0C700A5F081; - remoteInfo = KIF; - }; - F0C773881A94822700E0C486 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F0C7737D1A94822600E0C486 /* KIF.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = EB72047C1680DDAD00278DA2; - remoteInfo = "KIF-OCUnit"; - }; - F0C7738A1A94822700E0C486 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F0C7737D1A94822600E0C486 /* KIF.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = EB60ECC1177F8C83005A041A; - remoteInfo = "Test Host"; - }; - F0C7738C1A94822700E0C486 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F0C7737D1A94822600E0C486 /* KIF.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = EABD46CD1857A0F300A5F081; - remoteInfo = "KIF Tests"; - }; - F0C7738E1A94822700E0C486 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F0C7737D1A94822600E0C486 /* KIF.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = EB60ECEB177F8DB3005A041A; - remoteInfo = "KIF Tests-OCUnit"; - }; - F0C773901A94827E00E0C486 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = F0C7737D1A94822600E0C486 /* KIF.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = EABD46791857A0C700A5F081; - remoteInfo = KIF; - }; F0F952061A6AEB1000254160 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; @@ -876,7 +757,7 @@ isa = PBXCopyFilesBuildPhase; buildActionMask = 12; dstPath = ""; - dstSubfolderSpec = 11; + dstSubfolderSpec = 16; files = ( ); runOnlyForDeploymentPostprocessing = 0; @@ -885,85 +766,40 @@ /* Begin PBXFileReference section */ 045B5CB218D72E9A0088350C /* libbzrtp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbzrtp.a; path = "liblinphone-sdk/apple-darwin/lib/libbzrtp.a"; sourceTree = ""; }; - 15017E6F1773578400784ACB /* libxml2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libxml2.a; path = "liblinphone-sdk/apple-darwin/lib/libxml2.a"; sourceTree = ""; }; + 152F22351B15E889008C0621 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; }; 1560821E18EEF26100765332 /* libmsopenh264.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmsopenh264.a; path = "liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmsopenh264.a"; sourceTree = ""; }; - 1599104316F746B2007BF52B /* route_bluetooth_off_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_bluetooth_off_default_landscape.png; path = Resources/route_bluetooth_off_default_landscape.png; sourceTree = ""; }; - 1599104416F746B2007BF52B /* route_bluetooth_off_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_bluetooth_off_disabled_landscape.png; path = Resources/route_bluetooth_off_disabled_landscape.png; sourceTree = ""; }; - 1599104516F746B2007BF52B /* route_bluetooth_off_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_bluetooth_off_over_landscape.png; path = Resources/route_bluetooth_off_over_landscape.png; sourceTree = ""; }; - 1599104616F746B2007BF52B /* route_bluetooth_on_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_bluetooth_on_default_landscape.png; path = Resources/route_bluetooth_on_default_landscape.png; sourceTree = ""; }; - 1599104716F746B2007BF52B /* route_phone_off_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_phone_off_default_landscape.png; path = Resources/route_phone_off_default_landscape.png; sourceTree = ""; }; - 1599104816F746B2007BF52B /* route_phone_off_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_phone_off_disabled_landscape.png; path = Resources/route_phone_off_disabled_landscape.png; sourceTree = ""; }; - 1599104916F746B2007BF52B /* route_phone_off_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_phone_off_over_landscape.png; path = Resources/route_phone_off_over_landscape.png; sourceTree = ""; }; - 1599104A16F746B2007BF52B /* route_phone_on_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_phone_on_default_landscape.png; path = Resources/route_phone_on_default_landscape.png; sourceTree = ""; }; - 1599104B16F746B2007BF52B /* route_speaker_off_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_speaker_off_default_landscape.png; path = Resources/route_speaker_off_default_landscape.png; sourceTree = ""; }; - 1599104C16F746B2007BF52B /* route_speaker_off_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_speaker_off_disabled_landscape.png; path = Resources/route_speaker_off_disabled_landscape.png; sourceTree = ""; }; - 1599104D16F746B2007BF52B /* route_speaker_off_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_speaker_off_over_landscape.png; path = Resources/route_speaker_off_over_landscape.png; sourceTree = ""; }; - 1599104E16F746B2007BF52B /* route_speaker_on_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_speaker_on_default_landscape.png; path = Resources/route_speaker_on_default_landscape.png; sourceTree = ""; }; - 1599104F16F746B2007BF52B /* routes_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = routes_default_landscape.png; path = Resources/routes_default_landscape.png; sourceTree = ""; }; - 1599105016F746B2007BF52B /* routes_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = routes_disabled_landscape.png; path = Resources/routes_disabled_landscape.png; sourceTree = ""; }; - 1599105116F746B2007BF52B /* routes_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = routes_over_landscape.png; path = Resources/routes_over_landscape.png; sourceTree = ""; }; - 1599105216F746B2007BF52B /* routes_selected_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = routes_selected_landscape.png; path = Resources/routes_selected_landscape.png; sourceTree = ""; }; - 15AF3C4C16F37A3E00FC52EC /* route_bluetooth_off_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_bluetooth_off_default.png; path = Resources/route_bluetooth_off_default.png; sourceTree = ""; }; - 15AF3C4D16F37A3E00FC52EC /* route_bluetooth_off_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_bluetooth_off_disabled.png; path = Resources/route_bluetooth_off_disabled.png; sourceTree = ""; }; - 15AF3C4E16F37A3E00FC52EC /* route_bluetooth_off_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_bluetooth_off_over.png; path = Resources/route_bluetooth_off_over.png; sourceTree = ""; }; - 15AF3C5016F37A3E00FC52EC /* route_bluetooth_on_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_bluetooth_on_default.png; path = Resources/route_bluetooth_on_default.png; sourceTree = ""; }; - 15AF3C6416F37A4A00FC52EC /* route_phone_off_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_phone_off_default.png; path = Resources/route_phone_off_default.png; sourceTree = ""; }; - 15AF3C6516F37A4A00FC52EC /* route_phone_off_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_phone_off_disabled.png; path = Resources/route_phone_off_disabled.png; sourceTree = ""; }; - 15AF3C6616F37A4A00FC52EC /* route_phone_off_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_phone_off_over.png; path = Resources/route_phone_off_over.png; sourceTree = ""; }; - 15AF3C6816F37A4A00FC52EC /* route_phone_on_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_phone_on_default.png; path = Resources/route_phone_on_default.png; sourceTree = ""; }; - 15AF3C7C16F37A5500FC52EC /* route_speaker_off_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_speaker_off_default.png; path = Resources/route_speaker_off_default.png; sourceTree = ""; }; - 15AF3C7D16F37A5500FC52EC /* route_speaker_off_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_speaker_off_disabled.png; path = Resources/route_speaker_off_disabled.png; sourceTree = ""; }; - 15AF3C7E16F37A5500FC52EC /* route_speaker_off_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_speaker_off_over.png; path = Resources/route_speaker_off_over.png; sourceTree = ""; }; - 15AF3C8016F37A5500FC52EC /* route_speaker_on_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = route_speaker_on_default.png; path = Resources/route_speaker_on_default.png; sourceTree = ""; }; - 15AF3C9416F37A5D00FC52EC /* routes_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = routes_default.png; path = Resources/routes_default.png; sourceTree = ""; }; - 15AF3C9516F37A5D00FC52EC /* routes_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = routes_disabled.png; path = Resources/routes_disabled.png; sourceTree = ""; }; - 15AF3C9616F37A5D00FC52EC /* routes_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = routes_over.png; path = Resources/routes_over.png; sourceTree = ""; }; - 15AF3C9716F37A5D00FC52EC /* routes_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = routes_selected.png; path = Resources/routes_selected.png; sourceTree = ""; }; 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 1D3623240D0F684500981E51 /* LinphoneAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinphoneAppDelegate.h; sourceTree = ""; }; 1D3623250D0F684500981E51 /* LinphoneAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LinphoneAppDelegate.m; sourceTree = ""; }; 1D6058910D05DD3D006BFB54 /* linphone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = linphone.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - 1FE76362DA6217E7341ED1DF /* libPods-KifTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-KifTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 220FAD2910765B400068D98F /* libgsm.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgsm.a; path = "liblinphone-sdk/apple-darwin/lib/libgsm.a"; sourceTree = ""; }; 220FAD2C10765B400068D98F /* libortp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libortp.a; path = "liblinphone-sdk/apple-darwin/lib/libortp.a"; sourceTree = ""; }; 220FAD2F10765B400068D98F /* libspeex.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libspeex.a; path = "liblinphone-sdk/apple-darwin/lib/libspeex.a"; sourceTree = ""; }; 220FAD3010765B400068D98F /* libspeexdsp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libspeexdsp.a; path = "liblinphone-sdk/apple-darwin/lib/libspeexdsp.a"; sourceTree = ""; }; 2211DB911475562600DEE054 /* liblinphone.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblinphone.a; path = "liblinphone-sdk/apple-darwin/lib/liblinphone.a"; sourceTree = ""; }; - 2214783C1386A2030020F8B8 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = Resources/en.lproj/Localizable.strings; sourceTree = ""; }; 2214EB7812F846B1002A5394 /* UICallButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICallButton.h; sourceTree = ""; }; 2214EB7912F846B1002A5394 /* UICallButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICallButton.m; sourceTree = ""; }; 2214EB8712F84EBB002A5394 /* UIHangUpButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIHangUpButton.h; sourceTree = ""; }; 2214EB8812F84EBB002A5394 /* UIHangUpButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIHangUpButton.m; sourceTree = ""; }; 2214EBF112F86360002A5394 /* UIMicroButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIMicroButton.h; sourceTree = ""; }; 2214EBF212F86360002A5394 /* UIMicroButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIMicroButton.m; sourceTree = ""; }; - 2218A92212FBE1340088A667 /* FirstLoginViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FirstLoginViewController.h; sourceTree = ""; }; - 2218A92312FBE1340088A667 /* FirstLoginViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = FirstLoginViewController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 22276E8013C73D3100210156 /* libavcodec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavcodec.a; path = "liblinphone-sdk/apple-darwin/lib/libavcodec.a"; sourceTree = ""; }; 22276E8113C73D3100210156 /* libavutil.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavutil.a; path = "liblinphone-sdk/apple-darwin/lib/libavutil.a"; sourceTree = ""; }; 22276E8213C73D3100210156 /* libswscale.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libswscale.a; path = "liblinphone-sdk/apple-darwin/lib/libswscale.a"; sourceTree = ""; }; 22276E8613C73D8A00210156 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; 22276E8813C73DC000210156 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; - 223148E31178A08200637D6A /* libilbc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libilbc.a; path = "liblinphone-sdk/apple-darwin/lib/libilbc.a"; sourceTree = ""; }; - 223148E51178A09900637D6A /* libmsilbc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmsilbc.a; path = "liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmsilbc.a"; sourceTree = ""; }; - 2234C8E715EE2F7F00E18E83 /* chat_message_delivered.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_message_delivered.png; path = Resources/chat_message_delivered.png; sourceTree = ""; }; - 2234C8E815EE2F7F00E18E83 /* chat_message_not_delivered.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_message_not_delivered.png; path = Resources/chat_message_not_delivered.png; sourceTree = ""; }; - 2234C8ED15EE744200E18E83 /* chat_message_inprogress.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_message_inprogress.png; path = Resources/chat_message_inprogress.png; sourceTree = ""; }; - 2237D4081084D7A9001383EE /* ring.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = ring.wav; path = Resources/ring.wav; sourceTree = ""; }; 223CA7E416D9255800EF1BEC /* libantlr3c.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libantlr3c.a; path = "liblinphone-sdk/apple-darwin/lib/libantlr3c.a"; sourceTree = ""; }; 223CA7E516D9255800EF1BEC /* libbellesip.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbellesip.a; path = "liblinphone-sdk/apple-darwin/lib/libbellesip.a"; sourceTree = ""; }; 22405EE916006F0700B92522 /* libmediastreamer_base.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmediastreamer_base.a; path = "liblinphone-sdk/apple-darwin/lib/libmediastreamer_base.a"; sourceTree = ""; }; 22405EEA16006F0700B92522 /* libmediastreamer_voip.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmediastreamer_voip.a; path = "liblinphone-sdk/apple-darwin/lib/libmediastreamer_voip.a"; sourceTree = ""; }; 22405EED1600B4E400B92522 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; - 22405EFD1601C19000B92522 /* ImageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageViewController.h; sourceTree = ""; }; - 22405EFE1601C19100B92522 /* ImageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageViewController.m; sourceTree = ""; }; - 2242E312125235120061DDCE /* ring.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = ring.caf; path = Resources/ring.caf; sourceTree = ""; }; + 22405EFD1601C19000B92522 /* ImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageView.h; sourceTree = ""; }; + 22405EFE1601C19100B92522 /* ImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageView.m; sourceTree = ""; }; 224567C1107B968500F10948 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; 2248E90C12F7E4CF00220D9C /* UIDigitButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIDigitButton.h; sourceTree = ""; }; 2248E90D12F7E4CF00220D9C /* UIDigitButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIDigitButton.m; sourceTree = ""; }; 22509041196BD902007863F6 /* libopenh264.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopenh264.a; path = "liblinphone-sdk/apple-darwin/lib/libopenh264.a"; sourceTree = ""; }; - 225CB2F911ABB76400628906 /* linphone-banner.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "linphone-banner.png"; path = "liblinphone-sdk/apple-darwin/share/pixmaps/linphone/linphone-banner.png"; sourceTree = ""; }; - 226183AA1472527D0037138E /* libSKP_SILK_SDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSKP_SILK_SDK.a; path = "liblinphone-sdk/apple-darwin/lib/libSKP_SILK_SDK.a"; sourceTree = ""; }; 226183AB1472527D0037138E /* libsrtp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsrtp.a; path = "liblinphone-sdk/apple-darwin/lib/libsrtp.a"; sourceTree = ""; }; 226183AF147259670037138E /* libmssilk.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmssilk.a; path = "liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmssilk.a"; sourceTree = ""; }; 2264B6D111200342002C2C53 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; @@ -986,16 +822,13 @@ 22AF73C11754C0D000BE8398 /* libopus.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopus.a; path = "liblinphone-sdk/apple-darwin/lib/libopus.a"; sourceTree = ""; }; 22B5EFA210CE50BD00777D97 /* AddressBookUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBookUI.framework; path = System/Library/Frameworks/AddressBookUI.framework; sourceTree = SDKROOT; }; 22B5F03410CE6B2F00777D97 /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; }; - 22BB1A67132FF16A005CD7AA /* UIEraseButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIEraseButton.h; sourceTree = ""; }; - 22BB1A68132FF16A005CD7AA /* UIEraseButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIEraseButton.m; sourceTree = ""; }; 22C7555E1317E59C007BC101 /* UIBluetoothButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIBluetoothButton.h; sourceTree = ""; }; 22C7555F1317E59C007BC101 /* UIBluetoothButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIBluetoothButton.m; sourceTree = ""; }; 22D1B68012A3E0BE001AE361 /* libresolv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libresolv.dylib; path = usr/lib/libresolv.dylib; sourceTree = SDKROOT; }; - 22E0A81C111C44E100B04932 /* AboutViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutViewController.m; sourceTree = ""; }; - 22E0A81D111C44E100B04932 /* AboutViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutViewController.h; sourceTree = ""; }; - 22F2508B107141E100AC9B3F /* DialerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DialerViewController.h; sourceTree = ""; }; - 22F2508C107141E100AC9B3F /* DialerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = DialerViewController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - 22F254801073D99800AC9B3F /* ringback.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = ringback.wav; path = Resources/ringback.wav; sourceTree = ""; }; + 22E0A81C111C44E100B04932 /* AboutView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutView.m; sourceTree = ""; }; + 22E0A81D111C44E100B04932 /* AboutView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutView.h; sourceTree = ""; }; + 22F2508B107141E100AC9B3F /* DialerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DialerView.h; sourceTree = ""; }; + 22F2508C107141E100AC9B3F /* DialerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = DialerView.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* linphone_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linphone_Prefix.pch; sourceTree = ""; }; @@ -1007,261 +840,603 @@ 344ABDEF14850AE9007420B6 /* libc++.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.1.dylib"; path = "usr/lib/libc++.1.dylib"; sourceTree = SDKROOT; }; 344ABDF014850AE9007420B6 /* libstdc++.6.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.6.dylib"; path = "usr/lib/libstdc++.6.dylib"; sourceTree = SDKROOT; }; 57B0E35F173C010400A476B8 /* libpolarssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpolarssl.a; path = "liblinphone-sdk/apple-darwin/lib/libpolarssl.a"; sourceTree = ""; }; - 57F005C315EE2CCF00914747 /* linphonerc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = linphonerc; path = Resources/linphonerc; sourceTree = ""; }; - 57F005C615EE2D9200914747 /* linphonerc-factory */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "linphonerc-factory"; path = "Resources/linphonerc-factory"; sourceTree = ""; }; - 57F005C715EE2D9200914747 /* linphonerc-factory~ipad */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "linphonerc-factory~ipad"; path = "Resources/linphonerc-factory~ipad"; sourceTree = ""; }; - 631C4FAF19D2A8F2004BFE77 /* UIDigitButtonLongPlus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIDigitButtonLongPlus.h; sourceTree = ""; }; - 631C4FB019D2A8F2004BFE77 /* UIDigitButtonLongPlus.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIDigitButtonLongPlus.m; sourceTree = ""; }; - 631C4FB519D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIDigitButtonLongVoiceMail.h; sourceTree = ""; }; - 631C4FB619D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIDigitButtonLongVoiceMail.m; sourceTree = ""; }; + 630589DE1B4E810900EFAE36 /* ChatTester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatTester.h; sourceTree = ""; }; + 630589DF1B4E810900EFAE36 /* ChatTester.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatTester.m; sourceTree = ""; }; + 630589E01B4E810900EFAE36 /* ContactsTester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsTester.h; sourceTree = ""; }; + 630589E11B4E810900EFAE36 /* ContactsTester.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactsTester.m; sourceTree = ""; }; + 630589E31B4E810900EFAE36 /* LinphoneTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinphoneTestCase.h; sourceTree = ""; }; + 630589E41B4E810900EFAE36 /* LinphoneTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LinphoneTestCase.m; sourceTree = ""; }; + 630589E51B4E810900EFAE36 /* AssistantTester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssistantTester.h; sourceTree = ""; }; + 630589E61B4E810900EFAE36 /* AssistantTester.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AssistantTester.m; sourceTree = ""; }; + 630589F21B4E816900EFAE36 /* KIF.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = KIF.xcodeproj; path = Classes/KIF/KIF.xcodeproj; sourceTree = SOURCE_ROOT; }; + 63058A0A1B4E81B700EFAE36 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 63058A0D1B4E821E00EFAE36 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 63058A0E1B4E821E00EFAE36 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 63058A101B4E821E00EFAE36 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = ""; }; + 63058A121B4E821E00EFAE36 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Main_iPad.strings; sourceTree = ""; }; + 63058A141B4E821E00EFAE36 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Main_iPhone.strings; sourceTree = ""; }; + 63058A161B4E821E00EFAE36 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPad.storyboard; sourceTree = ""; }; + 63058A181B4E821E00EFAE36 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPhone.storyboard; sourceTree = ""; }; + 63058A191B4E821E00EFAE36 /* DetailView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailView.h; sourceTree = ""; }; + 63058A1A1B4E821E00EFAE36 /* DetailView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailView.m; sourceTree = ""; }; + 63058A1B1B4E821E00EFAE36 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 63058A1C1B4E821E00EFAE36 /* LinphoneTester-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "LinphoneTester-Info.plist"; sourceTree = ""; }; + 63058A1D1B4E821E00EFAE36 /* LinphoneTester-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "LinphoneTester-Prefix.pch"; sourceTree = ""; }; + 63058A1E1B4E821E00EFAE36 /* LogsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogsView.h; sourceTree = ""; }; + 63058A1F1B4E821E00EFAE36 /* LogsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LogsView.m; sourceTree = ""; }; + 63058A201B4E821E00EFAE36 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 63058A211B4E821E00EFAE36 /* MasterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MasterView.h; sourceTree = ""; }; + 63058A221B4E821E00EFAE36 /* MasterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MasterView.m; sourceTree = ""; }; + 63058A231B4E821E00EFAE36 /* TesterImages.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = TesterImages.xcassets; sourceTree = ""; }; + 63058A321B4E822F00EFAE36 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = ""; }; + 63058A331B4E822F00EFAE36 /* DTObjectBlockExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTObjectBlockExecutor.h; sourceTree = ""; }; + 63058A341B4E822F00EFAE36 /* DTObjectBlockExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTObjectBlockExecutor.m; sourceTree = ""; }; + 63058A351B4E822F00EFAE36 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 63058A381B4E822F00EFAE36 /* LinphoneTester_Tests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LinphoneTester_Tests.m; sourceTree = ""; }; + 63058A391B4E822F00EFAE36 /* NSObject+DTRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+DTRuntime.h"; sourceTree = ""; }; + 63058A3A1B4E822F00EFAE36 /* NSObject+DTRuntime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+DTRuntime.m"; sourceTree = ""; }; + 63058A401B4E82C400EFAE36 /* LinphoneTesterTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "LinphoneTesterTests-Info.plist"; sourceTree = ""; }; + 63058A411B4E82C400EFAE36 /* LinphoneTesterTests-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "LinphoneTesterTests-Prefix.pch"; sourceTree = ""; }; + 63058AC81B4E922500EFAE36 /* certificates */ = {isa = PBXFileReference; lastKnownFileType = folder; name = certificates; path = ../submodules/linphone/tester/certificates; sourceTree = ""; }; + 63058AC91B4E922500EFAE36 /* flexisip */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flexisip; path = ../submodules/linphone/tester/flexisip; sourceTree = ""; }; + 63058ACA1B4E922500EFAE36 /* images */ = {isa = PBXFileReference; lastKnownFileType = folder; name = images; path = ../submodules/linphone/tester/images; sourceTree = ""; }; + 63058ACB1B4E922500EFAE36 /* marie_xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = marie_xml; path = ../submodules/linphone/tester/marie_xml; sourceTree = ""; }; + 63058ACC1B4E922500EFAE36 /* messages.db */ = {isa = PBXFileReference; lastKnownFileType = file; name = messages.db; path = ../submodules/linphone/tester/messages.db; sourceTree = ""; }; + 63058ACD1B4E922500EFAE36 /* rcfiles */ = {isa = PBXFileReference; lastKnownFileType = folder; name = rcfiles; path = ../submodules/linphone/tester/rcfiles; sourceTree = ""; }; + 63058ACE1B4E922500EFAE36 /* sounds */ = {isa = PBXFileReference; lastKnownFileType = folder; name = sounds; path = ../submodules/linphone/tester/sounds; sourceTree = ""; }; + 63058AE11B4E93A100EFAE36 /* tester_hosts */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = tester_hosts; path = submodules/linphone/tester/tester_hosts; sourceTree = SOURCE_ROOT; }; + 63058AE41B4E952E00EFAE36 /* share */ = {isa = PBXFileReference; lastKnownFileType = folder; name = share; path = "../liblinphone-sdk/apple-darwin/share"; sourceTree = ""; }; + 6306440B1BECB08500134C72 /* FirstLoginView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FirstLoginView.h; sourceTree = ""; }; + 6306440C1BECB08500134C72 /* FirstLoginView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FirstLoginView.m; sourceTree = ""; }; + 6308F9C31BF0DD6600D1234B /* XMLRPCHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMLRPCHelper.h; path = Utils/XMLRPCHelper.h; sourceTree = ""; }; + 6308F9C41BF0DD6600D1234B /* XMLRPCHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XMLRPCHelper.m; path = Utils/XMLRPCHelper.m; sourceTree = ""; }; + 630CF5551AF7CE1500539F7A /* UITextField+DoneButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextField+DoneButton.h"; sourceTree = ""; }; + 630CF5561AF7CE1500539F7A /* UITextField+DoneButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextField+DoneButton.m"; sourceTree = ""; }; + 63130FB11C1ED06900371918 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Base.lproj/SideMenuView~ipad.xib"; sourceTree = ""; }; + 6313482E1B6F7B6600C6BDCB /* UIRoundBorderedButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIRoundBorderedButton.h; sourceTree = ""; }; + 6313482F1B6F7B6600C6BDCB /* UIRoundBorderedButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIRoundBorderedButton.m; sourceTree = ""; }; + 631348311B6FA53300C6BDCB /* rootca.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = rootca.pem; path = "liblinphone-sdk/apple-darwin/share/linphone/rootca.pem"; sourceTree = SOURCE_ROOT; }; + 6316FA6B1BE12A3E0050E441 /* UIRightImageButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIRightImageButton.h; sourceTree = ""; }; + 6316FA6C1BE12A3E0050E441 /* UIRightImageButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIRightImageButton.m; sourceTree = ""; }; + 6336715E1BCBAAD200BFCBDE /* ChatConversationCreateView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatConversationCreateView.h; sourceTree = ""; }; + 6336715F1BCBAAD200BFCBDE /* ChatConversationCreateView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatConversationCreateView.m; sourceTree = ""; }; + 633756371B67BAF400E21BAD /* SideMenuTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SideMenuTableView.h; sourceTree = ""; }; + 633756381B67BAF400E21BAD /* SideMenuTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SideMenuTableView.m; sourceTree = ""; }; + 633756421B67D2B100E21BAD /* SideMenuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SideMenuView.h; sourceTree = ""; }; + 633756431B67D2B100E21BAD /* SideMenuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SideMenuView.m; sourceTree = ""; }; + 633888411BFB2C49001D5E7B /* HPGrowingTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HPGrowingTextView.h; sourceTree = ""; }; + 633888421BFB2C49001D5E7B /* HPGrowingTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HPGrowingTextView.m; sourceTree = ""; }; + 633888431BFB2C49001D5E7B /* HPTextViewInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HPTextViewInternal.h; sourceTree = ""; }; + 633888441BFB2C49001D5E7B /* HPTextViewInternal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HPTextViewInternal.m; sourceTree = ""; }; 633E388219FFB0F400936D1C /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - 636316D21A1DEBCB0009B839 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AboutViewController.xib; sourceTree = ""; }; - 636316D51A1DEC650009B839 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/SettingsViewController.xib; sourceTree = ""; }; - 636316D81A1DECC90009B839 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PhoneMainView.xib; sourceTree = ""; }; - 636316DA1A1DEDD40009B839 /* fr */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/HistoryDetailsViewController.strings; sourceTree = ""; }; - 636316DB1A1DEDD80009B839 /* ru */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/HistoryDetailsViewController.strings; sourceTree = ""; }; - 636316DC1A1DEECB0009B839 /* UIButtonShrinkable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIButtonShrinkable.h; sourceTree = ""; }; - 636316DD1A1DEF2F0009B839 /* UIButtonShrinkable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIButtonShrinkable.m; sourceTree = ""; }; - 639CEAFE1A1DF4D9004DE38F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIStateBar.xib; sourceTree = ""; }; + 6341807A1BBC103100F71761 /* ChatConversationCreateTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatConversationCreateTableView.h; sourceTree = ""; }; + 6341807B1BBC103100F71761 /* ChatConversationCreateTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatConversationCreateTableView.m; sourceTree = ""; }; + 634610041B61330300548952 /* UILabel+Boldify.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UILabel+Boldify.h"; sourceTree = ""; }; + 634610051B61330300548952 /* UILabel+Boldify.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UILabel+Boldify.m"; sourceTree = ""; }; + 6346100D1B61409800548952 /* CallOutgoingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallOutgoingView.h; sourceTree = ""; }; + 6346100E1B61409800548952 /* CallOutgoingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallOutgoingView.m; sourceTree = ""; }; + 634610111B6140A500548952 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/CallOutgoingView.xib; sourceTree = ""; }; + 635173F71BA082A40095EB0A /* UIChatBubblePhotoCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIChatBubblePhotoCell.h; sourceTree = ""; }; + 635173F81BA082A40095EB0A /* UIChatBubblePhotoCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIChatBubblePhotoCell.m; sourceTree = ""; }; + 6352A5721BE0D4B800594C1C /* CallSideMenuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallSideMenuView.h; sourceTree = ""; }; + 6352A5731BE0D4B800594C1C /* CallSideMenuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallSideMenuView.m; sourceTree = ""; }; + 6352A5741BE0D4B800594C1C /* CallSideMenuView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CallSideMenuView.xib; sourceTree = ""; }; + 635775231B6673EC00C8B704 /* HistoryDetailsTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryDetailsTableView.h; sourceTree = ""; }; + 635775241B6673EC00C8B704 /* HistoryDetailsTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HistoryDetailsTableView.m; sourceTree = ""; }; + 636316D21A1DEBCB0009B839 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AboutView.xib; sourceTree = ""; }; + 636316D51A1DEC650009B839 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/SettingsView.xib; sourceTree = ""; }; + 636316DA1A1DEDD40009B839 /* fr */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/HistoryDetailsView.strings; sourceTree = ""; }; + 636316DB1A1DEDD80009B839 /* ru */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/HistoryDetailsView.strings; sourceTree = ""; }; + 636B967D1C298400003BA37C /* add_field_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = add_field_default.png; sourceTree = ""; }; + 636B967E1C298400003BA37C /* add_field_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add_field_default@2x.png"; sourceTree = ""; }; + 636B967F1C298400003BA37C /* add_field_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = add_field_over.png; sourceTree = ""; }; + 636B96801C298400003BA37C /* add_field_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "add_field_over@2x.png"; sourceTree = ""; }; + 636B96811C298400003BA37C /* avatar.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = avatar.png; sourceTree = ""; }; + 636B96821C298400003BA37C /* avatar@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar@2x.png"; sourceTree = ""; }; + 636B96831C298400003BA37C /* back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = back_default.png; sourceTree = ""; }; + 636B96841C298400003BA37C /* back_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_default@2x.png"; sourceTree = ""; }; + 636B96851C298400003BA37C /* back_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = back_disabled.png; sourceTree = ""; }; + 636B96861C298400003BA37C /* back_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_disabled@2x.png"; sourceTree = ""; }; + 636B96871C298400003BA37C /* backspace_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = backspace_default.png; sourceTree = ""; }; + 636B96881C298400003BA37C /* backspace_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "backspace_default@2x.png"; sourceTree = ""; }; + 636B96891C298400003BA37C /* backspace_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = backspace_disabled.png; sourceTree = ""; }; + 636B968A1C298400003BA37C /* backspace_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "backspace_disabled@2x.png"; sourceTree = ""; }; + 636B968B1C298400003BA37C /* backspace_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = backspace_over.png; sourceTree = ""; }; + 636B968C1C298400003BA37C /* backspace_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "backspace_over@2x.png"; sourceTree = ""; }; + 636B968D1C298400003BA37C /* call_add_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_add_default.png; sourceTree = ""; }; + 636B968E1C298400003BA37C /* call_add_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_add_default@2x.png"; sourceTree = ""; }; + 636B968F1C298400003BA37C /* call_add_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_add_disabled.png; sourceTree = ""; }; + 636B96901C298400003BA37C /* call_add_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_add_disabled@2x.png"; sourceTree = ""; }; + 636B96911C298400003BA37C /* call_alt_back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_alt_back_default.png; sourceTree = ""; }; + 636B96921C298400003BA37C /* call_alt_back_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_alt_back_default@2x.png"; sourceTree = ""; }; + 636B96931C298400003BA37C /* call_alt_back_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_alt_back_disabled.png; sourceTree = ""; }; + 636B96941C298400003BA37C /* call_alt_back_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_alt_back_disabled@2x.png"; sourceTree = ""; }; + 636B96951C298400003BA37C /* call_alt_start_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_alt_start_default.png; sourceTree = ""; }; + 636B96961C298400003BA37C /* call_alt_start_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_alt_start_default@2x.png"; sourceTree = ""; }; + 636B96971C298400003BA37C /* call_alt_start_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_alt_start_disabled.png; sourceTree = ""; }; + 636B96981C298400003BA37C /* call_alt_start_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_alt_start_disabled@2x.png"; sourceTree = ""; }; + 636B96991C298400003BA37C /* call_audio_start_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_audio_start_default.png; sourceTree = ""; }; + 636B969A1C298400003BA37C /* call_audio_start_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_audio_start_default@2x.png"; sourceTree = ""; }; + 636B969B1C298400003BA37C /* call_audio_start_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_audio_start_disabled.png; sourceTree = ""; }; + 636B969C1C298400003BA37C /* call_audio_start_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_audio_start_disabled@2x.png"; sourceTree = ""; }; + 636B969D1C298400003BA37C /* call_back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_back_default.png; sourceTree = ""; }; + 636B969E1C298400003BA37C /* call_back_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_back_default@2x.png"; sourceTree = ""; }; + 636B969F1C298400003BA37C /* call_back_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_back_disabled.png; sourceTree = ""; }; + 636B96A01C298400003BA37C /* call_back_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_back_disabled@2x.png"; sourceTree = ""; }; + 636B96A11C298400003BA37C /* call_hangup_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_hangup_default.png; sourceTree = ""; }; + 636B96A21C298400003BA37C /* call_hangup_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_hangup_default@2x.png"; sourceTree = ""; }; + 636B96A31C298400003BA37C /* call_hangup_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_hangup_disabled.png; sourceTree = ""; }; + 636B96A41C298400003BA37C /* call_hangup_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_hangup_disabled@2x.png"; sourceTree = ""; }; + 636B96A51C298400003BA37C /* call_incoming.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_incoming.png; sourceTree = ""; }; + 636B96A61C298400003BA37C /* call_incoming@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_incoming@2x.png"; sourceTree = ""; }; + 636B96A71C298400003BA37C /* call_missed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_missed.png; sourceTree = ""; }; + 636B96A81C298400003BA37C /* call_missed@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_missed@2x.png"; sourceTree = ""; }; + 636B96A91C298400003BA37C /* call_outgoing.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_outgoing.png; sourceTree = ""; }; + 636B96AA1C298400003BA37C /* call_outgoing@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_outgoing@2x.png"; sourceTree = ""; }; + 636B96AB1C298400003BA37C /* call_quality_indicator_0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_quality_indicator_0.png; sourceTree = ""; }; + 636B96AC1C298400003BA37C /* call_quality_indicator_0@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_quality_indicator_0@2x.png"; sourceTree = ""; }; + 636B96AD1C298400003BA37C /* call_quality_indicator_1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_quality_indicator_1.png; sourceTree = ""; }; + 636B96AE1C298400003BA37C /* call_quality_indicator_1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_quality_indicator_1@2x.png"; sourceTree = ""; }; + 636B96AF1C298400003BA37C /* call_quality_indicator_2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_quality_indicator_2.png; sourceTree = ""; }; + 636B96B01C298400003BA37C /* call_quality_indicator_2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_quality_indicator_2@2x.png"; sourceTree = ""; }; + 636B96B11C298400003BA37C /* call_quality_indicator_3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_quality_indicator_3.png; sourceTree = ""; }; + 636B96B21C298400003BA37C /* call_quality_indicator_3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_quality_indicator_3@2x.png"; sourceTree = ""; }; + 636B96B31C298400003BA37C /* call_quality_indicator_4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_quality_indicator_4.png; sourceTree = ""; }; + 636B96B41C298400003BA37C /* call_quality_indicator_4@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_quality_indicator_4@2x.png"; sourceTree = ""; }; + 636B96B51C298400003BA37C /* call_start_body_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_start_body_default.png; sourceTree = ""; }; + 636B96B61C298400003BA37C /* call_start_body_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_start_body_default@2x.png"; sourceTree = ""; }; + 636B96B71C298400003BA37C /* call_start_body_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_start_body_disabled.png; sourceTree = ""; }; + 636B96B81C298400003BA37C /* call_start_body_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_start_body_disabled@2x.png"; sourceTree = ""; }; + 636B96B91C298400003BA37C /* call_start_body_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_start_body_over.png; sourceTree = ""; }; + 636B96BA1C298400003BA37C /* call_start_body_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_start_body_over@2x.png"; sourceTree = ""; }; + 636B96BB1C298400003BA37C /* call_status_incoming.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_status_incoming.png; sourceTree = ""; }; + 636B96BC1C298400003BA37C /* call_status_incoming@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_status_incoming@2x.png"; sourceTree = ""; }; + 636B96BD1C298400003BA37C /* call_status_missed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_status_missed.png; sourceTree = ""; }; + 636B96BE1C298400003BA37C /* call_status_missed@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_status_missed@2x.png"; sourceTree = ""; }; + 636B96BF1C298400003BA37C /* call_status_outgoing.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_status_outgoing.png; sourceTree = ""; }; + 636B96C01C298400003BA37C /* call_status_outgoing@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_status_outgoing@2x.png"; sourceTree = ""; }; + 636B96C11C298400003BA37C /* call_transfer_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_transfer_default.png; sourceTree = ""; }; + 636B96C21C298400003BA37C /* call_transfer_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_transfer_default@2x.png"; sourceTree = ""; }; + 636B96C31C298400003BA37C /* call_transfer_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_transfer_disabled.png; sourceTree = ""; }; + 636B96C41C298400003BA37C /* call_transfer_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_transfer_disabled@2x.png"; sourceTree = ""; }; + 636B96C51C298400003BA37C /* call_video_start_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_video_start_default.png; sourceTree = ""; }; + 636B96C61C298400003BA37C /* call_video_start_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_video_start_default@2x.png"; sourceTree = ""; }; + 636B96C71C298400003BA37C /* call_video_start_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = call_video_start_disabled.png; sourceTree = ""; }; + 636B96C81C298400003BA37C /* call_video_start_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_video_start_disabled@2x.png"; sourceTree = ""; }; + 636B96C91C298400003BA37C /* camera_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = camera_default.png; sourceTree = ""; }; + 636B96CA1C298400003BA37C /* camera_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camera_default@2x.png"; sourceTree = ""; }; + 636B96CB1C298400003BA37C /* camera_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = camera_disabled.png; sourceTree = ""; }; + 636B96CC1C298400003BA37C /* camera_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camera_disabled@2x.png"; sourceTree = ""; }; + 636B96CD1C298400003BA37C /* camera_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = camera_selected.png; sourceTree = ""; }; + 636B96CE1C298400003BA37C /* camera_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camera_selected@2x.png"; sourceTree = ""; }; + 636B96CF1C298400003BA37C /* camera_switch_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = camera_switch_default.png; sourceTree = ""; }; + 636B96D01C298400003BA37C /* camera_switch_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camera_switch_default@2x.png"; sourceTree = ""; }; + 636B96D11C298400003BA37C /* camera_switch_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = camera_switch_disabled.png; sourceTree = ""; }; + 636B96D21C298400003BA37C /* camera_switch_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camera_switch_disabled@2x.png"; sourceTree = ""; }; + 636B96D31C298400003BA37C /* camera_switch_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = camera_switch_over.png; sourceTree = ""; }; + 636B96D41C298400003BA37C /* camera_switch_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camera_switch_over@2x.png"; sourceTree = ""; }; + 636B96D51C298400003BA37C /* cancel_edit_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cancel_edit_default.png; sourceTree = ""; }; + 636B96D61C298400003BA37C /* cancel_edit_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "cancel_edit_default@2x.png"; sourceTree = ""; }; + 636B96D71C298400003BA37C /* cancel_edit_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cancel_edit_disabled.png; sourceTree = ""; }; + 636B96D81C298400003BA37C /* cancel_edit_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "cancel_edit_disabled@2x.png"; sourceTree = ""; }; + 636B96D91C298400003BA37C /* chat_add_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_add_default.png; sourceTree = ""; }; + 636B96DA1C298400003BA37C /* chat_add_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_add_default@2x.png"; sourceTree = ""; }; + 636B96DB1C298400003BA37C /* chat_add_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_add_disabled.png; sourceTree = ""; }; + 636B96DC1C298400003BA37C /* chat_add_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_add_disabled@2x.png"; sourceTree = ""; }; + 636B96DD1C298400003BA37C /* chat_attachment_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_attachment_default.png; sourceTree = ""; }; + 636B96DE1C298400003BA37C /* chat_attachment_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_attachment_default@2x.png"; sourceTree = ""; }; + 636B96DF1C298400003BA37C /* chat_attachment_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_attachment_disabled.png; sourceTree = ""; }; + 636B96E01C298400003BA37C /* chat_attachment_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_attachment_disabled@2x.png"; sourceTree = ""; }; + 636B96E11C298400003BA37C /* chat_attachment_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_attachment_over.png; sourceTree = ""; }; + 636B96E21C298400003BA37C /* chat_attachment_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_attachment_over@2x.png"; sourceTree = ""; }; + 636B96E31C298400003BA37C /* chat_message_not_delivered.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_message_not_delivered.png; sourceTree = ""; }; + 636B96E41C298400003BA37C /* chat_message_not_delivered@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_message_not_delivered@2x.png"; sourceTree = ""; }; + 636B96E51C298400003BA37C /* chat_send_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_send_default.png; sourceTree = ""; }; + 636B96E61C298400003BA37C /* chat_send_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_send_default@2x.png"; sourceTree = ""; }; + 636B96E71C298400003BA37C /* chat_send_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_send_disabled.png; sourceTree = ""; }; + 636B96E81C298400003BA37C /* chat_send_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_send_disabled@2x.png"; sourceTree = ""; }; + 636B96E91C298400003BA37C /* chat_send_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_send_over.png; sourceTree = ""; }; + 636B96EA1C298400003BA37C /* chat_send_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_send_over@2x.png"; sourceTree = ""; }; + 636B96EB1C298400003BA37C /* chat_start_body_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_start_body_default.png; sourceTree = ""; }; + 636B96EC1C298400003BA37C /* chat_start_body_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_start_body_default@2x.png"; sourceTree = ""; }; + 636B96ED1C298400003BA37C /* chat_start_body_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_start_body_disabled.png; sourceTree = ""; }; + 636B96EE1C298400003BA37C /* chat_start_body_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_start_body_disabled@2x.png"; sourceTree = ""; }; + 636B96EF1C298400003BA37C /* chat_start_body_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_start_body_over.png; sourceTree = ""; }; + 636B96F01C298400003BA37C /* chat_start_body_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_start_body_over@2x.png"; sourceTree = ""; }; + 636B96F11C298400003BA37C /* checkbox_checked.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = checkbox_checked.png; sourceTree = ""; }; + 636B96F21C298400003BA37C /* checkbox_checked@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "checkbox_checked@2x.png"; sourceTree = ""; }; + 636B96F31C298400003BA37C /* checkbox_unchecked.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = checkbox_unchecked.png; sourceTree = ""; }; + 636B96F41C298400003BA37C /* checkbox_unchecked@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "checkbox_unchecked@2x.png"; sourceTree = ""; }; + 636B96F51C298400003BA37C /* color_A.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = color_A.png; sourceTree = ""; }; + 636B96F61C298400003BA37C /* color_C.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = color_C.png; sourceTree = ""; }; + 636B96F71C298400003BA37C /* color_D.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = color_D.png; sourceTree = ""; }; + 636B96F81C298400003BA37C /* color_E.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = color_E.png; sourceTree = ""; }; + 636B96F91C298400003BA37C /* color_F.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = color_F.png; sourceTree = ""; }; + 636B96FA1C298400003BA37C /* color_G.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = color_G.png; sourceTree = ""; }; + 636B96FB1C298400003BA37C /* color_H.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = color_H.png; sourceTree = ""; }; + 636B96FC1C298400003BA37C /* color_I.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = color_I.png; sourceTree = ""; }; + 636B96FD1C298400003BA37C /* color_L.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = color_L.png; sourceTree = ""; }; + 636B96FE1C298400003BA37C /* color_M.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = color_M.png; sourceTree = ""; }; + 636B96FF1C298400003BA37C /* conference_exit_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = conference_exit_default.png; sourceTree = ""; }; + 636B97001C298400003BA37C /* conference_exit_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "conference_exit_default@2x.png"; sourceTree = ""; }; + 636B97011C298400003BA37C /* conference_exit_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = conference_exit_over.png; sourceTree = ""; }; + 636B97021C298400003BA37C /* conference_exit_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "conference_exit_over@2x.png"; sourceTree = ""; }; + 636B97031C298400003BA37C /* contact_add_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contact_add_default.png; sourceTree = ""; }; + 636B97041C298400003BA37C /* contact_add_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "contact_add_default@2x.png"; sourceTree = ""; }; + 636B97051C298400003BA37C /* contact_add_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contact_add_disabled.png; sourceTree = ""; }; + 636B97061C298400003BA37C /* contact_add_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "contact_add_disabled@2x.png"; sourceTree = ""; }; + 636B97071C298400003BA37C /* contacts_all_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contacts_all_default.png; sourceTree = ""; }; + 636B97081C298400003BA37C /* contacts_all_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "contacts_all_default@2x.png"; sourceTree = ""; }; + 636B97091C298400003BA37C /* contacts_all_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contacts_all_disabled.png; sourceTree = ""; }; + 636B970A1C298400003BA37C /* contacts_all_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "contacts_all_disabled@2x.png"; sourceTree = ""; }; + 636B970B1C298400003BA37C /* contacts_all_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contacts_all_selected.png; sourceTree = ""; }; + 636B970C1C298400003BA37C /* contacts_all_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "contacts_all_selected@2x.png"; sourceTree = ""; }; + 636B970D1C298400003BA37C /* contacts_sip_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contacts_sip_default.png; sourceTree = ""; }; + 636B970E1C298400003BA37C /* contacts_sip_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "contacts_sip_default@2x.png"; sourceTree = ""; }; + 636B970F1C298400003BA37C /* contacts_sip_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contacts_sip_disabled.png; sourceTree = ""; }; + 636B97101C298400003BA37C /* contacts_sip_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "contacts_sip_disabled@2x.png"; sourceTree = ""; }; + 636B97111C298400003BA37C /* contacts_sip_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = contacts_sip_selected.png; sourceTree = ""; }; + 636B97121C298400003BA37C /* contacts_sip_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "contacts_sip_selected@2x.png"; sourceTree = ""; }; + 636B97131C298400003BA37C /* delete_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = delete_default.png; sourceTree = ""; }; + 636B97141C298400003BA37C /* delete_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "delete_default@2x.png"; sourceTree = ""; }; + 636B97151C298400003BA37C /* delete_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = delete_disabled.png; sourceTree = ""; }; + 636B97161C298400003BA37C /* delete_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "delete_disabled@2x.png"; sourceTree = ""; }; + 636B97171C298400003BA37C /* delete_field_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = delete_field_default.png; sourceTree = ""; }; + 636B97181C298400003BA37C /* delete_field_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "delete_field_default@2x.png"; sourceTree = ""; }; + 636B97191C298400003BA37C /* delete_field_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = delete_field_over.png; sourceTree = ""; }; + 636B971A1C298400003BA37C /* delete_field_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "delete_field_over@2x.png"; sourceTree = ""; }; + 636B971B1C298400003BA37C /* deselect_all.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = deselect_all.png; sourceTree = ""; }; + 636B971C1C298400003BA37C /* deselect_all@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "deselect_all@2x.png"; sourceTree = ""; }; + 636B971D1C298400003BA37C /* dialer_alt_back.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dialer_alt_back.png; sourceTree = ""; }; + 636B971E1C298400003BA37C /* dialer_alt_back@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "dialer_alt_back@2x.png"; sourceTree = ""; }; + 636B971F1C298400003BA37C /* dialer_back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dialer_back_default.png; sourceTree = ""; }; + 636B97201C298400003BA37C /* dialer_back_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "dialer_back_default@2x.png"; sourceTree = ""; }; + 636B97211C298400003BA37C /* dialer_back_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dialer_back_disabled.png; sourceTree = ""; }; + 636B97221C298400003BA37C /* dialer_back_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "dialer_back_disabled@2x.png"; sourceTree = ""; }; + 636B97231C298400003BA37C /* dialer_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dialer_background.png; sourceTree = ""; }; + 636B97241C298400003BA37C /* dialer_background@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "dialer_background@2x.png"; sourceTree = ""; }; + 636B97251C298400003BA37C /* edit_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = edit_default.png; sourceTree = ""; }; + 636B97261C298400003BA37C /* edit_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "edit_default@2x.png"; sourceTree = ""; }; + 636B97271C298400003BA37C /* edit_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = edit_disabled.png; sourceTree = ""; }; + 636B97281C298400003BA37C /* edit_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "edit_disabled@2x.png"; sourceTree = ""; }; + 636B97291C298400003BA37C /* edit_list_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = edit_list_default.png; sourceTree = ""; }; + 636B972A1C298400003BA37C /* edit_list_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "edit_list_default@2x.png"; sourceTree = ""; }; + 636B972B1C298400003BA37C /* edit_list_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = edit_list_disabled.png; sourceTree = ""; }; + 636B972C1C298400003BA37C /* edit_list_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "edit_list_disabled@2x.png"; sourceTree = ""; }; + 636B972D1C298400003BA37C /* footer_chat_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = footer_chat_default.png; sourceTree = ""; }; + 636B972E1C298400003BA37C /* footer_chat_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "footer_chat_default@2x.png"; sourceTree = ""; }; + 636B972F1C298400003BA37C /* footer_chat_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = footer_chat_disabled.png; sourceTree = ""; }; + 636B97301C298400003BA37C /* footer_chat_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "footer_chat_disabled@2x.png"; sourceTree = ""; }; + 636B97311C298400003BA37C /* footer_contacts_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = footer_contacts_default.png; sourceTree = ""; }; + 636B97321C298400003BA37C /* footer_contacts_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "footer_contacts_default@2x.png"; sourceTree = ""; }; + 636B97331C298400003BA37C /* footer_contacts_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = footer_contacts_disabled.png; sourceTree = ""; }; + 636B97341C298400003BA37C /* footer_contacts_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "footer_contacts_disabled@2x.png"; sourceTree = ""; }; + 636B97351C298400003BA37C /* footer_dialer_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = footer_dialer_default.png; sourceTree = ""; }; + 636B97361C298400003BA37C /* footer_dialer_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "footer_dialer_default@2x.png"; sourceTree = ""; }; + 636B97371C298400003BA37C /* footer_dialer_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = footer_dialer_disabled.png; sourceTree = ""; }; + 636B97381C298400003BA37C /* footer_dialer_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "footer_dialer_disabled@2x.png"; sourceTree = ""; }; + 636B97391C298400003BA37C /* footer_history_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = footer_history_default.png; sourceTree = ""; }; + 636B973A1C298400003BA37C /* footer_history_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "footer_history_default@2x.png"; sourceTree = ""; }; + 636B973B1C298400003BA37C /* footer_history_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = footer_history_disabled.png; sourceTree = ""; }; + 636B973C1C298400003BA37C /* footer_history_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "footer_history_disabled@2x.png"; sourceTree = ""; }; + 636B973D1C298400003BA37C /* history_all_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = history_all_default.png; sourceTree = ""; }; + 636B973E1C298400003BA37C /* history_all_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "history_all_default@2x.png"; sourceTree = ""; }; + 636B973F1C298400003BA37C /* history_all_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = history_all_disabled.png; sourceTree = ""; }; + 636B97401C298400003BA37C /* history_all_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "history_all_disabled@2x.png"; sourceTree = ""; }; + 636B97411C298400003BA37C /* history_all_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = history_all_selected.png; sourceTree = ""; }; + 636B97421C298400003BA37C /* history_all_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "history_all_selected@2x.png"; sourceTree = ""; }; + 636B97431C298400003BA37C /* history_chat_indicator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = history_chat_indicator.png; sourceTree = ""; }; + 636B97441C298400003BA37C /* history_chat_indicator@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "history_chat_indicator@2x.png"; sourceTree = ""; }; + 636B97451C298400003BA37C /* history_missed_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = history_missed_default.png; sourceTree = ""; }; + 636B97461C298400003BA37C /* history_missed_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "history_missed_default@2x.png"; sourceTree = ""; }; + 636B97471C298400003BA37C /* history_missed_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = history_missed_disabled.png; sourceTree = ""; }; + 636B97481C298400003BA37C /* history_missed_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "history_missed_disabled@2x.png"; sourceTree = ""; }; + 636B97491C298400003BA37C /* history_missed_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = history_missed_selected.png; sourceTree = ""; }; + 636B974A1C298400003BA37C /* history_missed_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "history_missed_selected@2x.png"; sourceTree = ""; }; + 636B974B1C298400003BA37C /* led_connected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = led_connected.png; sourceTree = ""; }; + 636B974C1C298400003BA37C /* led_connected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "led_connected@2x.png"; sourceTree = ""; }; + 636B974D1C298400003BA37C /* led_disconnected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = led_disconnected.png; sourceTree = ""; }; + 636B974E1C298400003BA37C /* led_disconnected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "led_disconnected@2x.png"; sourceTree = ""; }; + 636B974F1C298400003BA37C /* led_error.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = led_error.png; sourceTree = ""; }; + 636B97501C298400003BA37C /* led_error@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "led_error@2x.png"; sourceTree = ""; }; + 636B97511C298400003BA37C /* led_inprogress.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = led_inprogress.png; sourceTree = ""; }; + 636B97521C298400003BA37C /* led_inprogress@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "led_inprogress@2x.png"; sourceTree = ""; }; + 636B97531C298400003BA37C /* linphone_logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = linphone_logo.png; sourceTree = ""; }; + 636B97541C298400003BA37C /* linphone_logo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "linphone_logo@2x.png"; sourceTree = ""; }; + 636B97551C298400003BA37C /* linphone_user.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = linphone_user.png; sourceTree = ""; }; + 636B97561C298400003BA37C /* linphone_user@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "linphone_user@2x.png"; sourceTree = ""; }; + 636B97571C298401003BA37C /* list_details_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = list_details_default.png; sourceTree = ""; }; + 636B97581C298401003BA37C /* list_details_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "list_details_default@2x.png"; sourceTree = ""; }; + 636B97591C298401003BA37C /* list_details_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = list_details_over.png; sourceTree = ""; }; + 636B975A1C298401003BA37C /* list_details_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "list_details_over@2x.png"; sourceTree = ""; }; + 636B975B1C298401003BA37C /* menu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu.png; sourceTree = ""; }; + 636B975C1C298401003BA37C /* menu@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "menu@2x.png"; sourceTree = ""; }; + 636B975D1C298401003BA37C /* micro_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = micro_default.png; sourceTree = ""; }; + 636B975E1C298401003BA37C /* micro_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "micro_default@2x.png"; sourceTree = ""; }; + 636B975F1C298401003BA37C /* micro_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = micro_disabled.png; sourceTree = ""; }; + 636B97601C298401003BA37C /* micro_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "micro_disabled@2x.png"; sourceTree = ""; }; + 636B97611C298401003BA37C /* micro_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = micro_selected.png; sourceTree = ""; }; + 636B97621C298401003BA37C /* micro_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "micro_selected@2x.png"; sourceTree = ""; }; + 636B97631C298401003BA37C /* numpad_0_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_0_default.png; sourceTree = ""; }; + 636B97641C298401003BA37C /* numpad_0_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_0_default@2x.png"; sourceTree = ""; }; + 636B97651C298401003BA37C /* numpad_0_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_0_over.png; sourceTree = ""; }; + 636B97661C298401003BA37C /* numpad_0_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_0_over@2x.png"; sourceTree = ""; }; + 636B97671C298401003BA37C /* numpad_1_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_1_default.png; sourceTree = ""; }; + 636B97681C298401003BA37C /* numpad_1_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_1_default@2x.png"; sourceTree = ""; }; + 636B97691C298401003BA37C /* numpad_1_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_1_over.png; sourceTree = ""; }; + 636B976A1C298401003BA37C /* numpad_1_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_1_over@2x.png"; sourceTree = ""; }; + 636B976B1C298401003BA37C /* numpad_2_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_2_default.png; sourceTree = ""; }; + 636B976C1C298401003BA37C /* numpad_2_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_2_default@2x.png"; sourceTree = ""; }; + 636B976D1C298401003BA37C /* numpad_2_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_2_over.png; sourceTree = ""; }; + 636B976E1C298401003BA37C /* numpad_2_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_2_over@2x.png"; sourceTree = ""; }; + 636B976F1C298401003BA37C /* numpad_3_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_3_default.png; sourceTree = ""; }; + 636B97701C298401003BA37C /* numpad_3_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_3_default@2x.png"; sourceTree = ""; }; + 636B97711C298401003BA37C /* numpad_3_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_3_over.png; sourceTree = ""; }; + 636B97721C298401003BA37C /* numpad_3_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_3_over@2x.png"; sourceTree = ""; }; + 636B97731C298401003BA37C /* numpad_4_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_4_default.png; sourceTree = ""; }; + 636B97741C298401003BA37C /* numpad_4_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_4_default@2x.png"; sourceTree = ""; }; + 636B97751C298401003BA37C /* numpad_4_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_4_over.png; sourceTree = ""; }; + 636B97761C298401003BA37C /* numpad_4_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_4_over@2x.png"; sourceTree = ""; }; + 636B97771C298401003BA37C /* numpad_5_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_5_default.png; sourceTree = ""; }; + 636B97781C298401003BA37C /* numpad_5_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_5_default@2x.png"; sourceTree = ""; }; + 636B97791C298401003BA37C /* numpad_5_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_5_over.png; sourceTree = ""; }; + 636B977A1C298401003BA37C /* numpad_5_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_5_over@2x.png"; sourceTree = ""; }; + 636B977B1C298401003BA37C /* numpad_6_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_6_default.png; sourceTree = ""; }; + 636B977C1C298401003BA37C /* numpad_6_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_6_default@2x.png"; sourceTree = ""; }; + 636B977D1C298401003BA37C /* numpad_6_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_6_over.png; sourceTree = ""; }; + 636B977E1C298401003BA37C /* numpad_6_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_6_over@2x.png"; sourceTree = ""; }; + 636B977F1C298401003BA37C /* numpad_7_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_7_default.png; sourceTree = ""; }; + 636B97801C298401003BA37C /* numpad_7_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_7_default@2x.png"; sourceTree = ""; }; + 636B97811C298401003BA37C /* numpad_7_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_7_over.png; sourceTree = ""; }; + 636B97821C298401003BA37C /* numpad_7_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_7_over@2x.png"; sourceTree = ""; }; + 636B97831C298401003BA37C /* numpad_8_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_8_default.png; sourceTree = ""; }; + 636B97841C298401003BA37C /* numpad_8_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_8_default@2x.png"; sourceTree = ""; }; + 636B97851C298401003BA37C /* numpad_8_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_8_over.png; sourceTree = ""; }; + 636B97861C298401003BA37C /* numpad_8_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_8_over@2x.png"; sourceTree = ""; }; + 636B97871C298401003BA37C /* numpad_9_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_9_default.png; sourceTree = ""; }; + 636B97881C298401003BA37C /* numpad_9_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_9_default@2x.png"; sourceTree = ""; }; + 636B97891C298401003BA37C /* numpad_9_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_9_over.png; sourceTree = ""; }; + 636B978A1C298401003BA37C /* numpad_9_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_9_over@2x.png"; sourceTree = ""; }; + 636B978B1C298401003BA37C /* numpad_hash_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_hash_default.png; sourceTree = ""; }; + 636B978C1C298401003BA37C /* numpad_hash_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_hash_default@2x.png"; sourceTree = ""; }; + 636B978D1C298401003BA37C /* numpad_hash_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_hash_over.png; sourceTree = ""; }; + 636B978E1C298401003BA37C /* numpad_hash_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_hash_over@2x.png"; sourceTree = ""; }; + 636B978F1C298401003BA37C /* numpad_over_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_over_background.png; sourceTree = ""; }; + 636B97901C298401003BA37C /* numpad_star_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_star_default.png; sourceTree = ""; }; + 636B97911C298401003BA37C /* numpad_star_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_star_default@2x.png"; sourceTree = ""; }; + 636B97921C298401003BA37C /* numpad_star_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = numpad_star_over.png; sourceTree = ""; }; + 636B97931C298401003BA37C /* numpad_star_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "numpad_star_over@2x.png"; sourceTree = ""; }; + 636B97941C298401003BA37C /* options_add_call_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = options_add_call_default.png; sourceTree = ""; }; + 636B97951C298401003BA37C /* options_add_call_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "options_add_call_default@2x.png"; sourceTree = ""; }; + 636B97961C298401003BA37C /* options_add_call_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = options_add_call_disabled.png; sourceTree = ""; }; + 636B97971C298401003BA37C /* options_add_call_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "options_add_call_disabled@2x.png"; sourceTree = ""; }; + 636B97981C298401003BA37C /* options_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = options_default.png; sourceTree = ""; }; + 636B97991C298401003BA37C /* options_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "options_default@2x.png"; sourceTree = ""; }; + 636B979A1C298401003BA37C /* options_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = options_disabled.png; sourceTree = ""; }; + 636B979B1C298401003BA37C /* options_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "options_disabled@2x.png"; sourceTree = ""; }; + 636B979C1C298401003BA37C /* options_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = options_selected.png; sourceTree = ""; }; + 636B979D1C298401003BA37C /* options_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "options_selected@2x.png"; sourceTree = ""; }; + 636B979E1C298401003BA37C /* options_start_conference_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = options_start_conference_default.png; sourceTree = ""; }; + 636B979F1C298401003BA37C /* options_start_conference_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "options_start_conference_default@2x.png"; sourceTree = ""; }; + 636B97A01C298401003BA37C /* options_start_conference_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = options_start_conference_disabled.png; sourceTree = ""; }; + 636B97A11C298401003BA37C /* options_start_conference_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "options_start_conference_disabled@2x.png"; sourceTree = ""; }; + 636B97A21C298401003BA37C /* options_transfer_call_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = options_transfer_call_default.png; sourceTree = ""; }; + 636B97A31C298401003BA37C /* options_transfer_call_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "options_transfer_call_default@2x.png"; sourceTree = ""; }; + 636B97A41C298401003BA37C /* options_transfer_call_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = options_transfer_call_disabled.png; sourceTree = ""; }; + 636B97A51C298401003BA37C /* options_transfer_call_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "options_transfer_call_disabled@2x.png"; sourceTree = ""; }; + 636B97A61C298401003BA37C /* pause_big_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pause_big_default.png; sourceTree = ""; }; + 636B97A71C298401003BA37C /* pause_big_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pause_big_default@2x.png"; sourceTree = ""; }; + 636B97A81C298401003BA37C /* pause_big_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pause_big_disabled.png; sourceTree = ""; }; + 636B97A91C298401003BA37C /* pause_big_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pause_big_disabled@2x.png"; sourceTree = ""; }; + 636B97AA1C298401003BA37C /* pause_big_over_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pause_big_over_selected.png; sourceTree = ""; }; + 636B97AB1C298401003BA37C /* pause_big_over_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pause_big_over_selected@2x.png"; sourceTree = ""; }; + 636B97AC1C298401003BA37C /* pause_small_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pause_small_default.png; sourceTree = ""; }; + 636B97AD1C298401003BA37C /* pause_small_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pause_small_default@2x.png"; sourceTree = ""; }; + 636B97AE1C298401003BA37C /* pause_small_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pause_small_disabled.png; sourceTree = ""; }; + 636B97AF1C298401003BA37C /* pause_small_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pause_small_disabled@2x.png"; sourceTree = ""; }; + 636B97B01C298401003BA37C /* pause_small_over_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pause_small_over_selected.png; sourceTree = ""; }; + 636B97B11C298401003BA37C /* pause_small_over_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pause_small_over_selected@2x.png"; sourceTree = ""; }; + 636B97B21C298401003BA37C /* route_bluetooth_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = route_bluetooth_default.png; sourceTree = ""; }; + 636B97B31C298401003BA37C /* route_bluetooth_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "route_bluetooth_default@2x.png"; sourceTree = ""; }; + 636B97B41C298401003BA37C /* route_bluetooth_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = route_bluetooth_disabled.png; sourceTree = ""; }; + 636B97B51C298401003BA37C /* route_bluetooth_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "route_bluetooth_disabled@2x.png"; sourceTree = ""; }; + 636B97B61C298401003BA37C /* route_bluetooth_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = route_bluetooth_selected.png; sourceTree = ""; }; + 636B97B71C298401003BA37C /* route_bluetooth_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "route_bluetooth_selected@2x.png"; sourceTree = ""; }; + 636B97B81C298401003BA37C /* route_earpiece_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = route_earpiece_default.png; sourceTree = ""; }; + 636B97B91C298401003BA37C /* route_earpiece_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "route_earpiece_default@2x.png"; sourceTree = ""; }; + 636B97BA1C298401003BA37C /* route_earpiece_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = route_earpiece_disabled.png; sourceTree = ""; }; + 636B97BB1C298401003BA37C /* route_earpiece_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "route_earpiece_disabled@2x.png"; sourceTree = ""; }; + 636B97BC1C298401003BA37C /* route_earpiece_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = route_earpiece_selected.png; sourceTree = ""; }; + 636B97BD1C298401003BA37C /* route_earpiece_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "route_earpiece_selected@2x.png"; sourceTree = ""; }; + 636B97BE1C298401003BA37C /* route_speaker_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = route_speaker_default.png; sourceTree = ""; }; + 636B97BF1C298401003BA37C /* route_speaker_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "route_speaker_default@2x.png"; sourceTree = ""; }; + 636B97C01C298401003BA37C /* route_speaker_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = route_speaker_disabled.png; sourceTree = ""; }; + 636B97C11C298401003BA37C /* route_speaker_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "route_speaker_disabled@2x.png"; sourceTree = ""; }; + 636B97C21C298401003BA37C /* route_speaker_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = route_speaker_selected.png; sourceTree = ""; }; + 636B97C31C298401003BA37C /* route_speaker_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "route_speaker_selected@2x.png"; sourceTree = ""; }; + 636B97C41C298401003BA37C /* routes_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = routes_default.png; sourceTree = ""; }; + 636B97C51C298401003BA37C /* routes_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "routes_default@2x.png"; sourceTree = ""; }; + 636B97C61C298401003BA37C /* routes_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = routes_disabled.png; sourceTree = ""; }; + 636B97C71C298401003BA37C /* routes_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "routes_disabled@2x.png"; sourceTree = ""; }; + 636B97C81C298401003BA37C /* routes_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = routes_selected.png; sourceTree = ""; }; + 636B97C91C298401003BA37C /* routes_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "routes_selected@2x.png"; sourceTree = ""; }; + 636B97CA1C298401003BA37C /* security_ko.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = security_ko.png; sourceTree = ""; }; + 636B97CB1C298401003BA37C /* security_ko@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "security_ko@2x.png"; sourceTree = ""; }; + 636B97CC1C298401003BA37C /* security_ok.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = security_ok.png; sourceTree = ""; }; + 636B97CD1C298401003BA37C /* security_ok@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "security_ok@2x.png"; sourceTree = ""; }; + 636B97CE1C298401003BA37C /* security_pending.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = security_pending.png; sourceTree = ""; }; + 636B97CF1C298401003BA37C /* security_pending@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "security_pending@2x.png"; sourceTree = ""; }; + 636B97D01C298401003BA37C /* select_all_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = select_all_default.png; sourceTree = ""; }; + 636B97D11C298401003BA37C /* select_all_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "select_all_default@2x.png"; sourceTree = ""; }; + 636B97D21C298401003BA37C /* select_all_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = select_all_disabled.png; sourceTree = ""; }; + 636B97D31C298401003BA37C /* select_all_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "select_all_disabled@2x.png"; sourceTree = ""; }; + 636B97D41C298401003BA37C /* speaker_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = speaker_default.png; sourceTree = ""; }; + 636B97D51C298401003BA37C /* speaker_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "speaker_default@2x.png"; sourceTree = ""; }; + 636B97D61C298401003BA37C /* speaker_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = speaker_disabled.png; sourceTree = ""; }; + 636B97D71C298401003BA37C /* speaker_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "speaker_disabled@2x.png"; sourceTree = ""; }; + 636B97D81C298401003BA37C /* speaker_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = speaker_selected.png; sourceTree = ""; }; + 636B97D91C298401003BA37C /* speaker_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "speaker_selected@2x.png"; sourceTree = ""; }; + 636B97DA1C298401003BA37C /* splashscreen.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = splashscreen.png; sourceTree = ""; }; + 636B97DB1C298401003BA37C /* splashscreen@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "splashscreen@2x.png"; sourceTree = ""; }; + 636B97DC1C298401003BA37C /* valid_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = valid_default.png; sourceTree = ""; }; + 636B97DD1C298401003BA37C /* valid_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "valid_default@2x.png"; sourceTree = ""; }; + 636B97DE1C298401003BA37C /* valid_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = valid_disabled.png; sourceTree = ""; }; + 636B97DF1C298401003BA37C /* valid_disabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "valid_disabled@2x.png"; sourceTree = ""; }; + 636B97E01C298401003BA37C /* voicemail.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = voicemail.png; sourceTree = ""; }; + 636B97E11C298401003BA37C /* voicemail@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "voicemail@2x.png"; sourceTree = ""; }; + 636B97E21C298401003BA37C /* waiting_time.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = waiting_time.png; sourceTree = ""; }; + 636B97E31C298401003BA37C /* waiting_time@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "waiting_time@2x.png"; sourceTree = ""; }; + 636BC9951B5F921B00C754CE /* UIIconButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIIconButton.h; sourceTree = ""; }; + 636BC9961B5F921B00C754CE /* UIIconButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIIconButton.m; sourceTree = ""; }; + 63701DDD1BA32039006A9AE3 /* UIConfirmationDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIConfirmationDialog.h; sourceTree = ""; }; + 63701DDE1BA32039006A9AE3 /* UIConfirmationDialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIConfirmationDialog.m; sourceTree = ""; }; + 6371579F1B283FE200C91677 /* FileTransferDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileTransferDelegate.h; path = Utils/FileTransferDelegate.h; sourceTree = ""; }; + 637157A01B283FE200C91677 /* FileTransferDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FileTransferDelegate.m; path = Utils/FileTransferDelegate.m; sourceTree = ""; }; + 6377AC7E1BDE4068007F7625 /* UIBackToCallButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIBackToCallButton.h; sourceTree = ""; }; + 6377AC7F1BDE4069007F7625 /* UIBackToCallButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIBackToCallButton.m; sourceTree = ""; }; + 6381DA7B1C1AD5EA00DF3BBD /* UIBouncingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIBouncingView.h; sourceTree = ""; }; + 6381DA7C1C1AD5EA00DF3BBD /* UIBouncingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIBouncingView.m; sourceTree = ""; }; + 638F1A611C2021B2004B8E02 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Base.lproj/DialerView~ipad.xib"; sourceTree = ""; }; + 638F1A871C2167C2004B8E02 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Base.lproj/CallView~ipad.xib"; sourceTree = ""; }; + 638F1A901C21993D004B8E02 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Base.lproj/UICompositeView~ipad.xib"; sourceTree = ""; }; + 639CEAFE1A1DF4D9004DE38F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/StatusBarView.xib; sourceTree = ""; }; 639CEB011A1DF4E4004DE38F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIHistoryCell.xib; sourceTree = ""; }; - 639CEB041A1DF4EB004DE38F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UICompositeViewController.xib; sourceTree = ""; }; - 639CEB071A1DF4F1004DE38F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIChatRoomCell.xib; sourceTree = ""; }; + 639CEB041A1DF4EB004DE38F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UICompositeView.xib; sourceTree = ""; }; 639CEB0A1A1DF4FA004DE38F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIChatCell.xib; sourceTree = ""; }; - 639CEB0C1A1DF528004DE38F /* fr */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/UICallCell.strings; sourceTree = ""; }; - 639CEB0D1A1DF52C004DE38F /* ru */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/UICallCell.strings; sourceTree = ""; }; + 639E9C7E1C0DB13D00019A75 /* UICheckBoxTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICheckBoxTableView.h; sourceTree = ""; }; + 639E9C7F1C0DB13D00019A75 /* UICheckBoxTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICheckBoxTableView.m; sourceTree = ""; }; + 639E9C941C0DB7BE00019A75 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/FirstLoginView.xib; sourceTree = ""; }; + 639E9C9B1C0DB7D300019A75 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 639E9C9E1C0DB7DF00019A75 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UICallPausedCell.xib; sourceTree = ""; }; + 639E9CA11C0DB7E500019A75 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIChatBubblePhotoCell.xib; sourceTree = ""; }; + 639E9CA41C0DB7EA00019A75 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIChatBubbleTextCell.xib; sourceTree = ""; }; + 639E9CA71C0DB7F200019A75 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIChatCreateCell.xib; sourceTree = ""; }; + 639E9CAA1C0DB7FB00019A75 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIConfirmationDialog.xib; sourceTree = ""; }; + 639E9CAD1C0DB80300019A75 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIContactDetailsCell.xib; sourceTree = ""; }; + 639E9CB11C0DB83000019A75 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/SideMenuView.xib; sourceTree = ""; }; + 639E9CB41C0DB88200019A75 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PhoneMainView.xib; sourceTree = ""; }; + 63AADBC51B6A0FF200AA16FD /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; }; + 63AADBC61B6A0FF200AA16FD /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + 63AADBC71B6A0FF200AA16FD /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 63AADBC81B6A0FF200AA16FD /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + 63AADBC91B6A0FF200AA16FD /* hold.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = hold.wav; sourceTree = ""; }; + 63AADBCA1B6A0FF200AA16FD /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 63AADBCB1B6A0FF200AA16FD /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = ""; }; + 63AADBD51B6A0FF200AA16FD /* licenses.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = licenses.html; sourceTree = ""; }; + 63AADBD71B6A0FF200AA16FD /* linphonerc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = linphonerc; sourceTree = ""; }; + 63AADBD81B6A0FF200AA16FD /* linphonerc-factory */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "linphonerc-factory"; sourceTree = ""; }; + 63AADBDA1B6A0FF200AA16FD /* linphonerc~ipad */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "linphonerc~ipad"; sourceTree = ""; }; + 63AADBDD1B6A0FF200AA16FD /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; + 63AADBE11B6A0FF200AA16FD /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; + 63AADBE31B6A0FF200AA16FD /* assistant_external_sip.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = assistant_external_sip.rc; sourceTree = ""; }; + 63AADBE41B6A0FF200AA16FD /* assistant_linphone_create.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = assistant_linphone_create.rc; sourceTree = ""; }; + 63AADBE51B6A0FF200AA16FD /* assistant_linphone_existing.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = assistant_linphone_existing.rc; sourceTree = ""; }; + 63AADBE61B6A0FF200AA16FD /* assistant_remote.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = assistant_remote.rc; sourceTree = ""; }; + 63AADBE71B6A0FF200AA16FD /* zh_TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh_TW; path = zh_TW.lproj/Localizable.strings; sourceTree = ""; }; + 63B81A031B57DA33009604A6 /* LICENSE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE.txt; sourceTree = ""; }; + 63B81A041B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingCollectionView.h; sourceTree = ""; }; + 63B81A051B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPKeyboardAvoidingCollectionView.m; sourceTree = ""; }; + 63B81A061B57DA33009604A6 /* TPKeyboardAvoidingScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingScrollView.h; sourceTree = ""; }; + 63B81A071B57DA33009604A6 /* TPKeyboardAvoidingScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPKeyboardAvoidingScrollView.m; sourceTree = ""; }; + 63B81A081B57DA33009604A6 /* TPKeyboardAvoidingTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingTableView.h; sourceTree = ""; }; + 63B81A091B57DA33009604A6 /* TPKeyboardAvoidingTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPKeyboardAvoidingTableView.m; sourceTree = ""; }; + 63B81A0A1B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+TPKeyboardAvoidingAdditions.h"; sourceTree = ""; }; + 63B81A0B1B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+TPKeyboardAvoidingAdditions.m"; sourceTree = ""; }; + 63B8D68D1BCBE65600C12B09 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ChatConversationCreateView.xib; sourceTree = ""; }; + 63B8D69F1BCBF43100C12B09 /* UIChatCreateCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIChatCreateCell.h; sourceTree = ""; }; + 63B8D6A01BCBF43100C12B09 /* UIChatCreateCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIChatCreateCell.m; sourceTree = ""; }; + 63BC49E01BA2CDFC004EC273 /* UICallPausedCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICallPausedCell.h; sourceTree = ""; }; + 63BC49E11BA2CDFC004EC273 /* UICallPausedCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICallPausedCell.m; sourceTree = ""; }; + 63C441C11BBC23ED0053DC5E /* UIAssistantTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAssistantTextField.h; sourceTree = ""; }; + 63C441C21BBC23ED0053DC5E /* UIAssistantTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAssistantTextField.m; sourceTree = ""; }; 63CD4B4D1A5AAC8C00B84282 /* DTAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTAlertView.h; sourceTree = ""; }; 63CD4B4E1A5AAC8C00B84282 /* DTAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTAlertView.m; sourceTree = ""; }; - 63EF7FDC1A24B5810017A416 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AboutViewController.strings; sourceTree = ""; }; + 63CDC4521C3BDE370085F529 /* hold.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = hold.caf; sourceTree = ""; }; + 63CDC4531C3BDE370085F529 /* msg.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = msg.caf; sourceTree = ""; }; + 63CDC4541C3BDE370085F529 /* ringback.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = ringback.wav; sourceTree = ""; }; + 63CDC4561C3BDE370085F529 /* four_hands_together.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = four_hands_together.caf; sourceTree = ""; }; + 63CDC4571C3BDE370085F529 /* house_keeping.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = house_keeping.caf; sourceTree = ""; }; + 63CDC4581C3BDE370085F529 /* it_s_a_game.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = it_s_a_game.caf; sourceTree = ""; }; + 63CDC4591C3BDE370085F529 /* leaving_a_dream.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = leaving_a_dream.caf; sourceTree = ""; }; + 63CDC45A1C3BDE370085F529 /* notes_of_the_optimistic.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = notes_of_the_optimistic.caf; sourceTree = ""; }; + 63CDC45B1C3BDE370085F529 /* soft_as_snow.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = soft_as_snow.caf; sourceTree = ""; }; + 63CDC45C1C3BDE370085F529 /* shortring.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = shortring.caf; sourceTree = ""; }; + 63CFEDE21B9EDD36007EA5BD /* libswresample.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libswresample.a; path = "liblinphone-sdk/apple-darwin/lib/libswresample.a"; sourceTree = ""; }; + 63CFEDE31B9EDD36007EA5BD /* libvo-amrwbenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libvo-amrwbenc.a"; path = "liblinphone-sdk/apple-darwin/lib/libvo-amrwbenc.a"; sourceTree = ""; }; + 63CFEDE41B9EDD36007EA5BD /* libbcg729.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbcg729.a; path = "liblinphone-sdk/apple-darwin/lib/libbcg729.a"; sourceTree = ""; }; + 63E59A3D1ADE6ECB00646FB3 /* InAppProductsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InAppProductsManager.h; sourceTree = ""; }; + 63E59A3E1ADE70D900646FB3 /* InAppProductsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InAppProductsManager.m; sourceTree = ""; }; + 63EA4C941B50189D00922857 /* libmswebrtc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmswebrtc.a; path = "liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmswebrtc.a"; sourceTree = ""; }; + 63EEE4091BBA9B110087D3AF /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = usr/lib/libxml2.tbd; sourceTree = SDKROOT; }; + 63EEE40B1BBA9B1B0087D3AF /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; }; + 63EEE40D1BBA9B250087D3AF /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; }; + 63EF7FDC1A24B5810017A416 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AboutView.strings; sourceTree = ""; }; + 63F1DF421BCE618E00EDED90 /* UIAddressTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAddressTextField.h; sourceTree = ""; }; + 63F1DF431BCE618E00EDED90 /* UIAddressTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAddressTextField.m; sourceTree = ""; }; + 63F1DF491BCE983100EDED90 /* CallConferenceTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallConferenceTableView.h; sourceTree = ""; }; + 63F1DF4A1BCE983200EDED90 /* CallConferenceTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallConferenceTableView.m; sourceTree = ""; }; + 63F1DF4C1BCE985F00EDED90 /* UICallConferenceCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICallConferenceCell.h; sourceTree = ""; }; + 63F1DF4D1BCE985F00EDED90 /* UICallConferenceCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICallConferenceCell.m; sourceTree = ""; }; + 63F1DF521BCE986A00EDED90 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UICallConferenceCell.xib; sourceTree = ""; }; 63FB30331A680E73008CA393 /* UIRoundedImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIRoundedImageView.h; sourceTree = ""; }; 63FB30341A680E73008CA393 /* UIRoundedImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIRoundedImageView.m; sourceTree = ""; }; - 70571E1913FABCB000CDD3C2 /* rootca.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = rootca.pem; path = "liblinphone-sdk/apple-darwin/share/linphone/rootca.pem"; sourceTree = ""; }; 7066FC0B13E830E400EFC6DC /* libvpx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvpx.a; path = "liblinphone-sdk/apple-darwin/lib/libvpx.a"; sourceTree = ""; }; 70E542F213E147E3002BA2C0 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; 70E542F413E147EB002BA2C0 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; - 8D1107310486CEB800E47090 /* linphone-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "linphone-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; - C90FAA7615AF54E6002091CB /* HistoryDetailsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryDetailsViewController.h; sourceTree = ""; }; - C90FAA7715AF54E6002091CB /* HistoryDetailsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HistoryDetailsViewController.m; sourceTree = ""; }; + C90FAA7615AF54E6002091CB /* HistoryDetailsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryDetailsView.h; sourceTree = ""; }; + C90FAA7715AF54E6002091CB /* HistoryDetailsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HistoryDetailsView.m; sourceTree = ""; }; C9B3A6FD15B485DB006F52EE /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = Utils/Utils.h; sourceTree = ""; }; - C9C8253F15AE204D00D493FA /* options_add_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_add_disabled.png; path = Resources/options_add_disabled.png; sourceTree = ""; }; - C9C8254015AE204D00D493FA /* options_transfer_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_transfer_disabled.png; path = Resources/options_transfer_disabled.png; sourceTree = ""; }; - C9C8254115AE204D00D493FA /* transfer_call_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = transfer_call_default.png; path = Resources/transfer_call_default.png; sourceTree = ""; }; - C9C8254215AE204D00D493FA /* transfer_call_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = transfer_call_over.png; path = Resources/transfer_call_over.png; sourceTree = ""; }; - C9C8254B15AE207B00D493FA /* options_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_selected.png; path = Resources/options_selected.png; sourceTree = ""; }; - C9C8254E15AE256100D493FA /* transfer_call_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = transfer_call_disabled.png; path = Resources/transfer_call_disabled.png; sourceTree = ""; }; - D3012CC31610467D007CD926 /* linphone_logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = linphone_logo.png; path = Resources/linphone_logo.png; sourceTree = ""; }; D306459C1611EC2900BB571E /* UILoadingImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UILoadingImageView.h; sourceTree = ""; }; D306459D1611EC2900BB571E /* UILoadingImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UILoadingImageView.m; sourceTree = ""; }; D30BBD1215D3EFEB000F93DD /* ContactDetailsDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailsDelegate.h; sourceTree = ""; }; - D30BBD1715D402A7000F93DD /* contact_ok_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_ok_disabled.png; path = Resources/contact_ok_disabled.png; sourceTree = ""; }; D30BF33216A427BC00AF0026 /* libtunnel.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtunnel.a; path = "liblinphone-sdk/apple-darwin/lib/libtunnel.a"; sourceTree = ""; }; - D3119E7015B6A4710005D4A4 /* contacts_back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contacts_back_default.png; path = Resources/contacts_back_default.png; sourceTree = ""; }; - D3119E7115B6A4710005D4A4 /* contacts_back_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contacts_back_over.png; path = Resources/contacts_back_over.png; sourceTree = ""; }; - D3128FDE15AABC7E00A2147A /* ContactDetailsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailsViewController.h; sourceTree = ""; }; - D3128FDF15AABC7E00A2147A /* ContactDetailsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactDetailsViewController.m; sourceTree = ""; }; - D3128FE715AABE4E00A2147A /* contact_back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_back_default.png; path = Resources/contact_back_default.png; sourceTree = ""; }; - D3128FE815AABE4E00A2147A /* contact_back_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_back_over.png; path = Resources/contact_back_over.png; sourceTree = ""; }; - D3128FE915AABE4E00A2147A /* contact_edit_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_edit_default.png; path = Resources/contact_edit_default.png; sourceTree = ""; }; - D3128FEA15AABE4E00A2147A /* contact_edit_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_edit_over.png; path = Resources/contact_edit_over.png; sourceTree = ""; }; - D3157A8815B4466F00DD8C4C /* history_details_add_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_details_add_default.png; path = Resources/history_details_add_default.png; sourceTree = ""; }; - D3157A8915B4466F00DD8C4C /* history_details_add_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_details_add_over.png; path = Resources/history_details_add_over.png; sourceTree = ""; }; - D3157A8E15B446CB00DD8C4C /* history_details_back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_details_back_default.png; path = Resources/history_details_back_default.png; sourceTree = ""; }; - D3157A8F15B446CB00DD8C4C /* history_details_back_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_details_back_over.png; path = Resources/history_details_back_over.png; sourceTree = ""; }; - D3196D3015A321E2007FEEBA /* options_add_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_add_default.png; path = Resources/options_add_default.png; sourceTree = ""; }; - D3196D3115A321E2007FEEBA /* options_add_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_add_over.png; path = Resources/options_add_over.png; sourceTree = ""; }; - D3196D3215A321E3007FEEBA /* options_transfer_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_transfer_default.png; path = Resources/options_transfer_default.png; sourceTree = ""; }; - D3196D3315A321E3007FEEBA /* options_transfer_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_transfer_over.png; path = Resources/options_transfer_over.png; sourceTree = ""; }; + D3128FDE15AABC7E00A2147A /* ContactDetailsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailsView.h; sourceTree = ""; }; + D3128FDF15AABC7E00A2147A /* ContactDetailsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactDetailsView.m; sourceTree = ""; }; D3196D3C15A32BD7007FEEBA /* UITransferButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UITransferButton.h; sourceTree = ""; }; D3196D3D15A32BD8007FEEBA /* UITransferButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UITransferButton.m; sourceTree = ""; }; - D31AAF5C159B3919002C6B02 /* InCallTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InCallTableViewController.h; sourceTree = ""; }; - D31AAF5D159B3919002C6B02 /* InCallTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InCallTableViewController.m; sourceTree = ""; }; - D31AAF61159B5B6E002C6B02 /* conference_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = conference_default.png; path = Resources/conference_default.png; sourceTree = ""; }; - D31AAF62159B5B6E002C6B02 /* conference_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = conference_over.png; path = Resources/conference_over.png; sourceTree = ""; }; - D31AAF6D159B65E1002C6B02 /* call_state_ringing_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_state_ringing_default.png; path = Resources/call_state_ringing_default.png; sourceTree = ""; }; - D31B4B1E159876C0002E6C72 /* UICompositeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICompositeViewController.h; sourceTree = ""; }; - D31B4B1F159876C0002E6C72 /* UICompositeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICompositeViewController.m; sourceTree = ""; }; - D31B4B261598A390002E6C72 /* avatar_unknown.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = avatar_unknown.png; path = Resources/avatar_unknown.png; sourceTree = ""; }; - D31B4B271598A390002E6C72 /* avatar_unknown_small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = avatar_unknown_small.png; path = Resources/avatar_unknown_small.png; sourceTree = ""; }; - D31C9C8D158A1C1000756B45 /* call_status_incoming.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_status_incoming.png; path = Resources/call_status_incoming.png; sourceTree = ""; }; - D31C9C8E158A1C1000756B45 /* call_status_missed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_status_missed.png; path = Resources/call_status_missed.png; sourceTree = ""; }; - D31C9C8F158A1C1000756B45 /* call_status_outgoing.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_status_outgoing.png; path = Resources/call_status_outgoing.png; sourceTree = ""; }; + D31AAF5C159B3919002C6B02 /* CallPausedTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallPausedTableView.h; sourceTree = ""; }; + D31AAF5D159B3919002C6B02 /* CallPausedTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallPausedTableView.m; sourceTree = ""; }; + D31B4B1E159876C0002E6C72 /* UICompositeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICompositeView.h; sourceTree = ""; }; + D31B4B1F159876C0002E6C72 /* UICompositeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICompositeView.m; sourceTree = ""; }; D31C9C96158A1CDE00756B45 /* UIHistoryCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIHistoryCell.h; sourceTree = ""; }; D31C9C97158A1CDE00756B45 /* UIHistoryCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIHistoryCell.m; sourceTree = ""; }; - D3211BA5159C3D410098460B /* call_state_outgoing_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_state_outgoing_default.png; path = Resources/call_state_outgoing_default.png; sourceTree = ""; }; - D3211BAD159C4EF00098460B /* UIConferenceHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIConferenceHeader.h; sourceTree = ""; }; - D3211BAE159C4EF00098460B /* UIConferenceHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIConferenceHeader.m; sourceTree = ""; }; - D3211BB8159C8A820098460B /* cell_call_first.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = cell_call_first.png; path = Resources/cell_call_first.png; sourceTree = ""; }; - D3211BBB159CBFD60098460B /* back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = back_default.png; path = Resources/back_default.png; sourceTree = ""; }; - D3211BBC159CBFD60098460B /* back_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = back_disabled.png; path = Resources/back_disabled.png; sourceTree = ""; }; - D3211BBD159CBFD60098460B /* back_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = back_over.png; path = Resources/back_over.png; sourceTree = ""; }; - D321FF9815E628CB0098B5F4 /* linphonerc~ipad */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "linphonerc~ipad"; path = "Resources/linphonerc~ipad"; sourceTree = ""; }; - D32409C1158B49A600C8C119 /* UILongTouchButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UILongTouchButton.h; sourceTree = ""; }; - D32409C2158B49A600C8C119 /* UILongTouchButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UILongTouchButton.m; sourceTree = ""; }; - D32460E4159D9AAD00BA7F3A /* UITransparentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UITransparentView.h; sourceTree = ""; }; - D32460E5159D9AAD00BA7F3A /* UITransparentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UITransparentView.m; sourceTree = ""; }; D326483615887D5200930C67 /* OrderedDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OrderedDictionary.h; path = Utils/OrderedDictionary.h; sourceTree = ""; }; D326483715887D5200930C67 /* OrderedDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OrderedDictionary.m; path = Utils/OrderedDictionary.m; sourceTree = ""; }; - D326483B1588950F00930C67 /* UICallBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICallBar.h; sourceTree = ""; }; - D326483C1588950F00930C67 /* UICallBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICallBar.m; sourceTree = ""; }; D32648421588F6FA00930C67 /* UIToggleButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIToggleButton.h; sourceTree = ""; }; D32648431588F6FB00930C67 /* UIToggleButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIToggleButton.m; sourceTree = ""; }; - D32B6E2315A5B2020033019F /* chat_send_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_send_disabled.png; path = Resources/chat_send_disabled.png; sourceTree = ""; }; - D32B6E2715A5BC430033019F /* ChatRoomTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatRoomTableViewController.h; sourceTree = ""; }; - D32B6E2815A5BC430033019F /* ChatRoomTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatRoomTableViewController.m; sourceTree = ""; }; + D32B6E2715A5BC430033019F /* ChatConversationTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatConversationTableView.h; sourceTree = ""; }; + D32B6E2815A5BC430033019F /* ChatConversationTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatConversationTableView.m; sourceTree = ""; }; D32B6E2E15A5C0AC0033019F /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; D32B9DFA15A2F131000B6DEC /* FastAddressBook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FastAddressBook.h; path = Utils/FastAddressBook.h; sourceTree = ""; }; D32B9DFB15A2F131000B6DEC /* FastAddressBook.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FastAddressBook.m; path = Utils/FastAddressBook.m; sourceTree = ""; }; - D32D5AA515ADE5D9008593F3 /* button_alert_background_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = button_alert_background_default.png; path = Resources/button_alert_background_default.png; sourceTree = ""; }; - D32D5AA615ADE5D9008593F3 /* button_alert_background_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = button_alert_background_over.png; path = Resources/button_alert_background_over.png; sourceTree = ""; }; - D3328642160B5BC300E6435D /* dialer_alt_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_alt_disabled_landscape.png; path = Resources/dialer_alt_disabled_landscape.png; sourceTree = ""; }; - D3328643160B5BC300E6435D /* dialer_alt_disabled_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialer_alt_disabled_landscape~ipad.png"; path = "Resources/dialer_alt_disabled_landscape~ipad.png"; sourceTree = ""; }; - D3328644160B5BC300E6435D /* dialer_alt_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_alt_disabled.png; path = Resources/dialer_alt_disabled.png; sourceTree = ""; }; - D3328645160B5BC300E6435D /* dialer_alt_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialer_alt_disabled~ipad.png"; path = "Resources/dialer_alt_disabled~ipad.png"; sourceTree = ""; }; - D339888C15C6DD1600CAF1E4 /* conference_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "conference_default_landscape~ipad.png"; path = "Resources/conference_default_landscape~ipad.png"; sourceTree = ""; }; - D339888D15C6DD1600CAF1E4 /* conference_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "conference_over_landscape~ipad.png"; path = "Resources/conference_over_landscape~ipad.png"; sourceTree = ""; }; - D339888E15C6DD1600CAF1E4 /* dialer_alt_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialer_alt_default_landscape~ipad.png"; path = "Resources/dialer_alt_default_landscape~ipad.png"; sourceTree = ""; }; - D339888F15C6DD1600CAF1E4 /* dialer_alt_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialer_alt_over_landscape~ipad.png"; path = "Resources/dialer_alt_over_landscape~ipad.png"; sourceTree = ""; }; - D339889015C6DD1600CAF1E4 /* hangup_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "hangup_default_landscape~ipad.png"; path = "Resources/hangup_default_landscape~ipad.png"; sourceTree = ""; }; - D339889115C6DD1600CAF1E4 /* hangup_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "hangup_over_landscape~ipad.png"; path = "Resources/hangup_over_landscape~ipad.png"; sourceTree = ""; }; - D339889215C6DD1600CAF1E4 /* micro_off_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "micro_off_default_landscape~ipad.png"; path = "Resources/micro_off_default_landscape~ipad.png"; sourceTree = ""; }; - D339889315C6DD1600CAF1E4 /* micro_off_disabled_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "micro_off_disabled_landscape~ipad.png"; path = "Resources/micro_off_disabled_landscape~ipad.png"; sourceTree = ""; }; - D339889415C6DD1600CAF1E4 /* micro_off_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "micro_off_over_landscape~ipad.png"; path = "Resources/micro_off_over_landscape~ipad.png"; sourceTree = ""; }; - D339889515C6DD1600CAF1E4 /* micro_on_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "micro_on_default_landscape~ipad.png"; path = "Resources/micro_on_default_landscape~ipad.png"; sourceTree = ""; }; - D339889615C6DD1600CAF1E4 /* micro_on_disabled_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "micro_on_disabled_landscape~ipad.png"; path = "Resources/micro_on_disabled_landscape~ipad.png"; sourceTree = ""; }; - D339889715C6DD1600CAF1E4 /* micro_on_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "micro_on_over_landscape~ipad.png"; path = "Resources/micro_on_over_landscape~ipad.png"; sourceTree = ""; }; - D339889815C6DD1600CAF1E4 /* options_add_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_add_default_landscape~ipad.png"; path = "Resources/options_add_default_landscape~ipad.png"; sourceTree = ""; }; - D339889915C6DD1600CAF1E4 /* options_add_disabled_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_add_disabled_landscape~ipad.png"; path = "Resources/options_add_disabled_landscape~ipad.png"; sourceTree = ""; }; - D339889A15C6DD1600CAF1E4 /* options_add_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_add_over_landscape~ipad.png"; path = "Resources/options_add_over_landscape~ipad.png"; sourceTree = ""; }; - D339889B15C6DD1600CAF1E4 /* options_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_default_landscape~ipad.png"; path = "Resources/options_default_landscape~ipad.png"; sourceTree = ""; }; - D339889C15C6DD1600CAF1E4 /* options_disabled_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_disabled_landscape~ipad.png"; path = "Resources/options_disabled_landscape~ipad.png"; sourceTree = ""; }; - D339889D15C6DD1600CAF1E4 /* options_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_over_landscape~ipad.png"; path = "Resources/options_over_landscape~ipad.png"; sourceTree = ""; }; - D339889E15C6DD1600CAF1E4 /* options_selected_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_selected_landscape~ipad.png"; path = "Resources/options_selected_landscape~ipad.png"; sourceTree = ""; }; - D339889F15C6DD1600CAF1E4 /* options_transfer_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_transfer_default_landscape~ipad.png"; path = "Resources/options_transfer_default_landscape~ipad.png"; sourceTree = ""; }; - D33988A015C6DD1600CAF1E4 /* options_transfer_disabled_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_transfer_disabled_landscape~ipad.png"; path = "Resources/options_transfer_disabled_landscape~ipad.png"; sourceTree = ""; }; - D33988A115C6DD1600CAF1E4 /* options_transfer_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_transfer_over_landscape~ipad.png"; path = "Resources/options_transfer_over_landscape~ipad.png"; sourceTree = ""; }; - D33988A215C6DD1600CAF1E4 /* pause_off_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "pause_off_default_landscape~ipad.png"; path = "Resources/pause_off_default_landscape~ipad.png"; sourceTree = ""; }; - D33988A315C6DD1600CAF1E4 /* pause_off_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "pause_off_over_landscape~ipad.png"; path = "Resources/pause_off_over_landscape~ipad.png"; sourceTree = ""; }; - D33988A415C6DD1600CAF1E4 /* pause_on_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "pause_on_default_landscape~ipad.png"; path = "Resources/pause_on_default_landscape~ipad.png"; sourceTree = ""; }; - D33988A515C6DD1600CAF1E4 /* pause_on_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "pause_on_over_landscape~ipad.png"; path = "Resources/pause_on_over_landscape~ipad.png"; sourceTree = ""; }; - D33988A615C6DD1600CAF1E4 /* speaker_off_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "speaker_off_default_landscape~ipad.png"; path = "Resources/speaker_off_default_landscape~ipad.png"; sourceTree = ""; }; - D33988A715C6DD1600CAF1E4 /* speaker_off_disabled_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "speaker_off_disabled_landscape~ipad.png"; path = "Resources/speaker_off_disabled_landscape~ipad.png"; sourceTree = ""; }; - D33988A815C6DD1600CAF1E4 /* speaker_off_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "speaker_off_over_landscape~ipad.png"; path = "Resources/speaker_off_over_landscape~ipad.png"; sourceTree = ""; }; - D33988A915C6DD1600CAF1E4 /* speaker_on_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "speaker_on_default_landscape~ipad.png"; path = "Resources/speaker_on_default_landscape~ipad.png"; sourceTree = ""; }; - D33988AA15C6DD1600CAF1E4 /* speaker_on_disabled_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "speaker_on_disabled_landscape~ipad.png"; path = "Resources/speaker_on_disabled_landscape~ipad.png"; sourceTree = ""; }; - D33988AB15C6DD1600CAF1E4 /* speaker_on_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "speaker_on_over_landscape~ipad.png"; path = "Resources/speaker_on_over_landscape~ipad.png"; sourceTree = ""; }; - D33988AE15C6DD1600CAF1E4 /* video_off_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "video_off_default_landscape~ipad.png"; path = "Resources/video_off_default_landscape~ipad.png"; sourceTree = ""; }; - D33988AF15C6DD1600CAF1E4 /* video_off_disabled_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "video_off_disabled_landscape~ipad.png"; path = "Resources/video_off_disabled_landscape~ipad.png"; sourceTree = ""; }; - D33988B015C6DD1600CAF1E4 /* video_off_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "video_off_over_landscape~ipad.png"; path = "Resources/video_off_over_landscape~ipad.png"; sourceTree = ""; }; - D33988B115C6DD1600CAF1E4 /* video_on_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "video_on_default_landscape~ipad.png"; path = "Resources/video_on_default_landscape~ipad.png"; sourceTree = ""; }; - D33988B215C6DD1600CAF1E4 /* video_on_disabled_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "video_on_disabled_landscape~ipad.png"; path = "Resources/video_on_disabled_landscape~ipad.png"; sourceTree = ""; }; - D33988B315C6DD1600CAF1E4 /* video_on_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "video_on_over_landscape~ipad.png"; path = "Resources/video_on_over_landscape~ipad.png"; sourceTree = ""; }; - D339890415C6E16F00CAF1E4 /* dialer_alt_back_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialer_alt_back_default_landscape~ipad.png"; path = "Resources/dialer_alt_back_default_landscape~ipad.png"; sourceTree = ""; }; - D339890515C6E16F00CAF1E4 /* dialer_alt_back_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialer_alt_back_over_landscape~ipad.png"; path = "Resources/dialer_alt_back_over_landscape~ipad.png"; sourceTree = ""; }; - D33E1F06164CF35100CFA363 /* callbar_left_padding.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = callbar_left_padding.png; path = Resources/callbar_left_padding.png; sourceTree = ""; }; - D33E1F07164CF35100CFA363 /* callbar_right_padding.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = callbar_right_padding.png; path = Resources/callbar_right_padding.png; sourceTree = ""; }; - D3432A5C158A4446001C6B0B /* led_connected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = led_connected.png; path = Resources/led_connected.png; sourceTree = ""; }; - D3432A5D158A4446001C6B0B /* led_error.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = led_error.png; path = Resources/led_error.png; sourceTree = ""; }; - D3432A5E158A4446001C6B0B /* call_quality_indicator_0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_quality_indicator_0.png; path = Resources/call_quality_indicator_0.png; sourceTree = ""; }; - D3432A5F158A4446001C6B0B /* call_quality_indicator_1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_quality_indicator_1.png; path = Resources/call_quality_indicator_1.png; sourceTree = ""; }; - D3432A60158A4446001C6B0B /* call_quality_indicator_2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_quality_indicator_2.png; path = Resources/call_quality_indicator_2.png; sourceTree = ""; }; - D3432A61158A4446001C6B0B /* call_quality_indicator_3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_quality_indicator_3.png; path = Resources/call_quality_indicator_3.png; sourceTree = ""; }; - D3432A6F158A45AF001C6B0B /* led_inprogress.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = led_inprogress.png; path = Resources/led_inprogress.png; sourceTree = ""; }; - D3432A70158A45AF001C6B0B /* led_disconnected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = led_disconnected.png; path = Resources/led_disconnected.png; sourceTree = ""; }; - D347347C1580E5F8003C7B8C /* history_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_default.png; path = Resources/history_default.png; sourceTree = ""; }; - D347347D1580E5F8003C7B8C /* history_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_selected.png; path = Resources/history_selected.png; sourceTree = ""; }; D34F6F9D1594D3FB0095705B /* InAppSettings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = InAppSettings.bundle; sourceTree = ""; }; - D350F20B15A43BB100149E54 /* WizardViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WizardViewController.h; sourceTree = ""; }; - D350F20C15A43BB100149E54 /* WizardViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WizardViewController.m; sourceTree = ""; }; - D350F21315A43D3400149E54 /* setup_back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = setup_back_default.png; path = Resources/setup_back_default.png; sourceTree = ""; }; - D350F21415A43D3400149E54 /* setup_back_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = setup_back_over.png; path = Resources/setup_back_over.png; sourceTree = ""; }; - D350F21515A43D3400149E54 /* setup_cancel_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = setup_cancel_default.png; path = Resources/setup_cancel_default.png; sourceTree = ""; }; - D350F21615A43D3400149E54 /* setup_cancel_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = setup_cancel_over.png; path = Resources/setup_cancel_over.png; sourceTree = ""; }; - D350F21715A43D3400149E54 /* field_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = field_background.png; path = Resources/field_background.png; sourceTree = ""; }; - D350F21815A43D3400149E54 /* setup_start_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = setup_start_default.png; path = Resources/setup_start_default.png; sourceTree = ""; }; - D350F21915A43D3400149E54 /* setup_start_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = setup_start_over.png; path = Resources/setup_start_over.png; sourceTree = ""; }; - D350F21B15A43D3400149E54 /* setup_welcome_logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = setup_welcome_logo.png; path = Resources/setup_welcome_logo.png; sourceTree = ""; }; - D35406F515A47E9E007E7E81 /* button_background_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = button_background_default.png; path = Resources/button_background_default.png; sourceTree = ""; }; - D35406F615A47E9E007E7E81 /* button_background_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = button_background_over.png; path = Resources/button_background_over.png; sourceTree = ""; }; - D35497FB15875372000081D8 /* ContactsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsViewController.h; sourceTree = ""; }; - D35497FC15875372000081D8 /* ContactsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ContactsViewController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - D354980215875534000081D8 /* contacts_all_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contacts_all_selected.png; path = Resources/contacts_all_selected.png; sourceTree = ""; }; - D354980315875534000081D8 /* contacts_all_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contacts_all_default.png; path = Resources/contacts_all_default.png; sourceTree = ""; }; - D354980415875534000081D8 /* contacts_linphone_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contacts_linphone_selected.png; path = Resources/contacts_linphone_selected.png; sourceTree = ""; }; - D354980515875534000081D8 /* contacts_linphone_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contacts_linphone_default.png; path = Resources/contacts_linphone_default.png; sourceTree = ""; }; - D354980E15875608000081D8 /* contacts_add_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contacts_add_default.png; path = Resources/contacts_add_default.png; sourceTree = ""; }; - D354980F15875608000081D8 /* contacts_add_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contacts_add_over.png; path = Resources/contacts_add_over.png; sourceTree = ""; }; - D3549814158761CF000081D8 /* ContactsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsTableViewController.h; sourceTree = ""; }; - D3549815158761D0000081D8 /* ContactsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ContactsTableViewController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - D354981815876FE7000081D8 /* list_details_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = list_details_default.png; path = Resources/list_details_default.png; sourceTree = ""; }; - D354981915876FE7000081D8 /* list_details_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = list_details_over.png; path = Resources/list_details_over.png; sourceTree = ""; }; - D354981E1587716B000081D8 /* UIStateBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIStateBar.h; sourceTree = ""; }; - D354981F1587716B000081D8 /* UIStateBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIStateBar.m; sourceTree = ""; }; + D350F20B15A43BB100149E54 /* AssistantView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssistantView.h; sourceTree = ""; }; + D350F20C15A43BB100149E54 /* AssistantView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AssistantView.m; sourceTree = ""; }; + D35497FB15875372000081D8 /* ContactsListView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsListView.h; sourceTree = ""; }; + D35497FC15875372000081D8 /* ContactsListView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ContactsListView.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + D3549814158761CF000081D8 /* ContactsListTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsListTableView.h; sourceTree = ""; }; + D3549815158761D0000081D8 /* ContactsListTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ContactsListTableView.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + D354981E1587716B000081D8 /* StatusBarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StatusBarView.h; path = LinphoneUI/StatusBarView.h; sourceTree = ""; }; + D354981F1587716B000081D8 /* StatusBarView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = StatusBarView.m; path = LinphoneUI/StatusBarView.m; sourceTree = ""; }; D3554EC515CA79A900478841 /* XMLRPC.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = XMLRPC.xcodeproj; path = Utils/XMLRPC/XMLRPC.xcodeproj; sourceTree = ""; }; D35860D515B549B500513429 /* Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Utils.m; path = Utils/Utils.m; sourceTree = ""; }; - D35E757515931E5D0066B1C1 /* switch_camera_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = switch_camera_default.png; path = Resources/switch_camera_default.png; sourceTree = ""; }; - D35E757615931E5D0066B1C1 /* switch_camera_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = switch_camera_over.png; path = Resources/switch_camera_over.png; sourceTree = ""; }; - D35E757F159328EA0066B1C1 /* UIAddressTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAddressTextField.h; sourceTree = ""; }; - D35E7580159328EB0066B1C1 /* UIAddressTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAddressTextField.m; sourceTree = ""; }; - D35E758815932DE60066B1C1 /* backspace_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = backspace_disabled.png; path = Resources/backspace_disabled.png; sourceTree = ""; }; - D35E758C15934F360066B1C1 /* call_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_disabled.png; path = Resources/call_disabled.png; sourceTree = ""; }; - D35E7594159460560066B1C1 /* ChatViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatViewController.h; sourceTree = ""; }; - D35E7595159460560066B1C1 /* ChatViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatViewController.m; sourceTree = ""; }; - D35E759C159460B50066B1C1 /* SettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsViewController.h; sourceTree = ""; }; - D35E759D159460B50066B1C1 /* SettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsViewController.m; sourceTree = ""; }; - D35E91E9160CA0BD0023116B /* field_background.9@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "field_background.9@2x.png"; path = "Resources/field_background.9@2x.png"; sourceTree = ""; }; - D35E91EC160CA0C70023116B /* button_background_default.9@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "button_background_default.9@2x.png"; path = "Resources/button_background_default.9@2x.png"; sourceTree = ""; }; - D35E91ED160CA0C70023116B /* button_background_over.9@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "button_background_over.9@2x.png"; path = "Resources/button_background_over.9@2x.png"; sourceTree = ""; }; - D35E91F2160CA10B0023116B /* UILinphoneTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UILinphoneTextField.h; sourceTree = ""; }; - D35E91F3160CA10B0023116B /* UILinphoneTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UILinphoneTextField.m; sourceTree = ""; }; - D35E91F6160CA4FF0023116B /* UILinphoneButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UILinphoneButton.h; sourceTree = ""; }; - D35E91F7160CA4FF0023116B /* UILinphoneButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UILinphoneButton.m; sourceTree = ""; }; - D35E9208160CAA1F0023116B /* field_background.9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = field_background.9.png; path = Resources/field_background.9.png; sourceTree = ""; }; - D35E920B160CABD70023116B /* button_background_default.9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = button_background_default.9.png; path = Resources/button_background_default.9.png; sourceTree = ""; }; - D35E920C160CABD70023116B /* button_background_over.9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = button_background_over.9.png; path = Resources/button_background_over.9.png; sourceTree = ""; }; - D35EA76115A2DF8D003E025D /* micro_off_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = micro_off_disabled.png; path = Resources/micro_off_disabled.png; sourceTree = ""; }; - D35EA76215A2DF8D003E025D /* micro_on_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = micro_on_disabled.png; path = Resources/micro_on_disabled.png; sourceTree = ""; }; - D365AA7915A2DE7500CAFE3F /* speaker_off_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_off_disabled.png; path = Resources/speaker_off_disabled.png; sourceTree = ""; }; - D365AA7A15A2DE7500CAFE3F /* speaker_on_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_on_disabled.png; path = Resources/speaker_on_disabled.png; sourceTree = ""; }; - D36C43C4158F2E5A0048BA40 /* UICallCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICallCell.h; sourceTree = ""; }; - D36C43C5158F2E5A0048BA40 /* UICallCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICallCell.m; sourceTree = ""; }; - D36C43CC158F2F370048BA40 /* cell_call.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = cell_call.png; path = Resources/cell_call.png; sourceTree = ""; }; - D36C43CD158F2F370048BA40 /* cell_conference.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = cell_conference.png; path = Resources/cell_conference.png; sourceTree = ""; }; - D36C43CE158F2F370048BA40 /* header_conference.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = header_conference.png; path = Resources/header_conference.png; sourceTree = ""; }; - D36C43CF158F2F370048BA40 /* dialer_alt_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_alt_default.png; path = Resources/dialer_alt_default.png; sourceTree = ""; }; - D36C43D0158F2F370048BA40 /* dialer_alt_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_alt_over.png; path = Resources/dialer_alt_over.png; sourceTree = ""; }; - D36C43E7158F3F7E0048BA40 /* pause_on_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = pause_on_default.png; path = Resources/pause_on_default.png; sourceTree = ""; }; - D36C43E8158F3F7E0048BA40 /* pause_on_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = pause_on_over.png; path = Resources/pause_on_over.png; sourceTree = ""; }; - D36C43ED158F61EA0048BA40 /* call_state_pause_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_state_pause_default.png; path = Resources/call_state_pause_default.png; sourceTree = ""; }; - D36C43EE158F61EA0048BA40 /* call_state_pause_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_state_pause_over.png; path = Resources/call_state_pause_over.png; sourceTree = ""; }; - D36C43EF158F61EA0048BA40 /* call_state_play_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_state_play_default.png; path = Resources/call_state_play_default.png; sourceTree = ""; }; - D36C43F0158F61EA0048BA40 /* call_state_play_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_state_play_over.png; path = Resources/call_state_play_over.png; sourceTree = ""; }; + D35E7594159460560066B1C1 /* ChatsListView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatsListView.h; sourceTree = ""; }; + D35E7595159460560066B1C1 /* ChatsListView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatsListView.m; sourceTree = ""; }; + D35E759C159460B50066B1C1 /* SettingsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsView.h; sourceTree = ""; }; + D35E759D159460B50066B1C1 /* SettingsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsView.m; sourceTree = ""; }; D36FB2D31589EF7C0036F6F2 /* UIPauseButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIPauseButton.h; sourceTree = ""; }; D36FB2D41589EF7C0036F6F2 /* UIPauseButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIPauseButton.m; sourceTree = ""; }; - D37295DA158B3C9600D2C0C7 /* video_off_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = video_off_disabled.png; path = Resources/video_off_disabled.png; sourceTree = ""; }; - D374D3FB16071762003D25FF /* ImageSharing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageSharing.h; sourceTree = ""; }; - D374D3FC16071762003D25FF /* ImageSharing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageSharing.m; sourceTree = ""; }; - D377BBF915A19DA6002B696B /* video_on_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = video_on_disabled.png; path = Resources/video_on_disabled.png; sourceTree = ""; }; - D378906215AC373B00BD776C /* ContactDetailsLabelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailsLabelViewController.h; sourceTree = ""; }; - D378906315AC373B00BD776C /* ContactDetailsLabelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactDetailsLabelViewController.m; sourceTree = ""; }; - D378AB2815DCDB480098505D /* ImagePickerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImagePickerViewController.h; sourceTree = ""; }; - D378AB2915DCDB490098505D /* ImagePickerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImagePickerViewController.m; sourceTree = ""; }; - D37B96B515A1A6F20005CCD2 /* call_state_delete_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_state_delete_default.png; path = Resources/call_state_delete_default.png; sourceTree = ""; }; - D37B96B615A1A6F20005CCD2 /* call_state_delete_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_state_delete_over.png; path = Resources/call_state_delete_over.png; sourceTree = ""; }; - D37C638C15AAD251009D0BAC /* contact_number_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_number_over.png; path = Resources/contact_number_over.png; sourceTree = ""; }; - D37C638D15AAD251009D0BAC /* contact_number.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_number.png; path = Resources/contact_number.png; sourceTree = ""; }; - D37C639215AADDAE009D0BAC /* UIContactDetailsHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIContactDetailsHeader.h; sourceTree = ""; }; - D37C639315AADDAE009D0BAC /* UIContactDetailsHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIContactDetailsHeader.m; sourceTree = ""; }; - D37C639915AADEF4009D0BAC /* ContactDetailsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailsTableViewController.h; sourceTree = ""; }; - D37C639A15AADEF5009D0BAC /* ContactDetailsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactDetailsTableViewController.m; sourceTree = ""; }; + D378AB2815DCDB480098505D /* ImagePickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImagePickerView.h; sourceTree = ""; }; + D378AB2915DCDB490098505D /* ImagePickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImagePickerView.m; sourceTree = ""; }; + D37C639915AADEF4009D0BAC /* ContactDetailsTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailsTableView.h; sourceTree = ""; }; + D37C639A15AADEF5009D0BAC /* ContactDetailsTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactDetailsTableView.m; sourceTree = ""; }; D37DC6BF1594AE1800B2A5EB /* LinphoneCoreSettingsStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinphoneCoreSettingsStore.h; sourceTree = ""; }; D37DC6C01594AE1800B2A5EB /* LinphoneCoreSettingsStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LinphoneCoreSettingsStore.m; sourceTree = ""; }; D37DC7171594AF3400B2A5EB /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; D37E3ECB1619C27A0087659A /* CAAnimation+Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CAAnimation+Blocks.h"; sourceTree = ""; }; D37E3ECC1619C27A0087659A /* CAAnimation+Blocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CAAnimation+Blocks.m"; sourceTree = ""; }; - D37E3ECF1619DCC50087659A /* licenses.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = licenses.html; path = Resources/licenses.html; sourceTree = ""; }; D37EE160160377D7003608A6 /* DTActionSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTActionSheet.h; sourceTree = ""; }; D37EE161160377D7003608A6 /* DTActionSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTActionSheet.m; sourceTree = ""; }; - D3804E5E15D92A57008072A5 /* msg.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = msg.caf; path = Resources/msg.caf; sourceTree = ""; }; - D3804E5F15D92A57008072A5 /* msg.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = msg.wav; path = Resources/msg.wav; sourceTree = ""; }; D3807FB715C28940005BE9BC /* DCRoundSwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DCRoundSwitch.h; sourceTree = ""; }; D3807FB815C28940005BE9BC /* DCRoundSwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DCRoundSwitch.m; sourceTree = ""; }; D3807FB915C28940005BE9BC /* DCRoundSwitchKnobLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DCRoundSwitchKnobLayer.h; sourceTree = ""; }; @@ -1299,543 +1474,116 @@ D3807FE515C2894A005BE9BC /* IASKSwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSwitch.m; sourceTree = ""; }; D3807FE615C2894A005BE9BC /* IASKTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKTextField.h; sourceTree = ""; }; D3807FE715C2894A005BE9BC /* IASKTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKTextField.m; sourceTree = ""; }; - D380800415C28A7A005BE9BC /* UILinphone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UILinphone.m; sourceTree = ""; }; D380801115C29984005BE9BC /* ColorSpaceUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ColorSpaceUtilities.h; path = Utils/ColorSpaceUtilities.h; sourceTree = ""; }; D380801215C299D0005BE9BC /* ColorSpaceUtilites.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ColorSpaceUtilites.m; path = Utils/ColorSpaceUtilites.m; sourceTree = ""; }; - D381885815FE44A700C3EDCA /* fr */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = fr; path = Resources/fr.lproj/Localizable.strings; sourceTree = ""; }; - D38327EB1580FE3A00FA0D23 /* contacts_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contacts_default.png; path = Resources/contacts_default.png; sourceTree = ""; }; - D38327EC1580FE3A00FA0D23 /* contacts_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contacts_selected.png; path = Resources/contacts_selected.png; sourceTree = ""; }; - D38327ED1580FE3A00FA0D23 /* dialer_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_default.png; path = Resources/dialer_default.png; sourceTree = ""; }; - D38327EE1580FE3A00FA0D23 /* dialer_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_over.png; path = Resources/dialer_over.png; sourceTree = ""; }; - D38327EF1580FE3A00FA0D23 /* settings_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = settings_default.png; path = Resources/settings_default.png; sourceTree = ""; }; - D38327F01580FE3A00FA0D23 /* settings_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = settings_selected.png; path = Resources/settings_selected.png; sourceTree = ""; }; - D38327F11580FE3A00FA0D23 /* chat_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_default.png; path = Resources/chat_default.png; sourceTree = ""; }; - D38327F21580FE3A00FA0D23 /* chat_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_selected.png; path = Resources/chat_selected.png; sourceTree = ""; }; - D38327FC158100E400FA0D23 /* contacts_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contacts_over.png; path = Resources/contacts_over.png; sourceTree = ""; }; - D38327FD158100E400FA0D23 /* history_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_over.png; path = Resources/history_over.png; sourceTree = ""; }; - D38327FE158100E400FA0D23 /* settings_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = settings_over.png; path = Resources/settings_over.png; sourceTree = ""; }; - D38327FF158100E400FA0D23 /* chat_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_over.png; path = Resources/chat_over.png; sourceTree = ""; }; - D3866C261608CA1600830F95 /* image_back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = image_back_default.png; path = Resources/image_back_default.png; sourceTree = ""; }; - D3866C271608CA1600830F95 /* image_back_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = image_back_over.png; path = Resources/image_back_over.png; sourceTree = ""; }; - D389363715A6D53200A3A3AA /* chat_bubble_incoming.9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_bubble_incoming.9.png; path = Resources/chat_bubble_incoming.9.png; sourceTree = ""; }; - D389363815A6D53200A3A3AA /* chat_bubble_outgoing.9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_bubble_outgoing.9.png; path = Resources/chat_bubble_outgoing.9.png; sourceTree = ""; }; - D38D14AD15A30B3D008497E8 /* cell_call_first_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = cell_call_first_highlight.png; path = Resources/cell_call_first_highlight.png; sourceTree = ""; }; - D38D14AE15A30B3D008497E8 /* cell_call_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = cell_call_highlight.png; path = Resources/cell_call_highlight.png; sourceTree = ""; }; - D3998D0316031937009DD22C /* background_alt.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = background_alt.png; path = Resources/background_alt.png; sourceTree = ""; }; D3A55FBA15877E5E003FD403 /* UIContactCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIContactCell.h; sourceTree = ""; }; D3A55FBB15877E5E003FD403 /* UIContactCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIContactCell.m; sourceTree = ""; }; - D3A74E5815C68162001500B9 /* toolsbar_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = toolsbar_background.png; path = Resources/toolsbar_background.png; sourceTree = ""; }; - D3A74E5E15C69391001500B9 /* add_call_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "add_call_default~ipad.png"; path = "Resources/add_call_default~ipad.png"; sourceTree = ""; }; - D3A74E5F15C69391001500B9 /* add_call_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "add_call_disabled~ipad.png"; path = "Resources/add_call_disabled~ipad.png"; sourceTree = ""; }; - D3A74E6015C69391001500B9 /* add_call_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "add_call_over~ipad.png"; path = "Resources/add_call_over~ipad.png"; sourceTree = ""; }; - D3A74E6115C69391001500B9 /* add_contact_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "add_contact_default~ipad.png"; path = "Resources/add_contact_default~ipad.png"; sourceTree = ""; }; - D3A74E6215C69392001500B9 /* add_contact_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "add_contact_disabled~ipad.png"; path = "Resources/add_contact_disabled~ipad.png"; sourceTree = ""; }; - D3A74E6315C69392001500B9 /* add_contact_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "add_contact_over~ipad.png"; path = "Resources/add_contact_over~ipad.png"; sourceTree = ""; }; - D3A74E6415C69392001500B9 /* back_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "back_default~ipad.png"; path = "Resources/back_default~ipad.png"; sourceTree = ""; }; - D3A74E6515C69392001500B9 /* back_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "back_disabled~ipad.png"; path = "Resources/back_disabled~ipad.png"; sourceTree = ""; }; - D3A74E6615C69392001500B9 /* back_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "back_over~ipad.png"; path = "Resources/back_over~ipad.png"; sourceTree = ""; }; - D3A74E6715C69392001500B9 /* background_top~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "background_top~ipad.png"; path = "Resources/background_top~ipad.png"; sourceTree = ""; }; - D3A74E6815C69392001500B9 /* backspace_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "backspace_default~ipad.png"; path = "Resources/backspace_default~ipad.png"; sourceTree = ""; }; - D3A74E6915C69392001500B9 /* backspace_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "backspace_disabled~ipad.png"; path = "Resources/backspace_disabled~ipad.png"; sourceTree = ""; }; - D3A74E6A15C69392001500B9 /* backspace_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "backspace_over~ipad.png"; path = "Resources/backspace_over~ipad.png"; sourceTree = ""; }; - D3A74E6B15C69392001500B9 /* call_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "call_default~ipad.png"; path = "Resources/call_default~ipad.png"; sourceTree = ""; }; - D3A74E6C15C69392001500B9 /* call_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "call_disabled~ipad.png"; path = "Resources/call_disabled~ipad.png"; sourceTree = ""; }; - D3A74E6D15C69392001500B9 /* call_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "call_over~ipad.png"; path = "Resources/call_over~ipad.png"; sourceTree = ""; }; - D3A74E6E15C69392001500B9 /* chat_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "chat_default_landscape~ipad.png"; path = "Resources/chat_default_landscape~ipad.png"; sourceTree = ""; }; - D3A74E6F15C69392001500B9 /* chat_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "chat_default~ipad.png"; path = "Resources/chat_default~ipad.png"; sourceTree = ""; }; - D3A74E7015C69392001500B9 /* chat_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "chat_over_landscape~ipad.png"; path = "Resources/chat_over_landscape~ipad.png"; sourceTree = ""; }; - D3A74E7115C69392001500B9 /* chat_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "chat_over~ipad.png"; path = "Resources/chat_over~ipad.png"; sourceTree = ""; }; - D3A74E7215C69392001500B9 /* chat_selected_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "chat_selected_landscape~ipad.png"; path = "Resources/chat_selected_landscape~ipad.png"; sourceTree = ""; }; - D3A74E7315C69392001500B9 /* chat_selected~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "chat_selected~ipad.png"; path = "Resources/chat_selected~ipad.png"; sourceTree = ""; }; - D3A74E7415C69392001500B9 /* conference_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "conference_default~ipad.png"; path = "Resources/conference_default~ipad.png"; sourceTree = ""; }; - D3A74E7515C69392001500B9 /* conference_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "conference_over~ipad.png"; path = "Resources/conference_over~ipad.png"; sourceTree = ""; }; - D3A74E7615C69392001500B9 /* contacts_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "contacts_default_landscape~ipad.png"; path = "Resources/contacts_default_landscape~ipad.png"; sourceTree = ""; }; - D3A74E7715C69392001500B9 /* contacts_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "contacts_default~ipad.png"; path = "Resources/contacts_default~ipad.png"; sourceTree = ""; }; - D3A74E7815C69392001500B9 /* contacts_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "contacts_over_landscape~ipad.png"; path = "Resources/contacts_over_landscape~ipad.png"; sourceTree = ""; }; - D3A74E7915C69392001500B9 /* contacts_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "contacts_over~ipad.png"; path = "Resources/contacts_over~ipad.png"; sourceTree = ""; }; - D3A74E7A15C69392001500B9 /* contacts_selected_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "contacts_selected_landscape~ipad.png"; path = "Resources/contacts_selected_landscape~ipad.png"; sourceTree = ""; }; - D3A74E7B15C69392001500B9 /* contacts_selected~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "contacts_selected~ipad.png"; path = "Resources/contacts_selected~ipad.png"; sourceTree = ""; }; - D3A74E7C15C69392001500B9 /* dialer_address_background_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialer_address_background_landscape~ipad.png"; path = "Resources/dialer_address_background_landscape~ipad.png"; sourceTree = ""; }; - D3A74E7D15C69392001500B9 /* dialer_address_background~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialer_address_background~ipad.png"; path = "Resources/dialer_address_background~ipad.png"; sourceTree = ""; }; - D3A74E7E15C69392001500B9 /* dialer_alt_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialer_alt_default~ipad.png"; path = "Resources/dialer_alt_default~ipad.png"; sourceTree = ""; }; - D3A74E7F15C69392001500B9 /* dialer_alt_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialer_alt_over~ipad.png"; path = "Resources/dialer_alt_over~ipad.png"; sourceTree = ""; }; - D3A74E8015C69392001500B9 /* hangup_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "hangup_default~ipad.png"; path = "Resources/hangup_default~ipad.png"; sourceTree = ""; }; - D3A74E8115C69392001500B9 /* hangup_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "hangup_over~ipad.png"; path = "Resources/hangup_over~ipad.png"; sourceTree = ""; }; - D3A74E8215C69392001500B9 /* history_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "history_default_landscape~ipad.png"; path = "Resources/history_default_landscape~ipad.png"; sourceTree = ""; }; - D3A74E8315C69392001500B9 /* history_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "history_default~ipad.png"; path = "Resources/history_default~ipad.png"; sourceTree = ""; }; - D3A74E8415C69392001500B9 /* history_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "history_over_landscape~ipad.png"; path = "Resources/history_over_landscape~ipad.png"; sourceTree = ""; }; - D3A74E8515C69392001500B9 /* history_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "history_over~ipad.png"; path = "Resources/history_over~ipad.png"; sourceTree = ""; }; - D3A74E8615C69392001500B9 /* history_selected_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "history_selected_landscape~ipad.png"; path = "Resources/history_selected_landscape~ipad.png"; sourceTree = ""; }; - D3A74E8715C69392001500B9 /* history_selected~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "history_selected~ipad.png"; path = "Resources/history_selected~ipad.png"; sourceTree = ""; }; - D3A74E8815C69392001500B9 /* micro_off_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "micro_off_default~ipad.png"; path = "Resources/micro_off_default~ipad.png"; sourceTree = ""; }; - D3A74E8915C69392001500B9 /* micro_off_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "micro_off_disabled~ipad.png"; path = "Resources/micro_off_disabled~ipad.png"; sourceTree = ""; }; - D3A74E8A15C69392001500B9 /* micro_off_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "micro_off_over~ipad.png"; path = "Resources/micro_off_over~ipad.png"; sourceTree = ""; }; - D3A74E8B15C69392001500B9 /* micro_on_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "micro_on_default~ipad.png"; path = "Resources/micro_on_default~ipad.png"; sourceTree = ""; }; - D3A74E8C15C69392001500B9 /* micro_on_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "micro_on_disabled~ipad.png"; path = "Resources/micro_on_disabled~ipad.png"; sourceTree = ""; }; - D3A74E8D15C69392001500B9 /* micro_on_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "micro_on_over~ipad.png"; path = "Resources/micro_on_over~ipad.png"; sourceTree = ""; }; - D3A74E8E15C69392001500B9 /* options_add_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_add_default~ipad.png"; path = "Resources/options_add_default~ipad.png"; sourceTree = ""; }; - D3A74E8F15C69392001500B9 /* options_add_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_add_disabled~ipad.png"; path = "Resources/options_add_disabled~ipad.png"; sourceTree = ""; }; - D3A74E9015C69392001500B9 /* options_add_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_add_over~ipad.png"; path = "Resources/options_add_over~ipad.png"; sourceTree = ""; }; - D3A74E9115C69392001500B9 /* options_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_default~ipad.png"; path = "Resources/options_default~ipad.png"; sourceTree = ""; }; - D3A74E9215C69392001500B9 /* options_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_disabled~ipad.png"; path = "Resources/options_disabled~ipad.png"; sourceTree = ""; }; - D3A74E9315C69392001500B9 /* options_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_over~ipad.png"; path = "Resources/options_over~ipad.png"; sourceTree = ""; }; - D3A74E9415C69392001500B9 /* options_selected~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_selected~ipad.png"; path = "Resources/options_selected~ipad.png"; sourceTree = ""; }; - D3A74E9515C69392001500B9 /* options_transfer_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_transfer_default~ipad.png"; path = "Resources/options_transfer_default~ipad.png"; sourceTree = ""; }; - D3A74E9615C69392001500B9 /* options_transfer_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_transfer_disabled~ipad.png"; path = "Resources/options_transfer_disabled~ipad.png"; sourceTree = ""; }; - D3A74E9715C69392001500B9 /* options_transfer_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "options_transfer_over~ipad.png"; path = "Resources/options_transfer_over~ipad.png"; sourceTree = ""; }; - D3A74E9815C69392001500B9 /* pause_off_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "pause_off_default~ipad.png"; path = "Resources/pause_off_default~ipad.png"; sourceTree = ""; }; - D3A74E9915C69392001500B9 /* pause_off_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "pause_off_over~ipad.png"; path = "Resources/pause_off_over~ipad.png"; sourceTree = ""; }; - D3A74E9A15C69392001500B9 /* pause_on_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "pause_on_default~ipad.png"; path = "Resources/pause_on_default~ipad.png"; sourceTree = ""; }; - D3A74E9B15C69392001500B9 /* pause_on_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "pause_on_over~ipad.png"; path = "Resources/pause_on_over~ipad.png"; sourceTree = ""; }; - D3A74E9C15C69392001500B9 /* settings_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "settings_default_landscape~ipad.png"; path = "Resources/settings_default_landscape~ipad.png"; sourceTree = ""; }; - D3A74E9D15C69392001500B9 /* settings_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "settings_default~ipad.png"; path = "Resources/settings_default~ipad.png"; sourceTree = ""; }; - D3A74E9E15C69392001500B9 /* settings_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "settings_over_landscape~ipad.png"; path = "Resources/settings_over_landscape~ipad.png"; sourceTree = ""; }; - D3A74E9F15C69392001500B9 /* settings_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "settings_over~ipad.png"; path = "Resources/settings_over~ipad.png"; sourceTree = ""; }; - D3A74EA015C69392001500B9 /* settings_selected_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "settings_selected_landscape~ipad.png"; path = "Resources/settings_selected_landscape~ipad.png"; sourceTree = ""; }; - D3A74EA115C69392001500B9 /* settings_selected~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "settings_selected~ipad.png"; path = "Resources/settings_selected~ipad.png"; sourceTree = ""; }; - D3A74EA215C69392001500B9 /* speaker_off_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "speaker_off_default~ipad.png"; path = "Resources/speaker_off_default~ipad.png"; sourceTree = ""; }; - D3A74EA315C69392001500B9 /* speaker_off_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "speaker_off_disabled~ipad.png"; path = "Resources/speaker_off_disabled~ipad.png"; sourceTree = ""; }; - D3A74EA415C69392001500B9 /* speaker_off_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "speaker_off_over~ipad.png"; path = "Resources/speaker_off_over~ipad.png"; sourceTree = ""; }; - D3A74EA515C69392001500B9 /* speaker_on_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "speaker_on_default~ipad.png"; path = "Resources/speaker_on_default~ipad.png"; sourceTree = ""; }; - D3A74EA615C69392001500B9 /* speaker_on_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "speaker_on_disabled~ipad.png"; path = "Resources/speaker_on_disabled~ipad.png"; sourceTree = ""; }; - D3A74EA715C69392001500B9 /* speaker_on_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "speaker_on_over~ipad.png"; path = "Resources/speaker_on_over~ipad.png"; sourceTree = ""; }; - D3A74EA815C69392001500B9 /* statebar_background_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "statebar_background_landscape~ipad.png"; path = "Resources/statebar_background_landscape~ipad.png"; sourceTree = ""; }; - D3A74EA915C69392001500B9 /* statebar_background~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "statebar_background~ipad.png"; path = "Resources/statebar_background~ipad.png"; sourceTree = ""; }; - D3A74EAA15C69392001500B9 /* transfer_call_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "transfer_call_default~ipad.png"; path = "Resources/transfer_call_default~ipad.png"; sourceTree = ""; }; - D3A74EAB15C69392001500B9 /* transfer_call_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "transfer_call_over~ipad.png"; path = "Resources/transfer_call_over~ipad.png"; sourceTree = ""; }; - D3A74EAC15C69392001500B9 /* video_off_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "video_off_default~ipad.png"; path = "Resources/video_off_default~ipad.png"; sourceTree = ""; }; - D3A74EAD15C69392001500B9 /* video_off_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "video_off_disabled~ipad.png"; path = "Resources/video_off_disabled~ipad.png"; sourceTree = ""; }; - D3A74EAE15C69392001500B9 /* video_off_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "video_off_over~ipad.png"; path = "Resources/video_off_over~ipad.png"; sourceTree = ""; }; - D3A74EAF15C69392001500B9 /* video_on_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "video_on_default~ipad.png"; path = "Resources/video_on_default~ipad.png"; sourceTree = ""; }; - D3A74EB015C69392001500B9 /* video_on_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "video_on_disabled~ipad.png"; path = "Resources/video_on_disabled~ipad.png"; sourceTree = ""; }; - D3A74EB115C69392001500B9 /* video_on_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "video_on_over~ipad.png"; path = "Resources/video_on_over~ipad.png"; sourceTree = ""; }; - D3A8BB6E15A6C7D500F96BE5 /* UIChatRoomCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIChatRoomCell.h; sourceTree = ""; }; - D3A8BB6F15A6C7D500F96BE5 /* UIChatRoomCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIChatRoomCell.m; sourceTree = ""; }; - D3A8BB7615A6CC3200F96BE5 /* chat_bubble_outgoing.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_bubble_outgoing.png; path = Resources/chat_bubble_outgoing.png; sourceTree = ""; }; - D3A8BB7715A6CC3200F96BE5 /* chat_bubble_incoming.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_bubble_incoming.png; path = Resources/chat_bubble_incoming.png; sourceTree = ""; }; - D3A8BB7815A6CC3200F96BE5 /* setup_back_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = setup_back_disabled.png; path = Resources/setup_back_disabled.png; sourceTree = ""; }; - D3A8BB7915A6CC3200F96BE5 /* setup_cancel_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = setup_cancel_disabled.png; path = Resources/setup_cancel_disabled.png; sourceTree = ""; }; - D3A8BB7A15A6CC3200F96BE5 /* setup_start_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = setup_start_disabled.png; path = Resources/setup_start_disabled.png; sourceTree = ""; }; - D3ACB09915C6D59500E15894 /* dialer_alt_back_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialer_alt_back_default~ipad.png"; path = "Resources/dialer_alt_back_default~ipad.png"; sourceTree = ""; }; - D3ACB09A15C6D59500E15894 /* dialer_alt_back_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialer_alt_back_over~ipad.png"; path = "Resources/dialer_alt_back_over~ipad.png"; sourceTree = ""; }; - D3B90E1115C2CB5700F64F8C /* NinePatch.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = NinePatch.xcodeproj; path = Utils/NinePatch/NinePatch.xcodeproj; sourceTree = ""; }; - D3B9A3DB15A58C440096EA4E /* chat_ok_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_ok_default.png; path = Resources/chat_ok_default.png; sourceTree = ""; }; - D3B9A3DC15A58C440096EA4E /* chat_ok_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_ok_over.png; path = Resources/chat_ok_over.png; sourceTree = ""; }; - D3B9A3DD15A58C440096EA4E /* chat_send_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_send_default.png; path = Resources/chat_send_default.png; sourceTree = ""; }; - D3B9A3DE15A58C450096EA4E /* chat_send_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_send_over.png; path = Resources/chat_send_over.png; sourceTree = ""; }; - D3BDB9B815C6B5B1007BEAC1 /* transfer_call_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "transfer_call_disabled~ipad.png"; path = "Resources/transfer_call_disabled~ipad.png"; sourceTree = ""; }; - D3C2814A15A2D38D0098AA42 /* dialer_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_selected.png; path = Resources/dialer_selected.png; sourceTree = ""; }; - D3C2815115A2D64A0098AA42 /* numpad_star_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_star_over.png; path = Resources/numpad_star_over.png; sourceTree = ""; }; - D3C31A0715BD8DED008ED271 /* conference_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = conference_default_landscape.png; path = Resources/conference_default_landscape.png; sourceTree = ""; }; - D3C31A0815BD8DED008ED271 /* conference_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = conference_over_landscape.png; path = Resources/conference_over_landscape.png; sourceTree = ""; }; - D3C31A0915BD8DED008ED271 /* dialer_alt_back_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_alt_back_default_landscape.png; path = Resources/dialer_alt_back_default_landscape.png; sourceTree = ""; }; - D3C31A0A15BD8DED008ED271 /* dialer_alt_back_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_alt_back_over_landscape.png; path = Resources/dialer_alt_back_over_landscape.png; sourceTree = ""; }; - D3C31A0B15BD8DED008ED271 /* dialer_alt_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_alt_default_landscape.png; path = Resources/dialer_alt_default_landscape.png; sourceTree = ""; }; - D3C31A0C15BD8DED008ED271 /* dialer_alt_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_alt_over_landscape.png; path = Resources/dialer_alt_over_landscape.png; sourceTree = ""; }; - D3C31A0D15BD8DED008ED271 /* hangup_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = hangup_default_landscape.png; path = Resources/hangup_default_landscape.png; sourceTree = ""; }; - D3C31A0E15BD8DED008ED271 /* hangup_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = hangup_over_landscape.png; path = Resources/hangup_over_landscape.png; sourceTree = ""; }; - D3C31A0F15BD8DED008ED271 /* micro_off_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = micro_off_default_landscape.png; path = Resources/micro_off_default_landscape.png; sourceTree = ""; }; - D3C31A1015BD8DED008ED271 /* micro_off_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = micro_off_disabled_landscape.png; path = Resources/micro_off_disabled_landscape.png; sourceTree = ""; }; - D3C31A1115BD8DED008ED271 /* micro_off_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = micro_off_over_landscape.png; path = Resources/micro_off_over_landscape.png; sourceTree = ""; }; - D3C31A1215BD8DED008ED271 /* micro_on_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = micro_on_default_landscape.png; path = Resources/micro_on_default_landscape.png; sourceTree = ""; }; - D3C31A1315BD8DED008ED271 /* micro_on_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = micro_on_disabled_landscape.png; path = Resources/micro_on_disabled_landscape.png; sourceTree = ""; }; - D3C31A1415BD8DED008ED271 /* micro_on_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = micro_on_over_landscape.png; path = Resources/micro_on_over_landscape.png; sourceTree = ""; }; - D3C31A1515BD8DED008ED271 /* options_add_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_add_default_landscape.png; path = Resources/options_add_default_landscape.png; sourceTree = ""; }; - D3C31A1615BD8DED008ED271 /* options_add_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_add_disabled_landscape.png; path = Resources/options_add_disabled_landscape.png; sourceTree = ""; }; - D3C31A1715BD8DED008ED271 /* options_add_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_add_over_landscape.png; path = Resources/options_add_over_landscape.png; sourceTree = ""; }; - D3C31A1815BD8DED008ED271 /* options_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_default_landscape.png; path = Resources/options_default_landscape.png; sourceTree = ""; }; - D3C31A1915BD8DED008ED271 /* options_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_disabled_landscape.png; path = Resources/options_disabled_landscape.png; sourceTree = ""; }; - D3C31A1A15BD8DED008ED271 /* options_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_over_landscape.png; path = Resources/options_over_landscape.png; sourceTree = ""; }; - D3C31A1B15BD8DED008ED271 /* options_selected_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_selected_landscape.png; path = Resources/options_selected_landscape.png; sourceTree = ""; }; - D3C31A1C15BD8DED008ED271 /* options_transfer_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_transfer_default_landscape.png; path = Resources/options_transfer_default_landscape.png; sourceTree = ""; }; - D3C31A1D15BD8DED008ED271 /* options_transfer_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_transfer_disabled_landscape.png; path = Resources/options_transfer_disabled_landscape.png; sourceTree = ""; }; - D3C31A1E15BD8DED008ED271 /* options_transfer_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_transfer_over_landscape.png; path = Resources/options_transfer_over_landscape.png; sourceTree = ""; }; - D3C31A1F15BD8DED008ED271 /* pause_off_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = pause_off_default_landscape.png; path = Resources/pause_off_default_landscape.png; sourceTree = ""; }; - D3C31A2015BD8DED008ED271 /* pause_off_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = pause_off_over_landscape.png; path = Resources/pause_off_over_landscape.png; sourceTree = ""; }; - D3C31A2115BD8DED008ED271 /* pause_on_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = pause_on_default_landscape.png; path = Resources/pause_on_default_landscape.png; sourceTree = ""; }; - D3C31A2215BD8DED008ED271 /* pause_on_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = pause_on_over_landscape.png; path = Resources/pause_on_over_landscape.png; sourceTree = ""; }; - D3C31A2315BD8DED008ED271 /* speaker_off_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_off_default_landscape.png; path = Resources/speaker_off_default_landscape.png; sourceTree = ""; }; - D3C31A2415BD8DED008ED271 /* speaker_off_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_off_disabled_landscape.png; path = Resources/speaker_off_disabled_landscape.png; sourceTree = ""; }; - D3C31A2515BD8DED008ED271 /* speaker_off_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_off_over_landscape.png; path = Resources/speaker_off_over_landscape.png; sourceTree = ""; }; - D3C31A2615BD8DED008ED271 /* speaker_on_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_on_default_landscape.png; path = Resources/speaker_on_default_landscape.png; sourceTree = ""; }; - D3C31A2715BD8DED008ED271 /* speaker_on_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_on_disabled_landscape.png; path = Resources/speaker_on_disabled_landscape.png; sourceTree = ""; }; - D3C31A2815BD8DED008ED271 /* speaker_on_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_on_over_landscape.png; path = Resources/speaker_on_over_landscape.png; sourceTree = ""; }; - D3C31A2915BD8DED008ED271 /* statebar_background_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = statebar_background_landscape.png; path = Resources/statebar_background_landscape.png; sourceTree = ""; }; - D3C31A2C15BD8DED008ED271 /* video_off_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = video_off_default_landscape.png; path = Resources/video_off_default_landscape.png; sourceTree = ""; }; - D3C31A2D15BD8DED008ED271 /* video_off_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = video_off_disabled_landscape.png; path = Resources/video_off_disabled_landscape.png; sourceTree = ""; }; - D3C31A2E15BD8DED008ED271 /* video_off_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = video_off_over_landscape.png; path = Resources/video_off_over_landscape.png; sourceTree = ""; }; - D3C31A2F15BD8DED008ED271 /* video_on_default_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = video_on_default_landscape.png; path = Resources/video_on_default_landscape.png; sourceTree = ""; }; - D3C31A3015BD8DED008ED271 /* video_on_disabled_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = video_on_disabled_landscape.png; path = Resources/video_on_disabled_landscape.png; sourceTree = ""; }; - D3C31A3115BD8DED008ED271 /* video_on_over_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = video_on_over_landscape.png; path = Resources/video_on_over_landscape.png; sourceTree = ""; }; - D3C6526515AC1A8F0092A874 /* UIEditableTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIEditableTableViewCell.h; sourceTree = ""; }; - D3C6526615AC1A8F0092A874 /* UIEditableTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIEditableTableViewCell.m; sourceTree = ""; }; - D3C6526915AC228A0092A874 /* contact_ok_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_ok_default.png; path = Resources/contact_ok_default.png; sourceTree = ""; }; - D3C6526A15AC228A0092A874 /* contact_ok_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_ok_over.png; path = Resources/contact_ok_over.png; sourceTree = ""; }; - D3C714B2159DB84400705B8E /* hold.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = hold.wav; path = Resources/hold.wav; sourceTree = ""; }; - D3D14E7B15A711700074A527 /* avatar_shadow_small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = avatar_shadow_small.png; path = Resources/avatar_shadow_small.png; sourceTree = ""; }; - D3D5124C160B213900946DF8 /* setup_cancel_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_cancel_default~ipad.png"; path = "Resources/setup_cancel_default~ipad.png"; sourceTree = ""; }; - D3D5124D160B213900946DF8 /* setup_cancel_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_cancel_over~ipad.png"; path = "Resources/setup_cancel_over~ipad.png"; sourceTree = ""; }; - D3D51252160B35CB00946DF8 /* chat_message_background.9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_message_background.9.png; path = Resources/chat_message_background.9.png; sourceTree = ""; }; - D3D51253160B35CB00946DF8 /* chat_message_background.9@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "chat_message_background.9@2x.png"; path = "Resources/chat_message_background.9@2x.png"; sourceTree = ""; }; - D3D51254160B35CB00946DF8 /* chat_message_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_message_background.png; path = Resources/chat_message_background.png; sourceTree = ""; }; - D3D52A751614495300DEB00A /* accept_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "accept_default_landscape~ipad.png"; path = "Resources/accept_default_landscape~ipad.png"; sourceTree = ""; }; - D3D52A761614495300DEB00A /* accept_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "accept_default~ipad.png"; path = "Resources/accept_default~ipad.png"; sourceTree = ""; }; - D3D52A771614495300DEB00A /* accept_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "accept_over_landscape~ipad.png"; path = "Resources/accept_over_landscape~ipad.png"; sourceTree = ""; }; - D3D52A781614495300DEB00A /* accept_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "accept_over~ipad.png"; path = "Resources/accept_over~ipad.png"; sourceTree = ""; }; - D3D52A791614495300DEB00A /* decline_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "decline_default_landscape~ipad.png"; path = "Resources/decline_default_landscape~ipad.png"; sourceTree = ""; }; - D3D52A7A1614495300DEB00A /* decline_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "decline_default~ipad.png"; path = "Resources/decline_default~ipad.png"; sourceTree = ""; }; - D3D52A7B1614495300DEB00A /* decline_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "decline_over_landscape~ipad.png"; path = "Resources/decline_over_landscape~ipad.png"; sourceTree = ""; }; - D3D52A7C1614495300DEB00A /* decline_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "decline_over~ipad.png"; path = "Resources/decline_over~ipad.png"; sourceTree = ""; }; - D3D6A39B159B0EEF005F692C /* add_call_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = add_call_default.png; path = Resources/add_call_default.png; sourceTree = ""; }; - D3D6A39C159B0EEF005F692C /* add_call_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = add_call_disabled.png; path = Resources/add_call_disabled.png; sourceTree = ""; }; - D3D6A39D159B0EEF005F692C /* add_call_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = add_call_over.png; path = Resources/add_call_over.png; sourceTree = ""; }; - D3D6A3A5159B0EFE005F692C /* security_ko.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = security_ko.png; path = Resources/security_ko.png; sourceTree = ""; }; - D3D6A3A6159B0EFE005F692C /* security_pending.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = security_pending.png; path = Resources/security_pending.png; sourceTree = ""; }; - D3D6A3A7159B0EFE005F692C /* security_ok.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = security_ok.png; path = Resources/security_ok.png; sourceTree = ""; }; - D3D6A3A8159B0EFE005F692C /* options_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_default.png; path = Resources/options_default.png; sourceTree = ""; }; - D3D6A3A9159B0EFE005F692C /* options_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_disabled.png; path = Resources/options_disabled.png; sourceTree = ""; }; - D3D6A3AA159B0EFE005F692C /* options_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = options_over.png; path = Resources/options_over.png; sourceTree = ""; }; - D3E84F1715B00F4100420DAC /* cancel_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = cancel_default.png; path = Resources/cancel_default.png; sourceTree = ""; }; - D3E84F1815B00F4100420DAC /* cancel_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = cancel_over.png; path = Resources/cancel_over.png; sourceTree = ""; }; - D3E84F1B15B00F4100420DAC /* dialer_alt_back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_alt_back_default.png; path = Resources/dialer_alt_back_default.png; sourceTree = ""; }; - D3E84F1C15B00F4100420DAC /* dialer_alt_back_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_alt_back_over.png; path = Resources/dialer_alt_back_over.png; sourceTree = ""; }; - D3E84F1D15B00F4100420DAC /* dialer_alt_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_alt_background.png; path = Resources/dialer_alt_background.png; sourceTree = ""; }; - D3E84F3615B011AF00420DAC /* contact_cancel_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_cancel_default.png; path = Resources/contact_cancel_default.png; sourceTree = ""; }; - D3E84F3715B011AF00420DAC /* contact_cancel_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_cancel_over.png; path = Resources/contact_cancel_over.png; sourceTree = ""; }; - D3E84F3C15B018A600420DAC /* UILinphone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UILinphone.h; sourceTree = ""; }; - D3E8F68315ADE0570065A226 /* UIContactDetailsFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIContactDetailsFooter.h; sourceTree = ""; }; - D3E8F68415ADE0580065A226 /* UIContactDetailsFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIContactDetailsFooter.m; sourceTree = ""; }; + D3A8BB6E15A6C7D500F96BE5 /* UIChatBubbleTextCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIChatBubbleTextCell.h; sourceTree = ""; }; + D3A8BB6F15A6C7D500F96BE5 /* UIChatBubbleTextCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIChatBubbleTextCell.m; sourceTree = ""; }; + D3C6526515AC1A8F0092A874 /* UIContactDetailsCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIContactDetailsCell.h; sourceTree = ""; }; + D3C6526615AC1A8F0092A874 /* UIContactDetailsCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIContactDetailsCell.m; sourceTree = ""; }; D3EA53FB159850E80037DC6B /* LinphoneManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinphoneManager.h; sourceTree = ""; }; D3EA53FC159850E80037DC6B /* LinphoneManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LinphoneManager.m; sourceTree = ""; }; - D3EA53FF159852080037DC6B /* chat_edit_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_edit_default.png; path = Resources/chat_edit_default.png; sourceTree = ""; }; - D3EA5400159852080037DC6B /* chat_edit_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_edit_over.png; path = Resources/chat_edit_over.png; sourceTree = ""; }; - D3EA5401159852080037DC6B /* chat_add_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_add_default.png; path = Resources/chat_add_default.png; sourceTree = ""; }; - D3EA5402159852080037DC6B /* chat_add_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_add_over.png; path = Resources/chat_add_over.png; sourceTree = ""; }; - D3EA540B1598528B0037DC6B /* ChatTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatTableViewController.h; sourceTree = ""; }; - D3EA540C1598528B0037DC6B /* ChatTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatTableViewController.m; sourceTree = ""; }; + D3EA540B1598528B0037DC6B /* ChatsListTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatsListTableView.h; sourceTree = ""; }; + D3EA540C1598528B0037DC6B /* ChatsListTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatsListTableView.m; sourceTree = ""; }; D3EA540F159853750037DC6B /* UIChatCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIChatCell.h; sourceTree = ""; }; D3EA5410159853750037DC6B /* UIChatCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIChatCell.m; sourceTree = ""; }; - D3EA5416159858A80037DC6B /* list_delete_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = list_delete_default.png; path = Resources/list_delete_default.png; sourceTree = ""; }; - D3EA5417159858A80037DC6B /* list_delete_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = list_delete_over.png; path = Resources/list_delete_over.png; sourceTree = ""; }; - D3ED3E401585FB4A006C0DE4 /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = background.png; path = Resources/background.png; sourceTree = ""; }; - D3ED3E441585FB8C006C0DE4 /* dialer_address_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_address_background.png; path = Resources/dialer_address_background.png; sourceTree = ""; }; - D3ED3E511585FFFD006C0DE4 /* statebar_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = statebar_background.png; path = Resources/statebar_background.png; sourceTree = ""; }; - D3ED3E6715861A53006C0DE4 /* add_contact_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = add_contact_default.png; path = Resources/add_contact_default.png; sourceTree = ""; }; - D3ED3E6815861A53006C0DE4 /* add_contact_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = add_contact_disabled.png; path = Resources/add_contact_disabled.png; sourceTree = ""; }; - D3ED3E6915861A53006C0DE4 /* add_contact_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = add_contact_over.png; path = Resources/add_contact_over.png; sourceTree = ""; }; - D3ED3E7015861ABD006C0DE4 /* call_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_default.png; path = Resources/call_default.png; sourceTree = ""; }; - D3ED3E7115861ABD006C0DE4 /* call_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = call_over.png; path = Resources/call_over.png; sourceTree = ""; }; - D3ED3E7615861B1B006C0DE4 /* backspace_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = backspace_default.png; path = Resources/backspace_default.png; sourceTree = ""; }; - D3ED3E7715861B1B006C0DE4 /* backspace_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = backspace_over.png; path = Resources/backspace_over.png; sourceTree = ""; }; - D3ED3E841586291B006C0DE4 /* UIMainBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIMainBar.h; sourceTree = ""; }; - D3ED3E851586291B006C0DE4 /* UIMainBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIMainBar.m; sourceTree = ""; }; - D3ED3E9215872EF1006C0DE4 /* history_all_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_all_selected.png; path = Resources/history_all_selected.png; sourceTree = ""; }; - D3ED3E9315872EF1006C0DE4 /* history_all_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_all_default.png; path = Resources/history_all_default.png; sourceTree = ""; }; - D3ED3E9415872EF1006C0DE4 /* history_edit_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_edit_default.png; path = Resources/history_edit_default.png; sourceTree = ""; }; - D3ED3E9515872EF1006C0DE4 /* history_edit_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_edit_over.png; path = Resources/history_edit_over.png; sourceTree = ""; }; - D3ED3E9615872EF1006C0DE4 /* history_missed_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_missed_selected.png; path = Resources/history_missed_selected.png; sourceTree = ""; }; - D3ED3E9715872EF1006C0DE4 /* history_missed_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_missed_default.png; path = Resources/history_missed_default.png; sourceTree = ""; }; - D3ED3EA41587334B006C0DE4 /* HistoryTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryTableViewController.h; sourceTree = ""; }; - D3ED3EA51587334C006C0DE4 /* HistoryTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = HistoryTableViewController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - D3ED3EB515873928006C0DE4 /* HistoryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryViewController.h; sourceTree = ""; }; - D3ED3EB615873929006C0DE4 /* HistoryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = HistoryViewController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - D3ED40151602172200BF332B /* HPGrowingTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HPGrowingTextView.h; sourceTree = ""; }; - D3ED40161602172200BF332B /* HPGrowingTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HPGrowingTextView.m; sourceTree = ""; }; - D3ED40171602172200BF332B /* HPTextViewInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HPTextViewInternal.h; sourceTree = ""; }; - D3ED40181602172200BF332B /* HPTextViewInternal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HPTextViewInternal.m; sourceTree = ""; }; - D3F26BEE15986B71005F9CAB /* IncomingCallViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IncomingCallViewController.h; sourceTree = ""; }; - D3F26BEF15986B71005F9CAB /* IncomingCallViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IncomingCallViewController.m; sourceTree = ""; }; - D3F26BF515986DAD005F9CAB /* history_ok_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_ok_default.png; path = Resources/history_ok_default.png; sourceTree = ""; }; - D3F26BF615986DAD005F9CAB /* history_ok_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_ok_over.png; path = Resources/history_ok_over.png; sourceTree = ""; }; - D3F26BFB15987083005F9CAB /* header_incoming.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = header_incoming.png; path = Resources/header_incoming.png; sourceTree = ""; }; - D3F34F2F1599B008005BE94F /* avatar_shadow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = avatar_shadow.png; path = Resources/avatar_shadow.png; sourceTree = ""; }; - D3F5F8D91609A86700D3DA1A /* bubble.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = bubble.png; path = Resources/bubble.png; sourceTree = ""; }; - D3F5F8DA1609A86700D3DA1A /* chat_cancel_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_cancel_default.png; path = Resources/chat_cancel_default.png; sourceTree = ""; }; - D3F5F8DB1609A86700D3DA1A /* chat_cancel_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_cancel_over.png; path = Resources/chat_cancel_over.png; sourceTree = ""; }; - D3F5F8DC1609A86700D3DA1A /* chat_photo_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_photo_default.png; path = Resources/chat_photo_default.png; sourceTree = ""; }; - D3F5F8DD1609A86700D3DA1A /* chat_photo_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_photo_disabled.png; path = Resources/chat_photo_disabled.png; sourceTree = ""; }; - D3F5F8DE1609A86700D3DA1A /* chat_photo_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_photo_over.png; path = Resources/chat_photo_over.png; sourceTree = ""; }; - D3F5F8E01609A86700D3DA1A /* form_invalid.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = form_invalid.png; path = Resources/form_invalid.png; sourceTree = ""; }; - D3F5F8E11609A86700D3DA1A /* form_valid.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = form_valid.png; path = Resources/form_valid.png; sourceTree = ""; }; - D3F5F8E21609A86700D3DA1A /* history_delete_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_delete_default.png; path = Resources/history_delete_default.png; sourceTree = ""; }; - D3F5F8E31609A86700D3DA1A /* history_delete_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_delete_over.png; path = Resources/history_delete_over.png; sourceTree = ""; }; - D3F5F8E41609A86700D3DA1A /* logo_linphone_trame_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = logo_linphone_trame_background.png; path = Resources/logo_linphone_trame_background.png; sourceTree = ""; }; - D3F5F8E51609A86700D3DA1A /* setup_back_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_back_disabled~ipad.png"; path = "Resources/setup_back_disabled~ipad.png"; sourceTree = ""; }; - D3F5F8E61609A86700D3DA1A /* setup_back_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_back_over_landscape~ipad.png"; path = "Resources/setup_back_over_landscape~ipad.png"; sourceTree = ""; }; - D3F5F8E71609A86700D3DA1A /* setup_back_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_back_over~ipad.png"; path = "Resources/setup_back_over~ipad.png"; sourceTree = ""; }; - D3F5F8E81609A86700D3DA1A /* setup_cancel_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_cancel_default_landscape~ipad.png"; path = "Resources/setup_cancel_default_landscape~ipad.png"; sourceTree = ""; }; - D3F5F8EA1609A86700D3DA1A /* setup_cancel_disabled_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_cancel_disabled_landscape~ipad.png"; path = "Resources/setup_cancel_disabled_landscape~ipad.png"; sourceTree = ""; }; - D3F5F8EB1609A86700D3DA1A /* setup_cancel_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_cancel_disabled~ipad.png"; path = "Resources/setup_cancel_disabled~ipad.png"; sourceTree = ""; }; - D3F5F8EC1609A86700D3DA1A /* setup_cancel_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_cancel_over_landscape~ipad.png"; path = "Resources/setup_cancel_over_landscape~ipad.png"; sourceTree = ""; }; - D3F5F8EE1609A86700D3DA1A /* setup_start_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_start_default_landscape~ipad.png"; path = "Resources/setup_start_default_landscape~ipad.png"; sourceTree = ""; }; - D3F5F8EF1609A86700D3DA1A /* setup_start_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_start_default~ipad.png"; path = "Resources/setup_start_default~ipad.png"; sourceTree = ""; }; - D3F5F8F01609A86700D3DA1A /* setup_start_disabled_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_start_disabled_landscape~ipad.png"; path = "Resources/setup_start_disabled_landscape~ipad.png"; sourceTree = ""; }; - D3F5F8F11609A86700D3DA1A /* setup_start_disabled~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_start_disabled~ipad.png"; path = "Resources/setup_start_disabled~ipad.png"; sourceTree = ""; }; - D3F5F8F21609A86700D3DA1A /* setup_start_over_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_start_over_landscape~ipad.png"; path = "Resources/setup_start_over_landscape~ipad.png"; sourceTree = ""; }; - D3F5F8F31609A86700D3DA1A /* setup_start_over~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_start_over~ipad.png"; path = "Resources/setup_start_over~ipad.png"; sourceTree = ""; }; - D3F5F8F41609A86700D3DA1A /* setup_welcome_logo~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_welcome_logo~ipad.png"; path = "Resources/setup_welcome_logo~ipad.png"; sourceTree = ""; }; - D3F5F983160B1A0800D3DA1A /* chat_progressbar_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_progressbar_background.png; path = Resources/chat_progressbar_background.png; sourceTree = ""; }; - D3F5F984160B1A0800D3DA1A /* setup_back_default_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_back_default_landscape~ipad.png"; path = "Resources/setup_back_default_landscape~ipad.png"; sourceTree = ""; }; - D3F5F985160B1A0800D3DA1A /* setup_back_default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_back_default~ipad.png"; path = "Resources/setup_back_default~ipad.png"; sourceTree = ""; }; - D3F5F986160B1A0900D3DA1A /* setup_back_disabled_landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "setup_back_disabled_landscape~ipad.png"; path = "Resources/setup_back_disabled_landscape~ipad.png"; sourceTree = ""; }; - D3F795D315A582800077328B /* ChatRoomViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatRoomViewController.h; sourceTree = ""; }; - D3F795D415A582800077328B /* ChatRoomViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatRoomViewController.m; sourceTree = ""; }; - D3F795DB15A5831C0077328B /* chat_back_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_back_default.png; path = Resources/chat_back_default.png; sourceTree = ""; }; - D3F795DC15A5831C0077328B /* chat_back_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = chat_back_over.png; path = Resources/chat_back_over.png; sourceTree = ""; }; + D3ED3E841586291B006C0DE4 /* TabBarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TabBarView.h; path = LinphoneUI/TabBarView.h; sourceTree = ""; }; + D3ED3E851586291B006C0DE4 /* TabBarView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TabBarView.m; path = LinphoneUI/TabBarView.m; sourceTree = ""; }; + D3ED3EA41587334B006C0DE4 /* HistoryListTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryListTableView.h; sourceTree = ""; }; + D3ED3EA51587334C006C0DE4 /* HistoryListTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = HistoryListTableView.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + D3ED3EB515873928006C0DE4 /* HistoryListView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryListView.h; sourceTree = ""; }; + D3ED3EB615873929006C0DE4 /* HistoryListView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = HistoryListView.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + D3F26BEE15986B71005F9CAB /* CallIncomingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallIncomingView.h; sourceTree = ""; }; + D3F26BEF15986B71005F9CAB /* CallIncomingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallIncomingView.m; sourceTree = ""; }; + D3F795D315A582800077328B /* ChatConversationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatConversationView.h; sourceTree = ""; }; + D3F795D415A582800077328B /* ChatConversationView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatConversationView.m; sourceTree = ""; }; D3F7997F15BD32370018C273 /* TPMultiLayoutViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPMultiLayoutViewController.h; path = Utils/TPMultiLayoutViewController/TPMultiLayoutViewController.h; sourceTree = ""; }; D3F7998015BD32370018C273 /* TPMultiLayoutViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPMultiLayoutViewController.m; path = Utils/TPMultiLayoutViewController/TPMultiLayoutViewController.m; sourceTree = ""; }; - D3F83EE91582021700336684 /* InCallViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InCallViewController.h; sourceTree = ""; }; - D3F83EEA1582021700336684 /* InCallViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InCallViewController.m; sourceTree = ""; }; - D3F83EF4158205A100336684 /* micro_off_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = micro_off_default.png; path = Resources/micro_off_default.png; sourceTree = ""; }; - D3F83EF5158205A100336684 /* micro_off_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = micro_off_over.png; path = Resources/micro_off_over.png; sourceTree = ""; }; - D3F83EF6158205A100336684 /* micro_on_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = micro_on_default.png; path = Resources/micro_on_default.png; sourceTree = ""; }; - D3F83EF7158205A100336684 /* micro_on_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = micro_on_over.png; path = Resources/micro_on_over.png; sourceTree = ""; }; - D3F83EF8158205A100336684 /* pause_off_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = pause_off_default.png; path = Resources/pause_off_default.png; sourceTree = ""; }; - D3F83EF9158205A100336684 /* pause_off_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = pause_off_over.png; path = Resources/pause_off_over.png; sourceTree = ""; }; - D3F83EFA158205A100336684 /* hangup_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = hangup_default.png; path = Resources/hangup_default.png; sourceTree = ""; }; - D3F83EFB158205A100336684 /* hangup_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = hangup_over.png; path = Resources/hangup_over.png; sourceTree = ""; }; - D3F83EFC158205A100336684 /* speaker_off_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_off_default.png; path = Resources/speaker_off_default.png; sourceTree = ""; }; - D3F83EFD158205A100336684 /* speaker_off_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_off_over.png; path = Resources/speaker_off_over.png; sourceTree = ""; }; - D3F83EFE158205A100336684 /* speaker_on_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_on_default.png; path = Resources/speaker_on_default.png; sourceTree = ""; }; - D3F83EFF158205A100336684 /* speaker_on_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = speaker_on_over.png; path = Resources/speaker_on_over.png; sourceTree = ""; }; - D3F83F00158205A100336684 /* video_off_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = video_off_default.png; path = Resources/video_off_default.png; sourceTree = ""; }; - D3F83F01158205A100336684 /* video_off_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = video_off_over.png; path = Resources/video_off_over.png; sourceTree = ""; }; - D3F83F02158205A100336684 /* video_on_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = video_on_default.png; path = Resources/video_on_default.png; sourceTree = ""; }; - D3F83F03158205A100336684 /* video_on_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = video_on_over.png; path = Resources/video_on_over.png; sourceTree = ""; }; - D3F83F2C1582223B00336684 /* numpad_zero_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_zero_default.png; path = Resources/numpad_zero_default.png; sourceTree = ""; }; - D3F83F2D1582223B00336684 /* numpad_zero_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_zero_over.png; path = Resources/numpad_zero_over.png; sourceTree = ""; }; - D3F83F2E1582223B00336684 /* numpad_one_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_one_default.png; path = Resources/numpad_one_default.png; sourceTree = ""; }; - D3F83F2F1582223B00336684 /* numpad_one_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_one_over.png; path = Resources/numpad_one_over.png; sourceTree = ""; }; - D3F83F301582223B00336684 /* numpad_two_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_two_default.png; path = Resources/numpad_two_default.png; sourceTree = ""; }; - D3F83F311582223B00336684 /* numpad_two_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_two_over.png; path = Resources/numpad_two_over.png; sourceTree = ""; }; - D3F83F321582223B00336684 /* numpad_three_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_three_default.png; path = Resources/numpad_three_default.png; sourceTree = ""; }; - D3F83F331582223B00336684 /* numpad_three_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_three_over.png; path = Resources/numpad_three_over.png; sourceTree = ""; }; - D3F83F341582223B00336684 /* numpad_four_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_four_default.png; path = Resources/numpad_four_default.png; sourceTree = ""; }; - D3F83F351582223B00336684 /* numpad_four_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_four_over.png; path = Resources/numpad_four_over.png; sourceTree = ""; }; - D3F83F361582223B00336684 /* numpad_five_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_five_default.png; path = Resources/numpad_five_default.png; sourceTree = ""; }; - D3F83F371582223B00336684 /* numpad_five_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_five_over.png; path = Resources/numpad_five_over.png; sourceTree = ""; }; - D3F83F381582223B00336684 /* numpad_six_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_six_default.png; path = Resources/numpad_six_default.png; sourceTree = ""; }; - D3F83F391582223B00336684 /* numpad_six_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_six_over.png; path = Resources/numpad_six_over.png; sourceTree = ""; }; - D3F83F3A1582223B00336684 /* numpad_seven_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_seven_default.png; path = Resources/numpad_seven_default.png; sourceTree = ""; }; - D3F83F3B1582223B00336684 /* numpad_seven_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_seven_over.png; path = Resources/numpad_seven_over.png; sourceTree = ""; }; - D3F83F3C1582223B00336684 /* numpad_eight_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_eight_default.png; path = Resources/numpad_eight_default.png; sourceTree = ""; }; - D3F83F3D1582223B00336684 /* numpad_eight_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_eight_over.png; path = Resources/numpad_eight_over.png; sourceTree = ""; }; - D3F83F3E1582223B00336684 /* numpad_nine_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_nine_default.png; path = Resources/numpad_nine_default.png; sourceTree = ""; }; - D3F83F3F1582223B00336684 /* numpad_nine_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_nine_over.png; path = Resources/numpad_nine_over.png; sourceTree = ""; }; - D3F83F401582223B00336684 /* numpad_sharp_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_sharp_default.png; path = Resources/numpad_sharp_default.png; sourceTree = ""; }; - D3F83F411582223B00336684 /* numpad_sharp_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_sharp_over.png; path = Resources/numpad_sharp_over.png; sourceTree = ""; }; - D3F83F431582223B00336684 /* numpad_star_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = numpad_star_default.png; path = Resources/numpad_star_default.png; sourceTree = ""; }; - D3F83F741582253100336684 /* accept_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = accept_default.png; path = Resources/accept_default.png; sourceTree = ""; }; - D3F83F751582253100336684 /* accept_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = accept_over.png; path = Resources/accept_over.png; sourceTree = ""; }; - D3F83F761582253100336684 /* decline_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = decline_default.png; path = Resources/decline_default.png; sourceTree = ""; }; - D3F83F771582253100336684 /* decline_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = decline_over.png; path = Resources/decline_over.png; sourceTree = ""; }; + D3F83EE91582021700336684 /* CallView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallView.h; sourceTree = ""; }; + D3F83EEA1582021700336684 /* CallView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallView.m; sourceTree = ""; }; D3F83F8C158229C500336684 /* PhoneMainView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhoneMainView.h; sourceTree = ""; }; D3F83F8D15822ABD00336684 /* PhoneMainView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PhoneMainView.m; sourceTree = ""; }; - D3F9A9DA15AEEB940045320F /* history_notification.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = history_notification.png; path = Resources/history_notification.png; sourceTree = ""; }; - D3F9A9EC15AF277D0045320F /* UACellBackgroundView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UACellBackgroundView.h; path = Utils/UACellBackgroundView/UACellBackgroundView.h; sourceTree = ""; }; - D3F9A9ED15AF277D0045320F /* UACellBackgroundView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UACellBackgroundView.m; path = Utils/UACellBackgroundView/UACellBackgroundView.m; sourceTree = ""; }; - F0022B081A370915009B51FD /* messages.db */ = {isa = PBXFileReference; lastKnownFileType = file; name = messages.db; path = submodules/linphone/tester/messages.db; sourceTree = SOURCE_ROOT; }; F0181B6B18BF7B1200A9A357 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; - F01A77EA18ED989B00E287CA /* shortring.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = shortring.caf; path = Resources/shortring.caf; sourceTree = ""; }; - F03A9B3318C0CF7000C4D7FE /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; F03A9B7E18C0D9C900C4D7FE /* libcunit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcunit.a; path = "liblinphone-sdk/apple-darwin/lib/libcunit.a"; sourceTree = ""; }; F03A9B9418C0DAE100C4D7FE /* libstdc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.dylib"; path = "usr/lib/libstdc++.dylib"; sourceTree = SDKROOT; }; F03A9B9718C0DB6F00C4D7FE /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "usr/lib/libc++.dylib"; sourceTree = SDKROOT; }; F03CA84118C72F1A0008889D /* UITextViewNoDefine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UITextViewNoDefine.h; sourceTree = ""; }; F03CA84218C72F1A0008889D /* UITextViewNoDefine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UITextViewNoDefine.m; sourceTree = ""; }; - F04892FE180C3296002FED35 /* ImageOptim.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ImageOptim.sh; sourceTree = ""; }; F05BAA611A5D594E00411815 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; F0642EF019DAC891009DB336 /* MainStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = MainStoryboard.storyboard; sourceTree = ""; }; F0642EF719DAF32E009DB336 /* DTWeakSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DTWeakSupport.h; sourceTree = ""; }; - F066515317F9A02E0064280C /* UITransparentTVCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UITransparentTVCell.h; sourceTree = ""; }; - F066515417F9A02E0064280C /* UITransparentTVCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UITransparentTVCell.m; sourceTree = ""; }; - F070E62D1A2622EC00E17AFD /* dialer_padding_left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_padding_left.png; path = Resources/dialer_padding_left.png; sourceTree = ""; }; - F070E62E1A2622EC00E17AFD /* dialer_padding_right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_padding_right.png; path = Resources/dialer_padding_right.png; sourceTree = ""; }; - F070E62F1A2622EC00E17AFD /* incall_padding_left_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = incall_padding_left_landscape.png; path = Resources/incall_padding_left_landscape.png; sourceTree = ""; }; - F070E6301A2622EC00E17AFD /* incall_padding_left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = incall_padding_left.png; path = Resources/incall_padding_left.png; sourceTree = ""; }; - F070E6311A2622EC00E17AFD /* incall_padding_right_landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = incall_padding_right_landscape.png; path = Resources/incall_padding_right_landscape.png; sourceTree = ""; }; - F070E6321A2622EC00E17AFD /* incall_padding_right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = incall_padding_right.png; path = Resources/incall_padding_right.png; sourceTree = ""; }; F088488C19FF8C41007FFCF3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIContactCell.xib; sourceTree = ""; }; F088488F19FF8C44007FFCF3 /* fr */ = {isa = PBXFileReference; fileEncoding = 2483028224; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/UIContactCell.strings; sourceTree = ""; }; - F08F118419C09C6A007D70C2 /* LinphoneTester Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "LinphoneTester Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - F08F118A19C09C6B007D70C2 /* LinphoneTester Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "LinphoneTester Tests-Info.plist"; sourceTree = ""; }; - F08F118C19C09C6B007D70C2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - F08F118E19C09C6B007D70C2 /* LinphoneTester_Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LinphoneTester_Tests.m; sourceTree = ""; }; - F08F119019C09C6B007D70C2 /* LinphoneTester Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "LinphoneTester Tests-Prefix.pch"; sourceTree = ""; }; - F08F119819C09D88007D70C2 /* flexisip */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flexisip; path = submodules/linphone/tester/flexisip; sourceTree = SOURCE_ROOT; }; - F08F119B19C0A65A007D70C2 /* NSObject+DTRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+DTRuntime.h"; sourceTree = ""; }; - F08F119C19C0A65B007D70C2 /* NSObject+DTRuntime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+DTRuntime.m"; sourceTree = ""; }; - F08F119E19C0A6CB007D70C2 /* DTObjectBlockExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTObjectBlockExecutor.h; sourceTree = ""; }; - F08F119F19C0A6CB007D70C2 /* DTObjectBlockExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTObjectBlockExecutor.m; sourceTree = ""; }; + F08F118419C09C6A007D70C2 /* liblinphoneTesterTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = liblinphoneTesterTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; F0938158188E629800A55DFA /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = ""; }; - F09548181883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ChatRoomViewController.xib; sourceTree = ""; }; - F09548191883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ChatViewController.xib; sourceTree = ""; }; - F095481A1883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ContactDetailsLabelViewController.xib; sourceTree = ""; }; - F095481B1883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ContactDetailsViewController.xib; sourceTree = ""; }; - F095481C1883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ContactsViewController.xib; sourceTree = ""; }; - F095481D1883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/DialerViewController.xib; sourceTree = ""; }; - F095481E1883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Base.lproj/DialerViewController~ipad.xib"; sourceTree = ""; }; - F095481F1883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/FirstLoginViewController.xib; sourceTree = ""; }; - F09548201883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/HistoryDetailsViewController.xib; sourceTree = ""; }; - F09548211883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/HistoryViewController.xib; sourceTree = ""; }; - F09548221883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ImageViewController.xib; sourceTree = ""; }; - F09548231883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/InCallViewController.xib; sourceTree = ""; }; - F09548241883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/IncomingCallViewController.xib; sourceTree = ""; }; - F09548251883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Base.lproj/IncomingCallViewController~ipad.xib"; sourceTree = ""; }; - F09548261883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UICallBar.xib; sourceTree = ""; }; - F09548271883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Base.lproj/UICallBar~ipad.xib"; sourceTree = ""; }; - F09548281883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UICallCell.xib; sourceTree = ""; }; - F09548291883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIConferenceHeader.xib; sourceTree = ""; }; - F095482A1883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIContactDetailsFooter.xib; sourceTree = ""; }; - F095482B1883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIContactDetailsHeader.xib; sourceTree = ""; }; - F095482C1883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIMainBar.xib; sourceTree = ""; }; - F095482D1883F15500E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Base.lproj/UIMainBar~ipad.xib"; sourceTree = ""; }; - F095482E1883F15500E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/WizardViewController.xib; sourceTree = ""; }; - F095482F1883F15500E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Base.lproj/WizardViewController~ipad.xib"; sourceTree = ""; }; - F09548301883F15500E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/WizardViews.xib; sourceTree = ""; }; - F09548311883F1EB00E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ChatRoomViewController.strings; sourceTree = ""; }; - F09548321883F20A00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/ChatRoomViewController.strings; sourceTree = ""; }; - F09548331883F25C00E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ChatViewController.strings; sourceTree = ""; }; - F09548341883F25F00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/ChatViewController.strings; sourceTree = ""; }; - F09548351883F28100E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ContactDetailsLabelViewController.strings; sourceTree = ""; }; - F09548361883F28400E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/ContactDetailsLabelViewController.strings; sourceTree = ""; }; - F09548371883F29500E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ContactDetailsViewController.strings; sourceTree = ""; }; - F09548381883F29C00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/ContactDetailsViewController.strings; sourceTree = ""; }; - F09548391883F2C500E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ContactsViewController.strings; sourceTree = ""; }; - F095483A1883F2CA00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/ContactsViewController.strings; sourceTree = ""; }; - F095483B1883F2DE00E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/DialerViewController.strings; sourceTree = ""; }; - F095483C1883F2E300E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/DialerViewController.strings; sourceTree = ""; }; - F095483D1883F49E00E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = "fr.lproj/DialerViewController~ipad.strings"; sourceTree = ""; }; - F095483E1883F4A200E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "ru.lproj/DialerViewController~ipad.strings"; sourceTree = ""; }; - F095483F1883F4B700E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/FirstLoginViewController.strings; sourceTree = ""; }; - F09548401883F4BC00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/FirstLoginViewController.strings; sourceTree = ""; }; - F09548411883F51600E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/HistoryViewController.strings; sourceTree = ""; }; - F09548421883F51B00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/HistoryViewController.strings; sourceTree = ""; }; - F09548431883F52600E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ImageViewController.strings; sourceTree = ""; }; - F09548441883F52900E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/ImageViewController.strings; sourceTree = ""; }; - F09548451883F53F00E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InCallViewController.strings; sourceTree = ""; }; - F09548461883F54200E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InCallViewController.strings; sourceTree = ""; }; - F09548471883F55300E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/IncomingCallViewController.strings; sourceTree = ""; }; - F09548481883F55800E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/IncomingCallViewController.strings; sourceTree = ""; }; - F09548491883F56A00E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = "fr.lproj/IncomingCallViewController~ipad.strings"; sourceTree = ""; }; - F095484A1883F56E00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "ru.lproj/IncomingCallViewController~ipad.strings"; sourceTree = ""; }; - F095484B1883F58E00E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/UICallBar.strings; sourceTree = ""; }; - F095484C1883F59200E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/UICallBar.strings; sourceTree = ""; }; - F095484D1883F5AF00E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = "fr.lproj/UICallBar~ipad.strings"; sourceTree = ""; }; - F095484E1883F5B300E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "ru.lproj/UICallBar~ipad.strings"; sourceTree = ""; }; - F095484F1883F5D500E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/UIConferenceHeader.strings; sourceTree = ""; }; - F09548501883F5D900E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/UIConferenceHeader.strings; sourceTree = ""; }; - F09548511883F5E300E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/UIContactDetailsFooter.strings; sourceTree = ""; }; - F09548521883F5E600E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/UIContactDetailsFooter.strings; sourceTree = ""; }; - F09548531883F5F400E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/UIContactDetailsHeader.strings; sourceTree = ""; }; - F09548541883F5F700E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/UIContactDetailsHeader.strings; sourceTree = ""; }; - F09548551883F61300E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/UIMainBar.strings; sourceTree = ""; }; - F09548561883F61600E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/UIMainBar.strings; sourceTree = ""; }; - F09548571883F66600E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = "fr.lproj/UIMainBar~ipad.strings"; sourceTree = ""; }; - F09548581883F66A00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "ru.lproj/UIMainBar~ipad.strings"; sourceTree = ""; }; - F09548591883F67800E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/WizardViewController.strings; sourceTree = ""; }; - F095485A1883F67B00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/WizardViewController.strings; sourceTree = ""; }; - F095485B1883F68500E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = "fr.lproj/WizardViewController~ipad.strings"; sourceTree = ""; }; - F095485C1883F68800E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "ru.lproj/WizardViewController~ipad.strings"; sourceTree = ""; }; - F095485D1883F6E700E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/WizardViews.strings; sourceTree = ""; }; - F095485E1883F6EA00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/WizardViews.strings; sourceTree = ""; }; - F0A1CE061A6B056E001CA2BE /* ChatTester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatTester.h; sourceTree = ""; }; - F0A1CE071A6B056E001CA2BE /* ChatTester.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatTester.m; sourceTree = ""; }; - F0A1CE091A6B05A4001CA2BE /* WizardTester.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WizardTester.h; sourceTree = ""; }; - F0ADFCF91A78EB83004F1102 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = Resources/ar.lproj/Localizable.strings; sourceTree = ""; }; - F0AF06F01A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/AboutViewController.strings; sourceTree = ""; }; - F0AF06F11A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/ChatRoomViewController.strings; sourceTree = ""; }; - F0AF06F21A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/ChatViewController.strings; sourceTree = ""; }; - F0AF06F31A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/ContactDetailsLabelViewController.strings; sourceTree = ""; }; - F0AF06F41A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/ContactDetailsViewController.strings; sourceTree = ""; }; - F0AF06F51A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/ContactsViewController.strings; sourceTree = ""; }; - F0AF06F61A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/DialerViewController.strings; sourceTree = ""; }; - F0AF06F71A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = "ar.lproj/DialerViewController~ipad.strings"; sourceTree = ""; }; - F0AF06F81A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/FirstLoginViewController.strings; sourceTree = ""; }; - F0AF06F91A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/HistoryDetailsViewController.strings; sourceTree = ""; }; - F0AF06FA1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/HistoryViewController.strings; sourceTree = ""; }; - F0AF06FB1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/ImageViewController.strings; sourceTree = ""; }; - F0AF06FC1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InCallViewController.strings; sourceTree = ""; }; - F0AF06FD1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/IncomingCallViewController.strings; sourceTree = ""; }; - F0AF06FE1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = "ar.lproj/IncomingCallViewController~ipad.strings"; sourceTree = ""; }; - F0AF06FF1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UICallBar.strings; sourceTree = ""; }; - F0AF07001A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = "ar.lproj/UICallBar~ipad.strings"; sourceTree = ""; }; - F0AF07011A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UICallCell.strings; sourceTree = ""; }; + F09548181883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ChatConversationView.xib; sourceTree = ""; }; + F09548191883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ChatsListView.xib; sourceTree = ""; }; + F095481B1883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ContactDetailsView.xib; sourceTree = ""; }; + F095481C1883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ContactsListView.xib; sourceTree = ""; }; + F095481D1883F15300E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/DialerView.xib; sourceTree = ""; }; + F09548201883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/HistoryDetailsView.xib; sourceTree = ""; }; + F09548211883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/HistoryListView.xib; sourceTree = ""; }; + F09548221883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ImageView.xib; sourceTree = ""; }; + F09548231883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/CallView.xib; sourceTree = ""; }; + F09548241883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/CallIncomingView.xib; sourceTree = ""; }; + F095482C1883F15400E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/TabBarView.xib; sourceTree = ""; }; + F095482E1883F15500E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AssistantView.xib; sourceTree = ""; }; + F09548301883F15500E8A69B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AssistantViewScreens.xib; sourceTree = ""; }; + F09548311883F1EB00E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ChatConversationView.strings; sourceTree = ""; }; + F09548321883F20A00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/ChatConversationView.strings; sourceTree = ""; }; + F09548331883F25C00E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ChatsListView.strings; sourceTree = ""; }; + F09548341883F25F00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/ChatsListView.strings; sourceTree = ""; }; + F09548371883F29500E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ContactDetailsView.strings; sourceTree = ""; }; + F09548381883F29C00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/ContactDetailsView.strings; sourceTree = ""; }; + F09548391883F2C500E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ContactsListView.strings; sourceTree = ""; }; + F095483A1883F2CA00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/ContactsListView.strings; sourceTree = ""; }; + F095483B1883F2DE00E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/DialerView.strings; sourceTree = ""; }; + F095483C1883F2E300E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/DialerView.strings; sourceTree = ""; }; + F09548411883F51600E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/HistoryListView.strings; sourceTree = ""; }; + F09548421883F51B00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/HistoryListView.strings; sourceTree = ""; }; + F09548431883F52600E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/ImageView.strings; sourceTree = ""; }; + F09548441883F52900E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/ImageView.strings; sourceTree = ""; }; + F09548451883F53F00E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/CallView.strings; sourceTree = ""; }; + F09548461883F54200E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/CallView.strings; sourceTree = ""; }; + F09548471883F55300E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/CallIncomingView.strings; sourceTree = ""; }; + F09548481883F55800E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/CallIncomingView.strings; sourceTree = ""; }; + F09548551883F61300E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/TabBarView.strings; sourceTree = ""; }; + F09548561883F61600E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/TabBarView.strings; sourceTree = ""; }; + F09548591883F67800E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AssistantView.strings; sourceTree = ""; }; + F095485A1883F67B00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/AssistantView.strings; sourceTree = ""; }; + F095485D1883F6E700E8A69B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AssistantViewScreens.strings; sourceTree = ""; }; + F095485E1883F6EA00E8A69B /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/AssistantViewScreens.strings; sourceTree = ""; }; + F0AF06F01A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/AboutView.strings; sourceTree = ""; }; + F0AF06F11A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/ChatConversationView.strings; sourceTree = ""; }; + F0AF06F21A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/ChatsListView.strings; sourceTree = ""; }; + F0AF06F41A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/ContactDetailsView.strings; sourceTree = ""; }; + F0AF06F51A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/ContactsListView.strings; sourceTree = ""; }; + F0AF06F61A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/DialerView.strings; sourceTree = ""; }; + F0AF06F91A24BA760086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/HistoryDetailsView.strings; sourceTree = ""; }; + F0AF06FA1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/HistoryListView.strings; sourceTree = ""; }; + F0AF06FB1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/ImageView.strings; sourceTree = ""; }; + F0AF06FC1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/CallView.strings; sourceTree = ""; }; + F0AF06FD1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/CallIncomingView.strings; sourceTree = ""; }; F0AF07021A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UIChatCell.strings; sourceTree = ""; }; - F0AF07031A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UIChatRoomCell.strings; sourceTree = ""; }; - F0AF07041A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UICompositeViewController.strings; sourceTree = ""; }; - F0AF07051A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UIConferenceHeader.strings; sourceTree = ""; }; + F0AF07041A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UICompositeView.strings; sourceTree = ""; }; F0AF07061A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UIContactCell.strings; sourceTree = ""; }; - F0AF07071A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UIContactDetailsFooter.strings; sourceTree = ""; }; - F0AF07081A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UIContactDetailsHeader.strings; sourceTree = ""; }; F0AF07091A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UIHistoryCell.strings; sourceTree = ""; }; - F0AF070A1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UIMainBar.strings; sourceTree = ""; }; - F0AF070B1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = "ar.lproj/UIMainBar~ipad.strings"; sourceTree = ""; }; - F0AF070C1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/UIStateBar.strings; sourceTree = ""; }; - F0AF070D1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/PhoneMainView.strings; sourceTree = ""; }; - F0AF070E1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/SettingsViewController.strings; sourceTree = ""; }; - F0AF070F1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/WizardViewController.strings; sourceTree = ""; }; - F0AF07101A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = "ar.lproj/WizardViewController~ipad.strings"; sourceTree = ""; }; - F0AF07111A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/WizardViews.strings; sourceTree = ""; }; - F0AF07121A24BA780086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Main_iPad.strings; sourceTree = ""; }; - F0AF07131A24BA780086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Main_iPhone.strings; sourceTree = ""; }; - F0AF07151A24BA780086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = ""; }; - F0AF07161A24BA780086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = ""; }; - F0B4FB5C1A65550B00637027 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Resources/Images.xcassets; sourceTree = ""; }; + F0AF070A1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/TabBarView.strings; sourceTree = ""; }; + F0AF070C1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/StatusBarView.strings; sourceTree = ""; }; + F0AF070E1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/SettingsView.strings; sourceTree = ""; }; + F0AF070F1A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/AssistantView.strings; sourceTree = ""; }; + F0AF07111A24BA770086C9C1 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/AssistantViewScreens.strings; sourceTree = ""; }; + F0B026F21AA710AF00FF49F7 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = usr/lib/libiconv.dylib; sourceTree = SDKROOT; }; F0B89C2118DC89E30050B60E /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; - F0B89C2418DC973E0050B60E /* wizard_external_sip.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = wizard_external_sip.rc; path = Resources/wizard_external_sip.rc; sourceTree = ""; }; - F0B89C2518DC973E0050B60E /* wizard_linphone_create.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = wizard_linphone_create.rc; path = Resources/wizard_linphone_create.rc; sourceTree = ""; }; - F0B89C2618DC973E0050B60E /* wizard_linphone_existing.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = wizard_linphone_existing.rc; path = Resources/wizard_linphone_existing.rc; sourceTree = ""; }; - F0B89C2718DC973E0050B60E /* wizard_remote.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = wizard_remote.rc; path = Resources/wizard_remote.rc; sourceTree = ""; }; - F0BB8BD51936208100974404 /* LinphoneTester.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LinphoneTester.app; sourceTree = BUILT_PRODUCTS_DIR; }; - F0BB8BDB1936208100974404 /* LinphoneTester-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "LinphoneTester-Info.plist"; sourceTree = ""; }; - F0BB8BDD1936208100974404 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - F0BB8BDF1936208100974404 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - F0BB8BE11936208100974404 /* LinphoneTester-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "LinphoneTester-Prefix.pch"; sourceTree = ""; }; - F0BB8BE21936208100974404 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - F0BB8BE31936208100974404 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - F0BB8BE61936208100974404 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPhone.storyboard; sourceTree = ""; }; - F0BB8BE91936208200974404 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPad.storyboard; sourceTree = ""; }; - F0BB8BEB1936208200974404 /* MasterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MasterViewController.h; sourceTree = ""; }; - F0BB8BEC1936208200974404 /* MasterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MasterViewController.m; sourceTree = ""; }; - F0BB8BEE1936208200974404 /* DetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; }; - F0BB8BEF1936208200974404 /* DetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; }; - F0BB8BF11936208200974404 /* TesterImages.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = TesterImages.xcassets; sourceTree = ""; }; + F0BB8BD51936208100974404 /* liblinphoneTester.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = liblinphoneTester.app; sourceTree = BUILT_PRODUCTS_DIR; }; F0BB8C0F193623F200974404 /* liblinphonetester.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblinphonetester.a; path = "liblinphone-sdk/apple-darwin/lib/liblinphonetester.a"; sourceTree = ""; }; F0BB8C111936240300974404 /* libcunit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcunit.a; path = "liblinphone-sdk/apple-darwin/lib/libcunit.a"; sourceTree = ""; }; F0BB8C311936246600974404 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; F0BB8C34193624C800974404 /* libresolv.9.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libresolv.9.dylib; path = usr/lib/libresolv.9.dylib; sourceTree = SDKROOT; }; - F0BB8C3719362C1500974404 /* rcfiles */ = {isa = PBXFileReference; lastKnownFileType = folder; name = rcfiles; path = submodules/linphone/tester/rcfiles; sourceTree = SOURCE_ROOT; }; - F0BB8C3919362C2200974404 /* certificates */ = {isa = PBXFileReference; lastKnownFileType = folder; name = certificates; path = submodules/linphone/tester/certificates; sourceTree = SOURCE_ROOT; }; - F0BB8C3A19362C2200974404 /* images */ = {isa = PBXFileReference; lastKnownFileType = folder; name = images; path = submodules/linphone/tester/images; sourceTree = SOURCE_ROOT; }; - F0BB8C3B19362C2200974404 /* sounds */ = {isa = PBXFileReference; lastKnownFileType = folder; name = sounds; path = submodules/linphone/tester/sounds; sourceTree = SOURCE_ROOT; }; - F0BB8C40193630CA00974404 /* local_tester_hosts */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = local_tester_hosts; path = submodules/linphone/tester/local_tester_hosts; sourceTree = SOURCE_ROOT; }; - F0BB8C41193630CA00974404 /* marie_xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = marie_xml; path = submodules/linphone/tester/marie_xml; sourceTree = SOURCE_ROOT; }; - F0BB8C42193630CA00974404 /* tester_hosts */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = tester_hosts; path = submodules/linphone/tester/tester_hosts; sourceTree = SOURCE_ROOT; }; F0BB8C4A193631B300974404 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; }; - F0C1F8EA1A277ADA009402C9 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; - F0C1F9041A28781F009402C9 /* background-launch.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background-launch.png"; sourceTree = ""; }; - F0C1F9061A28781F009402C9 /* corner-left-bottom.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "corner-left-bottom.png"; sourceTree = ""; }; - F0C1F9071A28781F009402C9 /* corner-left-top.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "corner-left-top.png"; sourceTree = ""; }; - F0C1F9081A28781F009402C9 /* corner-right-bottom.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "corner-right-bottom.png"; sourceTree = ""; }; - F0C1F9091A28781F009402C9 /* corner-right-top.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "corner-right-top.png"; sourceTree = ""; }; - F0C1F90A1A28781F009402C9 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = ""; }; - F0C1F90B1A28781F009402C9 /* strech-bottom.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "strech-bottom.png"; sourceTree = ""; }; - F0C1F90C1A28781F009402C9 /* strech-top.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "strech-top.png"; sourceTree = ""; }; - F0C7737D1A94822600E0C486 /* KIF.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = KIF.xcodeproj; path = Classes/KIF/KIF.xcodeproj; sourceTree = SOURCE_ROOT; }; - F0F952001A6AEB1000254160 /* KifTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KifTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - F0F952031A6AEB1000254160 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - F0F952111A6AECD300254160 /* WizardTester.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WizardTester.m; sourceTree = ""; }; - F84015BC1939FE37006ABAB5 /* test_failed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = test_failed.png; path = Resources/test_failed.png; sourceTree = ""; }; - F84015BD1939FE37006ABAB5 /* test_inprogress.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = test_inprogress.png; path = Resources/test_inprogress.png; sourceTree = ""; }; - F84015BE1939FE37006ABAB5 /* test_passed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = test_passed.png; path = Resources/test_passed.png; sourceTree = ""; }; - F84015C5193B4E34006ABAB5 /* LogsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogsViewController.h; sourceTree = ""; }; - F84015C6193B4E34006ABAB5 /* LogsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LogsViewController.m; sourceTree = ""; }; - F844AB121A93E3A200428306 /* ContactsTester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsTester.h; sourceTree = ""; }; - F844AB131A93E3A200428306 /* ContactsTester.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactsTester.m; sourceTree = ""; }; - F85554461A6DA2F400A9F915 /* LinphoneTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinphoneTestCase.h; sourceTree = ""; }; - F85554471A6DA2F400A9F915 /* LinphoneTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LinphoneTestCase.m; sourceTree = ""; }; - FD979F30169E84670022A8B4 /* ru */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = ru; path = Resources/ru.lproj/Localizable.strings; sourceTree = ""; }; + F0F952001A6AEB1000254160 /* linphoneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = linphoneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + F0FF66AA1ACAEEB0008A4486 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = ../../../../Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1843,17 +1591,38 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F05BAA621A5D594E00411815 /* libz.dylib in Frameworks */, - 1560821F18EEF26100765332 /* libmsopenh264.a in Frameworks */, - 22509042196BD902007863F6 /* libopenh264.a in Frameworks */, - 15017E701773578400784ACB /* libxml2.a in Frameworks */, - 22AF73C21754C0D100BE8398 /* libopus.a in Frameworks */, - 57B0E360173C010400A476B8 /* libpolarssl.a in Frameworks */, - 223CA7E616D9255800EF1BEC /* libantlr3c.a in Frameworks */, - 223CA7E716D9255800EF1BEC /* libbellesip.a in Frameworks */, - 045B5CB318D72E9A0088350C /* libbzrtp.a in Frameworks */, - D30562151671DC4900C97967 /* libNinePatch.a in Frameworks */, - D30562161671DC4900C97967 /* libXMLRPC.a in Frameworks */, + 6334DDFA1BBAC97C00631900 /* libsqlite3.dylib in Frameworks */, + 152F22361B15E889008C0621 /* libxml2.dylib in Frameworks */, + 63CFEDE81B9EDD74007EA5BD /* libantlr3c.a in Frameworks */, + 63CFEDE91B9EDD74007EA5BD /* libavcodec.a in Frameworks */, + 63CFEDEA1B9EDD74007EA5BD /* libavutil.a in Frameworks */, + 63CFEDEB1B9EDD74007EA5BD /* libbcg729.a in Frameworks */, + 63CFEDEC1B9EDD74007EA5BD /* libbellesip.a in Frameworks */, + 63CFEDED1B9EDD74007EA5BD /* libbzrtp.a in Frameworks */, + 63CFEDEF1B9EDD74007EA5BD /* libgsm.a in Frameworks */, + 63CFEDF21B9EDD74007EA5BD /* liblinphone.a in Frameworks */, + 63CFEDF41B9EDD74007EA5BD /* libmediastreamer_base.a in Frameworks */, + 63CFEDF51B9EDD74007EA5BD /* libmediastreamer_voip.a in Frameworks */, + 63CFEE061B9EDD88007EA5BD /* libmsamr.a in Frameworks */, + 63CFEE071B9EDD88007EA5BD /* libmsbcg729.a in Frameworks */, + 63CFEE091B9EDD88007EA5BD /* libmsopenh264.a in Frameworks */, + 63CFEE0A1B9EDD88007EA5BD /* libmssilk.a in Frameworks */, + 63CFEE0B1B9EDD88007EA5BD /* libmswebrtc.a in Frameworks */, + 63CFEE0C1B9EDD88007EA5BD /* libmsx264.a in Frameworks */, + 63CFEDF61B9EDD74007EA5BD /* libopencore-amrnb.a in Frameworks */, + 63CFEDF71B9EDD74007EA5BD /* libopencore-amrwb.a in Frameworks */, + 63CFEDF81B9EDD74007EA5BD /* libopenh264.a in Frameworks */, + 63CFEDF91B9EDD74007EA5BD /* libopus.a in Frameworks */, + 63CFEDFA1B9EDD74007EA5BD /* libortp.a in Frameworks */, + 63CFEDFB1B9EDD74007EA5BD /* libpolarssl.a in Frameworks */, + 63CFEDFD1B9EDD74007EA5BD /* libspeex.a in Frameworks */, + 63CFEDFE1B9EDD74007EA5BD /* libspeexdsp.a in Frameworks */, + 63CFEDFF1B9EDD74007EA5BD /* libsrtp.a in Frameworks */, + 63CFEE011B9EDD74007EA5BD /* libswscale.a in Frameworks */, + 63CFEE021B9EDD74007EA5BD /* libtunnel.a in Frameworks */, + 63CFEE131B9EDF65007EA5BD /* libvo-amrwbenc.a in Frameworks */, + 63CFEE041B9EDD74007EA5BD /* libvpx.a in Frameworks */, + 63CFEE051B9EDD74007EA5BD /* libx264.a in Frameworks */, 22B5F03510CE6B2F00777D97 /* AddressBook.framework in Frameworks */, 22B5EFA310CE50BD00777D97 /* AddressBookUI.framework in Frameworks */, 22405EEE1600B4E400B92522 /* AssetsLibrary.framework in Frameworks */, @@ -1873,32 +1642,12 @@ 70E542F513E147EB002BA2C0 /* QuartzCore.framework in Frameworks */, 2264B6D211200342002C2C53 /* SystemConfiguration.framework in Frameworks */, 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + D30562161671DC4900C97967 /* libXMLRPC.a in Frameworks */, + F0B026F31AA710AF00FF49F7 /* libiconv.dylib in Frameworks */, + F05BAA621A5D594E00411815 /* libz.dylib in Frameworks */, 344ABDF114850AE9007420B6 /* libc++.1.dylib in Frameworks */, - D32B6E2F15A5C0AC0033019F /* libsqlite3.dylib in Frameworks */, 344ABDF214850AE9007420B6 /* libstdc++.6.dylib in Frameworks */, 22D1B68112A3E0BE001AE361 /* libresolv.dylib in Frameworks */, - 22276E8313C73D3100210156 /* libavcodec.a in Frameworks */, - 22276E8413C73D3100210156 /* libavutil.a in Frameworks */, - 220FAD3210765B400068D98F /* libgsm.a in Frameworks */, - 223148E41178A08200637D6A /* libilbc.a in Frameworks */, - F476004B147AAF2800FFF19B /* liblinphone.a in Frameworks */, - D37EE10916032DA4003608A6 /* libmediastreamer_base.a in Frameworks */, - D37EE10A16032DA4003608A6 /* libmediastreamer_voip.a in Frameworks */, - 226F2ED81344B0EF00F6EF27 /* libmsamr.a in Frameworks */, - 223148E61178A09900637D6A /* libmsilbc.a in Frameworks */, - 226183B0147259670037138E /* libmssilk.a in Frameworks */, - 22AA8AFE13D7125600B30535 /* libmsx264.a in Frameworks */, - 22A10F3B11F8960300373793 /* libortp.a in Frameworks */, - 226F2ED71344B0EF00F6EF27 /* libopencore-amrnb.a in Frameworks */, - 226F2ED61344B0EF00F6EF27 /* libopencore-amrwb.a in Frameworks */, - 226CDAE014E2D0B800513B67 /* libmsbcg729.a in Frameworks */, - 220FAD3810765B400068D98F /* libspeex.a in Frameworks */, - 220FAD3910765B400068D98F /* libspeexdsp.a in Frameworks */, - 226183AE1472527D0037138E /* libsrtp.a in Frameworks */, - 226183AD1472527D0037138E /* libSKP_SILK_SDK.a in Frameworks */, - 22276E8513C73D3100210156 /* libswscale.a in Frameworks */, - 7066FC0C13E830E400EFC6DC /* libvpx.a in Frameworks */, - 22AA8AFD13D7125600B30535 /* libx264.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1906,8 +1655,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F08BDC3D1A35E60F006210C9 /* liblinphonetester.a in Frameworks */, - F08F118519C09C6B007D70C2 /* XCTest.framework in Frameworks */, + 63058AD61B4E92D400EFAE36 /* liblinphonetester.a in Frameworks */, F08F118719C09C6B007D70C2 /* UIKit.framework in Frameworks */, F08F118619C09C6B007D70C2 /* Foundation.framework in Frameworks */, ); @@ -1917,6 +1665,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 15F728741B16FF9A00A1C901 /* libxml2.dylib in Frameworks */, + F0A54B0C1AD56F4600C22733 /* libc++.dylib in Frameworks */, + F0A54B0D1AD56F4600C22733 /* libstdc++.dylib in Frameworks */, + F08D468D1AA86849001E8CB5 /* libiconv.dylib in Frameworks */, F05BAA631A5D75BC00411815 /* libz.dylib in Frameworks */, F0BB8C4D193631DF00974404 /* AVFoundation.framework in Frameworks */, F0BB8C4C193631D200974404 /* CoreMedia.framework in Frameworks */, @@ -1931,30 +1683,24 @@ F0BB8C1A1936245300974404 /* libbzrtp.a in Frameworks */, F0BB8C121936240300974404 /* libcunit.a in Frameworks */, F0BB8C1B1936245300974404 /* libgsm.a in Frameworks */, - F0BB8C1C1936245300974404 /* libilbc.a in Frameworks */, F0BB8C131936242400974404 /* liblinphone.a in Frameworks */, F0BB8C10193623F300974404 /* liblinphonetester.a in Frameworks */, F0BB8C141936242400974404 /* libmediastreamer_base.a in Frameworks */, F0BB8C151936242400974404 /* libmediastreamer_voip.a in Frameworks */, F0BB8C1D1936245300974404 /* libmsamr.a in Frameworks */, F0BB8C1E1936245300974404 /* libmsbcg729.a in Frameworks */, - F0BB8C1F1936245300974404 /* libmsilbc.a in Frameworks */, F0BB8C201936245300974404 /* libmssilk.a in Frameworks */, - F0BB8C211936245300974404 /* libmsx264.a in Frameworks */, F0BB8C221936245300974404 /* libopencore-amrnb.a in Frameworks */, F0BB8C231936245300974404 /* libopencore-amrwb.a in Frameworks */, F0BB8C241936245300974404 /* libopus.a in Frameworks */, F0BB8C251936245300974404 /* libortp.a in Frameworks */, F0BB8C261936245300974404 /* libpolarssl.a in Frameworks */, - F0BB8C271936245300974404 /* libSKP_SILK_SDK.a in Frameworks */, F0BB8C281936245300974404 /* libspeex.a in Frameworks */, F0BB8C291936245300974404 /* libspeexdsp.a in Frameworks */, F0BB8C2A1936245300974404 /* libsrtp.a in Frameworks */, F0BB8C2B1936245300974404 /* libswscale.a in Frameworks */, F0BB8C2C1936245300974404 /* libtunnel.a in Frameworks */, F0BB8C2D1936245300974404 /* libvpx.a in Frameworks */, - F0BB8C2E1936245300974404 /* libx264.a in Frameworks */, - F0BB8C2F1936245300974404 /* libxml2.a in Frameworks */, F0BB8BD81936208100974404 /* UIKit.framework in Frameworks */, F0BB8BD61936208100974404 /* Foundation.framework in Frameworks */, ); @@ -1964,7 +1710,18 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F0C773921A94828900E0C486 /* libKIF.a in Frameworks */, + 6334DDFD1BBAC9A200631900 /* libiconv.dylib in Frameworks */, + 6334DDFC1BBAC99B00631900 /* libxml2.dylib in Frameworks */, + 6334DDFB1BBAC99400631900 /* libsqlite3.dylib in Frameworks */, + 63EEE4041BBA9B010087D3AF /* libbellesip.a in Frameworks */, + 63EEE4051BBA9B010087D3AF /* liblinphone.a in Frameworks */, + 63EEE4061BBA9B010087D3AF /* libmediastreamer_base.a in Frameworks */, + 63EEE4071BBA9B010087D3AF /* libmediastreamer_voip.a in Frameworks */, + 63EEE4081BBA9B010087D3AF /* libortp.a in Frameworks */, + 63EEE3FF1BBA9AC00087D3AF /* libcunit.a in Frameworks */, + 63EEE4001BBA9AC00087D3AF /* liblinphonetester.a in Frameworks */, + 63058A4F1B4E835200EFAE36 /* libKIF.a in Frameworks */, + F0FF66AC1ACAEF4F008A4486 /* IOKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1974,65 +1731,81 @@ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( - 22E0A81D111C44E100B04932 /* AboutViewController.h */, - 22E0A81C111C44E100B04932 /* AboutViewController.m */, - 636316D31A1DEBCB0009B839 /* AboutViewController.xib */, - D32B6E2715A5BC430033019F /* ChatRoomTableViewController.h */, - D32B6E2815A5BC430033019F /* ChatRoomTableViewController.m */, - D3F795D315A582800077328B /* ChatRoomViewController.h */, - D3F795D415A582800077328B /* ChatRoomViewController.m */, - D38187B015FE340100C3EDCA /* ChatRoomViewController.xib */, - D3EA540B1598528B0037DC6B /* ChatTableViewController.h */, - D3EA540C1598528B0037DC6B /* ChatTableViewController.m */, - D35E7594159460560066B1C1 /* ChatViewController.h */, - D35E7595159460560066B1C1 /* ChatViewController.m */, - D38187B415FE340500C3EDCA /* ChatViewController.xib */, + 22E0A81D111C44E100B04932 /* AboutView.h */, + 22E0A81C111C44E100B04932 /* AboutView.m */, + 636316D31A1DEBCB0009B839 /* AboutView.xib */, + D350F20B15A43BB100149E54 /* AssistantView.h */, + D350F20C15A43BB100149E54 /* AssistantView.m */, + D38187E015FE348A00C3EDCA /* AssistantView.xib */, + D3D5126A160B3A8E00946DF8 /* AssistantViewScreens.xib */, + 63F1DF491BCE983100EDED90 /* CallConferenceTableView.h */, + 63F1DF4A1BCE983200EDED90 /* CallConferenceTableView.m */, + D3F26BEE15986B71005F9CAB /* CallIncomingView.h */, + D3F26BEF15986B71005F9CAB /* CallIncomingView.m */, + D38187DC15FE347700C3EDCA /* CallIncomingView.xib */, + 6346100D1B61409800548952 /* CallOutgoingView.h */, + 6346100E1B61409800548952 /* CallOutgoingView.m */, + 634610101B6140A500548952 /* CallOutgoingView.xib */, + D31AAF5C159B3919002C6B02 /* CallPausedTableView.h */, + D31AAF5D159B3919002C6B02 /* CallPausedTableView.m */, + 6352A5721BE0D4B800594C1C /* CallSideMenuView.h */, + 6352A5731BE0D4B800594C1C /* CallSideMenuView.m */, + 6352A5741BE0D4B800594C1C /* CallSideMenuView.xib */, + D3F83EE91582021700336684 /* CallView.h */, + D3F83EEA1582021700336684 /* CallView.m */, + D381881C15FE3FCA00C3EDCA /* CallView.xib */, + 638F1A861C2167C2004B8E02 /* CallView~ipad.xib */, + 6341807A1BBC103100F71761 /* ChatConversationCreateTableView.h */, + 6341807B1BBC103100F71761 /* ChatConversationCreateTableView.m */, + 6336715E1BCBAAD200BFCBDE /* ChatConversationCreateView.h */, + 6336715F1BCBAAD200BFCBDE /* ChatConversationCreateView.m */, + 63B8D68E1BCBE65600C12B09 /* ChatConversationCreateView.xib */, + D32B6E2715A5BC430033019F /* ChatConversationTableView.h */, + D32B6E2815A5BC430033019F /* ChatConversationTableView.m */, + D3F795D315A582800077328B /* ChatConversationView.h */, + D3F795D415A582800077328B /* ChatConversationView.m */, + D38187B015FE340100C3EDCA /* ChatConversationView.xib */, + D3EA540B1598528B0037DC6B /* ChatsListTableView.h */, + D3EA540C1598528B0037DC6B /* ChatsListTableView.m */, + D35E7594159460560066B1C1 /* ChatsListView.h */, + D35E7595159460560066B1C1 /* ChatsListView.m */, + D38187B415FE340500C3EDCA /* ChatsListView.xib */, D30BBD1215D3EFEB000F93DD /* ContactDetailsDelegate.h */, - D378906215AC373B00BD776C /* ContactDetailsLabelViewController.h */, - D378906315AC373B00BD776C /* ContactDetailsLabelViewController.m */, - D38187B815FE341B00C3EDCA /* ContactDetailsLabelViewController.xib */, - D37C639915AADEF4009D0BAC /* ContactDetailsTableViewController.h */, - D37C639A15AADEF5009D0BAC /* ContactDetailsTableViewController.m */, - D3128FDE15AABC7E00A2147A /* ContactDetailsViewController.h */, - D3128FDF15AABC7E00A2147A /* ContactDetailsViewController.m */, - D38187BC15FE342200C3EDCA /* ContactDetailsViewController.xib */, - D3549814158761CF000081D8 /* ContactsTableViewController.h */, - D3549815158761D0000081D8 /* ContactsTableViewController.m */, - D35497FB15875372000081D8 /* ContactsViewController.h */, - D35497FC15875372000081D8 /* ContactsViewController.m */, - D38187C015FE342800C3EDCA /* ContactsViewController.xib */, - 22F2508B107141E100AC9B3F /* DialerViewController.h */, - 22F2508C107141E100AC9B3F /* DialerViewController.m */, - D38187C415FE345B00C3EDCA /* DialerViewController.xib */, - D38187C815FE345F00C3EDCA /* DialerViewController~ipad.xib */, - 2218A92212FBE1340088A667 /* FirstLoginViewController.h */, - 2218A92312FBE1340088A667 /* FirstLoginViewController.m */, - D38187CC15FE346400C3EDCA /* FirstLoginViewController.xib */, - C90FAA7615AF54E6002091CB /* HistoryDetailsViewController.h */, - C90FAA7715AF54E6002091CB /* HistoryDetailsViewController.m */, - D38187D015FE346700C3EDCA /* HistoryDetailsViewController.xib */, - D3ED3EA41587334B006C0DE4 /* HistoryTableViewController.h */, - D3ED3EA51587334C006C0DE4 /* HistoryTableViewController.m */, - D3ED3EB515873928006C0DE4 /* HistoryViewController.h */, - D3ED3EB615873929006C0DE4 /* HistoryViewController.m */, - D38187D415FE346B00C3EDCA /* HistoryViewController.xib */, - D378AB2815DCDB480098505D /* ImagePickerViewController.h */, - D378AB2915DCDB490098505D /* ImagePickerViewController.m */, - D374D3FB16071762003D25FF /* ImageSharing.h */, - D374D3FC16071762003D25FF /* ImageSharing.m */, - 22405EFD1601C19000B92522 /* ImageViewController.h */, - 22405EFE1601C19100B92522 /* ImageViewController.m */, - D37EE11016035793003608A6 /* ImageViewController.xib */, - D31AAF5C159B3919002C6B02 /* InCallTableViewController.h */, - D31AAF5D159B3919002C6B02 /* InCallTableViewController.m */, - D3F83EE91582021700336684 /* InCallViewController.h */, - D3F83EEA1582021700336684 /* InCallViewController.m */, - D381881C15FE3FCA00C3EDCA /* InCallViewController.xib */, - D3F26BEE15986B71005F9CAB /* IncomingCallViewController.h */, - D3F26BEF15986B71005F9CAB /* IncomingCallViewController.m */, - D38187DC15FE347700C3EDCA /* IncomingCallViewController.xib */, - D3D52A711614480700DEB00A /* IncomingCallViewController~ipad.xib */, - F0C1F8EA1A277ADA009402C9 /* LaunchScreen.xib */, + D37C639915AADEF4009D0BAC /* ContactDetailsTableView.h */, + D37C639A15AADEF5009D0BAC /* ContactDetailsTableView.m */, + D3128FDE15AABC7E00A2147A /* ContactDetailsView.h */, + D3128FDF15AABC7E00A2147A /* ContactDetailsView.m */, + D38187BC15FE342200C3EDCA /* ContactDetailsView.xib */, + D3549814158761CF000081D8 /* ContactsListTableView.h */, + D3549815158761D0000081D8 /* ContactsListTableView.m */, + D35497FB15875372000081D8 /* ContactsListView.h */, + D35497FC15875372000081D8 /* ContactsListView.m */, + D38187C015FE342800C3EDCA /* ContactsListView.xib */, + 22F2508B107141E100AC9B3F /* DialerView.h */, + 22F2508C107141E100AC9B3F /* DialerView.m */, + D38187C415FE345B00C3EDCA /* DialerView.xib */, + 638F1A601C2021B2004B8E02 /* DialerView~ipad.xib */, + 6306440B1BECB08500134C72 /* FirstLoginView.h */, + 6306440C1BECB08500134C72 /* FirstLoginView.m */, + 639E9C951C0DB7BE00019A75 /* FirstLoginView.xib */, + 635775231B6673EC00C8B704 /* HistoryDetailsTableView.h */, + 635775241B6673EC00C8B704 /* HistoryDetailsTableView.m */, + C90FAA7615AF54E6002091CB /* HistoryDetailsView.h */, + C90FAA7715AF54E6002091CB /* HistoryDetailsView.m */, + D38187D015FE346700C3EDCA /* HistoryDetailsView.xib */, + D3ED3EA41587334B006C0DE4 /* HistoryListTableView.h */, + D3ED3EA51587334C006C0DE4 /* HistoryListTableView.m */, + D3ED3EB515873928006C0DE4 /* HistoryListView.h */, + D3ED3EB615873929006C0DE4 /* HistoryListView.m */, + D38187D415FE346B00C3EDCA /* HistoryListView.xib */, + D378AB2815DCDB480098505D /* ImagePickerView.h */, + D378AB2915DCDB490098505D /* ImagePickerView.m */, + 22405EFD1601C19000B92522 /* ImageView.h */, + 22405EFE1601C19100B92522 /* ImageView.m */, + D37EE11016035793003608A6 /* ImageView.xib */, + 63E59A3D1ADE6ECB00646FB3 /* InAppProductsManager.h */, + 63E59A3E1ADE70D900646FB3 /* InAppProductsManager.m */, + 639E9C9C1C0DB7D300019A75 /* LaunchScreen.xib */, 1D3623240D0F684500981E51 /* LinphoneAppDelegate.h */, 1D3623250D0F684500981E51 /* LinphoneAppDelegate.m */, D37DC6BF1594AE1800B2A5EB /* LinphoneCoreSettingsStore.h */, @@ -2043,18 +1816,25 @@ F0642EF019DAC891009DB336 /* MainStoryboard.storyboard */, D3F83F8C158229C500336684 /* PhoneMainView.h */, D3F83F8D15822ABD00336684 /* PhoneMainView.m */, - 636316D71A1DECC90009B839 /* PhoneMainView.xib */, - D35E759C159460B50066B1C1 /* SettingsViewController.h */, - D35E759D159460B50066B1C1 /* SettingsViewController.m */, - 636316D61A1DEC650009B839 /* SettingsViewController.xib */, + 639E9CB31C0DB88200019A75 /* PhoneMainView.xib */, + D35E759C159460B50066B1C1 /* SettingsView.h */, + D35E759D159460B50066B1C1 /* SettingsView.m */, + 636316D61A1DEC650009B839 /* SettingsView.xib */, + 633756371B67BAF400E21BAD /* SideMenuTableView.h */, + 633756381B67BAF400E21BAD /* SideMenuTableView.m */, + 633756421B67D2B100E21BAD /* SideMenuView.h */, + 633756431B67D2B100E21BAD /* SideMenuView.m */, + 639E9CB21C0DB83000019A75 /* SideMenuView.xib */, + 63130FB01C1ED06900371918 /* SideMenuView~ipad.xib */, + D354981E1587716B000081D8 /* StatusBarView.h */, + D354981F1587716B000081D8 /* StatusBarView.m */, + 639CEAFF1A1DF4D9004DE38F /* StatusBarView.xib */, + D3ED3E841586291B006C0DE4 /* TabBarView.h */, + D3ED3E851586291B006C0DE4 /* TabBarView.m */, + D38187FB15FE355D00C3EDCA /* TabBarView.xib */, D326483415887D4400930C67 /* Utils */, 34216F3E1547EBCD00EA9777 /* VideoZoomHandler.h */, 34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */, - D350F20B15A43BB100149E54 /* WizardViewController.h */, - D350F20C15A43BB100149E54 /* WizardViewController.m */, - D38187E015FE348A00C3EDCA /* WizardViewController.xib */, - D3D5126E160B3AD400946DF8 /* WizardViewController~ipad.xib */, - D3D5126A160B3A8E00946DF8 /* WizardViews.xib */, ); path = Classes; sourceTree = ""; @@ -2063,9 +1843,9 @@ isa = PBXGroup; children = ( 1D6058910D05DD3D006BFB54 /* linphone.app */, - F0BB8BD51936208100974404 /* LinphoneTester.app */, - F08F118419C09C6A007D70C2 /* LinphoneTester Tests.xctest */, - F0F952001A6AEB1000254160 /* KifTests.xctest */, + F0BB8BD51936208100974404 /* liblinphoneTester.app */, + F08F118419C09C6A007D70C2 /* liblinphoneTesterTests.xctest */, + F0F952001A6AEB1000254160 /* linphoneTests.xctest */, ); name = Products; sourceTree = ""; @@ -2073,96 +1853,88 @@ 2214EB7012F84668002A5394 /* LinphoneUI */ = { isa = PBXGroup; children = ( - D35E757F159328EA0066B1C1 /* UIAddressTextField.h */, - D35E7580159328EB0066B1C1 /* UIAddressTextField.m */, + 63F1DF421BCE618E00EDED90 /* UIAddressTextField.h */, + 63F1DF431BCE618E00EDED90 /* UIAddressTextField.m */, + 63C441C11BBC23ED0053DC5E /* UIAssistantTextField.h */, + 63C441C21BBC23ED0053DC5E /* UIAssistantTextField.m */, + 6377AC7E1BDE4068007F7625 /* UIBackToCallButton.h */, + 6377AC7F1BDE4069007F7625 /* UIBackToCallButton.m */, 22C7555E1317E59C007BC101 /* UIBluetoothButton.h */, 22C7555F1317E59C007BC101 /* UIBluetoothButton.m */, - 636316DC1A1DEECB0009B839 /* UIButtonShrinkable.h */, - 636316DD1A1DEF2F0009B839 /* UIButtonShrinkable.m */, - D326483B1588950F00930C67 /* UICallBar.h */, - D326483C1588950F00930C67 /* UICallBar.m */, - D38187E415FE349700C3EDCA /* UICallBar.xib */, - D38187E815FE349D00C3EDCA /* UICallBar~ipad.xib */, 2214EB7812F846B1002A5394 /* UICallButton.h */, 2214EB7912F846B1002A5394 /* UICallButton.m */, - D36C43C4158F2E5A0048BA40 /* UICallCell.h */, - D36C43C5158F2E5A0048BA40 /* UICallCell.m */, - D381881415FE3F0B00C3EDCA /* UICallCell.xib */, + 63F1DF4C1BCE985F00EDED90 /* UICallConferenceCell.h */, + 63F1DF4D1BCE985F00EDED90 /* UICallConferenceCell.m */, + 63F1DF531BCE986A00EDED90 /* UICallConferenceCell.xib */, + 63BC49E01BA2CDFC004EC273 /* UICallPausedCell.h */, + 63BC49E11BA2CDFC004EC273 /* UICallPausedCell.m */, + 639E9C9F1C0DB7DF00019A75 /* UICallPausedCell.xib */, 22AA8AFF13D83F6300B30535 /* UICamSwitch.h */, 22AA8B0013D83F6300B30535 /* UICamSwitch.m */, + 635173F71BA082A40095EB0A /* UIChatBubblePhotoCell.h */, + 635173F81BA082A40095EB0A /* UIChatBubblePhotoCell.m */, + 639E9CA21C0DB7E500019A75 /* UIChatBubblePhotoCell.xib */, + D3A8BB6E15A6C7D500F96BE5 /* UIChatBubbleTextCell.h */, + D3A8BB6F15A6C7D500F96BE5 /* UIChatBubbleTextCell.m */, + 639E9CA51C0DB7EA00019A75 /* UIChatBubbleTextCell.xib */, D3EA540F159853750037DC6B /* UIChatCell.h */, D3EA5410159853750037DC6B /* UIChatCell.m */, 639CEB0B1A1DF4FA004DE38F /* UIChatCell.xib */, - D3A8BB6E15A6C7D500F96BE5 /* UIChatRoomCell.h */, - D3A8BB6F15A6C7D500F96BE5 /* UIChatRoomCell.m */, - 639CEB081A1DF4F1004DE38F /* UIChatRoomCell.xib */, - D31B4B1E159876C0002E6C72 /* UICompositeViewController.h */, - D31B4B1F159876C0002E6C72 /* UICompositeViewController.m */, - 639CEB051A1DF4EB004DE38F /* UICompositeViewController.xib */, - D3211BAD159C4EF00098460B /* UIConferenceHeader.h */, - D3211BAE159C4EF00098460B /* UIConferenceHeader.m */, - D38187F315FE354000C3EDCA /* UIConferenceHeader.xib */, + 63B8D69F1BCBF43100C12B09 /* UIChatCreateCell.h */, + 63B8D6A01BCBF43100C12B09 /* UIChatCreateCell.m */, + 639E9CA81C0DB7F200019A75 /* UIChatCreateCell.xib */, + 639E9C7E1C0DB13D00019A75 /* UICheckBoxTableView.h */, + 639E9C7F1C0DB13D00019A75 /* UICheckBoxTableView.m */, + D31B4B1E159876C0002E6C72 /* UICompositeView.h */, + D31B4B1F159876C0002E6C72 /* UICompositeView.m */, + 639CEB051A1DF4EB004DE38F /* UICompositeView.xib */, + 638F1A8F1C21993D004B8E02 /* UICompositeView~ipad.xib */, + 63701DDD1BA32039006A9AE3 /* UIConfirmationDialog.h */, + 63701DDE1BA32039006A9AE3 /* UIConfirmationDialog.m */, + 639E9CAB1C0DB7FB00019A75 /* UIConfirmationDialog.xib */, D3A55FBA15877E5E003FD403 /* UIContactCell.h */, D3A55FBB15877E5E003FD403 /* UIContactCell.m */, F088488D19FF8C41007FFCF3 /* UIContactCell.xib */, - D3E8F68315ADE0570065A226 /* UIContactDetailsFooter.h */, - D3E8F68415ADE0580065A226 /* UIContactDetailsFooter.m */, - D38187F715FE354700C3EDCA /* UIContactDetailsFooter.xib */, - D37C639215AADDAE009D0BAC /* UIContactDetailsHeader.h */, - D37C639315AADDAE009D0BAC /* UIContactDetailsHeader.m */, - D381881815FE3F7F00C3EDCA /* UIContactDetailsHeader.xib */, + D3C6526515AC1A8F0092A874 /* UIContactDetailsCell.h */, + D3C6526615AC1A8F0092A874 /* UIContactDetailsCell.m */, + 639E9CAE1C0DB80300019A75 /* UIContactDetailsCell.xib */, 2248E90C12F7E4CF00220D9C /* UIDigitButton.h */, 2248E90D12F7E4CF00220D9C /* UIDigitButton.m */, - 631C4FAF19D2A8F2004BFE77 /* UIDigitButtonLongPlus.h */, - 631C4FB019D2A8F2004BFE77 /* UIDigitButtonLongPlus.m */, - 631C4FB519D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.h */, - 631C4FB619D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m */, - D3C6526515AC1A8F0092A874 /* UIEditableTableViewCell.h */, - D3C6526615AC1A8F0092A874 /* UIEditableTableViewCell.m */, - 22BB1A67132FF16A005CD7AA /* UIEraseButton.h */, - 22BB1A68132FF16A005CD7AA /* UIEraseButton.m */, 2214EB8712F84EBB002A5394 /* UIHangUpButton.h */, 2214EB8812F84EBB002A5394 /* UIHangUpButton.m */, D31C9C96158A1CDE00756B45 /* UIHistoryCell.h */, D31C9C97158A1CDE00756B45 /* UIHistoryCell.m */, 639CEB021A1DF4E4004DE38F /* UIHistoryCell.xib */, - D3E84F3C15B018A600420DAC /* UILinphone.h */, - D380800415C28A7A005BE9BC /* UILinphone.m */, - D35E91F6160CA4FF0023116B /* UILinphoneButton.h */, - D35E91F7160CA4FF0023116B /* UILinphoneButton.m */, - D35E91F2160CA10B0023116B /* UILinphoneTextField.h */, - D35E91F3160CA10B0023116B /* UILinphoneTextField.m */, + 636BC9951B5F921B00C754CE /* UIIconButton.h */, + 636BC9961B5F921B00C754CE /* UIIconButton.m */, + 634610041B61330300548952 /* UILabel+Boldify.h */, + 634610051B61330300548952 /* UILabel+Boldify.m */, D306459C1611EC2900BB571E /* UILoadingImageView.h */, D306459D1611EC2900BB571E /* UILoadingImageView.m */, - D32409C1158B49A600C8C119 /* UILongTouchButton.h */, - D32409C2158B49A600C8C119 /* UILongTouchButton.m */, - D3ED3E841586291B006C0DE4 /* UIMainBar.h */, - D3ED3E851586291B006C0DE4 /* UIMainBar.m */, - D38187FB15FE355D00C3EDCA /* UIMainBar.xib */, - D38187FF15FE356100C3EDCA /* UIMainBar~ipad.xib */, 2214EBF112F86360002A5394 /* UIMicroButton.h */, 2214EBF212F86360002A5394 /* UIMicroButton.m */, D36FB2D31589EF7C0036F6F2 /* UIPauseButton.h */, D36FB2D41589EF7C0036F6F2 /* UIPauseButton.m */, + 6316FA6B1BE12A3E0050E441 /* UIRightImageButton.h */, + 6316FA6C1BE12A3E0050E441 /* UIRightImageButton.m */, + 6313482E1B6F7B6600C6BDCB /* UIRoundBorderedButton.h */, + 6313482F1B6F7B6600C6BDCB /* UIRoundBorderedButton.m */, 63FB30331A680E73008CA393 /* UIRoundedImageView.h */, 63FB30341A680E73008CA393 /* UIRoundedImageView.m */, 22968A5D12F875C600588287 /* UISpeakerButton.h */, 22968A5E12F875C600588287 /* UISpeakerButton.m */, - D354981E1587716B000081D8 /* UIStateBar.h */, - D354981F1587716B000081D8 /* UIStateBar.m */, - 639CEAFF1A1DF4D9004DE38F /* UIStateBar.xib */, + 630CF5551AF7CE1500539F7A /* UITextField+DoneButton.h */, + 630CF5561AF7CE1500539F7A /* UITextField+DoneButton.m */, F03CA84118C72F1A0008889D /* UITextViewNoDefine.h */, F03CA84218C72F1A0008889D /* UITextViewNoDefine.m */, D32648421588F6FA00930C67 /* UIToggleButton.h */, D32648431588F6FB00930C67 /* UIToggleButton.m */, D3196D3C15A32BD7007FEEBA /* UITransferButton.h */, D3196D3D15A32BD8007FEEBA /* UITransferButton.m */, - F066515317F9A02E0064280C /* UITransparentTVCell.h */, - F066515417F9A02E0064280C /* UITransparentTVCell.m */, - D32460E4159D9AAD00BA7F3A /* UITransparentView.h */, - D32460E5159D9AAD00BA7F3A /* UITransparentView.m */, 340751E5150F38FC00B89C47 /* UIVideoButton.h */, 340751E6150F38FD00B89C47 /* UIVideoButton.m */, + 6381DA7B1C1AD5EA00DF3BBD /* UIBouncingView.h */, + 6381DA7C1C1AD5EA00DF3BBD /* UIBouncingView.m */, ); path = LinphoneUI; sourceTree = ""; @@ -2170,17 +1942,17 @@ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( - 633E388219FFB0F400936D1C /* README.md */, 080E96DDFE201D6D7F000001 /* Classes */, - F0F952011A6AEB1000254160 /* UITests */, 29B97323FDCFA39411CA2CEA /* Frameworks */, - F04892FE180C3296002FED35 /* ImageOptim.sh */, F0938158188E629800A55DFA /* iTunesArtwork */, - F0BB8BD91936208100974404 /* LinphoneTester */, + 63058A0C1B4E821E00EFAE36 /* LiblinphoneTester */, 29B97315FDCFA39411CA2CEA /* Other Sources */, 19C28FACFE9D520D11CA2CBB /* Products */, - 29B97317FDCFA39411CA2CEA /* Resources */, + 633E388219FFB0F400936D1C /* README.md */, + 63AADBC31B6A0FF200AA16FD /* Resources */, D398D3031594B0FB00FD553C /* Settings */, + 63058A301B4E822F00EFAE36 /* TestsLiblinphone */, + 630589DD1B4E810900EFAE36 /* TestsUI */, ); name = CustomTemplate; sourceTree = ""; @@ -2194,38 +1966,9 @@ name = "Other Sources"; sourceTree = ""; }; - 29B97317FDCFA39411CA2CEA /* Resources */ = { - isa = PBXGroup; - children = ( - D3C714B2159DB84400705B8E /* hold.wav */, - F0B4FB5C1A65550B00637027 /* Images.xcassets */, - F0B89C2318DC90850050B60E /* images */, - D37E3ECF1619DCC50087659A /* licenses.html */, - 8D1107310486CEB800E47090 /* linphone-Info.plist */, - 57F005C315EE2CCF00914747 /* linphonerc */, - 57F005C615EE2D9200914747 /* linphonerc-factory */, - 57F005C715EE2D9200914747 /* linphonerc-factory~ipad */, - D321FF9815E628CB0098B5F4 /* linphonerc~ipad */, - 2214783B1386A2030020F8B8 /* Localizable.strings */, - D3804E5E15D92A57008072A5 /* msg.caf */, - D3804E5F15D92A57008072A5 /* msg.wav */, - 2242E312125235120061DDCE /* ring.caf */, - 2237D4081084D7A9001383EE /* ring.wav */, - 22F254801073D99800AC9B3F /* ringback.wav */, - 70571E1913FABCB000CDD3C2 /* rootca.pem */, - F01A77EA18ED989B00E287CA /* shortring.caf */, - F0B89C2418DC973E0050B60E /* wizard_external_sip.rc */, - F0B89C2518DC973E0050B60E /* wizard_linphone_create.rc */, - F0B89C2618DC973E0050B60E /* wizard_linphone_existing.rc */, - F0B89C2718DC973E0050B60E /* wizard_remote.rc */, - ); - name = Resources; - sourceTree = ""; - }; 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( - F05BAA611A5D594E00411815 /* libz.dylib */, 22B5F03410CE6B2F00777D97 /* AddressBook.framework */, 22B5EFA210CE50BD00777D97 /* AddressBookUI.framework */, 22405EED1600B4E400B92522 /* AssetsLibrary.framework */, @@ -2241,47 +1984,53 @@ 22276E8613C73D8A00210156 /* CoreVideo.framework */, 1D30AB110D05D00D00671497 /* Foundation.framework */, F0BB8C4A193631B300974404 /* ImageIO.framework */, + F0FF66AA1ACAEEB0008A4486 /* IOKit.framework */, 223CA7E416D9255800EF1BEC /* libantlr3c.a */, 22276E8013C73D3100210156 /* libavcodec.a */, 22276E8113C73D3100210156 /* libavutil.a */, + 63CFEDE41B9EDD36007EA5BD /* libbcg729.a */, 223CA7E516D9255800EF1BEC /* libbellesip.a */, 045B5CB218D72E9A0088350C /* libbzrtp.a */, 344ABDEF14850AE9007420B6 /* libc++.1.dylib */, F03A9B9718C0DB6F00C4D7FE /* libc++.dylib */, F0BB8C111936240300974404 /* libcunit.a */, 220FAD2910765B400068D98F /* libgsm.a */, - 223148E31178A08200637D6A /* libilbc.a */, + F0B026F21AA710AF00FF49F7 /* libiconv.dylib */, + 63EEE40D1BBA9B250087D3AF /* libiconv.tbd */, 2211DB911475562600DEE054 /* liblinphone.a */, F0BB8C0F193623F200974404 /* liblinphonetester.a */, 22405EE916006F0700B92522 /* libmediastreamer_base.a */, 22405EEA16006F0700B92522 /* libmediastreamer_voip.a */, 226F2ED51344B0EF00F6EF27 /* libmsamr.a */, 226CDADE14E2D0B800513B67 /* libmsbcg729.a */, - 223148E51178A09900637D6A /* libmsilbc.a */, 1560821E18EEF26100765332 /* libmsopenh264.a */, 226183AF147259670037138E /* libmssilk.a */, + 63EA4C941B50189D00922857 /* libmswebrtc.a */, 22AA8AFC13D7125500B30535 /* libmsx264.a */, 226F2ED41344B0EF00F6EF27 /* libopencore-amrnb.a */, 226F2ED31344B0EF00F6EF27 /* libopencore-amrwb.a */, 22509041196BD902007863F6 /* libopenh264.a */, 22AF73C11754C0D000BE8398 /* libopus.a */, 220FAD2C10765B400068D98F /* libortp.a */, - 1FE76362DA6217E7341ED1DF /* libPods-KifTests.a */, 57B0E35F173C010400A476B8 /* libpolarssl.a */, F0BB8C34193624C800974404 /* libresolv.9.dylib */, 22D1B68012A3E0BE001AE361 /* libresolv.dylib */, - 226183AA1472527D0037138E /* libSKP_SILK_SDK.a */, 220FAD2F10765B400068D98F /* libspeex.a */, 220FAD3010765B400068D98F /* libspeexdsp.a */, D32B6E2E15A5C0AC0033019F /* libsqlite3.dylib */, + 63EEE40B1BBA9B1B0087D3AF /* libsqlite3.tbd */, 226183AB1472527D0037138E /* libsrtp.a */, 344ABDF014850AE9007420B6 /* libstdc++.6.dylib */, F03A9B9418C0DAE100C4D7FE /* libstdc++.dylib */, + 63CFEDE21B9EDD36007EA5BD /* libswresample.a */, 22276E8213C73D3100210156 /* libswscale.a */, D30BF33216A427BC00AF0026 /* libtunnel.a */, + 63CFEDE31B9EDD36007EA5BD /* libvo-amrwbenc.a */, 7066FC0B13E830E400EFC6DC /* libvpx.a */, 22AA8AFB13D7125500B30535 /* libx264.a */, - 15017E6F1773578400784ACB /* libxml2.a */, + 152F22351B15E889008C0621 /* libxml2.dylib */, + 63EEE4091BBA9B110087D3AF /* libxml2.tbd */, + F05BAA611A5D594E00411815 /* libz.dylib */, F0B89C2118DC89E30050B60E /* MediaPlayer.framework */, D37DC7171594AF3400B2A5EB /* MessageUI.framework */, 226EF06B15FA256B005865C7 /* MobileCoreServices.framework */, @@ -2291,12 +2040,528 @@ F0181B6B18BF7B1200A9A357 /* SenTestingKit.framework */, 2264B6D111200342002C2C53 /* SystemConfiguration.framework */, 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, - F03A9B3318C0CF7000C4D7FE /* XCTest.framework */, F03A9B7E18C0D9C900C4D7FE /* libcunit.a */, ); name = Frameworks; sourceTree = ""; }; + 630589DD1B4E810900EFAE36 /* TestsUI */ = { + isa = PBXGroup; + children = ( + 630589F21B4E816900EFAE36 /* KIF.xcodeproj */, + 63058A0A1B4E81B700EFAE36 /* Info.plist */, + 630589DE1B4E810900EFAE36 /* ChatTester.h */, + 630589DF1B4E810900EFAE36 /* ChatTester.m */, + 630589E01B4E810900EFAE36 /* ContactsTester.h */, + 630589E11B4E810900EFAE36 /* ContactsTester.m */, + 630589E31B4E810900EFAE36 /* LinphoneTestCase.h */, + 630589E41B4E810900EFAE36 /* LinphoneTestCase.m */, + 630589E51B4E810900EFAE36 /* AssistantTester.h */, + 630589E61B4E810900EFAE36 /* AssistantTester.m */, + ); + path = TestsUI; + sourceTree = ""; + }; + 630589F31B4E816900EFAE36 /* Products */ = { + isa = PBXGroup; + children = ( + 630589FD1B4E816A00EFAE36 /* libKIF.a */, + 63058A011B4E816A00EFAE36 /* Test Host.app */, + 63058A031B4E816A00EFAE36 /* KIF Tests - XCTest.xctest */, + 63058A071B4E816A00EFAE36 /* KIF.framework */, + ); + name = Products; + sourceTree = ""; + }; + 63058A0C1B4E821E00EFAE36 /* LiblinphoneTester */ = { + isa = PBXGroup; + children = ( + 63058AE41B4E952E00EFAE36 /* share */, + 63058AE11B4E93A100EFAE36 /* tester_hosts */, + 63058AC81B4E922500EFAE36 /* certificates */, + 63058AC91B4E922500EFAE36 /* flexisip */, + 63058ACA1B4E922500EFAE36 /* images */, + 63058ACB1B4E922500EFAE36 /* marie_xml */, + 63058ACC1B4E922500EFAE36 /* messages.db */, + 63058ACD1B4E922500EFAE36 /* rcfiles */, + 63058ACE1B4E922500EFAE36 /* sounds */, + 63058A0D1B4E821E00EFAE36 /* AppDelegate.h */, + 63058A0E1B4E821E00EFAE36 /* AppDelegate.m */, + 63058A0F1B4E821E00EFAE36 /* InfoPlist.strings */, + 63058A111B4E821E00EFAE36 /* Main_iPad.strings */, + 63058A131B4E821E00EFAE36 /* Main_iPhone.strings */, + 63058A151B4E821E00EFAE36 /* Main_iPad.storyboard */, + 63058A171B4E821E00EFAE36 /* Main_iPhone.storyboard */, + 63058A191B4E821E00EFAE36 /* DetailView.h */, + 63058A1A1B4E821E00EFAE36 /* DetailView.m */, + 63058A1C1B4E821E00EFAE36 /* LinphoneTester-Info.plist */, + 63058A1D1B4E821E00EFAE36 /* LinphoneTester-Prefix.pch */, + 63058A1E1B4E821E00EFAE36 /* LogsView.h */, + 63058A1F1B4E821E00EFAE36 /* LogsView.m */, + 63058A201B4E821E00EFAE36 /* main.m */, + 63058A211B4E821E00EFAE36 /* MasterView.h */, + 63058A221B4E821E00EFAE36 /* MasterView.m */, + 63058A231B4E821E00EFAE36 /* TesterImages.xcassets */, + ); + path = LiblinphoneTester; + sourceTree = ""; + }; + 63058A301B4E822F00EFAE36 /* TestsLiblinphone */ = { + isa = PBXGroup; + children = ( + 63058A311B4E822F00EFAE36 /* InfoPlist.strings */, + 63058A331B4E822F00EFAE36 /* DTObjectBlockExecutor.h */, + 63058A341B4E822F00EFAE36 /* DTObjectBlockExecutor.m */, + 63058A401B4E82C400EFAE36 /* LinphoneTesterTests-Info.plist */, + 63058A411B4E82C400EFAE36 /* LinphoneTesterTests-Prefix.pch */, + 63058A381B4E822F00EFAE36 /* LinphoneTester_Tests.m */, + 63058A391B4E822F00EFAE36 /* NSObject+DTRuntime.h */, + 63058A3A1B4E822F00EFAE36 /* NSObject+DTRuntime.m */, + ); + path = TestsLiblinphone; + sourceTree = ""; + }; + 633888401BFB2C49001D5E7B /* HPGrowingTextView */ = { + isa = PBXGroup; + children = ( + 633888411BFB2C49001D5E7B /* HPGrowingTextView.h */, + 633888421BFB2C49001D5E7B /* HPGrowingTextView.m */, + 633888431BFB2C49001D5E7B /* HPTextViewInternal.h */, + 633888441BFB2C49001D5E7B /* HPTextViewInternal.m */, + ); + name = HPGrowingTextView; + path = Utils/HPGrowingTextView; + sourceTree = ""; + }; + 636B967C1C298400003BA37C /* images */ = { + isa = PBXGroup; + children = ( + 636B967D1C298400003BA37C /* add_field_default.png */, + 636B967E1C298400003BA37C /* add_field_default@2x.png */, + 636B967F1C298400003BA37C /* add_field_over.png */, + 636B96801C298400003BA37C /* add_field_over@2x.png */, + 636B96811C298400003BA37C /* avatar.png */, + 636B96821C298400003BA37C /* avatar@2x.png */, + 636B96831C298400003BA37C /* back_default.png */, + 636B96841C298400003BA37C /* back_default@2x.png */, + 636B96851C298400003BA37C /* back_disabled.png */, + 636B96861C298400003BA37C /* back_disabled@2x.png */, + 636B96871C298400003BA37C /* backspace_default.png */, + 636B96881C298400003BA37C /* backspace_default@2x.png */, + 636B96891C298400003BA37C /* backspace_disabled.png */, + 636B968A1C298400003BA37C /* backspace_disabled@2x.png */, + 636B968B1C298400003BA37C /* backspace_over.png */, + 636B968C1C298400003BA37C /* backspace_over@2x.png */, + 636B968D1C298400003BA37C /* call_add_default.png */, + 636B968E1C298400003BA37C /* call_add_default@2x.png */, + 636B968F1C298400003BA37C /* call_add_disabled.png */, + 636B96901C298400003BA37C /* call_add_disabled@2x.png */, + 636B96911C298400003BA37C /* call_alt_back_default.png */, + 636B96921C298400003BA37C /* call_alt_back_default@2x.png */, + 636B96931C298400003BA37C /* call_alt_back_disabled.png */, + 636B96941C298400003BA37C /* call_alt_back_disabled@2x.png */, + 636B96951C298400003BA37C /* call_alt_start_default.png */, + 636B96961C298400003BA37C /* call_alt_start_default@2x.png */, + 636B96971C298400003BA37C /* call_alt_start_disabled.png */, + 636B96981C298400003BA37C /* call_alt_start_disabled@2x.png */, + 636B96991C298400003BA37C /* call_audio_start_default.png */, + 636B969A1C298400003BA37C /* call_audio_start_default@2x.png */, + 636B969B1C298400003BA37C /* call_audio_start_disabled.png */, + 636B969C1C298400003BA37C /* call_audio_start_disabled@2x.png */, + 636B969D1C298400003BA37C /* call_back_default.png */, + 636B969E1C298400003BA37C /* call_back_default@2x.png */, + 636B969F1C298400003BA37C /* call_back_disabled.png */, + 636B96A01C298400003BA37C /* call_back_disabled@2x.png */, + 636B96A11C298400003BA37C /* call_hangup_default.png */, + 636B96A21C298400003BA37C /* call_hangup_default@2x.png */, + 636B96A31C298400003BA37C /* call_hangup_disabled.png */, + 636B96A41C298400003BA37C /* call_hangup_disabled@2x.png */, + 636B96A51C298400003BA37C /* call_incoming.png */, + 636B96A61C298400003BA37C /* call_incoming@2x.png */, + 636B96A71C298400003BA37C /* call_missed.png */, + 636B96A81C298400003BA37C /* call_missed@2x.png */, + 636B96A91C298400003BA37C /* call_outgoing.png */, + 636B96AA1C298400003BA37C /* call_outgoing@2x.png */, + 636B96AB1C298400003BA37C /* call_quality_indicator_0.png */, + 636B96AC1C298400003BA37C /* call_quality_indicator_0@2x.png */, + 636B96AD1C298400003BA37C /* call_quality_indicator_1.png */, + 636B96AE1C298400003BA37C /* call_quality_indicator_1@2x.png */, + 636B96AF1C298400003BA37C /* call_quality_indicator_2.png */, + 636B96B01C298400003BA37C /* call_quality_indicator_2@2x.png */, + 636B96B11C298400003BA37C /* call_quality_indicator_3.png */, + 636B96B21C298400003BA37C /* call_quality_indicator_3@2x.png */, + 636B96B31C298400003BA37C /* call_quality_indicator_4.png */, + 636B96B41C298400003BA37C /* call_quality_indicator_4@2x.png */, + 636B96B51C298400003BA37C /* call_start_body_default.png */, + 636B96B61C298400003BA37C /* call_start_body_default@2x.png */, + 636B96B71C298400003BA37C /* call_start_body_disabled.png */, + 636B96B81C298400003BA37C /* call_start_body_disabled@2x.png */, + 636B96B91C298400003BA37C /* call_start_body_over.png */, + 636B96BA1C298400003BA37C /* call_start_body_over@2x.png */, + 636B96BB1C298400003BA37C /* call_status_incoming.png */, + 636B96BC1C298400003BA37C /* call_status_incoming@2x.png */, + 636B96BD1C298400003BA37C /* call_status_missed.png */, + 636B96BE1C298400003BA37C /* call_status_missed@2x.png */, + 636B96BF1C298400003BA37C /* call_status_outgoing.png */, + 636B96C01C298400003BA37C /* call_status_outgoing@2x.png */, + 636B96C11C298400003BA37C /* call_transfer_default.png */, + 636B96C21C298400003BA37C /* call_transfer_default@2x.png */, + 636B96C31C298400003BA37C /* call_transfer_disabled.png */, + 636B96C41C298400003BA37C /* call_transfer_disabled@2x.png */, + 636B96C51C298400003BA37C /* call_video_start_default.png */, + 636B96C61C298400003BA37C /* call_video_start_default@2x.png */, + 636B96C71C298400003BA37C /* call_video_start_disabled.png */, + 636B96C81C298400003BA37C /* call_video_start_disabled@2x.png */, + 636B96C91C298400003BA37C /* camera_default.png */, + 636B96CA1C298400003BA37C /* camera_default@2x.png */, + 636B96CB1C298400003BA37C /* camera_disabled.png */, + 636B96CC1C298400003BA37C /* camera_disabled@2x.png */, + 636B96CD1C298400003BA37C /* camera_selected.png */, + 636B96CE1C298400003BA37C /* camera_selected@2x.png */, + 636B96CF1C298400003BA37C /* camera_switch_default.png */, + 636B96D01C298400003BA37C /* camera_switch_default@2x.png */, + 636B96D11C298400003BA37C /* camera_switch_disabled.png */, + 636B96D21C298400003BA37C /* camera_switch_disabled@2x.png */, + 636B96D31C298400003BA37C /* camera_switch_over.png */, + 636B96D41C298400003BA37C /* camera_switch_over@2x.png */, + 636B96D51C298400003BA37C /* cancel_edit_default.png */, + 636B96D61C298400003BA37C /* cancel_edit_default@2x.png */, + 636B96D71C298400003BA37C /* cancel_edit_disabled.png */, + 636B96D81C298400003BA37C /* cancel_edit_disabled@2x.png */, + 636B96D91C298400003BA37C /* chat_add_default.png */, + 636B96DA1C298400003BA37C /* chat_add_default@2x.png */, + 636B96DB1C298400003BA37C /* chat_add_disabled.png */, + 636B96DC1C298400003BA37C /* chat_add_disabled@2x.png */, + 636B96DD1C298400003BA37C /* chat_attachment_default.png */, + 636B96DE1C298400003BA37C /* chat_attachment_default@2x.png */, + 636B96DF1C298400003BA37C /* chat_attachment_disabled.png */, + 636B96E01C298400003BA37C /* chat_attachment_disabled@2x.png */, + 636B96E11C298400003BA37C /* chat_attachment_over.png */, + 636B96E21C298400003BA37C /* chat_attachment_over@2x.png */, + 636B96E31C298400003BA37C /* chat_message_not_delivered.png */, + 636B96E41C298400003BA37C /* chat_message_not_delivered@2x.png */, + 636B96E51C298400003BA37C /* chat_send_default.png */, + 636B96E61C298400003BA37C /* chat_send_default@2x.png */, + 636B96E71C298400003BA37C /* chat_send_disabled.png */, + 636B96E81C298400003BA37C /* chat_send_disabled@2x.png */, + 636B96E91C298400003BA37C /* chat_send_over.png */, + 636B96EA1C298400003BA37C /* chat_send_over@2x.png */, + 636B96EB1C298400003BA37C /* chat_start_body_default.png */, + 636B96EC1C298400003BA37C /* chat_start_body_default@2x.png */, + 636B96ED1C298400003BA37C /* chat_start_body_disabled.png */, + 636B96EE1C298400003BA37C /* chat_start_body_disabled@2x.png */, + 636B96EF1C298400003BA37C /* chat_start_body_over.png */, + 636B96F01C298400003BA37C /* chat_start_body_over@2x.png */, + 636B96F11C298400003BA37C /* checkbox_checked.png */, + 636B96F21C298400003BA37C /* checkbox_checked@2x.png */, + 636B96F31C298400003BA37C /* checkbox_unchecked.png */, + 636B96F41C298400003BA37C /* checkbox_unchecked@2x.png */, + 636B96F51C298400003BA37C /* color_A.png */, + 636B96F61C298400003BA37C /* color_C.png */, + 636B96F71C298400003BA37C /* color_D.png */, + 636B96F81C298400003BA37C /* color_E.png */, + 636B96F91C298400003BA37C /* color_F.png */, + 636B96FA1C298400003BA37C /* color_G.png */, + 636B96FB1C298400003BA37C /* color_H.png */, + 636B96FC1C298400003BA37C /* color_I.png */, + 636B96FD1C298400003BA37C /* color_L.png */, + 636B96FE1C298400003BA37C /* color_M.png */, + 636B96FF1C298400003BA37C /* conference_exit_default.png */, + 636B97001C298400003BA37C /* conference_exit_default@2x.png */, + 636B97011C298400003BA37C /* conference_exit_over.png */, + 636B97021C298400003BA37C /* conference_exit_over@2x.png */, + 636B97031C298400003BA37C /* contact_add_default.png */, + 636B97041C298400003BA37C /* contact_add_default@2x.png */, + 636B97051C298400003BA37C /* contact_add_disabled.png */, + 636B97061C298400003BA37C /* contact_add_disabled@2x.png */, + 636B97071C298400003BA37C /* contacts_all_default.png */, + 636B97081C298400003BA37C /* contacts_all_default@2x.png */, + 636B97091C298400003BA37C /* contacts_all_disabled.png */, + 636B970A1C298400003BA37C /* contacts_all_disabled@2x.png */, + 636B970B1C298400003BA37C /* contacts_all_selected.png */, + 636B970C1C298400003BA37C /* contacts_all_selected@2x.png */, + 636B970D1C298400003BA37C /* contacts_sip_default.png */, + 636B970E1C298400003BA37C /* contacts_sip_default@2x.png */, + 636B970F1C298400003BA37C /* contacts_sip_disabled.png */, + 636B97101C298400003BA37C /* contacts_sip_disabled@2x.png */, + 636B97111C298400003BA37C /* contacts_sip_selected.png */, + 636B97121C298400003BA37C /* contacts_sip_selected@2x.png */, + 636B97131C298400003BA37C /* delete_default.png */, + 636B97141C298400003BA37C /* delete_default@2x.png */, + 636B97151C298400003BA37C /* delete_disabled.png */, + 636B97161C298400003BA37C /* delete_disabled@2x.png */, + 636B97171C298400003BA37C /* delete_field_default.png */, + 636B97181C298400003BA37C /* delete_field_default@2x.png */, + 636B97191C298400003BA37C /* delete_field_over.png */, + 636B971A1C298400003BA37C /* delete_field_over@2x.png */, + 636B971B1C298400003BA37C /* deselect_all.png */, + 636B971C1C298400003BA37C /* deselect_all@2x.png */, + 636B971D1C298400003BA37C /* dialer_alt_back.png */, + 636B971E1C298400003BA37C /* dialer_alt_back@2x.png */, + 636B971F1C298400003BA37C /* dialer_back_default.png */, + 636B97201C298400003BA37C /* dialer_back_default@2x.png */, + 636B97211C298400003BA37C /* dialer_back_disabled.png */, + 636B97221C298400003BA37C /* dialer_back_disabled@2x.png */, + 636B97231C298400003BA37C /* dialer_background.png */, + 636B97241C298400003BA37C /* dialer_background@2x.png */, + 636B97251C298400003BA37C /* edit_default.png */, + 636B97261C298400003BA37C /* edit_default@2x.png */, + 636B97271C298400003BA37C /* edit_disabled.png */, + 636B97281C298400003BA37C /* edit_disabled@2x.png */, + 636B97291C298400003BA37C /* edit_list_default.png */, + 636B972A1C298400003BA37C /* edit_list_default@2x.png */, + 636B972B1C298400003BA37C /* edit_list_disabled.png */, + 636B972C1C298400003BA37C /* edit_list_disabled@2x.png */, + 636B972D1C298400003BA37C /* footer_chat_default.png */, + 636B972E1C298400003BA37C /* footer_chat_default@2x.png */, + 636B972F1C298400003BA37C /* footer_chat_disabled.png */, + 636B97301C298400003BA37C /* footer_chat_disabled@2x.png */, + 636B97311C298400003BA37C /* footer_contacts_default.png */, + 636B97321C298400003BA37C /* footer_contacts_default@2x.png */, + 636B97331C298400003BA37C /* footer_contacts_disabled.png */, + 636B97341C298400003BA37C /* footer_contacts_disabled@2x.png */, + 636B97351C298400003BA37C /* footer_dialer_default.png */, + 636B97361C298400003BA37C /* footer_dialer_default@2x.png */, + 636B97371C298400003BA37C /* footer_dialer_disabled.png */, + 636B97381C298400003BA37C /* footer_dialer_disabled@2x.png */, + 636B97391C298400003BA37C /* footer_history_default.png */, + 636B973A1C298400003BA37C /* footer_history_default@2x.png */, + 636B973B1C298400003BA37C /* footer_history_disabled.png */, + 636B973C1C298400003BA37C /* footer_history_disabled@2x.png */, + 636B973D1C298400003BA37C /* history_all_default.png */, + 636B973E1C298400003BA37C /* history_all_default@2x.png */, + 636B973F1C298400003BA37C /* history_all_disabled.png */, + 636B97401C298400003BA37C /* history_all_disabled@2x.png */, + 636B97411C298400003BA37C /* history_all_selected.png */, + 636B97421C298400003BA37C /* history_all_selected@2x.png */, + 636B97431C298400003BA37C /* history_chat_indicator.png */, + 636B97441C298400003BA37C /* history_chat_indicator@2x.png */, + 636B97451C298400003BA37C /* history_missed_default.png */, + 636B97461C298400003BA37C /* history_missed_default@2x.png */, + 636B97471C298400003BA37C /* history_missed_disabled.png */, + 636B97481C298400003BA37C /* history_missed_disabled@2x.png */, + 636B97491C298400003BA37C /* history_missed_selected.png */, + 636B974A1C298400003BA37C /* history_missed_selected@2x.png */, + 636B974B1C298400003BA37C /* led_connected.png */, + 636B974C1C298400003BA37C /* led_connected@2x.png */, + 636B974D1C298400003BA37C /* led_disconnected.png */, + 636B974E1C298400003BA37C /* led_disconnected@2x.png */, + 636B974F1C298400003BA37C /* led_error.png */, + 636B97501C298400003BA37C /* led_error@2x.png */, + 636B97511C298400003BA37C /* led_inprogress.png */, + 636B97521C298400003BA37C /* led_inprogress@2x.png */, + 636B97531C298400003BA37C /* linphone_logo.png */, + 636B97541C298400003BA37C /* linphone_logo@2x.png */, + 636B97551C298400003BA37C /* linphone_user.png */, + 636B97561C298400003BA37C /* linphone_user@2x.png */, + 636B97571C298401003BA37C /* list_details_default.png */, + 636B97581C298401003BA37C /* list_details_default@2x.png */, + 636B97591C298401003BA37C /* list_details_over.png */, + 636B975A1C298401003BA37C /* list_details_over@2x.png */, + 636B975B1C298401003BA37C /* menu.png */, + 636B975C1C298401003BA37C /* menu@2x.png */, + 636B975D1C298401003BA37C /* micro_default.png */, + 636B975E1C298401003BA37C /* micro_default@2x.png */, + 636B975F1C298401003BA37C /* micro_disabled.png */, + 636B97601C298401003BA37C /* micro_disabled@2x.png */, + 636B97611C298401003BA37C /* micro_selected.png */, + 636B97621C298401003BA37C /* micro_selected@2x.png */, + 636B97631C298401003BA37C /* numpad_0_default.png */, + 636B97641C298401003BA37C /* numpad_0_default@2x.png */, + 636B97651C298401003BA37C /* numpad_0_over.png */, + 636B97661C298401003BA37C /* numpad_0_over@2x.png */, + 636B97671C298401003BA37C /* numpad_1_default.png */, + 636B97681C298401003BA37C /* numpad_1_default@2x.png */, + 636B97691C298401003BA37C /* numpad_1_over.png */, + 636B976A1C298401003BA37C /* numpad_1_over@2x.png */, + 636B976B1C298401003BA37C /* numpad_2_default.png */, + 636B976C1C298401003BA37C /* numpad_2_default@2x.png */, + 636B976D1C298401003BA37C /* numpad_2_over.png */, + 636B976E1C298401003BA37C /* numpad_2_over@2x.png */, + 636B976F1C298401003BA37C /* numpad_3_default.png */, + 636B97701C298401003BA37C /* numpad_3_default@2x.png */, + 636B97711C298401003BA37C /* numpad_3_over.png */, + 636B97721C298401003BA37C /* numpad_3_over@2x.png */, + 636B97731C298401003BA37C /* numpad_4_default.png */, + 636B97741C298401003BA37C /* numpad_4_default@2x.png */, + 636B97751C298401003BA37C /* numpad_4_over.png */, + 636B97761C298401003BA37C /* numpad_4_over@2x.png */, + 636B97771C298401003BA37C /* numpad_5_default.png */, + 636B97781C298401003BA37C /* numpad_5_default@2x.png */, + 636B97791C298401003BA37C /* numpad_5_over.png */, + 636B977A1C298401003BA37C /* numpad_5_over@2x.png */, + 636B977B1C298401003BA37C /* numpad_6_default.png */, + 636B977C1C298401003BA37C /* numpad_6_default@2x.png */, + 636B977D1C298401003BA37C /* numpad_6_over.png */, + 636B977E1C298401003BA37C /* numpad_6_over@2x.png */, + 636B977F1C298401003BA37C /* numpad_7_default.png */, + 636B97801C298401003BA37C /* numpad_7_default@2x.png */, + 636B97811C298401003BA37C /* numpad_7_over.png */, + 636B97821C298401003BA37C /* numpad_7_over@2x.png */, + 636B97831C298401003BA37C /* numpad_8_default.png */, + 636B97841C298401003BA37C /* numpad_8_default@2x.png */, + 636B97851C298401003BA37C /* numpad_8_over.png */, + 636B97861C298401003BA37C /* numpad_8_over@2x.png */, + 636B97871C298401003BA37C /* numpad_9_default.png */, + 636B97881C298401003BA37C /* numpad_9_default@2x.png */, + 636B97891C298401003BA37C /* numpad_9_over.png */, + 636B978A1C298401003BA37C /* numpad_9_over@2x.png */, + 636B978B1C298401003BA37C /* numpad_hash_default.png */, + 636B978C1C298401003BA37C /* numpad_hash_default@2x.png */, + 636B978D1C298401003BA37C /* numpad_hash_over.png */, + 636B978E1C298401003BA37C /* numpad_hash_over@2x.png */, + 636B978F1C298401003BA37C /* numpad_over_background.png */, + 636B97901C298401003BA37C /* numpad_star_default.png */, + 636B97911C298401003BA37C /* numpad_star_default@2x.png */, + 636B97921C298401003BA37C /* numpad_star_over.png */, + 636B97931C298401003BA37C /* numpad_star_over@2x.png */, + 636B97941C298401003BA37C /* options_add_call_default.png */, + 636B97951C298401003BA37C /* options_add_call_default@2x.png */, + 636B97961C298401003BA37C /* options_add_call_disabled.png */, + 636B97971C298401003BA37C /* options_add_call_disabled@2x.png */, + 636B97981C298401003BA37C /* options_default.png */, + 636B97991C298401003BA37C /* options_default@2x.png */, + 636B979A1C298401003BA37C /* options_disabled.png */, + 636B979B1C298401003BA37C /* options_disabled@2x.png */, + 636B979C1C298401003BA37C /* options_selected.png */, + 636B979D1C298401003BA37C /* options_selected@2x.png */, + 636B979E1C298401003BA37C /* options_start_conference_default.png */, + 636B979F1C298401003BA37C /* options_start_conference_default@2x.png */, + 636B97A01C298401003BA37C /* options_start_conference_disabled.png */, + 636B97A11C298401003BA37C /* options_start_conference_disabled@2x.png */, + 636B97A21C298401003BA37C /* options_transfer_call_default.png */, + 636B97A31C298401003BA37C /* options_transfer_call_default@2x.png */, + 636B97A41C298401003BA37C /* options_transfer_call_disabled.png */, + 636B97A51C298401003BA37C /* options_transfer_call_disabled@2x.png */, + 636B97A61C298401003BA37C /* pause_big_default.png */, + 636B97A71C298401003BA37C /* pause_big_default@2x.png */, + 636B97A81C298401003BA37C /* pause_big_disabled.png */, + 636B97A91C298401003BA37C /* pause_big_disabled@2x.png */, + 636B97AA1C298401003BA37C /* pause_big_over_selected.png */, + 636B97AB1C298401003BA37C /* pause_big_over_selected@2x.png */, + 636B97AC1C298401003BA37C /* pause_small_default.png */, + 636B97AD1C298401003BA37C /* pause_small_default@2x.png */, + 636B97AE1C298401003BA37C /* pause_small_disabled.png */, + 636B97AF1C298401003BA37C /* pause_small_disabled@2x.png */, + 636B97B01C298401003BA37C /* pause_small_over_selected.png */, + 636B97B11C298401003BA37C /* pause_small_over_selected@2x.png */, + 636B97B21C298401003BA37C /* route_bluetooth_default.png */, + 636B97B31C298401003BA37C /* route_bluetooth_default@2x.png */, + 636B97B41C298401003BA37C /* route_bluetooth_disabled.png */, + 636B97B51C298401003BA37C /* route_bluetooth_disabled@2x.png */, + 636B97B61C298401003BA37C /* route_bluetooth_selected.png */, + 636B97B71C298401003BA37C /* route_bluetooth_selected@2x.png */, + 636B97B81C298401003BA37C /* route_earpiece_default.png */, + 636B97B91C298401003BA37C /* route_earpiece_default@2x.png */, + 636B97BA1C298401003BA37C /* route_earpiece_disabled.png */, + 636B97BB1C298401003BA37C /* route_earpiece_disabled@2x.png */, + 636B97BC1C298401003BA37C /* route_earpiece_selected.png */, + 636B97BD1C298401003BA37C /* route_earpiece_selected@2x.png */, + 636B97BE1C298401003BA37C /* route_speaker_default.png */, + 636B97BF1C298401003BA37C /* route_speaker_default@2x.png */, + 636B97C01C298401003BA37C /* route_speaker_disabled.png */, + 636B97C11C298401003BA37C /* route_speaker_disabled@2x.png */, + 636B97C21C298401003BA37C /* route_speaker_selected.png */, + 636B97C31C298401003BA37C /* route_speaker_selected@2x.png */, + 636B97C41C298401003BA37C /* routes_default.png */, + 636B97C51C298401003BA37C /* routes_default@2x.png */, + 636B97C61C298401003BA37C /* routes_disabled.png */, + 636B97C71C298401003BA37C /* routes_disabled@2x.png */, + 636B97C81C298401003BA37C /* routes_selected.png */, + 636B97C91C298401003BA37C /* routes_selected@2x.png */, + 636B97CA1C298401003BA37C /* security_ko.png */, + 636B97CB1C298401003BA37C /* security_ko@2x.png */, + 636B97CC1C298401003BA37C /* security_ok.png */, + 636B97CD1C298401003BA37C /* security_ok@2x.png */, + 636B97CE1C298401003BA37C /* security_pending.png */, + 636B97CF1C298401003BA37C /* security_pending@2x.png */, + 636B97D01C298401003BA37C /* select_all_default.png */, + 636B97D11C298401003BA37C /* select_all_default@2x.png */, + 636B97D21C298401003BA37C /* select_all_disabled.png */, + 636B97D31C298401003BA37C /* select_all_disabled@2x.png */, + 636B97D41C298401003BA37C /* speaker_default.png */, + 636B97D51C298401003BA37C /* speaker_default@2x.png */, + 636B97D61C298401003BA37C /* speaker_disabled.png */, + 636B97D71C298401003BA37C /* speaker_disabled@2x.png */, + 636B97D81C298401003BA37C /* speaker_selected.png */, + 636B97D91C298401003BA37C /* speaker_selected@2x.png */, + 636B97DA1C298401003BA37C /* splashscreen.png */, + 636B97DB1C298401003BA37C /* splashscreen@2x.png */, + 636B97DC1C298401003BA37C /* valid_default.png */, + 636B97DD1C298401003BA37C /* valid_default@2x.png */, + 636B97DE1C298401003BA37C /* valid_disabled.png */, + 636B97DF1C298401003BA37C /* valid_disabled@2x.png */, + 636B97E01C298401003BA37C /* voicemail.png */, + 636B97E11C298401003BA37C /* voicemail@2x.png */, + 636B97E21C298401003BA37C /* waiting_time.png */, + 636B97E31C298401003BA37C /* waiting_time@2x.png */, + ); + path = images; + sourceTree = ""; + }; + 63AADBC31B6A0FF200AA16FD /* Resources */ = { + isa = PBXGroup; + children = ( + 63AADBE31B6A0FF200AA16FD /* assistant_external_sip.rc */, + 63AADBE41B6A0FF200AA16FD /* assistant_linphone_create.rc */, + 63AADBE51B6A0FF200AA16FD /* assistant_linphone_existing.rc */, + 63AADBE61B6A0FF200AA16FD /* assistant_remote.rc */, + 63AADBC91B6A0FF200AA16FD /* hold.wav */, + 63AADBCA1B6A0FF200AA16FD /* Images.xcassets */, + 63AADBD51B6A0FF200AA16FD /* licenses.html */, + 63AADBD71B6A0FF200AA16FD /* linphonerc */, + 63AADBD81B6A0FF200AA16FD /* linphonerc-factory */, + 63AADBDA1B6A0FF200AA16FD /* linphonerc~ipad */, + 63CDC4511C3BDE370085F529 /* sounds */, + 63AADBC41B6A0FF200AA16FD /* Localizable.strings */, + 636B967C1C298400003BA37C /* images */, + 631348311B6FA53300C6BDCB /* rootca.pem */, + ); + path = Resources; + sourceTree = ""; + }; + 63B81A021B57DA33009604A6 /* TPKeyboardAvoiding */ = { + isa = PBXGroup; + children = ( + 63B81A031B57DA33009604A6 /* LICENSE.txt */, + 63B81A041B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.h */, + 63B81A051B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.m */, + 63B81A061B57DA33009604A6 /* TPKeyboardAvoidingScrollView.h */, + 63B81A071B57DA33009604A6 /* TPKeyboardAvoidingScrollView.m */, + 63B81A081B57DA33009604A6 /* TPKeyboardAvoidingTableView.h */, + 63B81A091B57DA33009604A6 /* TPKeyboardAvoidingTableView.m */, + 63B81A0A1B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.h */, + 63B81A0B1B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.m */, + ); + name = TPKeyboardAvoiding; + path = Utils/TPKeyboardAvoiding; + sourceTree = ""; + }; + 63CDC4511C3BDE370085F529 /* sounds */ = { + isa = PBXGroup; + children = ( + 63CDC4521C3BDE370085F529 /* hold.caf */, + 63CDC4531C3BDE370085F529 /* msg.caf */, + 63CDC4541C3BDE370085F529 /* ringback.wav */, + 63CDC4551C3BDE370085F529 /* rings */, + 63CDC45C1C3BDE370085F529 /* shortring.caf */, + ); + path = sounds; + sourceTree = ""; + }; + 63CDC4551C3BDE370085F529 /* rings */ = { + isa = PBXGroup; + children = ( + 63CDC4561C3BDE370085F529 /* four_hands_together.caf */, + 63CDC4571C3BDE370085F529 /* house_keeping.caf */, + 63CDC4581C3BDE370085F529 /* it_s_a_game.caf */, + 63CDC4591C3BDE370085F529 /* leaving_a_dream.caf */, + 63CDC45A1C3BDE370085F529 /* notes_of_the_optimistic.caf */, + 63CDC45B1C3BDE370085F529 /* soft_as_snow.caf */, + ); + path = rings; + sourceTree = ""; + }; D326483415887D4400930C67 /* Utils */ = { isa = PBXGroup; children = ( @@ -2307,13 +2572,16 @@ D37EE15F160377D7003608A6 /* DTFoundation */, D32B9DFA15A2F131000B6DEC /* FastAddressBook.h */, D32B9DFB15A2F131000B6DEC /* FastAddressBook.m */, - D3ED40141602172200BF332B /* GrowingTextView */, + 6371579F1B283FE200C91677 /* FileTransferDelegate.h */, + 637157A01B283FE200C91677 /* FileTransferDelegate.m */, + 633888401BFB2C49001D5E7B /* HPGrowingTextView */, D3807FC715C2894A005BE9BC /* InAppSettingsKit */, - D3B90E1115C2CB5700F64F8C /* NinePatch.xcodeproj */, D326483615887D5200930C67 /* OrderedDictionary.h */, D326483715887D5200930C67 /* OrderedDictionary.m */, + 63B81A021B57DA33009604A6 /* TPKeyboardAvoiding */, D3F7997E15BD31EC0018C273 /* TPMultiLayoutViewController */, - D3F9A9EB15AF27620045320F /* UACellBackgroundView */, + 6308F9C31BF0DD6600D1234B /* XMLRPCHelper.h */, + 6308F9C41BF0DD6600D1234B /* XMLRPCHelper.m */, C9B3A6FD15B485DB006F52EE /* Utils.h */, D35860D515B549B500513429 /* Utils.m */, D3554EC515CA79A900478841 /* XMLRPC.xcodeproj */, @@ -2437,26 +2705,6 @@ path = Settings; sourceTree = ""; }; - D3B90E1215C2CB5700F64F8C /* Products */ = { - isa = PBXGroup; - children = ( - D3B90E1915C2CB5800F64F8C /* libNinePatch.a */, - ); - name = Products; - sourceTree = ""; - }; - D3ED40141602172200BF332B /* GrowingTextView */ = { - isa = PBXGroup; - children = ( - D3ED40151602172200BF332B /* HPGrowingTextView.h */, - D3ED40161602172200BF332B /* HPGrowingTextView.m */, - D3ED40171602172200BF332B /* HPTextViewInternal.h */, - D3ED40181602172200BF332B /* HPTextViewInternal.m */, - ); - name = GrowingTextView; - path = Utils/GrowingTextView; - sourceTree = ""; - }; D3F7997E15BD31EC0018C273 /* TPMultiLayoutViewController */ = { isa = PBXGroup; children = ( @@ -2466,620 +2714,6 @@ name = TPMultiLayoutViewController; sourceTree = ""; }; - D3F9A9EB15AF27620045320F /* UACellBackgroundView */ = { - isa = PBXGroup; - children = ( - D3F9A9EC15AF277D0045320F /* UACellBackgroundView.h */, - D3F9A9ED15AF277D0045320F /* UACellBackgroundView.m */, - ); - name = UACellBackgroundView; - sourceTree = ""; - }; - F08F118819C09C6B007D70C2 /* LinphoneTester Tests */ = { - isa = PBXGroup; - children = ( - F08F118E19C09C6B007D70C2 /* LinphoneTester_Tests.m */, - F08F119E19C0A6CB007D70C2 /* DTObjectBlockExecutor.h */, - F08F119F19C0A6CB007D70C2 /* DTObjectBlockExecutor.m */, - F08F119B19C0A65A007D70C2 /* NSObject+DTRuntime.h */, - F08F119C19C0A65B007D70C2 /* NSObject+DTRuntime.m */, - F08F118919C09C6B007D70C2 /* Supporting Files */, - ); - path = "LinphoneTester Tests"; - sourceTree = SOURCE_ROOT; - }; - F08F118919C09C6B007D70C2 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - F08F118A19C09C6B007D70C2 /* LinphoneTester Tests-Info.plist */, - F08F118B19C09C6B007D70C2 /* InfoPlist.strings */, - F08F119019C09C6B007D70C2 /* LinphoneTester Tests-Prefix.pch */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - F0B89C2318DC90850050B60E /* images */ = { - isa = PBXGroup; - children = ( - D3D52A751614495300DEB00A /* accept_default_landscape~ipad.png */, - D3F83F741582253100336684 /* accept_default.png */, - D3D52A761614495300DEB00A /* accept_default~ipad.png */, - D3D52A771614495300DEB00A /* accept_over_landscape~ipad.png */, - D3F83F751582253100336684 /* accept_over.png */, - D3D52A781614495300DEB00A /* accept_over~ipad.png */, - D3D6A39B159B0EEF005F692C /* add_call_default.png */, - D3A74E5E15C69391001500B9 /* add_call_default~ipad.png */, - D3D6A39C159B0EEF005F692C /* add_call_disabled.png */, - D3A74E5F15C69391001500B9 /* add_call_disabled~ipad.png */, - D3D6A39D159B0EEF005F692C /* add_call_over.png */, - D3A74E6015C69391001500B9 /* add_call_over~ipad.png */, - D3ED3E6715861A53006C0DE4 /* add_contact_default.png */, - D3A74E6115C69391001500B9 /* add_contact_default~ipad.png */, - D3ED3E6815861A53006C0DE4 /* add_contact_disabled.png */, - D3A74E6215C69392001500B9 /* add_contact_disabled~ipad.png */, - D3ED3E6915861A53006C0DE4 /* add_contact_over.png */, - D3A74E6315C69392001500B9 /* add_contact_over~ipad.png */, - D3D14E7B15A711700074A527 /* avatar_shadow_small.png */, - D3F34F2F1599B008005BE94F /* avatar_shadow.png */, - D31B4B271598A390002E6C72 /* avatar_unknown_small.png */, - D31B4B261598A390002E6C72 /* avatar_unknown.png */, - D3211BBB159CBFD60098460B /* back_default.png */, - D3A74E6415C69392001500B9 /* back_default~ipad.png */, - D3211BBC159CBFD60098460B /* back_disabled.png */, - D3A74E6515C69392001500B9 /* back_disabled~ipad.png */, - D3211BBD159CBFD60098460B /* back_over.png */, - D3A74E6615C69392001500B9 /* back_over~ipad.png */, - D3998D0316031937009DD22C /* background_alt.png */, - D3A74E6715C69392001500B9 /* background_top~ipad.png */, - D3ED3E401585FB4A006C0DE4 /* background.png */, - D3ED3E7615861B1B006C0DE4 /* backspace_default.png */, - D3A74E6815C69392001500B9 /* backspace_default~ipad.png */, - D35E758815932DE60066B1C1 /* backspace_disabled.png */, - D3A74E6915C69392001500B9 /* backspace_disabled~ipad.png */, - D3ED3E7715861B1B006C0DE4 /* backspace_over.png */, - D3A74E6A15C69392001500B9 /* backspace_over~ipad.png */, - D3F5F8D91609A86700D3DA1A /* bubble.png */, - D32D5AA515ADE5D9008593F3 /* button_alert_background_default.png */, - D32D5AA615ADE5D9008593F3 /* button_alert_background_over.png */, - D35E920B160CABD70023116B /* button_background_default.9.png */, - D35E91EC160CA0C70023116B /* button_background_default.9@2x.png */, - D35406F515A47E9E007E7E81 /* button_background_default.png */, - D35E920C160CABD70023116B /* button_background_over.9.png */, - D35E91ED160CA0C70023116B /* button_background_over.9@2x.png */, - D35406F615A47E9E007E7E81 /* button_background_over.png */, - D3ED3E7015861ABD006C0DE4 /* call_default.png */, - D3A74E6B15C69392001500B9 /* call_default~ipad.png */, - D35E758C15934F360066B1C1 /* call_disabled.png */, - D3A74E6C15C69392001500B9 /* call_disabled~ipad.png */, - D3ED3E7115861ABD006C0DE4 /* call_over.png */, - D3A74E6D15C69392001500B9 /* call_over~ipad.png */, - D3432A5E158A4446001C6B0B /* call_quality_indicator_0.png */, - D3432A5F158A4446001C6B0B /* call_quality_indicator_1.png */, - D3432A60158A4446001C6B0B /* call_quality_indicator_2.png */, - D3432A61158A4446001C6B0B /* call_quality_indicator_3.png */, - D37B96B515A1A6F20005CCD2 /* call_state_delete_default.png */, - D37B96B615A1A6F20005CCD2 /* call_state_delete_over.png */, - D3211BA5159C3D410098460B /* call_state_outgoing_default.png */, - D36C43ED158F61EA0048BA40 /* call_state_pause_default.png */, - D36C43EE158F61EA0048BA40 /* call_state_pause_over.png */, - D36C43EF158F61EA0048BA40 /* call_state_play_default.png */, - D36C43F0158F61EA0048BA40 /* call_state_play_over.png */, - D31AAF6D159B65E1002C6B02 /* call_state_ringing_default.png */, - D31C9C8D158A1C1000756B45 /* call_status_incoming.png */, - D31C9C8E158A1C1000756B45 /* call_status_missed.png */, - D31C9C8F158A1C1000756B45 /* call_status_outgoing.png */, - D33E1F06164CF35100CFA363 /* callbar_left_padding.png */, - D33E1F07164CF35100CFA363 /* callbar_right_padding.png */, - D3E84F1715B00F4100420DAC /* cancel_default.png */, - D3E84F1815B00F4100420DAC /* cancel_over.png */, - D38D14AD15A30B3D008497E8 /* cell_call_first_highlight.png */, - D3211BB8159C8A820098460B /* cell_call_first.png */, - D38D14AE15A30B3D008497E8 /* cell_call_highlight.png */, - D36C43CC158F2F370048BA40 /* cell_call.png */, - D36C43CD158F2F370048BA40 /* cell_conference.png */, - D3EA5401159852080037DC6B /* chat_add_default.png */, - D3EA5402159852080037DC6B /* chat_add_over.png */, - D3F795DB15A5831C0077328B /* chat_back_default.png */, - D3F795DC15A5831C0077328B /* chat_back_over.png */, - D389363715A6D53200A3A3AA /* chat_bubble_incoming.9.png */, - D3A8BB7715A6CC3200F96BE5 /* chat_bubble_incoming.png */, - D389363815A6D53200A3A3AA /* chat_bubble_outgoing.9.png */, - D3A8BB7615A6CC3200F96BE5 /* chat_bubble_outgoing.png */, - D3F5F8DA1609A86700D3DA1A /* chat_cancel_default.png */, - D3F5F8DB1609A86700D3DA1A /* chat_cancel_over.png */, - D3A74E6E15C69392001500B9 /* chat_default_landscape~ipad.png */, - D38327F11580FE3A00FA0D23 /* chat_default.png */, - D3A74E6F15C69392001500B9 /* chat_default~ipad.png */, - D3EA53FF159852080037DC6B /* chat_edit_default.png */, - D3EA5400159852080037DC6B /* chat_edit_over.png */, - D3D51252160B35CB00946DF8 /* chat_message_background.9.png */, - D3D51253160B35CB00946DF8 /* chat_message_background.9@2x.png */, - D3D51254160B35CB00946DF8 /* chat_message_background.png */, - 2234C8E715EE2F7F00E18E83 /* chat_message_delivered.png */, - 2234C8ED15EE744200E18E83 /* chat_message_inprogress.png */, - 2234C8E815EE2F7F00E18E83 /* chat_message_not_delivered.png */, - D3B9A3DB15A58C440096EA4E /* chat_ok_default.png */, - D3B9A3DC15A58C440096EA4E /* chat_ok_over.png */, - D3A74E7015C69392001500B9 /* chat_over_landscape~ipad.png */, - D38327FF158100E400FA0D23 /* chat_over.png */, - D3A74E7115C69392001500B9 /* chat_over~ipad.png */, - D3F5F8DC1609A86700D3DA1A /* chat_photo_default.png */, - D3F5F8DD1609A86700D3DA1A /* chat_photo_disabled.png */, - D3F5F8DE1609A86700D3DA1A /* chat_photo_over.png */, - D3F5F983160B1A0800D3DA1A /* chat_progressbar_background.png */, - D3A74E7215C69392001500B9 /* chat_selected_landscape~ipad.png */, - D38327F21580FE3A00FA0D23 /* chat_selected.png */, - D3A74E7315C69392001500B9 /* chat_selected~ipad.png */, - D3B9A3DD15A58C440096EA4E /* chat_send_default.png */, - D32B6E2315A5B2020033019F /* chat_send_disabled.png */, - D3B9A3DE15A58C450096EA4E /* chat_send_over.png */, - D3C31A0715BD8DED008ED271 /* conference_default_landscape.png */, - D339888C15C6DD1600CAF1E4 /* conference_default_landscape~ipad.png */, - D31AAF61159B5B6E002C6B02 /* conference_default.png */, - D3A74E7415C69392001500B9 /* conference_default~ipad.png */, - D3C31A0815BD8DED008ED271 /* conference_over_landscape.png */, - D339888D15C6DD1600CAF1E4 /* conference_over_landscape~ipad.png */, - D31AAF62159B5B6E002C6B02 /* conference_over.png */, - D3A74E7515C69392001500B9 /* conference_over~ipad.png */, - D3128FE715AABE4E00A2147A /* contact_back_default.png */, - D3128FE815AABE4E00A2147A /* contact_back_over.png */, - D3E84F3615B011AF00420DAC /* contact_cancel_default.png */, - D3E84F3715B011AF00420DAC /* contact_cancel_over.png */, - D3128FE915AABE4E00A2147A /* contact_edit_default.png */, - D3128FEA15AABE4E00A2147A /* contact_edit_over.png */, - D37C638C15AAD251009D0BAC /* contact_number_over.png */, - D37C638D15AAD251009D0BAC /* contact_number.png */, - D3C6526915AC228A0092A874 /* contact_ok_default.png */, - D30BBD1715D402A7000F93DD /* contact_ok_disabled.png */, - D3C6526A15AC228A0092A874 /* contact_ok_over.png */, - D354980E15875608000081D8 /* contacts_add_default.png */, - D354980F15875608000081D8 /* contacts_add_over.png */, - D354980315875534000081D8 /* contacts_all_default.png */, - D354980215875534000081D8 /* contacts_all_selected.png */, - D3119E7015B6A4710005D4A4 /* contacts_back_default.png */, - D3119E7115B6A4710005D4A4 /* contacts_back_over.png */, - D3A74E7615C69392001500B9 /* contacts_default_landscape~ipad.png */, - D38327EB1580FE3A00FA0D23 /* contacts_default.png */, - D3A74E7715C69392001500B9 /* contacts_default~ipad.png */, - D354980515875534000081D8 /* contacts_linphone_default.png */, - D354980415875534000081D8 /* contacts_linphone_selected.png */, - D3A74E7815C69392001500B9 /* contacts_over_landscape~ipad.png */, - D38327FC158100E400FA0D23 /* contacts_over.png */, - D3A74E7915C69392001500B9 /* contacts_over~ipad.png */, - D3A74E7A15C69392001500B9 /* contacts_selected_landscape~ipad.png */, - D38327EC1580FE3A00FA0D23 /* contacts_selected.png */, - D3A74E7B15C69392001500B9 /* contacts_selected~ipad.png */, - D3D52A791614495300DEB00A /* decline_default_landscape~ipad.png */, - D3F83F761582253100336684 /* decline_default.png */, - D3D52A7A1614495300DEB00A /* decline_default~ipad.png */, - D3D52A7B1614495300DEB00A /* decline_over_landscape~ipad.png */, - D3F83F771582253100336684 /* decline_over.png */, - D3D52A7C1614495300DEB00A /* decline_over~ipad.png */, - D3A74E7C15C69392001500B9 /* dialer_address_background_landscape~ipad.png */, - D3ED3E441585FB8C006C0DE4 /* dialer_address_background.png */, - D3A74E7D15C69392001500B9 /* dialer_address_background~ipad.png */, - D3C31A0915BD8DED008ED271 /* dialer_alt_back_default_landscape.png */, - D339890415C6E16F00CAF1E4 /* dialer_alt_back_default_landscape~ipad.png */, - D3E84F1B15B00F4100420DAC /* dialer_alt_back_default.png */, - D3ACB09915C6D59500E15894 /* dialer_alt_back_default~ipad.png */, - D3C31A0A15BD8DED008ED271 /* dialer_alt_back_over_landscape.png */, - D339890515C6E16F00CAF1E4 /* dialer_alt_back_over_landscape~ipad.png */, - D3E84F1C15B00F4100420DAC /* dialer_alt_back_over.png */, - D3ACB09A15C6D59500E15894 /* dialer_alt_back_over~ipad.png */, - D3E84F1D15B00F4100420DAC /* dialer_alt_background.png */, - D3C31A0B15BD8DED008ED271 /* dialer_alt_default_landscape.png */, - D339888E15C6DD1600CAF1E4 /* dialer_alt_default_landscape~ipad.png */, - D36C43CF158F2F370048BA40 /* dialer_alt_default.png */, - D3A74E7E15C69392001500B9 /* dialer_alt_default~ipad.png */, - D3328642160B5BC300E6435D /* dialer_alt_disabled_landscape.png */, - D3328643160B5BC300E6435D /* dialer_alt_disabled_landscape~ipad.png */, - D3328644160B5BC300E6435D /* dialer_alt_disabled.png */, - D3328645160B5BC300E6435D /* dialer_alt_disabled~ipad.png */, - D3C31A0C15BD8DED008ED271 /* dialer_alt_over_landscape.png */, - D339888F15C6DD1600CAF1E4 /* dialer_alt_over_landscape~ipad.png */, - D36C43D0158F2F370048BA40 /* dialer_alt_over.png */, - D3A74E7F15C69392001500B9 /* dialer_alt_over~ipad.png */, - D38327ED1580FE3A00FA0D23 /* dialer_default.png */, - D38327EE1580FE3A00FA0D23 /* dialer_over.png */, - F070E62D1A2622EC00E17AFD /* dialer_padding_left.png */, - F070E62E1A2622EC00E17AFD /* dialer_padding_right.png */, - D3C2814A15A2D38D0098AA42 /* dialer_selected.png */, - D35E9208160CAA1F0023116B /* field_background.9.png */, - D35E91E9160CA0BD0023116B /* field_background.9@2x.png */, - D350F21715A43D3400149E54 /* field_background.png */, - D3F5F8E01609A86700D3DA1A /* form_invalid.png */, - D3F5F8E11609A86700D3DA1A /* form_valid.png */, - D3C31A0D15BD8DED008ED271 /* hangup_default_landscape.png */, - D339889015C6DD1600CAF1E4 /* hangup_default_landscape~ipad.png */, - D3F83EFA158205A100336684 /* hangup_default.png */, - D3A74E8015C69392001500B9 /* hangup_default~ipad.png */, - D3C31A0E15BD8DED008ED271 /* hangup_over_landscape.png */, - D339889115C6DD1600CAF1E4 /* hangup_over_landscape~ipad.png */, - D3F83EFB158205A100336684 /* hangup_over.png */, - D3A74E8115C69392001500B9 /* hangup_over~ipad.png */, - D36C43CE158F2F370048BA40 /* header_conference.png */, - D3F26BFB15987083005F9CAB /* header_incoming.png */, - D3ED3E9315872EF1006C0DE4 /* history_all_default.png */, - D3ED3E9215872EF1006C0DE4 /* history_all_selected.png */, - D3A74E8215C69392001500B9 /* history_default_landscape~ipad.png */, - D347347C1580E5F8003C7B8C /* history_default.png */, - D3A74E8315C69392001500B9 /* history_default~ipad.png */, - D3F5F8E21609A86700D3DA1A /* history_delete_default.png */, - D3F5F8E31609A86700D3DA1A /* history_delete_over.png */, - D3157A8815B4466F00DD8C4C /* history_details_add_default.png */, - D3157A8915B4466F00DD8C4C /* history_details_add_over.png */, - D3157A8E15B446CB00DD8C4C /* history_details_back_default.png */, - D3157A8F15B446CB00DD8C4C /* history_details_back_over.png */, - D3ED3E9415872EF1006C0DE4 /* history_edit_default.png */, - D3ED3E9515872EF1006C0DE4 /* history_edit_over.png */, - D3ED3E9715872EF1006C0DE4 /* history_missed_default.png */, - D3ED3E9615872EF1006C0DE4 /* history_missed_selected.png */, - D3F9A9DA15AEEB940045320F /* history_notification.png */, - D3F26BF515986DAD005F9CAB /* history_ok_default.png */, - D3F26BF615986DAD005F9CAB /* history_ok_over.png */, - D3A74E8415C69392001500B9 /* history_over_landscape~ipad.png */, - D38327FD158100E400FA0D23 /* history_over.png */, - D3A74E8515C69392001500B9 /* history_over~ipad.png */, - D3A74E8615C69392001500B9 /* history_selected_landscape~ipad.png */, - D347347D1580E5F8003C7B8C /* history_selected.png */, - D3A74E8715C69392001500B9 /* history_selected~ipad.png */, - D3866C261608CA1600830F95 /* image_back_default.png */, - D3866C271608CA1600830F95 /* image_back_over.png */, - F070E62F1A2622EC00E17AFD /* incall_padding_left_landscape.png */, - F070E6301A2622EC00E17AFD /* incall_padding_left.png */, - F070E6311A2622EC00E17AFD /* incall_padding_right_landscape.png */, - F070E6321A2622EC00E17AFD /* incall_padding_right.png */, - F0C1F9021A28781F009402C9 /* launchscreen */, - D3432A5C158A4446001C6B0B /* led_connected.png */, - D3432A70158A45AF001C6B0B /* led_disconnected.png */, - D3432A5D158A4446001C6B0B /* led_error.png */, - D3432A6F158A45AF001C6B0B /* led_inprogress.png */, - D3012CC31610467D007CD926 /* linphone_logo.png */, - 225CB2F911ABB76400628906 /* linphone-banner.png */, - D3EA5416159858A80037DC6B /* list_delete_default.png */, - D3EA5417159858A80037DC6B /* list_delete_over.png */, - D354981815876FE7000081D8 /* list_details_default.png */, - D354981915876FE7000081D8 /* list_details_over.png */, - D3F5F8E41609A86700D3DA1A /* logo_linphone_trame_background.png */, - D3C31A0F15BD8DED008ED271 /* micro_off_default_landscape.png */, - D339889215C6DD1600CAF1E4 /* micro_off_default_landscape~ipad.png */, - D3F83EF4158205A100336684 /* micro_off_default.png */, - D3A74E8815C69392001500B9 /* micro_off_default~ipad.png */, - D3C31A1015BD8DED008ED271 /* micro_off_disabled_landscape.png */, - D339889315C6DD1600CAF1E4 /* micro_off_disabled_landscape~ipad.png */, - D35EA76115A2DF8D003E025D /* micro_off_disabled.png */, - D3A74E8915C69392001500B9 /* micro_off_disabled~ipad.png */, - D3C31A1115BD8DED008ED271 /* micro_off_over_landscape.png */, - D339889415C6DD1600CAF1E4 /* micro_off_over_landscape~ipad.png */, - D3F83EF5158205A100336684 /* micro_off_over.png */, - D3A74E8A15C69392001500B9 /* micro_off_over~ipad.png */, - D3C31A1215BD8DED008ED271 /* micro_on_default_landscape.png */, - D339889515C6DD1600CAF1E4 /* micro_on_default_landscape~ipad.png */, - D3F83EF6158205A100336684 /* micro_on_default.png */, - D3A74E8B15C69392001500B9 /* micro_on_default~ipad.png */, - D3C31A1315BD8DED008ED271 /* micro_on_disabled_landscape.png */, - D339889615C6DD1600CAF1E4 /* micro_on_disabled_landscape~ipad.png */, - D35EA76215A2DF8D003E025D /* micro_on_disabled.png */, - D3A74E8C15C69392001500B9 /* micro_on_disabled~ipad.png */, - D3C31A1415BD8DED008ED271 /* micro_on_over_landscape.png */, - D339889715C6DD1600CAF1E4 /* micro_on_over_landscape~ipad.png */, - D3F83EF7158205A100336684 /* micro_on_over.png */, - D3A74E8D15C69392001500B9 /* micro_on_over~ipad.png */, - D3F83F3C1582223B00336684 /* numpad_eight_default.png */, - D3F83F3D1582223B00336684 /* numpad_eight_over.png */, - D3F83F361582223B00336684 /* numpad_five_default.png */, - D3F83F371582223B00336684 /* numpad_five_over.png */, - D3F83F341582223B00336684 /* numpad_four_default.png */, - D3F83F351582223B00336684 /* numpad_four_over.png */, - D3F83F3E1582223B00336684 /* numpad_nine_default.png */, - D3F83F3F1582223B00336684 /* numpad_nine_over.png */, - D3F83F2E1582223B00336684 /* numpad_one_default.png */, - D3F83F2F1582223B00336684 /* numpad_one_over.png */, - D3F83F3A1582223B00336684 /* numpad_seven_default.png */, - D3F83F3B1582223B00336684 /* numpad_seven_over.png */, - D3F83F401582223B00336684 /* numpad_sharp_default.png */, - D3F83F411582223B00336684 /* numpad_sharp_over.png */, - D3F83F381582223B00336684 /* numpad_six_default.png */, - D3F83F391582223B00336684 /* numpad_six_over.png */, - D3F83F431582223B00336684 /* numpad_star_default.png */, - D3C2815115A2D64A0098AA42 /* numpad_star_over.png */, - D3F83F321582223B00336684 /* numpad_three_default.png */, - D3F83F331582223B00336684 /* numpad_three_over.png */, - D3F83F301582223B00336684 /* numpad_two_default.png */, - D3F83F311582223B00336684 /* numpad_two_over.png */, - D3F83F2C1582223B00336684 /* numpad_zero_default.png */, - D3F83F2D1582223B00336684 /* numpad_zero_over.png */, - D3C31A1515BD8DED008ED271 /* options_add_default_landscape.png */, - D339889815C6DD1600CAF1E4 /* options_add_default_landscape~ipad.png */, - D3196D3015A321E2007FEEBA /* options_add_default.png */, - D3A74E8E15C69392001500B9 /* options_add_default~ipad.png */, - D3C31A1615BD8DED008ED271 /* options_add_disabled_landscape.png */, - D339889915C6DD1600CAF1E4 /* options_add_disabled_landscape~ipad.png */, - C9C8253F15AE204D00D493FA /* options_add_disabled.png */, - D3A74E8F15C69392001500B9 /* options_add_disabled~ipad.png */, - D3C31A1715BD8DED008ED271 /* options_add_over_landscape.png */, - D339889A15C6DD1600CAF1E4 /* options_add_over_landscape~ipad.png */, - D3196D3115A321E2007FEEBA /* options_add_over.png */, - D3A74E9015C69392001500B9 /* options_add_over~ipad.png */, - D3C31A1815BD8DED008ED271 /* options_default_landscape.png */, - D339889B15C6DD1600CAF1E4 /* options_default_landscape~ipad.png */, - D3D6A3A8159B0EFE005F692C /* options_default.png */, - D3A74E9115C69392001500B9 /* options_default~ipad.png */, - D3C31A1915BD8DED008ED271 /* options_disabled_landscape.png */, - D339889C15C6DD1600CAF1E4 /* options_disabled_landscape~ipad.png */, - D3D6A3A9159B0EFE005F692C /* options_disabled.png */, - D3A74E9215C69392001500B9 /* options_disabled~ipad.png */, - D3C31A1A15BD8DED008ED271 /* options_over_landscape.png */, - D339889D15C6DD1600CAF1E4 /* options_over_landscape~ipad.png */, - D3D6A3AA159B0EFE005F692C /* options_over.png */, - D3A74E9315C69392001500B9 /* options_over~ipad.png */, - D3C31A1B15BD8DED008ED271 /* options_selected_landscape.png */, - D339889E15C6DD1600CAF1E4 /* options_selected_landscape~ipad.png */, - C9C8254B15AE207B00D493FA /* options_selected.png */, - D3A74E9415C69392001500B9 /* options_selected~ipad.png */, - D3C31A1C15BD8DED008ED271 /* options_transfer_default_landscape.png */, - D339889F15C6DD1600CAF1E4 /* options_transfer_default_landscape~ipad.png */, - D3196D3215A321E3007FEEBA /* options_transfer_default.png */, - D3A74E9515C69392001500B9 /* options_transfer_default~ipad.png */, - D3C31A1D15BD8DED008ED271 /* options_transfer_disabled_landscape.png */, - D33988A015C6DD1600CAF1E4 /* options_transfer_disabled_landscape~ipad.png */, - C9C8254015AE204D00D493FA /* options_transfer_disabled.png */, - D3A74E9615C69392001500B9 /* options_transfer_disabled~ipad.png */, - D3C31A1E15BD8DED008ED271 /* options_transfer_over_landscape.png */, - D33988A115C6DD1600CAF1E4 /* options_transfer_over_landscape~ipad.png */, - D3196D3315A321E3007FEEBA /* options_transfer_over.png */, - D3A74E9715C69392001500B9 /* options_transfer_over~ipad.png */, - D3C31A1F15BD8DED008ED271 /* pause_off_default_landscape.png */, - D33988A215C6DD1600CAF1E4 /* pause_off_default_landscape~ipad.png */, - D3F83EF8158205A100336684 /* pause_off_default.png */, - D3A74E9815C69392001500B9 /* pause_off_default~ipad.png */, - D3C31A2015BD8DED008ED271 /* pause_off_over_landscape.png */, - D33988A315C6DD1600CAF1E4 /* pause_off_over_landscape~ipad.png */, - D3F83EF9158205A100336684 /* pause_off_over.png */, - D3A74E9915C69392001500B9 /* pause_off_over~ipad.png */, - D3C31A2115BD8DED008ED271 /* pause_on_default_landscape.png */, - D33988A415C6DD1600CAF1E4 /* pause_on_default_landscape~ipad.png */, - D36C43E7158F3F7E0048BA40 /* pause_on_default.png */, - D3A74E9A15C69392001500B9 /* pause_on_default~ipad.png */, - D3C31A2215BD8DED008ED271 /* pause_on_over_landscape.png */, - D33988A515C6DD1600CAF1E4 /* pause_on_over_landscape~ipad.png */, - D36C43E8158F3F7E0048BA40 /* pause_on_over.png */, - D3A74E9B15C69392001500B9 /* pause_on_over~ipad.png */, - 1599104316F746B2007BF52B /* route_bluetooth_off_default_landscape.png */, - 15AF3C4C16F37A3E00FC52EC /* route_bluetooth_off_default.png */, - 1599104416F746B2007BF52B /* route_bluetooth_off_disabled_landscape.png */, - 15AF3C4D16F37A3E00FC52EC /* route_bluetooth_off_disabled.png */, - 1599104516F746B2007BF52B /* route_bluetooth_off_over_landscape.png */, - 15AF3C4E16F37A3E00FC52EC /* route_bluetooth_off_over.png */, - 1599104616F746B2007BF52B /* route_bluetooth_on_default_landscape.png */, - 15AF3C5016F37A3E00FC52EC /* route_bluetooth_on_default.png */, - 1599104716F746B2007BF52B /* route_phone_off_default_landscape.png */, - 15AF3C6416F37A4A00FC52EC /* route_phone_off_default.png */, - 1599104816F746B2007BF52B /* route_phone_off_disabled_landscape.png */, - 15AF3C6516F37A4A00FC52EC /* route_phone_off_disabled.png */, - 1599104916F746B2007BF52B /* route_phone_off_over_landscape.png */, - 15AF3C6616F37A4A00FC52EC /* route_phone_off_over.png */, - 1599104A16F746B2007BF52B /* route_phone_on_default_landscape.png */, - 15AF3C6816F37A4A00FC52EC /* route_phone_on_default.png */, - 1599104B16F746B2007BF52B /* route_speaker_off_default_landscape.png */, - 15AF3C7C16F37A5500FC52EC /* route_speaker_off_default.png */, - 1599104C16F746B2007BF52B /* route_speaker_off_disabled_landscape.png */, - 15AF3C7D16F37A5500FC52EC /* route_speaker_off_disabled.png */, - 1599104D16F746B2007BF52B /* route_speaker_off_over_landscape.png */, - 15AF3C7E16F37A5500FC52EC /* route_speaker_off_over.png */, - 1599104E16F746B2007BF52B /* route_speaker_on_default_landscape.png */, - 15AF3C8016F37A5500FC52EC /* route_speaker_on_default.png */, - 1599104F16F746B2007BF52B /* routes_default_landscape.png */, - 15AF3C9416F37A5D00FC52EC /* routes_default.png */, - 1599105016F746B2007BF52B /* routes_disabled_landscape.png */, - 15AF3C9516F37A5D00FC52EC /* routes_disabled.png */, - 1599105116F746B2007BF52B /* routes_over_landscape.png */, - 15AF3C9616F37A5D00FC52EC /* routes_over.png */, - 1599105216F746B2007BF52B /* routes_selected_landscape.png */, - 15AF3C9716F37A5D00FC52EC /* routes_selected.png */, - D3D6A3A5159B0EFE005F692C /* security_ko.png */, - D3D6A3A7159B0EFE005F692C /* security_ok.png */, - D3D6A3A6159B0EFE005F692C /* security_pending.png */, - D3A74E9C15C69392001500B9 /* settings_default_landscape~ipad.png */, - D38327EF1580FE3A00FA0D23 /* settings_default.png */, - D3A74E9D15C69392001500B9 /* settings_default~ipad.png */, - D3A74E9E15C69392001500B9 /* settings_over_landscape~ipad.png */, - D38327FE158100E400FA0D23 /* settings_over.png */, - D3A74E9F15C69392001500B9 /* settings_over~ipad.png */, - D3A74EA015C69392001500B9 /* settings_selected_landscape~ipad.png */, - D38327F01580FE3A00FA0D23 /* settings_selected.png */, - D3A74EA115C69392001500B9 /* settings_selected~ipad.png */, - D3F5F984160B1A0800D3DA1A /* setup_back_default_landscape~ipad.png */, - D350F21315A43D3400149E54 /* setup_back_default.png */, - D3F5F985160B1A0800D3DA1A /* setup_back_default~ipad.png */, - D3F5F986160B1A0900D3DA1A /* setup_back_disabled_landscape~ipad.png */, - D3A8BB7815A6CC3200F96BE5 /* setup_back_disabled.png */, - D3F5F8E51609A86700D3DA1A /* setup_back_disabled~ipad.png */, - D3F5F8E61609A86700D3DA1A /* setup_back_over_landscape~ipad.png */, - D350F21415A43D3400149E54 /* setup_back_over.png */, - D3F5F8E71609A86700D3DA1A /* setup_back_over~ipad.png */, - D3F5F8E81609A86700D3DA1A /* setup_cancel_default_landscape~ipad.png */, - D350F21515A43D3400149E54 /* setup_cancel_default.png */, - D3D5124C160B213900946DF8 /* setup_cancel_default~ipad.png */, - D3F5F8EA1609A86700D3DA1A /* setup_cancel_disabled_landscape~ipad.png */, - D3A8BB7915A6CC3200F96BE5 /* setup_cancel_disabled.png */, - D3F5F8EB1609A86700D3DA1A /* setup_cancel_disabled~ipad.png */, - D3F5F8EC1609A86700D3DA1A /* setup_cancel_over_landscape~ipad.png */, - D350F21615A43D3400149E54 /* setup_cancel_over.png */, - D3D5124D160B213900946DF8 /* setup_cancel_over~ipad.png */, - D3F5F8EE1609A86700D3DA1A /* setup_start_default_landscape~ipad.png */, - D350F21815A43D3400149E54 /* setup_start_default.png */, - D3F5F8EF1609A86700D3DA1A /* setup_start_default~ipad.png */, - D3F5F8F01609A86700D3DA1A /* setup_start_disabled_landscape~ipad.png */, - D3A8BB7A15A6CC3200F96BE5 /* setup_start_disabled.png */, - D3F5F8F11609A86700D3DA1A /* setup_start_disabled~ipad.png */, - D3F5F8F21609A86700D3DA1A /* setup_start_over_landscape~ipad.png */, - D350F21915A43D3400149E54 /* setup_start_over.png */, - D3F5F8F31609A86700D3DA1A /* setup_start_over~ipad.png */, - D350F21B15A43D3400149E54 /* setup_welcome_logo.png */, - D3F5F8F41609A86700D3DA1A /* setup_welcome_logo~ipad.png */, - D3C31A2315BD8DED008ED271 /* speaker_off_default_landscape.png */, - D33988A615C6DD1600CAF1E4 /* speaker_off_default_landscape~ipad.png */, - D3F83EFC158205A100336684 /* speaker_off_default.png */, - D3A74EA215C69392001500B9 /* speaker_off_default~ipad.png */, - D3C31A2415BD8DED008ED271 /* speaker_off_disabled_landscape.png */, - D33988A715C6DD1600CAF1E4 /* speaker_off_disabled_landscape~ipad.png */, - D365AA7915A2DE7500CAFE3F /* speaker_off_disabled.png */, - D3A74EA315C69392001500B9 /* speaker_off_disabled~ipad.png */, - D3C31A2515BD8DED008ED271 /* speaker_off_over_landscape.png */, - D33988A815C6DD1600CAF1E4 /* speaker_off_over_landscape~ipad.png */, - D3F83EFD158205A100336684 /* speaker_off_over.png */, - D3A74EA415C69392001500B9 /* speaker_off_over~ipad.png */, - D3C31A2615BD8DED008ED271 /* speaker_on_default_landscape.png */, - D33988A915C6DD1600CAF1E4 /* speaker_on_default_landscape~ipad.png */, - D3F83EFE158205A100336684 /* speaker_on_default.png */, - D3A74EA515C69392001500B9 /* speaker_on_default~ipad.png */, - D3C31A2715BD8DED008ED271 /* speaker_on_disabled_landscape.png */, - D33988AA15C6DD1600CAF1E4 /* speaker_on_disabled_landscape~ipad.png */, - D365AA7A15A2DE7500CAFE3F /* speaker_on_disabled.png */, - D3A74EA615C69392001500B9 /* speaker_on_disabled~ipad.png */, - D3C31A2815BD8DED008ED271 /* speaker_on_over_landscape.png */, - D33988AB15C6DD1600CAF1E4 /* speaker_on_over_landscape~ipad.png */, - D3F83EFF158205A100336684 /* speaker_on_over.png */, - D3A74EA715C69392001500B9 /* speaker_on_over~ipad.png */, - D3C31A2915BD8DED008ED271 /* statebar_background_landscape.png */, - D3A74EA815C69392001500B9 /* statebar_background_landscape~ipad.png */, - D3ED3E511585FFFD006C0DE4 /* statebar_background.png */, - D3A74EA915C69392001500B9 /* statebar_background~ipad.png */, - D35E757515931E5D0066B1C1 /* switch_camera_default.png */, - D35E757615931E5D0066B1C1 /* switch_camera_over.png */, - F84015BC1939FE37006ABAB5 /* test_failed.png */, - F84015BD1939FE37006ABAB5 /* test_inprogress.png */, - F84015BE1939FE37006ABAB5 /* test_passed.png */, - D3A74E5815C68162001500B9 /* toolsbar_background.png */, - C9C8254115AE204D00D493FA /* transfer_call_default.png */, - D3A74EAA15C69392001500B9 /* transfer_call_default~ipad.png */, - C9C8254E15AE256100D493FA /* transfer_call_disabled.png */, - D3BDB9B815C6B5B1007BEAC1 /* transfer_call_disabled~ipad.png */, - C9C8254215AE204D00D493FA /* transfer_call_over.png */, - D3A74EAB15C69392001500B9 /* transfer_call_over~ipad.png */, - D3C31A2C15BD8DED008ED271 /* video_off_default_landscape.png */, - D33988AE15C6DD1600CAF1E4 /* video_off_default_landscape~ipad.png */, - D3F83F00158205A100336684 /* video_off_default.png */, - D3A74EAC15C69392001500B9 /* video_off_default~ipad.png */, - D3C31A2D15BD8DED008ED271 /* video_off_disabled_landscape.png */, - D33988AF15C6DD1600CAF1E4 /* video_off_disabled_landscape~ipad.png */, - D37295DA158B3C9600D2C0C7 /* video_off_disabled.png */, - D3A74EAD15C69392001500B9 /* video_off_disabled~ipad.png */, - D3C31A2E15BD8DED008ED271 /* video_off_over_landscape.png */, - D33988B015C6DD1600CAF1E4 /* video_off_over_landscape~ipad.png */, - D3F83F01158205A100336684 /* video_off_over.png */, - D3A74EAE15C69392001500B9 /* video_off_over~ipad.png */, - D3C31A2F15BD8DED008ED271 /* video_on_default_landscape.png */, - D33988B115C6DD1600CAF1E4 /* video_on_default_landscape~ipad.png */, - D3F83F02158205A100336684 /* video_on_default.png */, - D3A74EAF15C69392001500B9 /* video_on_default~ipad.png */, - D3C31A3015BD8DED008ED271 /* video_on_disabled_landscape.png */, - D33988B215C6DD1600CAF1E4 /* video_on_disabled_landscape~ipad.png */, - D377BBF915A19DA6002B696B /* video_on_disabled.png */, - D3A74EB015C69392001500B9 /* video_on_disabled~ipad.png */, - D3C31A3115BD8DED008ED271 /* video_on_over_landscape.png */, - D33988B315C6DD1600CAF1E4 /* video_on_over_landscape~ipad.png */, - D3F83F03158205A100336684 /* video_on_over.png */, - D3A74EB115C69392001500B9 /* video_on_over~ipad.png */, - ); - name = images; - sourceTree = ""; - }; - F0BB8BD91936208100974404 /* LinphoneTester */ = { - isa = PBXGroup; - children = ( - F08F118819C09C6B007D70C2 /* LinphoneTester Tests */, - F0BB8BE21936208100974404 /* AppDelegate.h */, - F0BB8BE31936208100974404 /* AppDelegate.m */, - F0BB8BEE1936208200974404 /* DetailViewController.h */, - F0BB8BEF1936208200974404 /* DetailViewController.m */, - F0BB8BF11936208200974404 /* TesterImages.xcassets */, - F0BB8BE81936208200974404 /* Main_iPad.storyboard */, - F0BB8BE51936208100974404 /* Main_iPhone.storyboard */, - F0BB8BEB1936208200974404 /* MasterViewController.h */, - F0BB8BEC1936208200974404 /* MasterViewController.m */, - F0BB8BDA1936208100974404 /* Supporting Files */, - F84015C5193B4E34006ABAB5 /* LogsViewController.h */, - F84015C6193B4E34006ABAB5 /* LogsViewController.m */, - ); - path = LinphoneTester; - sourceTree = ""; - }; - F0BB8BDA1936208100974404 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - F08F119819C09D88007D70C2 /* flexisip */, - F0BB8C40193630CA00974404 /* local_tester_hosts */, - F0022B081A370915009B51FD /* messages.db */, - F0BB8C41193630CA00974404 /* marie_xml */, - F0BB8C42193630CA00974404 /* tester_hosts */, - F0BB8C3919362C2200974404 /* certificates */, - F0BB8C3A19362C2200974404 /* images */, - F0BB8C3B19362C2200974404 /* sounds */, - F0BB8C3719362C1500974404 /* rcfiles */, - F0BB8BDB1936208100974404 /* LinphoneTester-Info.plist */, - F0BB8BDC1936208100974404 /* InfoPlist.strings */, - F0BB8BDF1936208100974404 /* main.m */, - F0BB8BE11936208100974404 /* LinphoneTester-Prefix.pch */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - F0C1F9021A28781F009402C9 /* launchscreen */ = { - isa = PBXGroup; - children = ( - F0C1F9041A28781F009402C9 /* background-launch.png */, - F0C1F9061A28781F009402C9 /* corner-left-bottom.png */, - F0C1F9071A28781F009402C9 /* corner-left-top.png */, - F0C1F9081A28781F009402C9 /* corner-right-bottom.png */, - F0C1F9091A28781F009402C9 /* corner-right-top.png */, - F0C1F90A1A28781F009402C9 /* logo.png */, - F0C1F90B1A28781F009402C9 /* strech-bottom.png */, - F0C1F90C1A28781F009402C9 /* strech-top.png */, - ); - name = launchscreen; - path = Resources/launchscreen; - sourceTree = ""; - }; - F0C7737E1A94822600E0C486 /* Products */ = { - isa = PBXGroup; - children = ( - F0C773871A94822700E0C486 /* libKIF.a */, - F0C773891A94822700E0C486 /* libKIF-OCUnit.a */, - F0C7738B1A94822700E0C486 /* Test Host.app */, - F0C7738D1A94822700E0C486 /* KIF Tests - XCTest.xctest */, - F0C7738F1A94822700E0C486 /* KIF Tests-OCUnit.octest */, - ); - name = Products; - sourceTree = ""; - }; - F0F952011A6AEB1000254160 /* UITests */ = { - isa = PBXGroup; - children = ( - F0C7737D1A94822600E0C486 /* KIF.xcodeproj */, - F0F952021A6AEB1000254160 /* Supporting Files */, - F0F952111A6AECD300254160 /* WizardTester.m */, - F0A1CE091A6B05A4001CA2BE /* WizardTester.h */, - F0A1CE061A6B056E001CA2BE /* ChatTester.h */, - F0A1CE071A6B056E001CA2BE /* ChatTester.m */, - F85554461A6DA2F400A9F915 /* LinphoneTestCase.h */, - F85554471A6DA2F400A9F915 /* LinphoneTestCase.m */, - F844AB121A93E3A200428306 /* ContactsTester.h */, - F844AB131A93E3A200428306 /* ContactsTester.m */, - ); - name = UITests; - path = KifTests; - sourceTree = ""; - }; - F0F952021A6AEB1000254160 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - F0F952031A6AEB1000254160 /* Info.plist */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -3089,7 +2723,6 @@ buildPhases = ( 1D60588D0D05DD3D006BFB54 /* Resources */, 63DCC71D1A07B08E00916627 /* Run Script */, - D33CF34715D3985000CD4B85 /* ShellScript */, 1D60588E0D05DD3D006BFB54 /* Sources */, 1D60588F0D05DD3D006BFB54 /* Frameworks */, 2247673A129C3B9C002B94B4 /* CopyFiles */, @@ -3098,16 +2731,15 @@ ); dependencies = ( D3554ED515CA79B900478841 /* PBXTargetDependency */, - D3B90E1B15C2CBC800F64F8C /* PBXTargetDependency */, ); name = linphone; productName = linphone; productReference = 1D6058910D05DD3D006BFB54 /* linphone.app */; productType = "com.apple.product-type.application"; }; - F08F118319C09C6A007D70C2 /* LinphoneTester Tests */ = { + F08F118319C09C6A007D70C2 /* liblinphoneTesterTests */ = { isa = PBXNativeTarget; - buildConfigurationList = F08F119319C09C6B007D70C2 /* Build configuration list for PBXNativeTarget "LinphoneTester Tests" */; + buildConfigurationList = F08F119319C09C6B007D70C2 /* Build configuration list for PBXNativeTarget "liblinphoneTesterTests" */; buildPhases = ( F08F118019C09C6A007D70C2 /* Sources */, F08F118119C09C6A007D70C2 /* Frameworks */, @@ -3118,14 +2750,14 @@ dependencies = ( F08F119219C09C6B007D70C2 /* PBXTargetDependency */, ); - name = "LinphoneTester Tests"; - productName = "LinphoneTester Tests"; - productReference = F08F118419C09C6A007D70C2 /* LinphoneTester Tests.xctest */; + name = liblinphoneTesterTests; + productName = LinphoneTesterTests; + productReference = F08F118419C09C6A007D70C2 /* liblinphoneTesterTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - F0BB8BD41936208100974404 /* LinphoneTester */ = { + F0BB8BD41936208100974404 /* liblinphoneTester */ = { isa = PBXNativeTarget; - buildConfigurationList = F0BB8C051936208200974404 /* Build configuration list for PBXNativeTarget "LinphoneTester" */; + buildConfigurationList = F0BB8C051936208200974404 /* Build configuration list for PBXNativeTarget "liblinphoneTester" */; buildPhases = ( F0BB8BD11936208100974404 /* Sources */, F0BB8BD21936208100974404 /* Frameworks */, @@ -3136,14 +2768,14 @@ ); dependencies = ( ); - name = LinphoneTester; + name = liblinphoneTester; productName = LinphoneTester; - productReference = F0BB8BD51936208100974404 /* LinphoneTester.app */; + productReference = F0BB8BD51936208100974404 /* liblinphoneTester.app */; productType = "com.apple.product-type.application"; }; - F0F951FF1A6AEB1000254160 /* KifTests */ = { + F0F951FF1A6AEB1000254160 /* linphoneTests */ = { isa = PBXNativeTarget; - buildConfigurationList = F0F9520C1A6AEB1100254160 /* Build configuration list for PBXNativeTarget "KifTests" */; + buildConfigurationList = F0F9520C1A6AEB1100254160 /* Build configuration list for PBXNativeTarget "linphoneTests" */; buildPhases = ( F0F951FC1A6AEB1000254160 /* Sources */, F0F951FD1A6AEB1000254160 /* Frameworks */, @@ -3152,12 +2784,12 @@ buildRules = ( ); dependencies = ( - F0C773911A94827E00E0C486 /* PBXTargetDependency */, + 63058A4E1B4E832500EFAE36 /* PBXTargetDependency */, F0F952071A6AEB1000254160 /* PBXTargetDependency */, ); - name = KifTests; + name = linphoneTests; productName = KifTests; - productReference = F0F952001A6AEB1000254160 /* KifTests.xctest */; + productReference = F0F952001A6AEB1000254160 /* linphoneTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ @@ -3166,10 +2798,15 @@ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0610; + LastUpgradeCheck = 0720; TargetAttributes = { 1D6058900D05DD3D006BFB54 = { DevelopmentTeam = Z2V957B3D6; + SystemCapabilities = { + com.apple.InAppPurchase = { + enabled = 0; + }; + }; }; F08F118319C09C6A007D70C2 = { DevelopmentTeam = Z2V957B3D6; @@ -3199,17 +2836,17 @@ ru, Base, ar, + de, + ja, + nl, + zh_TW, ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectReferences = ( { - ProductGroup = F0C7737E1A94822600E0C486 /* Products */; - ProjectRef = F0C7737D1A94822600E0C486 /* KIF.xcodeproj */; - }, - { - ProductGroup = D3B90E1215C2CB5700F64F8C /* Products */; - ProjectRef = D3B90E1115C2CB5700F64F8C /* NinePatch.xcodeproj */; + ProductGroup = 630589F31B4E816900EFAE36 /* Products */; + ProjectRef = 630589F21B4E816900EFAE36 /* KIF.xcodeproj */; }, { ProductGroup = D3554EC615CA79A900478841 /* Products */; @@ -3219,14 +2856,42 @@ projectRoot = ""; targets = ( 1D6058900D05DD3D006BFB54 /* linphone */, - F0BB8BD41936208100974404 /* LinphoneTester */, - F08F118319C09C6A007D70C2 /* LinphoneTester Tests */, - F0F951FF1A6AEB1000254160 /* KifTests */, + F0F951FF1A6AEB1000254160 /* linphoneTests */, + F0BB8BD41936208100974404 /* liblinphoneTester */, + F08F118319C09C6A007D70C2 /* liblinphoneTesterTests */, ); }; /* End PBXProject section */ /* Begin PBXReferenceProxy section */ + 630589FD1B4E816A00EFAE36 /* libKIF.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libKIF.a; + remoteRef = 630589FC1B4E816A00EFAE36 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 63058A011B4E816A00EFAE36 /* Test Host.app */ = { + isa = PBXReferenceProxy; + fileType = wrapper.application; + path = "Test Host.app"; + remoteRef = 63058A001B4E816A00EFAE36 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 63058A031B4E816A00EFAE36 /* KIF Tests - XCTest.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "KIF Tests - XCTest.xctest"; + remoteRef = 63058A021B4E816A00EFAE36 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 63058A071B4E816A00EFAE36 /* KIF.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = KIF.framework; + remoteRef = 63058A061B4E816A00EFAE36 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; D3554ED115CA79AA00478841 /* libXMLRPC.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -3234,48 +2899,6 @@ remoteRef = D3554ED015CA79AA00478841 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - D3B90E1915C2CB5800F64F8C /* libNinePatch.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libNinePatch.a; - remoteRef = D3B90E1815C2CB5800F64F8C /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F0C773871A94822700E0C486 /* libKIF.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libKIF.a; - remoteRef = F0C773861A94822700E0C486 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F0C773891A94822700E0C486 /* libKIF-OCUnit.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libKIF-OCUnit.a"; - remoteRef = F0C773881A94822700E0C486 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F0C7738B1A94822700E0C486 /* Test Host.app */ = { - isa = PBXReferenceProxy; - fileType = wrapper.application; - path = "Test Host.app"; - remoteRef = F0C7738A1A94822700E0C486 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F0C7738D1A94822700E0C486 /* KIF Tests - XCTest.xctest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = "KIF Tests - XCTest.xctest"; - remoteRef = F0C7738C1A94822700E0C486 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F0C7738F1A94822700E0C486 /* KIF Tests-OCUnit.octest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = "KIF Tests-OCUnit.octest"; - remoteRef = F0C7738E1A94822700E0C486 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ @@ -3283,546 +2906,429 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 22F254811073D99800AC9B3F /* ringback.wav in Resources */, - 2237D4091084D7A9001383EE /* ring.wav in Resources */, - 225CB2FA11ABB76400628906 /* linphone-banner.png in Resources */, - 636316D11A1DEBCB0009B839 /* AboutViewController.xib in Resources */, - 2242E313125235120061DDCE /* ring.caf in Resources */, - D38187C915FE346400C3EDCA /* FirstLoginViewController.xib in Resources */, - 2214783D1386A2030020F8B8 /* Localizable.strings in Resources */, - 70571E1A13FABCB000CDD3C2 /* rootca.pem in Resources */, - D347347E1580E5F8003C7B8C /* history_default.png in Resources */, - D347347F1580E5F8003C7B8C /* history_selected.png in Resources */, - D38327F31580FE3A00FA0D23 /* contacts_default.png in Resources */, - D38327F41580FE3A00FA0D23 /* contacts_selected.png in Resources */, - D38327F51580FE3A00FA0D23 /* dialer_default.png in Resources */, - D38327F61580FE3A00FA0D23 /* dialer_over.png in Resources */, - D38327F71580FE3A00FA0D23 /* settings_default.png in Resources */, - D38327F81580FE3A00FA0D23 /* settings_selected.png in Resources */, - D38327F91580FE3A00FA0D23 /* chat_default.png in Resources */, - D38327FA1580FE3A00FA0D23 /* chat_selected.png in Resources */, - D3832800158100E400FA0D23 /* contacts_over.png in Resources */, - D3832801158100E400FA0D23 /* history_over.png in Resources */, - D3832802158100E400FA0D23 /* settings_over.png in Resources */, - D3832803158100E400FA0D23 /* chat_over.png in Resources */, - D3F83F0C158205A100336684 /* micro_off_default.png in Resources */, - D3F83F0E158205A100336684 /* micro_off_over.png in Resources */, - D3F83F10158205A100336684 /* micro_on_default.png in Resources */, - D3F83F12158205A100336684 /* micro_on_over.png in Resources */, - D3F83F14158205A100336684 /* pause_off_default.png in Resources */, - D3F83F16158205A100336684 /* pause_off_over.png in Resources */, - D3F83F18158205A100336684 /* hangup_default.png in Resources */, - D3F83F1A158205A100336684 /* hangup_over.png in Resources */, - F0C1F9151A28781F009402C9 /* strech-bottom.png in Resources */, - D3F83F1C158205A100336684 /* speaker_off_default.png in Resources */, - D3F83F1E158205A100336684 /* speaker_off_over.png in Resources */, - D3F83F20158205A100336684 /* speaker_on_default.png in Resources */, - D3F83F22158205A100336684 /* speaker_on_over.png in Resources */, - F01A77EB18ED989B00E287CA /* shortring.caf in Resources */, - D3F83F24158205A100336684 /* video_off_default.png in Resources */, - D3F83F26158205A100336684 /* video_off_over.png in Resources */, - D3F83F28158205A100336684 /* video_on_default.png in Resources */, - D3F83F2A158205A100336684 /* video_on_over.png in Resources */, - D3F83F441582223B00336684 /* numpad_zero_default.png in Resources */, - D3F83F461582223B00336684 /* numpad_zero_over.png in Resources */, - D3F83F481582223B00336684 /* numpad_one_default.png in Resources */, - D3F83F4A1582223B00336684 /* numpad_one_over.png in Resources */, - D3F83F4C1582223B00336684 /* numpad_two_default.png in Resources */, - D3F83F4E1582223B00336684 /* numpad_two_over.png in Resources */, - D3F83F501582223B00336684 /* numpad_three_default.png in Resources */, - D3F83F521582223B00336684 /* numpad_three_over.png in Resources */, - D3F83F541582223B00336684 /* numpad_four_default.png in Resources */, - D3F83F561582223B00336684 /* numpad_four_over.png in Resources */, - D3F83F581582223B00336684 /* numpad_five_default.png in Resources */, - D3F83F5A1582223B00336684 /* numpad_five_over.png in Resources */, - D3F83F5C1582223B00336684 /* numpad_six_default.png in Resources */, - 636316D91A1DECC90009B839 /* PhoneMainView.xib in Resources */, - D3F83F5E1582223B00336684 /* numpad_six_over.png in Resources */, - D3F83F601582223B00336684 /* numpad_seven_default.png in Resources */, - D3F83F621582223B00336684 /* numpad_seven_over.png in Resources */, - D3F83F641582223B00336684 /* numpad_eight_default.png in Resources */, - D3F83F661582223B00336684 /* numpad_eight_over.png in Resources */, - D3F83F681582223B00336684 /* numpad_nine_default.png in Resources */, - D3F83F6A1582223B00336684 /* numpad_nine_over.png in Resources */, - D3F83F6C1582223B00336684 /* numpad_sharp_default.png in Resources */, - D3F83F6E1582223B00336684 /* numpad_sharp_over.png in Resources */, - D3F83F721582223B00336684 /* numpad_star_default.png in Resources */, - D3F83F781582253100336684 /* accept_default.png in Resources */, - D3F83F7A1582253100336684 /* accept_over.png in Resources */, - D3F83F7C1582253100336684 /* decline_default.png in Resources */, - F0B4FB5D1A65550B00637027 /* Images.xcassets in Resources */, - D3F83F7E1582253100336684 /* decline_over.png in Resources */, - D3ED3E411585FB4A006C0DE4 /* background.png in Resources */, - D3ED3E451585FB8C006C0DE4 /* dialer_address_background.png in Resources */, - D3ED3E521585FFFD006C0DE4 /* statebar_background.png in Resources */, - F070E6381A2622EC00E17AFD /* incall_padding_right.png in Resources */, - D3ED3E6A15861A53006C0DE4 /* add_contact_default.png in Resources */, - D3ED3E6C15861A53006C0DE4 /* add_contact_disabled.png in Resources */, - D3ED3E6E15861A53006C0DE4 /* add_contact_over.png in Resources */, - D3ED3E7215861ABD006C0DE4 /* call_default.png in Resources */, - D3ED3E7415861ABD006C0DE4 /* call_over.png in Resources */, - D3ED3E7815861B1B006C0DE4 /* backspace_default.png in Resources */, - D3ED3E7A15861B1B006C0DE4 /* backspace_over.png in Resources */, - D38187F815FE355D00C3EDCA /* UIMainBar.xib in Resources */, - D3ED3E9815872EF1006C0DE4 /* history_all_selected.png in Resources */, - D3ED3E9A15872EF1006C0DE4 /* history_all_default.png in Resources */, - D3ED3E9C15872EF1006C0DE4 /* history_edit_default.png in Resources */, - D3ED3E9E15872EF1006C0DE4 /* history_edit_over.png in Resources */, - D3ED3EA015872EF1006C0DE4 /* history_missed_selected.png in Resources */, - D3ED3EA215872EF1006C0DE4 /* history_missed_default.png in Resources */, - D38187D115FE346B00C3EDCA /* HistoryViewController.xib in Resources */, - D38187BD15FE342800C3EDCA /* ContactsViewController.xib in Resources */, - D354980615875534000081D8 /* contacts_all_selected.png in Resources */, - D354980815875534000081D8 /* contacts_all_default.png in Resources */, - D354980A15875534000081D8 /* contacts_linphone_selected.png in Resources */, - D354980C15875534000081D8 /* contacts_linphone_default.png in Resources */, - F0B89C2E18DC973E0050B60E /* wizard_remote.rc in Resources */, - D354981015875608000081D8 /* contacts_add_default.png in Resources */, - D354981215875608000081D8 /* contacts_add_over.png in Resources */, - D354981A15876FE7000081D8 /* list_details_default.png in Resources */, - F0C1F9131A28781F009402C9 /* corner-right-top.png in Resources */, - D354981C15876FE7000081D8 /* list_details_over.png in Resources */, - 639CEAFD1A1DF4D9004DE38F /* UIStateBar.xib in Resources */, + 636B983A1C298401003BA37C /* camera_switch_over.png in Resources */, + 636B98941C298401003BA37C /* footer_chat_default.png in Resources */, + 636B98631C298401003BA37C /* color_I.png in Resources */, + 636B98C71C298401003BA37C /* micro_disabled@2x.png in Resources */, + 636B980A1C298401003BA37C /* call_hangup_disabled.png in Resources */, + 636B986B1C298401003BA37C /* contact_add_default@2x.png in Resources */, + 636B97EE1C298401003BA37C /* backspace_default.png in Resources */, + 636B99041C298401003BA37C /* options_selected@2x.png in Resources */, + 636B98BB1C298401003BA37C /* linphone_logo@2x.png in Resources */, + 636B99171C298401003BA37C /* pause_small_over_selected.png in Resources */, + 636B98831C298401003BA37C /* deselect_all@2x.png in Resources */, + 636B98951C298401003BA37C /* footer_chat_default@2x.png in Resources */, + 636316D11A1DEBCB0009B839 /* AboutView.xib in Resources */, + 636B980E1C298401003BA37C /* call_missed.png in Resources */, + 636B980C1C298401003BA37C /* call_incoming.png in Resources */, + 638F1A621C2021B2004B8E02 /* DialerView~ipad.xib in Resources */, + 636B98931C298401003BA37C /* edit_list_disabled@2x.png in Resources */, + 636B98961C298401003BA37C /* footer_chat_disabled.png in Resources */, + 63AADBF31B6A0FF200AA16FD /* licenses.html in Resources */, + 636B980B1C298401003BA37C /* call_hangup_disabled@2x.png in Resources */, + 636B98981C298401003BA37C /* footer_contacts_default.png in Resources */, + 636B98741C298401003BA37C /* contacts_sip_default.png in Resources */, + 636B988B1C298401003BA37C /* dialer_background@2x.png in Resources */, + 63AADBFF1B6A0FF200AA16FD /* assistant_external_sip.rc in Resources */, + 636B98081C298401003BA37C /* call_hangup_default.png in Resources */, + 636B98881C298401003BA37C /* dialer_back_disabled.png in Resources */, + 634610121B6140A500548952 /* CallOutgoingView.xib in Resources */, + 636B98C31C298401003BA37C /* menu@2x.png in Resources */, + D38187F815FE355D00C3EDCA /* TabBarView.xib in Resources */, + 636B987A1C298401003BA37C /* delete_default.png in Resources */, + 636B98AA1C298401003BA37C /* history_chat_indicator.png in Resources */, + 636B98251C298401003BA37C /* call_status_missed@2x.png in Resources */, + 636B98F21C298401003BA37C /* numpad_hash_default.png in Resources */, + 636B98211C298401003BA37C /* call_start_body_over@2x.png in Resources */, + 636B990E1C298401003BA37C /* pause_big_default@2x.png in Resources */, + 636B98841C298401003BA37C /* dialer_alt_back.png in Resources */, + 636B97F11C298401003BA37C /* backspace_disabled@2x.png in Resources */, + 636B99101C298401003BA37C /* pause_big_disabled@2x.png in Resources */, + 636B98AB1C298401003BA37C /* history_chat_indicator@2x.png in Resources */, + 636B981A1C298401003BA37C /* call_quality_indicator_4.png in Resources */, + 636B984C1C298401003BA37C /* chat_send_default.png in Resources */, + D38187D115FE346B00C3EDCA /* HistoryListView.xib in Resources */, + D38187BD15FE342800C3EDCA /* ContactsListView.xib in Resources */, + 636B98611C298401003BA37C /* color_G.png in Resources */, + 636B98C91C298401003BA37C /* micro_selected@2x.png in Resources */, + 636B97ED1C298401003BA37C /* back_disabled@2x.png in Resources */, + 636B98031C298401003BA37C /* call_audio_start_disabled@2x.png in Resources */, + 636B99301C298401003BA37C /* routes_selected@2x.png in Resources */, + 636B98861C298401003BA37C /* dialer_back_default.png in Resources */, + 639E9CB01C0DB83000019A75 /* SideMenuView.xib in Resources */, + 636B98B11C298401003BA37C /* history_missed_selected@2x.png in Resources */, + 639E9CB51C0DB88200019A75 /* PhoneMainView.xib in Resources */, + 636B991E1C298401003BA37C /* route_bluetooth_selected@2x.png in Resources */, + 636B987E1C298401003BA37C /* delete_field_default.png in Resources */, + 636B99381C298401003BA37C /* select_all_default@2x.png in Resources */, + 636B98011C298401003BA37C /* call_audio_start_default@2x.png in Resources */, + 636B99471C298401003BA37C /* voicemail.png in Resources */, + 636B98481C298401003BA37C /* chat_attachment_over.png in Resources */, + 636B982E1C298401003BA37C /* call_video_start_disabled.png in Resources */, + 636B987F1C298401003BA37C /* delete_field_default@2x.png in Resources */, + 636B990C1C298401003BA37C /* options_transfer_call_disabled@2x.png in Resources */, + 6352A5761BE0D4B800594C1C /* CallSideMenuView.xib in Resources */, + 636B98F11C298401003BA37C /* numpad_9_over@2x.png in Resources */, + 636B99391C298401003BA37C /* select_all_disabled.png in Resources */, + 636B98471C298401003BA37C /* chat_attachment_disabled@2x.png in Resources */, + 636B97FC1C298401003BA37C /* call_alt_start_default.png in Resources */, + 636B98321C298401003BA37C /* camera_disabled.png in Resources */, + 63CDC4611C3BDE370085F529 /* house_keeping.caf in Resources */, + 636B97E41C298401003BA37C /* add_field_default.png in Resources */, + 636B98F31C298401003BA37C /* numpad_hash_default@2x.png in Resources */, + 636B98601C298401003BA37C /* color_F.png in Resources */, + 636B99021C298401003BA37C /* options_disabled@2x.png in Resources */, + 636B99491C298401003BA37C /* waiting_time.png in Resources */, + 636B98121C298401003BA37C /* call_quality_indicator_0.png in Resources */, + 639E9C931C0DB7BE00019A75 /* FirstLoginView.xib in Resources */, + 636B98D51C298401003BA37C /* numpad_2_over@2x.png in Resources */, + 639CEAFD1A1DF4D9004DE38F /* StatusBarView.xib in Resources */, + 636B98221C298401003BA37C /* call_status_incoming.png in Resources */, + 636B983F1C298401003BA37C /* cancel_edit_disabled@2x.png in Resources */, + 63CDC4641C3BDE370085F529 /* notes_of_the_optimistic.caf in Resources */, + 63CDC4621C3BDE370085F529 /* it_s_a_game.caf in Resources */, + 636B98541C298401003BA37C /* chat_start_body_disabled.png in Resources */, + 636B97F31C298401003BA37C /* backspace_over@2x.png in Resources */, + 636B98351C298401003BA37C /* camera_selected@2x.png in Resources */, + 639E9CAC1C0DB80300019A75 /* UIContactDetailsCell.xib in Resources */, + 636B98761C298401003BA37C /* contacts_sip_disabled.png in Resources */, F088488A19FF8C41007FFCF3 /* UIContactCell.xib in Resources */, - D38187E115FE349700C3EDCA /* UICallBar.xib in Resources */, - D31C9C90158A1C1000756B45 /* call_status_incoming.png in Resources */, - D31C9C92158A1C1000756B45 /* call_status_missed.png in Resources */, - D31C9C94158A1C1000756B45 /* call_status_outgoing.png in Resources */, + 63130FB21C1ED06900371918 /* SideMenuView~ipad.xib in Resources */, + 636B98821C298401003BA37C /* deselect_all.png in Resources */, + 636B98291C298401003BA37C /* call_transfer_default@2x.png in Resources */, + 636B98671C298401003BA37C /* conference_exit_default@2x.png in Resources */, + 636B98061C298401003BA37C /* call_back_disabled.png in Resources */, + 636B98871C298401003BA37C /* dialer_back_default@2x.png in Resources */, + 636B98921C298401003BA37C /* edit_list_disabled.png in Resources */, + 636B98791C298401003BA37C /* contacts_sip_selected@2x.png in Resources */, + 636B98DE1C298401003BA37C /* numpad_5_default.png in Resources */, + 636B99281C298401003BA37C /* route_speaker_disabled@2x.png in Resources */, + 636B98A01C298401003BA37C /* footer_history_default.png in Resources */, + 63CDC4661C3BDE370085F529 /* shortring.caf in Resources */, + 636B98381C298401003BA37C /* camera_switch_disabled.png in Resources */, 639CEB001A1DF4E4004DE38F /* UIHistoryCell.xib in Resources */, - D3432A62158A4446001C6B0B /* led_connected.png in Resources */, - D3432A64158A4446001C6B0B /* led_error.png in Resources */, - D3432A66158A4446001C6B0B /* call_quality_indicator_0.png in Resources */, - D3432A68158A4446001C6B0B /* call_quality_indicator_1.png in Resources */, - D3432A6A158A4446001C6B0B /* call_quality_indicator_2.png in Resources */, - D3432A6C158A4446001C6B0B /* call_quality_indicator_3.png in Resources */, - D3432A71158A45AF001C6B0B /* led_inprogress.png in Resources */, - D3432A73158A45AF001C6B0B /* led_disconnected.png in Resources */, - D37295DB158B3C9600D2C0C7 /* video_off_disabled.png in Resources */, - D36C43D1158F2F370048BA40 /* cell_call.png in Resources */, - D36C43D3158F2F370048BA40 /* cell_conference.png in Resources */, - D36C43D5158F2F370048BA40 /* header_conference.png in Resources */, - D36C43D7158F2F370048BA40 /* dialer_alt_default.png in Resources */, - D36C43D9158F2F370048BA40 /* dialer_alt_over.png in Resources */, - D36C43E9158F3F7E0048BA40 /* pause_on_default.png in Resources */, - F0C1F9121A28781F009402C9 /* corner-right-bottom.png in Resources */, - D36C43EB158F3F7E0048BA40 /* pause_on_over.png in Resources */, - D36C43F1158F61EA0048BA40 /* call_state_pause_default.png in Resources */, - D36C43F3158F61EA0048BA40 /* call_state_pause_over.png in Resources */, - D36C43F5158F61EA0048BA40 /* call_state_play_default.png in Resources */, - D36C43F7158F61EA0048BA40 /* call_state_play_over.png in Resources */, - D35E757815931E5D0066B1C1 /* switch_camera_default.png in Resources */, - D35E757A15931E5D0066B1C1 /* switch_camera_over.png in Resources */, - D35E758915932DE60066B1C1 /* backspace_disabled.png in Resources */, - D35E758D15934F360066B1C1 /* call_disabled.png in Resources */, - D38187B115FE340500C3EDCA /* ChatViewController.xib in Resources */, - 636316D41A1DEC650009B839 /* SettingsViewController.xib in Resources */, + 636B981B1C298401003BA37C /* call_quality_indicator_4@2x.png in Resources */, + 639E9CA31C0DB7EA00019A75 /* UIChatBubbleTextCell.xib in Resources */, + 636B98661C298401003BA37C /* conference_exit_default.png in Resources */, + D38187B115FE340500C3EDCA /* ChatsListView.xib in Resources */, + 636B99161C298401003BA37C /* pause_small_disabled@2x.png in Resources */, + 636B983B1C298401003BA37C /* camera_switch_over@2x.png in Resources */, + 636B982A1C298401003BA37C /* call_transfer_disabled.png in Resources */, + 636B98EE1C298401003BA37C /* numpad_9_default.png in Resources */, + 636B99071C298401003BA37C /* options_start_conference_disabled.png in Resources */, + 636B98E61C298401003BA37C /* numpad_7_default.png in Resources */, + 636B99351C298401003BA37C /* security_pending.png in Resources */, + 636B98DB1C298401003BA37C /* numpad_4_default@2x.png in Resources */, + 636B99421C298401003BA37C /* splashscreen@2x.png in Resources */, + 636B98181C298401003BA37C /* call_quality_indicator_3.png in Resources */, + 636B99011C298401003BA37C /* options_disabled.png in Resources */, + 636B989A1C298401003BA37C /* footer_contacts_disabled.png in Resources */, + 636B994A1C298401003BA37C /* waiting_time@2x.png in Resources */, + 636B97F51C298401003BA37C /* call_add_default@2x.png in Resources */, + 639E9C9D1C0DB7DF00019A75 /* UICallPausedCell.xib in Resources */, + 636B98C81C298401003BA37C /* micro_selected.png in Resources */, + 636B98911C298401003BA37C /* edit_list_default@2x.png in Resources */, + 636B981F1C298401003BA37C /* call_start_body_disabled@2x.png in Resources */, + 636B97EA1C298401003BA37C /* back_default.png in Resources */, + 636B98781C298401003BA37C /* contacts_sip_selected.png in Resources */, + 636B98801C298401003BA37C /* delete_field_over.png in Resources */, + 636B99031C298401003BA37C /* options_selected.png in Resources */, + 636B98D01C298401003BA37C /* numpad_1_over.png in Resources */, + 636B97F21C298401003BA37C /* backspace_over.png in Resources */, + 636B97EB1C298401003BA37C /* back_default@2x.png in Resources */, + 636B99181C298401003BA37C /* pause_small_over_selected@2x.png in Resources */, + 636B98C01C298401003BA37C /* list_details_over.png in Resources */, + 636B993C1C298401003BA37C /* speaker_default@2x.png in Resources */, + 636B99091C298401003BA37C /* options_transfer_call_default.png in Resources */, + 638F1A911C21993D004B8E02 /* UICompositeView~ipad.xib in Resources */, + 636B98451C298401003BA37C /* chat_attachment_default@2x.png in Resources */, + 636B98ED1C298401003BA37C /* numpad_8_over@2x.png in Resources */, + 636B97E71C298401003BA37C /* add_field_over@2x.png in Resources */, + 636B98521C298401003BA37C /* chat_start_body_default.png in Resources */, + 636B991C1C298401003BA37C /* route_bluetooth_disabled@2x.png in Resources */, + 636B98771C298401003BA37C /* contacts_sip_disabled@2x.png in Resources */, + 63AADC011B6A0FF200AA16FD /* assistant_linphone_existing.rc in Resources */, + 636B98171C298401003BA37C /* call_quality_indicator_2@2x.png in Resources */, + 636B98021C298401003BA37C /* call_audio_start_disabled.png in Resources */, + 636B985D1C298401003BA37C /* color_C.png in Resources */, + 636316D41A1DEC650009B839 /* SettingsView.xib in Resources */, + 636B98131C298401003BA37C /* call_quality_indicator_0@2x.png in Resources */, + 636B99251C298401003BA37C /* route_speaker_default.png in Resources */, + 63CDC4651C3BDE370085F529 /* soft_as_snow.caf in Resources */, + 636B98421C298401003BA37C /* chat_add_disabled.png in Resources */, + 636B98D11C298401003BA37C /* numpad_1_over@2x.png in Resources */, + 636B981C1C298401003BA37C /* call_start_body_default.png in Resources */, + 636B98C11C298401003BA37C /* list_details_over@2x.png in Resources */, + 636B98D91C298401003BA37C /* numpad_3_over@2x.png in Resources */, + 636B98531C298401003BA37C /* chat_start_body_default@2x.png in Resources */, D34F6F9E1594D3FB0095705B /* InAppSettings.bundle in Resources */, - D3EA5403159852080037DC6B /* chat_edit_default.png in Resources */, - F0C1F9161A28781F009402C9 /* strech-top.png in Resources */, - D3EA5405159852080037DC6B /* chat_edit_over.png in Resources */, - D3EA5407159852080037DC6B /* chat_add_default.png in Resources */, - D3EA5409159852080037DC6B /* chat_add_over.png in Resources */, + 636B98711C298401003BA37C /* contacts_all_disabled@2x.png in Resources */, + 636B983E1C298401003BA37C /* cancel_edit_disabled.png in Resources */, + 636B98C41C298401003BA37C /* micro_default.png in Resources */, + 636B98651C298401003BA37C /* color_M.png in Resources */, + 636B98BA1C298401003BA37C /* linphone_logo.png in Resources */, + 636B98571C298401003BA37C /* chat_start_body_over@2x.png in Resources */, + 636B98621C298401003BA37C /* color_H.png in Resources */, + 636B982C1C298401003BA37C /* call_video_start_default.png in Resources */, 639CEB091A1DF4FA004DE38F /* UIChatCell.xib in Resources */, - D3EA5418159858A80037DC6B /* list_delete_default.png in Resources */, - F070E6351A2622EC00E17AFD /* incall_padding_left_landscape.png in Resources */, - D3EA541A159858A80037DC6B /* list_delete_over.png in Resources */, - D38187D915FE347700C3EDCA /* IncomingCallViewController.xib in Resources */, - F0C1F90E1A28781F009402C9 /* background-launch.png in Resources */, - D3F26BF715986DAD005F9CAB /* history_ok_default.png in Resources */, - D3F26BF915986DAD005F9CAB /* history_ok_over.png in Resources */, - D3F26BFC15987083005F9CAB /* header_incoming.png in Resources */, - 639CEB031A1DF4EB004DE38F /* UICompositeViewController.xib in Resources */, - D31B4B281598A390002E6C72 /* avatar_unknown.png in Resources */, - D31B4B2A1598A390002E6C72 /* avatar_unknown_small.png in Resources */, - D3F34F301599B008005BE94F /* avatar_shadow.png in Resources */, - D3D6A39E159B0EEF005F692C /* add_call_default.png in Resources */, - D3D6A3A0159B0EEF005F692C /* add_call_disabled.png in Resources */, - D3D6A3A2159B0EEF005F692C /* add_call_over.png in Resources */, - D3D6A3AB159B0EFE005F692C /* security_ko.png in Resources */, - D3D6A3AD159B0EFE005F692C /* security_pending.png in Resources */, - D3D6A3AF159B0EFE005F692C /* security_ok.png in Resources */, - D3D6A3B1159B0EFE005F692C /* options_default.png in Resources */, - D3D6A3B3159B0EFE005F692C /* options_disabled.png in Resources */, - D3D6A3B5159B0EFE005F692C /* options_over.png in Resources */, - D31AAF63159B5B6F002C6B02 /* conference_default.png in Resources */, - D31AAF65159B5B6F002C6B02 /* conference_over.png in Resources */, - D31AAF6E159B65E1002C6B02 /* call_state_ringing_default.png in Resources */, - D3211BA6159C3D410098460B /* call_state_outgoing_default.png in Resources */, - D38187F015FE354000C3EDCA /* UIConferenceHeader.xib in Resources */, - D3211BB9159C8A820098460B /* cell_call_first.png in Resources */, - D3211BBE159CBFD60098460B /* back_default.png in Resources */, - D3211BC0159CBFD70098460B /* back_disabled.png in Resources */, - D3211BC2159CBFD70098460B /* back_over.png in Resources */, - D3C714B3159DB84400705B8E /* hold.wav in Resources */, - D377BBFA15A19DA6002B696B /* video_on_disabled.png in Resources */, - D37B96B715A1A6F20005CCD2 /* call_state_delete_default.png in Resources */, - D37B96B915A1A6F20005CCD2 /* call_state_delete_over.png in Resources */, - D3C2814B15A2D38D0098AA42 /* dialer_selected.png in Resources */, - D3C2815215A2D64A0098AA42 /* numpad_star_over.png in Resources */, - D365AA7B15A2DE7500CAFE3F /* speaker_off_disabled.png in Resources */, - D365AA7D15A2DE7500CAFE3F /* speaker_on_disabled.png in Resources */, - D35EA76315A2DF8D003E025D /* micro_off_disabled.png in Resources */, - D35EA76515A2DF8D003E025D /* micro_on_disabled.png in Resources */, - D38D14AF15A30B3D008497E8 /* cell_call_first_highlight.png in Resources */, - D38D14B115A30B3D008497E8 /* cell_call_highlight.png in Resources */, - D3196D3415A321E3007FEEBA /* options_add_default.png in Resources */, - D3196D3615A321E3007FEEBA /* options_add_over.png in Resources */, - D3196D3815A321E3007FEEBA /* options_transfer_default.png in Resources */, - D3196D3A15A321E3007FEEBA /* options_transfer_over.png in Resources */, - D38187DD15FE348A00C3EDCA /* WizardViewController.xib in Resources */, - D350F21C15A43D3400149E54 /* setup_back_default.png in Resources */, - D350F21E15A43D3400149E54 /* setup_back_over.png in Resources */, - D350F22015A43D3400149E54 /* setup_cancel_default.png in Resources */, - D350F22215A43D3400149E54 /* setup_cancel_over.png in Resources */, - D350F22415A43D3400149E54 /* field_background.png in Resources */, - D350F22615A43D3400149E54 /* setup_start_default.png in Resources */, - D350F22815A43D3400149E54 /* setup_start_over.png in Resources */, - D350F22C15A43D3400149E54 /* setup_welcome_logo.png in Resources */, - D35406F715A47E9E007E7E81 /* button_background_default.png in Resources */, - D35406F915A47E9E007E7E81 /* button_background_over.png in Resources */, - D38187AD15FE340100C3EDCA /* ChatRoomViewController.xib in Resources */, - D3F795DD15A5831C0077328B /* chat_back_default.png in Resources */, - D3F795DF15A5831C0077328B /* chat_back_over.png in Resources */, - D3B9A3E115A58C450096EA4E /* chat_ok_default.png in Resources */, - D3B9A3E315A58C450096EA4E /* chat_ok_over.png in Resources */, - D3B9A3E515A58C450096EA4E /* chat_send_default.png in Resources */, - D3B9A3E715A58C450096EA4E /* chat_send_over.png in Resources */, - D32B6E2415A5B2020033019F /* chat_send_disabled.png in Resources */, - 639CEB061A1DF4F1004DE38F /* UIChatRoomCell.xib in Resources */, - D3A8BB7B15A6CC3200F96BE5 /* chat_bubble_outgoing.png in Resources */, - D3A8BB7D15A6CC3200F96BE5 /* chat_bubble_incoming.png in Resources */, - F0C1F9101A28781F009402C9 /* corner-left-bottom.png in Resources */, - D3A8BB7F15A6CC3200F96BE5 /* setup_back_disabled.png in Resources */, - D3A8BB8115A6CC3200F96BE5 /* setup_cancel_disabled.png in Resources */, - D3A8BB8315A6CC3200F96BE5 /* setup_start_disabled.png in Resources */, - D389363915A6D53200A3A3AA /* chat_bubble_incoming.9.png in Resources */, - D389363B15A6D53200A3A3AA /* chat_bubble_outgoing.9.png in Resources */, - D3D14E7C15A711700074A527 /* avatar_shadow_small.png in Resources */, - D38187B915FE342200C3EDCA /* ContactDetailsViewController.xib in Resources */, - D3128FEF15AABE4E00A2147A /* contact_back_default.png in Resources */, - D3128FF115AABE4E00A2147A /* contact_back_over.png in Resources */, - D3128FF315AABE4E00A2147A /* contact_edit_default.png in Resources */, - D3128FF515AABE4E00A2147A /* contact_edit_over.png in Resources */, - D37C638E15AAD251009D0BAC /* contact_number_over.png in Resources */, - D37C639015AAD251009D0BAC /* contact_number.png in Resources */, - D381881515FE3F7F00C3EDCA /* UIContactDetailsHeader.xib in Resources */, - D3C6526B15AC228A0092A874 /* contact_ok_default.png in Resources */, - D3C6526D15AC228A0092A874 /* contact_ok_over.png in Resources */, - D38187B515FE341B00C3EDCA /* ContactDetailsLabelViewController.xib in Resources */, - D38187F415FE354700C3EDCA /* UIContactDetailsFooter.xib in Resources */, - D32D5AA715ADE5D9008593F3 /* button_alert_background_default.png in Resources */, - D32D5AA915ADE5D9008593F3 /* button_alert_background_over.png in Resources */, - C9C8254315AE204D00D493FA /* options_add_disabled.png in Resources */, - C9C8254515AE204D00D493FA /* options_transfer_disabled.png in Resources */, - C9C8254715AE204D00D493FA /* transfer_call_default.png in Resources */, - C9C8254915AE204D00D493FA /* transfer_call_over.png in Resources */, - C9C8254C15AE207B00D493FA /* options_selected.png in Resources */, - C9C8254F15AE256100D493FA /* transfer_call_disabled.png in Resources */, - D38187CD15FE346700C3EDCA /* HistoryDetailsViewController.xib in Resources */, - D3F9A9DB15AEEB940045320F /* history_notification.png in Resources */, - D3E84F1E15B00F4100420DAC /* cancel_default.png in Resources */, - D3E84F2015B00F4100420DAC /* cancel_over.png in Resources */, - D3E84F2615B00F4100420DAC /* dialer_alt_back_default.png in Resources */, - D3E84F2815B00F4100420DAC /* dialer_alt_back_over.png in Resources */, - D3E84F2A15B00F4100420DAC /* dialer_alt_background.png in Resources */, - D3E84F3815B011AF00420DAC /* contact_cancel_default.png in Resources */, - D3E84F3A15B011AF00420DAC /* contact_cancel_over.png in Resources */, - D3157A8A15B4466F00DD8C4C /* history_details_add_default.png in Resources */, - D3157A8C15B4466F00DD8C4C /* history_details_add_over.png in Resources */, - D3157A9015B446CB00DD8C4C /* history_details_back_default.png in Resources */, - D3157A9215B446CB00DD8C4C /* history_details_back_over.png in Resources */, - D3119E7215B6A4710005D4A4 /* contacts_back_default.png in Resources */, - D3119E7415B6A4710005D4A4 /* contacts_back_over.png in Resources */, - D3C31A3215BD8DED008ED271 /* conference_default_landscape.png in Resources */, - D3C31A3415BD8DED008ED271 /* conference_over_landscape.png in Resources */, - D3C31A3615BD8DED008ED271 /* dialer_alt_back_default_landscape.png in Resources */, - D3C31A3815BD8DED008ED271 /* dialer_alt_back_over_landscape.png in Resources */, - D3C31A3A15BD8DED008ED271 /* dialer_alt_default_landscape.png in Resources */, - D3C31A3C15BD8DED008ED271 /* dialer_alt_over_landscape.png in Resources */, - D3C31A3E15BD8DED008ED271 /* hangup_default_landscape.png in Resources */, - D3C31A4015BD8DED008ED271 /* hangup_over_landscape.png in Resources */, - D3C31A4215BD8DED008ED271 /* micro_off_default_landscape.png in Resources */, - D3C31A4415BD8DED008ED271 /* micro_off_disabled_landscape.png in Resources */, - D3C31A4615BD8DED008ED271 /* micro_off_over_landscape.png in Resources */, - D3C31A4815BD8DED008ED271 /* micro_on_default_landscape.png in Resources */, - D3C31A4A15BD8DED008ED271 /* micro_on_disabled_landscape.png in Resources */, - D3C31A4C15BD8DED008ED271 /* micro_on_over_landscape.png in Resources */, - D3C31A4E15BD8DED008ED271 /* options_add_default_landscape.png in Resources */, - D3C31A5015BD8DED008ED271 /* options_add_disabled_landscape.png in Resources */, - D3C31A5215BD8DED008ED271 /* options_add_over_landscape.png in Resources */, - D3C31A5415BD8DED008ED271 /* options_default_landscape.png in Resources */, - D3C31A5615BD8DED008ED271 /* options_disabled_landscape.png in Resources */, - D3C31A5815BD8DED008ED271 /* options_over_landscape.png in Resources */, - D3C31A5A15BD8DED008ED271 /* options_selected_landscape.png in Resources */, - D3C31A5C15BD8DED008ED271 /* options_transfer_default_landscape.png in Resources */, - D3C31A5E15BD8DED008ED271 /* options_transfer_disabled_landscape.png in Resources */, - D3C31A6015BD8DED008ED271 /* options_transfer_over_landscape.png in Resources */, - D3C31A6215BD8DED008ED271 /* pause_off_default_landscape.png in Resources */, - D3C31A6415BD8DED008ED271 /* pause_off_over_landscape.png in Resources */, - D3C31A6615BD8DED008ED271 /* pause_on_default_landscape.png in Resources */, - D3C31A6815BD8DED008ED271 /* pause_on_over_landscape.png in Resources */, - D3C31A6A15BD8DED008ED271 /* speaker_off_default_landscape.png in Resources */, - D3C31A6C15BD8DED008ED271 /* speaker_off_disabled_landscape.png in Resources */, - D3C31A6E15BD8DED008ED271 /* speaker_off_over_landscape.png in Resources */, - D3C31A7015BD8DED008ED271 /* speaker_on_default_landscape.png in Resources */, - D3C31A7215BD8DED008ED271 /* speaker_on_disabled_landscape.png in Resources */, - D3C31A7415BD8DED008ED271 /* speaker_on_over_landscape.png in Resources */, - D3C31A7615BD8DED008ED271 /* statebar_background_landscape.png in Resources */, - D3C31A7C15BD8DED008ED271 /* video_off_default_landscape.png in Resources */, - D3C31A7E15BD8DED008ED271 /* video_off_disabled_landscape.png in Resources */, - D3C31A8015BD8DED008ED271 /* video_off_over_landscape.png in Resources */, - D3C31A8215BD8DED008ED271 /* video_on_default_landscape.png in Resources */, - D3C31A8415BD8DED008ED271 /* video_on_disabled_landscape.png in Resources */, - D3C31A8615BD8DED008ED271 /* video_on_over_landscape.png in Resources */, - D3A74E5915C68162001500B9 /* toolsbar_background.png in Resources */, - D38187FC15FE356100C3EDCA /* UIMainBar~ipad.xib in Resources */, - D3A74EB215C69392001500B9 /* add_call_default~ipad.png in Resources */, - D3A74EB415C69392001500B9 /* add_call_disabled~ipad.png in Resources */, - D3A74EB615C69392001500B9 /* add_call_over~ipad.png in Resources */, - D3A74EB815C69392001500B9 /* add_contact_default~ipad.png in Resources */, - D3A74EBA15C69392001500B9 /* add_contact_disabled~ipad.png in Resources */, - D3A74EBC15C69392001500B9 /* add_contact_over~ipad.png in Resources */, - D3A74EBE15C69392001500B9 /* back_default~ipad.png in Resources */, - D3A74EC015C69392001500B9 /* back_disabled~ipad.png in Resources */, - D3A74EC215C69392001500B9 /* back_over~ipad.png in Resources */, - D3A74EC415C69392001500B9 /* background_top~ipad.png in Resources */, - D3A74EC615C69392001500B9 /* backspace_default~ipad.png in Resources */, - D3A74EC815C69392001500B9 /* backspace_disabled~ipad.png in Resources */, - D3A74ECA15C69392001500B9 /* backspace_over~ipad.png in Resources */, - D3A74ECC15C69392001500B9 /* call_default~ipad.png in Resources */, - F0B89C2C18DC973E0050B60E /* wizard_linphone_existing.rc in Resources */, - D3A74ECE15C69392001500B9 /* call_disabled~ipad.png in Resources */, - D3A74ED015C69392001500B9 /* call_over~ipad.png in Resources */, - D3A74ED215C69392001500B9 /* chat_default_landscape~ipad.png in Resources */, - D3A74ED415C69392001500B9 /* chat_default~ipad.png in Resources */, - D3A74ED615C69392001500B9 /* chat_over_landscape~ipad.png in Resources */, - D3A74ED815C69392001500B9 /* chat_over~ipad.png in Resources */, - D3A74EDA15C69392001500B9 /* chat_selected_landscape~ipad.png in Resources */, - D3A74EDC15C69392001500B9 /* chat_selected~ipad.png in Resources */, - D3A74EDE15C69392001500B9 /* conference_default~ipad.png in Resources */, - D3A74EE015C69392001500B9 /* conference_over~ipad.png in Resources */, - D3A74EE215C69392001500B9 /* contacts_default_landscape~ipad.png in Resources */, - D3A74EE415C69392001500B9 /* contacts_default~ipad.png in Resources */, - D3A74EE615C69392001500B9 /* contacts_over_landscape~ipad.png in Resources */, - D3A74EE815C69392001500B9 /* contacts_over~ipad.png in Resources */, - D3A74EEA15C69392001500B9 /* contacts_selected_landscape~ipad.png in Resources */, - D3A74EEC15C69392001500B9 /* contacts_selected~ipad.png in Resources */, - D3A74EEE15C69392001500B9 /* dialer_address_background_landscape~ipad.png in Resources */, - D3A74EF015C69392001500B9 /* dialer_address_background~ipad.png in Resources */, - D3A74EF215C69392001500B9 /* dialer_alt_default~ipad.png in Resources */, - D3A74EF415C69392001500B9 /* dialer_alt_over~ipad.png in Resources */, - D3A74EF615C69392001500B9 /* hangup_default~ipad.png in Resources */, - D3A74EF815C69392001500B9 /* hangup_over~ipad.png in Resources */, - D3A74EFA15C69392001500B9 /* history_default_landscape~ipad.png in Resources */, - D3A74EFC15C69392001500B9 /* history_default~ipad.png in Resources */, - D3A74EFE15C69392001500B9 /* history_over_landscape~ipad.png in Resources */, - D3A74F0015C69392001500B9 /* history_over~ipad.png in Resources */, - D3A74F0215C69392001500B9 /* history_selected_landscape~ipad.png in Resources */, - D3A74F0415C69392001500B9 /* history_selected~ipad.png in Resources */, - D3A74F0615C69392001500B9 /* micro_off_default~ipad.png in Resources */, - F0C1F9141A28781F009402C9 /* logo.png in Resources */, - D3A74F0815C69392001500B9 /* micro_off_disabled~ipad.png in Resources */, - D3A74F0A15C69392001500B9 /* micro_off_over~ipad.png in Resources */, - D3A74F0C15C69392001500B9 /* micro_on_default~ipad.png in Resources */, - D3A74F0E15C69392001500B9 /* micro_on_disabled~ipad.png in Resources */, - D3A74F1015C69392001500B9 /* micro_on_over~ipad.png in Resources */, - D3A74F1215C69392001500B9 /* options_add_default~ipad.png in Resources */, - D3A74F1415C69392001500B9 /* options_add_disabled~ipad.png in Resources */, - D3A74F1615C69392001500B9 /* options_add_over~ipad.png in Resources */, - D3A74F1815C69392001500B9 /* options_default~ipad.png in Resources */, - D3A74F1A15C69392001500B9 /* options_disabled~ipad.png in Resources */, - D3A74F1C15C69392001500B9 /* options_over~ipad.png in Resources */, - F070E6371A2622EC00E17AFD /* incall_padding_right_landscape.png in Resources */, - D3A74F1E15C69392001500B9 /* options_selected~ipad.png in Resources */, - D3A74F2015C69392001500B9 /* options_transfer_default~ipad.png in Resources */, - D3A74F2215C69392001500B9 /* options_transfer_disabled~ipad.png in Resources */, - D3A74F2415C69392001500B9 /* options_transfer_over~ipad.png in Resources */, - D3A74F2615C69392001500B9 /* pause_off_default~ipad.png in Resources */, - D3A74F2815C69392001500B9 /* pause_off_over~ipad.png in Resources */, - D3A74F2A15C69392001500B9 /* pause_on_default~ipad.png in Resources */, - D3A74F2C15C69392001500B9 /* pause_on_over~ipad.png in Resources */, - D3A74F2E15C69392001500B9 /* settings_default_landscape~ipad.png in Resources */, - F0C1F9111A28781F009402C9 /* corner-left-top.png in Resources */, - D3A74F3015C69392001500B9 /* settings_default~ipad.png in Resources */, - D3A74F3215C69392001500B9 /* settings_over_landscape~ipad.png in Resources */, - D3A74F3415C69392001500B9 /* settings_over~ipad.png in Resources */, - D3A74F3615C69392001500B9 /* settings_selected_landscape~ipad.png in Resources */, - D3A74F3815C69392001500B9 /* settings_selected~ipad.png in Resources */, - D3A74F3A15C69392001500B9 /* speaker_off_default~ipad.png in Resources */, - D3A74F3C15C69392001500B9 /* speaker_off_disabled~ipad.png in Resources */, - D3A74F3E15C69392001500B9 /* speaker_off_over~ipad.png in Resources */, - D3A74F4015C69392001500B9 /* speaker_on_default~ipad.png in Resources */, - D3A74F4215C69392001500B9 /* speaker_on_disabled~ipad.png in Resources */, - D3A74F4415C69392001500B9 /* speaker_on_over~ipad.png in Resources */, - D3A74F4615C69392001500B9 /* statebar_background_landscape~ipad.png in Resources */, + 636B99001C298401003BA37C /* options_default@2x.png in Resources */, + 636B99401C298401003BA37C /* speaker_selected@2x.png in Resources */, + 636B985F1C298401003BA37C /* color_E.png in Resources */, + 63AADBF61B6A0FF200AA16FD /* linphonerc-factory in Resources */, + 636B991B1C298401003BA37C /* route_bluetooth_disabled.png in Resources */, + 636B98FE1C298401003BA37C /* options_add_call_disabled@2x.png in Resources */, + 636B990F1C298401003BA37C /* pause_big_disabled.png in Resources */, + 63B8D68C1BCBE65600C12B09 /* ChatConversationCreateView.xib in Resources */, + D38187D915FE347700C3EDCA /* CallIncomingView.xib in Resources */, + 63CDC45F1C3BDE370085F529 /* ringback.wav in Resources */, + 639CEB031A1DF4EB004DE38F /* UICompositeView.xib in Resources */, + 63AADBF81B6A0FF200AA16FD /* linphonerc~ipad in Resources */, + 636B98E21C298401003BA37C /* numpad_6_default.png in Resources */, + 636B99441C298401003BA37C /* valid_default@2x.png in Resources */, + 636B98B31C298401003BA37C /* led_connected@2x.png in Resources */, + 636B989F1C298401003BA37C /* footer_dialer_disabled@2x.png in Resources */, + 636B983D1C298401003BA37C /* cancel_edit_default@2x.png in Resources */, + 636B98371C298401003BA37C /* camera_switch_default@2x.png in Resources */, + 636B99411C298401003BA37C /* splashscreen.png in Resources */, + 636B98BD1C298401003BA37C /* linphone_user@2x.png in Resources */, + 636B98FC1C298401003BA37C /* options_add_call_default@2x.png in Resources */, + 636B98391C298401003BA37C /* camera_switch_disabled@2x.png in Resources */, + 636B98B51C298401003BA37C /* led_disconnected@2x.png in Resources */, + 636B98D71C298401003BA37C /* numpad_3_default@2x.png in Resources */, + 636B984D1C298401003BA37C /* chat_send_default@2x.png in Resources */, + 636B97F41C298401003BA37C /* call_add_default.png in Resources */, + 636B980F1C298401003BA37C /* call_missed@2x.png in Resources */, + 63CDC45E1C3BDE370085F529 /* msg.caf in Resources */, + 636B98F41C298401003BA37C /* numpad_hash_over.png in Resources */, + 63CDC4601C3BDE370085F529 /* four_hands_together.caf in Resources */, + 636B98901C298401003BA37C /* edit_list_default.png in Resources */, + 636B98F01C298401003BA37C /* numpad_9_over.png in Resources */, + 636B984A1C298401003BA37C /* chat_message_not_delivered.png in Resources */, + 636B98231C298401003BA37C /* call_status_incoming@2x.png in Resources */, + 636B98E31C298401003BA37C /* numpad_6_default@2x.png in Resources */, + 636B99151C298401003BA37C /* pause_small_disabled.png in Resources */, + 636B98DF1C298401003BA37C /* numpad_5_default@2x.png in Resources */, + 636B97FB1C298401003BA37C /* call_alt_back_disabled@2x.png in Resources */, + D38187DD15FE348A00C3EDCA /* AssistantView.xib in Resources */, + 638F1A881C2167C2004B8E02 /* CallView~ipad.xib in Resources */, + 636B98CF1C298401003BA37C /* numpad_1_default@2x.png in Resources */, + 636B98B81C298401003BA37C /* led_inprogress.png in Resources */, + 636B98721C298401003BA37C /* contacts_all_selected.png in Resources */, + 636B97F91C298401003BA37C /* call_alt_back_default@2x.png in Resources */, + 636B98FD1C298401003BA37C /* options_add_call_disabled.png in Resources */, + 636B982D1C298401003BA37C /* call_video_start_default@2x.png in Resources */, + 636B988D1C298401003BA37C /* edit_default@2x.png in Resources */, + 636B990B1C298401003BA37C /* options_transfer_call_disabled.png in Resources */, + 636B98151C298401003BA37C /* call_quality_indicator_1@2x.png in Resources */, + D38187AD15FE340100C3EDCA /* ChatConversationView.xib in Resources */, + 636B98CB1C298401003BA37C /* numpad_0_default@2x.png in Resources */, + 636B98E51C298401003BA37C /* numpad_6_over@2x.png in Resources */, + 636B97F71C298401003BA37C /* call_add_disabled@2x.png in Resources */, + 636B98691C298401003BA37C /* conference_exit_over@2x.png in Resources */, + 636B989B1C298401003BA37C /* footer_contacts_disabled@2x.png in Resources */, + 636B97F81C298401003BA37C /* call_alt_back_default.png in Resources */, + 636B981D1C298401003BA37C /* call_start_body_default@2x.png in Resources */, + D38187B915FE342200C3EDCA /* ContactDetailsView.xib in Resources */, + 636B98491C298401003BA37C /* chat_attachment_over@2x.png in Resources */, + 636B98201C298401003BA37C /* call_start_body_over.png in Resources */, + 636B99131C298401003BA37C /* pause_small_default.png in Resources */, + 63AADC001B6A0FF200AA16FD /* assistant_linphone_create.rc in Resources */, + 636B99121C298401003BA37C /* pause_big_over_selected@2x.png in Resources */, + 636B98E91C298401003BA37C /* numpad_7_over@2x.png in Resources */, + 636B98D41C298401003BA37C /* numpad_2_over.png in Resources */, + 636B99311C298401003BA37C /* security_ko.png in Resources */, + 636B99241C298401003BA37C /* route_earpiece_selected@2x.png in Resources */, + 636B98CD1C298401003BA37C /* numpad_0_over@2x.png in Resources */, + 636B98731C298401003BA37C /* contacts_all_selected@2x.png in Resources */, + 636B98A21C298401003BA37C /* footer_history_disabled.png in Resources */, + 636B98431C298401003BA37C /* chat_add_disabled@2x.png in Resources */, + 636B97EC1C298401003BA37C /* back_disabled.png in Resources */, + 636B992A1C298401003BA37C /* route_speaker_selected@2x.png in Resources */, + 636B98A41C298401003BA37C /* history_all_default.png in Resources */, + 636B98A91C298401003BA37C /* history_all_selected@2x.png in Resources */, + 636B98D21C298401003BA37C /* numpad_2_default.png in Resources */, + 636B98331C298401003BA37C /* camera_disabled@2x.png in Resources */, + 636B989E1C298401003BA37C /* footer_dialer_disabled.png in Resources */, + 636B98FB1C298401003BA37C /* options_add_call_default.png in Resources */, + 636B992B1C298401003BA37C /* routes_default.png in Resources */, + 636B97E81C298401003BA37C /* avatar.png in Resources */, + 636B988F1C298401003BA37C /* edit_disabled@2x.png in Resources */, + 636B987D1C298401003BA37C /* delete_disabled@2x.png in Resources */, + 636B98B41C298401003BA37C /* led_disconnected.png in Resources */, + 636B98341C298401003BA37C /* camera_selected.png in Resources */, + D38187CD15FE346700C3EDCA /* HistoryDetailsView.xib in Resources */, + 636B98F71C298401003BA37C /* numpad_star_default.png in Resources */, + 636B992C1C298401003BA37C /* routes_default@2x.png in Resources */, + 636B982B1C298401003BA37C /* call_transfer_disabled@2x.png in Resources */, + 636B99331C298401003BA37C /* security_ok.png in Resources */, + 636B98551C298401003BA37C /* chat_start_body_disabled@2x.png in Resources */, + 639E9CA61C0DB7F200019A75 /* UIChatCreateCell.xib in Resources */, + 636B98B71C298401003BA37C /* led_error@2x.png in Resources */, + 636B98BE1C298401003BA37C /* list_details_default.png in Resources */, + 636B98101C298401003BA37C /* call_outgoing.png in Resources */, + 636B98B91C298401003BA37C /* led_inprogress@2x.png in Resources */, + 636B98241C298401003BA37C /* call_status_missed.png in Resources */, + 636B99321C298401003BA37C /* security_ko@2x.png in Resources */, + 636B98E41C298401003BA37C /* numpad_6_over.png in Resources */, + 636B983C1C298401003BA37C /* cancel_edit_default.png in Resources */, F0642EF119DAC891009DB336 /* MainStoryboard.storyboard in Resources */, - D3A74F4815C69392001500B9 /* statebar_background~ipad.png in Resources */, - D3A74F4A15C69392001500B9 /* transfer_call_default~ipad.png in Resources */, - D3A74F4C15C69392001500B9 /* transfer_call_over~ipad.png in Resources */, - D3A74F4E15C69392001500B9 /* video_off_default~ipad.png in Resources */, - D3A74F5015C69392001500B9 /* video_off_disabled~ipad.png in Resources */, - D3A74F5215C69392001500B9 /* video_off_over~ipad.png in Resources */, - F0B89C2818DC973E0050B60E /* wizard_external_sip.rc in Resources */, - D3A74F5415C69392001500B9 /* video_on_default~ipad.png in Resources */, - D3A74F5615C69392001500B9 /* video_on_disabled~ipad.png in Resources */, - D3A74F5815C69392001500B9 /* video_on_over~ipad.png in Resources */, - D38187C515FE345F00C3EDCA /* DialerViewController~ipad.xib in Resources */, - D3BDB9B915C6B5B1007BEAC1 /* transfer_call_disabled~ipad.png in Resources */, - D38187E515FE349D00C3EDCA /* UICallBar~ipad.xib in Resources */, - D3ACB09B15C6D59500E15894 /* dialer_alt_back_default~ipad.png in Resources */, - D3ACB09D15C6D59500E15894 /* dialer_alt_back_over~ipad.png in Resources */, - D33988B415C6DD1600CAF1E4 /* conference_default_landscape~ipad.png in Resources */, - D33988B615C6DD1600CAF1E4 /* conference_over_landscape~ipad.png in Resources */, - D33988B815C6DD1600CAF1E4 /* dialer_alt_default_landscape~ipad.png in Resources */, - D33988BA15C6DD1600CAF1E4 /* dialer_alt_over_landscape~ipad.png in Resources */, - D33988BC15C6DD1600CAF1E4 /* hangup_default_landscape~ipad.png in Resources */, - D33988BE15C6DD1600CAF1E4 /* hangup_over_landscape~ipad.png in Resources */, - D33988C015C6DD1600CAF1E4 /* micro_off_default_landscape~ipad.png in Resources */, - D33988C215C6DD1600CAF1E4 /* micro_off_disabled_landscape~ipad.png in Resources */, - D33988C415C6DD1600CAF1E4 /* micro_off_over_landscape~ipad.png in Resources */, - D33988C615C6DD1600CAF1E4 /* micro_on_default_landscape~ipad.png in Resources */, - D33988C815C6DD1600CAF1E4 /* micro_on_disabled_landscape~ipad.png in Resources */, - D33988CA15C6DD1600CAF1E4 /* micro_on_over_landscape~ipad.png in Resources */, - D33988CC15C6DD1600CAF1E4 /* options_add_default_landscape~ipad.png in Resources */, - D33988CE15C6DD1600CAF1E4 /* options_add_disabled_landscape~ipad.png in Resources */, - D33988D015C6DD1600CAF1E4 /* options_add_over_landscape~ipad.png in Resources */, - D33988D215C6DD1600CAF1E4 /* options_default_landscape~ipad.png in Resources */, - D33988D415C6DD1600CAF1E4 /* options_disabled_landscape~ipad.png in Resources */, - D33988D615C6DD1600CAF1E4 /* options_over_landscape~ipad.png in Resources */, - D33988D815C6DD1600CAF1E4 /* options_selected_landscape~ipad.png in Resources */, - D33988DA15C6DD1600CAF1E4 /* options_transfer_default_landscape~ipad.png in Resources */, - D33988DC15C6DD1600CAF1E4 /* options_transfer_disabled_landscape~ipad.png in Resources */, - D33988DE15C6DD1600CAF1E4 /* options_transfer_over_landscape~ipad.png in Resources */, - D33988E015C6DD1600CAF1E4 /* pause_off_default_landscape~ipad.png in Resources */, - D33988E215C6DD1600CAF1E4 /* pause_off_over_landscape~ipad.png in Resources */, - D33988E415C6DD1600CAF1E4 /* pause_on_default_landscape~ipad.png in Resources */, - D33988E615C6DD1600CAF1E4 /* pause_on_over_landscape~ipad.png in Resources */, - D33988E815C6DD1600CAF1E4 /* speaker_off_default_landscape~ipad.png in Resources */, - D33988EA15C6DD1600CAF1E4 /* speaker_off_disabled_landscape~ipad.png in Resources */, - D33988EC15C6DD1600CAF1E4 /* speaker_off_over_landscape~ipad.png in Resources */, - D33988EE15C6DD1600CAF1E4 /* speaker_on_default_landscape~ipad.png in Resources */, - D33988F015C6DD1600CAF1E4 /* speaker_on_disabled_landscape~ipad.png in Resources */, - D33988F215C6DD1600CAF1E4 /* speaker_on_over_landscape~ipad.png in Resources */, - D33988F815C6DD1600CAF1E4 /* video_off_default_landscape~ipad.png in Resources */, - D33988FA15C6DD1600CAF1E4 /* video_off_disabled_landscape~ipad.png in Resources */, - D33988FC15C6DD1600CAF1E4 /* video_off_over_landscape~ipad.png in Resources */, - D33988FE15C6DD1600CAF1E4 /* video_on_default_landscape~ipad.png in Resources */, - D339890015C6DD1600CAF1E4 /* video_on_disabled_landscape~ipad.png in Resources */, - D339890215C6DD1600CAF1E4 /* video_on_over_landscape~ipad.png in Resources */, - D339890615C6E16F00CAF1E4 /* dialer_alt_back_default_landscape~ipad.png in Resources */, - D339890815C6E16F00CAF1E4 /* dialer_alt_back_over_landscape~ipad.png in Resources */, - D30BBD1815D402A7000F93DD /* contact_ok_disabled.png in Resources */, - D3804E6015D92A57008072A5 /* msg.caf in Resources */, - D3804E6215D92A57008072A5 /* msg.wav in Resources */, - D321FF9915E628CB0098B5F4 /* linphonerc~ipad in Resources */, - D38187C115FE345B00C3EDCA /* DialerViewController.xib in Resources */, - 57F005C415EE2CCF00914747 /* linphonerc in Resources */, - 57F005C815EE2D9200914747 /* linphonerc-factory in Resources */, - 57F005CA15EE2D9200914747 /* linphonerc-factory~ipad in Resources */, - F0B89C2A18DC973E0050B60E /* wizard_linphone_create.rc in Resources */, - 2234C8E915EE2F7F00E18E83 /* chat_message_delivered.png in Resources */, - 2234C8EB15EE2F7F00E18E83 /* chat_message_not_delivered.png in Resources */, - 2234C8EE15EE744200E18E83 /* chat_message_inprogress.png in Resources */, - F04892FF180C3296002FED35 /* ImageOptim.sh in Resources */, - D37EE10D16035793003608A6 /* ImageViewController.xib in Resources */, - D381881115FE3F0B00C3EDCA /* UICallCell.xib in Resources */, - D381881915FE3FCA00C3EDCA /* InCallViewController.xib in Resources */, - D3998D0416031937009DD22C /* background_alt.png in Resources */, - D3866C281608CA1600830F95 /* image_back_default.png in Resources */, - D3866C2A1608CA1600830F95 /* image_back_over.png in Resources */, - D3F5F8F71609A86700D3DA1A /* chat_cancel_default.png in Resources */, - D3F5F8F91609A86700D3DA1A /* chat_cancel_over.png in Resources */, - D3F5F8FB1609A86700D3DA1A /* chat_photo_default.png in Resources */, - D3F5F8FD1609A86700D3DA1A /* chat_photo_disabled.png in Resources */, - D3F5F8FF1609A86700D3DA1A /* chat_photo_over.png in Resources */, - D3F5F9071609A86700D3DA1A /* history_delete_default.png in Resources */, - D3F5F9091609A86700D3DA1A /* history_delete_over.png in Resources */, - D3F5F90B1609A86700D3DA1A /* logo_linphone_trame_background.png in Resources */, - D3F5F90D1609A86700D3DA1A /* setup_back_disabled~ipad.png in Resources */, - D3F5F90F1609A86700D3DA1A /* setup_back_over_landscape~ipad.png in Resources */, - D3F5F9111609A86700D3DA1A /* setup_back_over~ipad.png in Resources */, - D3F5F9131609A86700D3DA1A /* setup_cancel_default_landscape~ipad.png in Resources */, - F070E6341A2622EC00E17AFD /* dialer_padding_right.png in Resources */, - D3F5F9171609A86700D3DA1A /* setup_cancel_disabled_landscape~ipad.png in Resources */, - D3F5F9191609A86700D3DA1A /* setup_cancel_disabled~ipad.png in Resources */, - D3F5F91B1609A86700D3DA1A /* setup_cancel_over_landscape~ipad.png in Resources */, - D3F5F91F1609A86700D3DA1A /* setup_start_default_landscape~ipad.png in Resources */, - D3F5F9211609A86700D3DA1A /* setup_start_default~ipad.png in Resources */, - D3F5F9231609A86700D3DA1A /* setup_start_disabled_landscape~ipad.png in Resources */, - D3F5F9251609A86700D3DA1A /* setup_start_disabled~ipad.png in Resources */, - D3F5F9271609A86700D3DA1A /* setup_start_over_landscape~ipad.png in Resources */, - D3F5F9291609A86700D3DA1A /* setup_start_over~ipad.png in Resources */, - D3F5F92B1609A86700D3DA1A /* setup_welcome_logo~ipad.png in Resources */, - D3F5F987160B1A0900D3DA1A /* chat_progressbar_background.png in Resources */, - D3F5F989160B1A0900D3DA1A /* setup_back_default_landscape~ipad.png in Resources */, - D3F5F98B160B1A0900D3DA1A /* setup_back_default~ipad.png in Resources */, - D3F5F98D160B1A0900D3DA1A /* setup_back_disabled_landscape~ipad.png in Resources */, - D3D5124E160B213900946DF8 /* setup_cancel_default~ipad.png in Resources */, - D3D51250160B213900946DF8 /* setup_cancel_over~ipad.png in Resources */, - D3D51255160B35CB00946DF8 /* chat_message_background.9.png in Resources */, - D3D51257160B35CB00946DF8 /* chat_message_background.9@2x.png in Resources */, - D3D5126C160B3A8E00946DF8 /* WizardViews.xib in Resources */, - D3D51270160B3AD400946DF8 /* WizardViewController~ipad.xib in Resources */, - D3328646160B5BC300E6435D /* dialer_alt_disabled_landscape.png in Resources */, - D3328648160B5BC300E6435D /* dialer_alt_disabled_landscape~ipad.png in Resources */, - D332864A160B5BC300E6435D /* dialer_alt_disabled.png in Resources */, - D332864C160B5BC300E6435D /* dialer_alt_disabled~ipad.png in Resources */, - F070E6331A2622EC00E17AFD /* dialer_padding_left.png in Resources */, - F0C1F8EB1A277ADA009402C9 /* LaunchScreen.xib in Resources */, - D35E91EA160CA0BD0023116B /* field_background.9@2x.png in Resources */, - D35E91EE160CA0C70023116B /* button_background_default.9@2x.png in Resources */, - D35E91F0160CA0C70023116B /* button_background_over.9@2x.png in Resources */, - D35E9209160CAA1F0023116B /* field_background.9.png in Resources */, - D35E920D160CABD70023116B /* button_background_default.9.png in Resources */, - D35E920F160CABD70023116B /* button_background_over.9.png in Resources */, - D3012CC41610467D007CD926 /* linphone_logo.png in Resources */, - D3012CC616105ECF007CD926 /* bubble.png in Resources */, - D3D52A731614480700DEB00A /* IncomingCallViewController~ipad.xib in Resources */, - D3D52A7D1614495300DEB00A /* accept_default_landscape~ipad.png in Resources */, - D3D52A7F1614495300DEB00A /* accept_default~ipad.png in Resources */, - D3D52A811614495300DEB00A /* accept_over_landscape~ipad.png in Resources */, - D3D52A831614495300DEB00A /* accept_over~ipad.png in Resources */, - F070E6361A2622EC00E17AFD /* incall_padding_left.png in Resources */, - D3D52A851614495300DEB00A /* decline_default_landscape~ipad.png in Resources */, - D3D52A871614495300DEB00A /* decline_default~ipad.png in Resources */, - D3D52A891614495300DEB00A /* decline_over_landscape~ipad.png in Resources */, - D3D52A8B1614495300DEB00A /* decline_over~ipad.png in Resources */, - D37E3ED01619DCC50087659A /* licenses.html in Resources */, - D33E1F08164CF35100CFA363 /* callbar_left_padding.png in Resources */, - D33E1F0A164CF35100CFA363 /* callbar_right_padding.png in Resources */, - 15AF3C5416F37A3E00FC52EC /* route_bluetooth_off_default.png in Resources */, - 15AF3C5616F37A3E00FC52EC /* route_bluetooth_off_disabled.png in Resources */, - 15AF3C5816F37A3E00FC52EC /* route_bluetooth_off_over.png in Resources */, - 15AF3C5C16F37A3E00FC52EC /* route_bluetooth_on_default.png in Resources */, + 636B98811C298401003BA37C /* delete_field_over@2x.png in Resources */, + 636B98CA1C298401003BA37C /* numpad_0_default.png in Resources */, + 636B98441C298401003BA37C /* chat_attachment_default.png in Resources */, + 636B98CC1C298401003BA37C /* numpad_0_over.png in Resources */, + 63AADC021B6A0FF200AA16FD /* assistant_remote.rc in Resources */, + 636B989C1C298401003BA37C /* footer_dialer_default.png in Resources */, + 63F1DF511BCE986A00EDED90 /* UICallConferenceCell.xib in Resources */, + 636B99481C298401003BA37C /* voicemail@2x.png in Resources */, + 636B97F61C298401003BA37C /* call_add_disabled.png in Resources */, + 636B991A1C298401003BA37C /* route_bluetooth_default@2x.png in Resources */, + 636B99371C298401003BA37C /* select_all_default.png in Resources */, + 636B99461C298401003BA37C /* valid_disabled@2x.png in Resources */, + 63AADBE91B6A0FF200AA16FD /* hold.wav in Resources */, + 63B81A0C1B57DA33009604A6 /* LICENSE.txt in Resources */, + 636B986A1C298401003BA37C /* contact_add_default.png in Resources */, + 636B98F61C298401003BA37C /* numpad_over_background.png in Resources */, + 636B98B01C298401003BA37C /* history_missed_selected.png in Resources */, + 636B988A1C298401003BA37C /* dialer_background.png in Resources */, + 636B97EF1C298401003BA37C /* backspace_default@2x.png in Resources */, + 636B98DC1C298401003BA37C /* numpad_4_over.png in Resources */, + D38187C115FE345B00C3EDCA /* DialerView.xib in Resources */, + 636B97FF1C298401003BA37C /* call_alt_start_disabled@2x.png in Resources */, + 636B99261C298401003BA37C /* route_speaker_default@2x.png in Resources */, + 636B98FF1C298401003BA37C /* options_default.png in Resources */, + 636B99061C298401003BA37C /* options_start_conference_default@2x.png in Resources */, + 636B99451C298401003BA37C /* valid_disabled.png in Resources */, + 636B98091C298401003BA37C /* call_hangup_default@2x.png in Resources */, + 636B99211C298401003BA37C /* route_earpiece_disabled.png in Resources */, + 636B99291C298401003BA37C /* route_speaker_selected.png in Resources */, + 636B98BC1C298401003BA37C /* linphone_user.png in Resources */, + 636B990D1C298401003BA37C /* pause_big_default.png in Resources */, + 636B98A61C298401003BA37C /* history_all_disabled.png in Resources */, + 636B98AE1C298401003BA37C /* history_missed_disabled.png in Resources */, + 636B98401C298401003BA37C /* chat_add_default.png in Resources */, + D37EE10D16035793003608A6 /* ImageView.xib in Resources */, + 636B98AD1C298401003BA37C /* history_missed_default@2x.png in Resources */, + 636B98A71C298401003BA37C /* history_all_disabled@2x.png in Resources */, + 636B98641C298401003BA37C /* color_L.png in Resources */, + 63CDC4631C3BDE370085F529 /* leaving_a_dream.caf in Resources */, + 636B98191C298401003BA37C /* call_quality_indicator_3@2x.png in Resources */, + 636B98991C298401003BA37C /* footer_contacts_default@2x.png in Resources */, + 636B98681C298401003BA37C /* conference_exit_over.png in Resources */, + 636B98A11C298401003BA37C /* footer_history_default@2x.png in Resources */, + 636B986F1C298401003BA37C /* contacts_all_default@2x.png in Resources */, + 636B991F1C298401003BA37C /* route_earpiece_default.png in Resources */, + 636B98271C298401003BA37C /* call_status_outgoing@2x.png in Resources */, + 636B98041C298401003BA37C /* call_back_default.png in Resources */, + 636B993B1C298401003BA37C /* speaker_default.png in Resources */, + 636B98511C298401003BA37C /* chat_send_over@2x.png in Resources */, + 636B99271C298401003BA37C /* route_speaker_disabled.png in Resources */, + 636B98E81C298401003BA37C /* numpad_7_over.png in Resources */, + 636B98AF1C298401003BA37C /* history_missed_disabled@2x.png in Resources */, + 636B99111C298401003BA37C /* pause_big_over_selected.png in Resources */, + 63AADBE81B6A0FF200AA16FD /* Localizable.strings in Resources */, + 636B99431C298401003BA37C /* valid_default.png in Resources */, + 631348321B6FA53300C6BDCB /* rootca.pem in Resources */, + 636B992F1C298401003BA37C /* routes_selected.png in Resources */, + 636B98411C298401003BA37C /* chat_add_default@2x.png in Resources */, + 636B99341C298401003BA37C /* security_ok@2x.png in Resources */, + 636B985C1C298401003BA37C /* color_A.png in Resources */, + 636B97E51C298401003BA37C /* add_field_default@2x.png in Resources */, + D381881915FE3FCA00C3EDCA /* CallView.xib in Resources */, + 636B98A81C298401003BA37C /* history_all_selected.png in Resources */, + 636B98CE1C298401003BA37C /* numpad_1_default.png in Resources */, + 636B992E1C298401003BA37C /* routes_disabled@2x.png in Resources */, + 636B98BF1C298401003BA37C /* list_details_default@2x.png in Resources */, + 636B98701C298401003BA37C /* contacts_all_disabled.png in Resources */, + 636B98F51C298401003BA37C /* numpad_hash_over@2x.png in Resources */, + 636B98C61C298401003BA37C /* micro_disabled.png in Resources */, + 636B98051C298401003BA37C /* call_back_default@2x.png in Resources */, + D3D5126C160B3A8E00946DF8 /* AssistantViewScreens.xib in Resources */, + 636B993A1C298401003BA37C /* select_all_disabled@2x.png in Resources */, + 636B984B1C298401003BA37C /* chat_message_not_delivered@2x.png in Resources */, + 636B98111C298401003BA37C /* call_outgoing@2x.png in Resources */, + 636B984E1C298401003BA37C /* chat_send_disabled.png in Resources */, + 636B97E61C298401003BA37C /* add_field_over.png in Resources */, + 636B986E1C298401003BA37C /* contacts_all_default.png in Resources */, + 636B98851C298401003BA37C /* dialer_alt_back@2x.png in Resources */, + 636B97E91C298401003BA37C /* avatar@2x.png in Resources */, + 636B98EC1C298401003BA37C /* numpad_8_over.png in Resources */, + 636B98461C298401003BA37C /* chat_attachment_disabled.png in Resources */, + 636B98B61C298401003BA37C /* led_error.png in Resources */, + 636B981E1C298401003BA37C /* call_start_body_disabled.png in Resources */, + 636B986D1C298401003BA37C /* contact_add_disabled@2x.png in Resources */, + 636B97FD1C298401003BA37C /* call_alt_start_default@2x.png in Resources */, + 636B98361C298401003BA37C /* camera_switch_default.png in Resources */, + 636B98FA1C298401003BA37C /* numpad_star_over@2x.png in Resources */, + 636B98891C298401003BA37C /* dialer_back_disabled@2x.png in Resources */, + 636B993F1C298401003BA37C /* speaker_selected.png in Resources */, + 63AADBEA1B6A0FF200AA16FD /* Images.xcassets in Resources */, + 636B98301C298401003BA37C /* camera_default.png in Resources */, + 636B98281C298401003BA37C /* call_transfer_default.png in Resources */, + 639E9CA91C0DB7FB00019A75 /* UIConfirmationDialog.xib in Resources */, + 636B98F91C298401003BA37C /* numpad_star_over.png in Resources */, + 63CDC45D1C3BDE370085F529 /* hold.caf in Resources */, + 636B99081C298401003BA37C /* options_start_conference_disabled@2x.png in Resources */, + 636B980D1C298401003BA37C /* call_incoming@2x.png in Resources */, + 636B99231C298401003BA37C /* route_earpiece_selected.png in Resources */, + 636B98B21C298401003BA37C /* led_connected.png in Resources */, + 636B98E71C298401003BA37C /* numpad_7_default@2x.png in Resources */, + 636B97FE1C298401003BA37C /* call_alt_start_disabled.png in Resources */, + 636B993D1C298401003BA37C /* speaker_disabled.png in Resources */, + 636B98A51C298401003BA37C /* history_all_default@2x.png in Resources */, + 636B98311C298401003BA37C /* camera_default@2x.png in Resources */, + 639E9C9A1C0DB7D300019A75 /* LaunchScreen.xib in Resources */, + 636B99201C298401003BA37C /* route_earpiece_default@2x.png in Resources */, + 636B986C1C298401003BA37C /* contact_add_disabled.png in Resources */, + 636B98501C298401003BA37C /* chat_send_over.png in Resources */, + 636B98C21C298401003BA37C /* menu.png in Resources */, + 636B98D31C298401003BA37C /* numpad_2_default@2x.png in Resources */, + 636B98EA1C298401003BA37C /* numpad_8_default.png in Resources */, + 636B985B1C298401003BA37C /* checkbox_unchecked@2x.png in Resources */, + 636B98561C298401003BA37C /* chat_start_body_over.png in Resources */, + 636B98C51C298401003BA37C /* micro_default@2x.png in Resources */, + 636B97FA1C298401003BA37C /* call_alt_back_disabled.png in Resources */, + 636B98071C298401003BA37C /* call_back_disabled@2x.png in Resources */, + 636B990A1C298401003BA37C /* options_transfer_call_default@2x.png in Resources */, + 636B99191C298401003BA37C /* route_bluetooth_default.png in Resources */, + 636B98D81C298401003BA37C /* numpad_3_over.png in Resources */, + 636B98581C298401003BA37C /* checkbox_checked.png in Resources */, + 636B98E01C298401003BA37C /* numpad_5_over.png in Resources */, + 636B988C1C298401003BA37C /* edit_default.png in Resources */, + 636B98DA1C298401003BA37C /* numpad_4_default.png in Resources */, + 636B98971C298401003BA37C /* footer_chat_disabled@2x.png in Resources */, + 636B98261C298401003BA37C /* call_status_outgoing.png in Resources */, + 636B98EB1C298401003BA37C /* numpad_8_default@2x.png in Resources */, + 636B98E11C298401003BA37C /* numpad_5_over@2x.png in Resources */, + 636B98D61C298401003BA37C /* numpad_3_default.png in Resources */, + 636B98751C298401003BA37C /* contacts_sip_default@2x.png in Resources */, + 636B984F1C298401003BA37C /* chat_send_disabled@2x.png in Resources */, + 636B987C1C298401003BA37C /* delete_disabled.png in Resources */, + 636B98161C298401003BA37C /* call_quality_indicator_2.png in Resources */, + 636B989D1C298401003BA37C /* footer_dialer_default@2x.png in Resources */, + 636B988E1C298401003BA37C /* edit_disabled.png in Resources */, + 636B985A1C298401003BA37C /* checkbox_unchecked.png in Resources */, + 636B987B1C298401003BA37C /* delete_default@2x.png in Resources */, + 636B98001C298401003BA37C /* call_audio_start_default.png in Resources */, + 636B991D1C298401003BA37C /* route_bluetooth_selected.png in Resources */, + 63AADBF51B6A0FF200AA16FD /* linphonerc in Resources */, + 636B98141C298401003BA37C /* call_quality_indicator_1.png in Resources */, + 636B98EF1C298401003BA37C /* numpad_9_default@2x.png in Resources */, + 636B99361C298401003BA37C /* security_pending@2x.png in Resources */, + 636B98F81C298401003BA37C /* numpad_star_default@2x.png in Resources */, + 636B98DD1C298401003BA37C /* numpad_4_over@2x.png in Resources */, + 636B97F01C298401003BA37C /* backspace_disabled.png in Resources */, + 636B98591C298401003BA37C /* checkbox_checked@2x.png in Resources */, + 636B99141C298401003BA37C /* pause_small_default@2x.png in Resources */, + 636B98A31C298401003BA37C /* footer_history_disabled@2x.png in Resources */, + 636B99051C298401003BA37C /* options_start_conference_default.png in Resources */, + 636B98AC1C298401003BA37C /* history_missed_default.png in Resources */, F0938159188E629800A55DFA /* iTunesArtwork in Resources */, - 15AF3C6C16F37A4A00FC52EC /* route_phone_off_default.png in Resources */, - 15AF3C6E16F37A4A00FC52EC /* route_phone_off_disabled.png in Resources */, - 15AF3C7016F37A4A00FC52EC /* route_phone_off_over.png in Resources */, - 15AF3C7416F37A4A00FC52EC /* route_phone_on_default.png in Resources */, - 15AF3C8416F37A5500FC52EC /* route_speaker_off_default.png in Resources */, - 15AF3C8616F37A5500FC52EC /* route_speaker_off_disabled.png in Resources */, - 15AF3C8816F37A5500FC52EC /* route_speaker_off_over.png in Resources */, - 15AF3C8C16F37A5500FC52EC /* route_speaker_on_default.png in Resources */, - 15AF3C9816F37A5D00FC52EC /* routes_default.png in Resources */, - 15AF3C9A16F37A5D00FC52EC /* routes_disabled.png in Resources */, - 15AF3C9C16F37A5D00FC52EC /* routes_over.png in Resources */, - 15AF3C9E16F37A5D00FC52EC /* routes_selected.png in Resources */, - 1599105316F746B2007BF52B /* route_bluetooth_off_default_landscape.png in Resources */, - 1599105516F746B2007BF52B /* route_bluetooth_off_disabled_landscape.png in Resources */, - 1599105716F746B2007BF52B /* route_bluetooth_off_over_landscape.png in Resources */, - 1599105916F746B2007BF52B /* route_bluetooth_on_default_landscape.png in Resources */, - 1599105B16F746B2007BF52B /* route_phone_off_default_landscape.png in Resources */, - 1599105D16F746B2007BF52B /* route_phone_off_disabled_landscape.png in Resources */, - 1599105F16F746B2007BF52B /* route_phone_off_over_landscape.png in Resources */, - 1599106116F746B2007BF52B /* route_phone_on_default_landscape.png in Resources */, - 1599106316F746B2007BF52B /* route_speaker_off_default_landscape.png in Resources */, - 1599106516F746B2007BF52B /* route_speaker_off_disabled_landscape.png in Resources */, - 1599106716F746B2007BF52B /* route_speaker_off_over_landscape.png in Resources */, - 1599106916F746B2007BF52B /* route_speaker_on_default_landscape.png in Resources */, - 1599106B16F746B2007BF52B /* routes_default_landscape.png in Resources */, - 1599106D16F746B2007BF52B /* routes_disabled_landscape.png in Resources */, - 1599106F16F746B2007BF52B /* routes_over_landscape.png in Resources */, - 1599107116F746B2007BF52B /* routes_selected_landscape.png in Resources */, + 639E9CA01C0DB7E500019A75 /* UIChatBubblePhotoCell.xib in Resources */, + 636B993E1C298401003BA37C /* speaker_disabled@2x.png in Resources */, + 636B985E1C298401003BA37C /* color_D.png in Resources */, + 636B982F1C298401003BA37C /* call_video_start_disabled@2x.png in Resources */, + 636B99221C298401003BA37C /* route_earpiece_disabled@2x.png in Resources */, + 636B992D1C298401003BA37C /* routes_disabled.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3830,16 +3336,15 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - F08F119A19C09D88007D70C2 /* flexisip in Resources */, - F0022B0A1A370915009B51FD /* messages.db in Resources */, - F0C1F91D1A2CA345009402C9 /* local_tester_hosts in Resources */, - F0C1F9211A2CA35A009402C9 /* sounds in Resources */, - F08F118D19C09C6B007D70C2 /* InfoPlist.strings in Resources */, - F0C1F9231A2CA35E009402C9 /* certificates in Resources */, - F0C1F9221A2CA35C009402C9 /* images in Resources */, - F0C1F9201A2CA358009402C9 /* rcfiles in Resources */, - F0C1F91F1A2CA354009402C9 /* tester_hosts in Resources */, - F0C1F91E1A2CA352009402C9 /* marie_xml in Resources */, + 63058AE31B4E93B300EFAE36 /* tester_hosts in Resources */, + 63058ACF1B4E922500EFAE36 /* certificates in Resources */, + 63058AD01B4E922500EFAE36 /* flexisip in Resources */, + 63058AD11B4E922500EFAE36 /* images in Resources */, + 63058AD21B4E922500EFAE36 /* marie_xml in Resources */, + 63058AD31B4E922500EFAE36 /* messages.db in Resources */, + 63058AD41B4E922500EFAE36 /* rcfiles in Resources */, + 63058AD51B4E922500EFAE36 /* sounds in Resources */, + 63058A3B1B4E822F00EFAE36 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3847,22 +3352,20 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - F0BB8C3819362C1500974404 /* rcfiles in Resources */, - F84015C11939FE37006ABAB5 /* test_passed.png in Resources */, - F08F119919C09D88007D70C2 /* flexisip in Resources */, - F0BB8C46193630CA00974404 /* marie_xml in Resources */, - F0BB8BEA1936208200974404 /* Main_iPad.storyboard in Resources */, - F0BB8C3E19362C2200974404 /* sounds in Resources */, - F84015BF1939FE37006ABAB5 /* test_failed.png in Resources */, - F0022B091A370915009B51FD /* messages.db in Resources */, - F0BB8BF21936208200974404 /* TesterImages.xcassets in Resources */, - F0BB8BE71936208200974404 /* Main_iPhone.storyboard in Resources */, - F0BB8C47193630CA00974404 /* tester_hosts in Resources */, - F84015C01939FE37006ABAB5 /* test_inprogress.png in Resources */, - F0BB8C3C19362C2200974404 /* certificates in Resources */, - F0BB8C45193630CA00974404 /* local_tester_hosts in Resources */, - F0BB8C3D19362C2200974404 /* images in Resources */, - F0BB8BDE1936208100974404 /* InfoPlist.strings in Resources */, + 63058ADA1B4E937300EFAE36 /* certificates in Resources */, + 63058ADB1B4E937300EFAE36 /* flexisip in Resources */, + 63058ADC1B4E937300EFAE36 /* images in Resources */, + 63058ADD1B4E937300EFAE36 /* marie_xml in Resources */, + 63058ADE1B4E937300EFAE36 /* messages.db in Resources */, + 63058ADF1B4E937300EFAE36 /* rcfiles in Resources */, + 63058AE01B4E937300EFAE36 /* sounds in Resources */, + 63058AE21B4E93A100EFAE36 /* tester_hosts in Resources */, + 63058A2F1B4E821E00EFAE36 /* TesterImages.xcassets in Resources */, + 63058A251B4E821E00EFAE36 /* InfoPlist.strings in Resources */, + 63058A271B4E821E00EFAE36 /* Main_iPhone.strings in Resources */, + 63058A261B4E821E00EFAE36 /* Main_iPad.strings in Resources */, + 63058A291B4E821E00EFAE36 /* Main_iPhone.storyboard in Resources */, + 63058A281B4E821E00EFAE36 /* Main_iPad.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3890,19 +3393,6 @@ shellPath = /bin/sh; shellScript = $SRCROOT/Tools/git_version.sh; }; - D33CF34715D3985000CD4B85 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = $SRCROOT/ImageOptim.sh; - }; F08F11A219C0AC2F007D70C2 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 12; @@ -3923,73 +3413,87 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 63B81A0F1B57DA33009604A6 /* TPKeyboardAvoidingTableView.m in Sources */, 1D60589B0D05DD56006BFB54 /* main.m in Sources */, 1D3623260D0F684500981E51 /* LinphoneAppDelegate.m in Sources */, - 22F2508E107141E100AC9B3F /* DialerViewController.m in Sources */, - 22E0A822111C44E100B04932 /* AboutViewController.m in Sources */, - 631C4FB119D2A8F2004BFE77 /* UIDigitButtonLongPlus.m in Sources */, + 22F2508E107141E100AC9B3F /* DialerView.m in Sources */, + 633756451B67D2B200E21BAD /* SideMenuView.m in Sources */, + 22E0A822111C44E100B04932 /* AboutView.m in Sources */, + 633671611BCBAAD200BFCBDE /* ChatConversationCreateView.m in Sources */, + 634610061B61330300548952 /* UILabel+Boldify.m in Sources */, 2248E90E12F7E4CF00220D9C /* UIDigitButton.m in Sources */, + 633756391B67BAF400E21BAD /* SideMenuTableView.m in Sources */, 2214EB7A12F846B1002A5394 /* UICallButton.m in Sources */, + 6352A5751BE0D4B800594C1C /* CallSideMenuView.m in Sources */, 2214EB8912F84EBB002A5394 /* UIHangUpButton.m in Sources */, + 630CF5571AF7CE1500539F7A /* UITextField+DoneButton.m in Sources */, 2214EBF312F86360002A5394 /* UIMicroButton.m in Sources */, 22968A5F12F875C600588287 /* UISpeakerButton.m in Sources */, - 2218A92512FBE1340088A667 /* FirstLoginViewController.m in Sources */, + 63701DDF1BA32039006A9AE3 /* UIConfirmationDialog.m in Sources */, 22C755601317E59C007BC101 /* UIBluetoothButton.m in Sources */, - 22BB1A69132FF16A005CD7AA /* UIEraseButton.m in Sources */, 22AA8B0113D83F6300B30535 /* UICamSwitch.m in Sources */, + 63B8D6A21BCBF43100C12B09 /* UIChatCreateCell.m in Sources */, + 636BC9971B5F921B00C754CE /* UIIconButton.m in Sources */, 340751E7150F38FD00B89C47 /* UIVideoButton.m in Sources */, 34216F401547EBCD00EA9777 /* VideoZoomHandler.m in Sources */, - D3F83EEC1582021700336684 /* InCallViewController.m in Sources */, + D3F83EEC1582021700336684 /* CallView.m in Sources */, + 63F1DF4B1BCE983200EDED90 /* CallConferenceTableView.m in Sources */, D3F83F8E15822ABE00336684 /* PhoneMainView.m in Sources */, - D3ED3E871586291E006C0DE4 /* UIMainBar.m in Sources */, - D3ED3EA71587334E006C0DE4 /* HistoryTableViewController.m in Sources */, - D3ED3EB81587392C006C0DE4 /* HistoryViewController.m in Sources */, - D35497FE15875372000081D8 /* ContactsViewController.m in Sources */, - D3549816158761D0000081D8 /* ContactsTableViewController.m in Sources */, - D35498211587716B000081D8 /* UIStateBar.m in Sources */, + 6377AC801BDE4069007F7625 /* UIBackToCallButton.m in Sources */, + 6308F9C51BF0DD6600D1234B /* XMLRPCHelper.m in Sources */, + D3ED3E871586291E006C0DE4 /* TabBarView.m in Sources */, + D3ED3EA71587334E006C0DE4 /* HistoryListTableView.m in Sources */, + D3ED3EB81587392C006C0DE4 /* HistoryListView.m in Sources */, + D35497FE15875372000081D8 /* ContactsListView.m in Sources */, + 635173F91BA082A40095EB0A /* UIChatBubblePhotoCell.m in Sources */, + D3549816158761D0000081D8 /* ContactsListTableView.m in Sources */, + 633888461BFB2C49001D5E7B /* HPTextViewInternal.m in Sources */, + D35498211587716B000081D8 /* StatusBarView.m in Sources */, D3A55FBC15877E5E003FD403 /* UIContactCell.m in Sources */, + 6341807C1BBC103100F71761 /* ChatConversationCreateTableView.m in Sources */, D326483815887D5200930C67 /* OrderedDictionary.m in Sources */, - D326483E1588950F00930C67 /* UICallBar.m in Sources */, D32648441588F6FC00930C67 /* UIToggleButton.m in Sources */, D36FB2D51589EF7C0036F6F2 /* UIPauseButton.m in Sources */, D31C9C98158A1CDF00756B45 /* UIHistoryCell.m in Sources */, - D32409C3158B49A600C8C119 /* UILongTouchButton.m in Sources */, - D36C43C6158F2E5A0048BA40 /* UICallCell.m in Sources */, - D35E7581159328EB0066B1C1 /* UIAddressTextField.m in Sources */, - D35E7597159460580066B1C1 /* ChatViewController.m in Sources */, - D35E759F159460B70066B1C1 /* SettingsViewController.m in Sources */, + D35E7597159460580066B1C1 /* ChatsListView.m in Sources */, + D35E759F159460B70066B1C1 /* SettingsView.m in Sources */, + 63B81A101B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */, F03CA84318C72F1A0008889D /* UITextViewNoDefine.m in Sources */, + 63B81A0D1B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.m in Sources */, + 63F1DF4F1BCE985F00EDED90 /* UICallConferenceCell.m in Sources */, D37DC6C11594AE1800B2A5EB /* LinphoneCoreSettingsStore.m in Sources */, 63CD4B4F1A5AAC8C00B84282 /* DTAlertView.m in Sources */, D3EA53FD159850E80037DC6B /* LinphoneManager.m in Sources */, - D3EA540D1598528B0037DC6B /* ChatTableViewController.m in Sources */, + 63B81A0E1B57DA33009604A6 /* TPKeyboardAvoidingScrollView.m in Sources */, + 633888451BFB2C49001D5E7B /* HPGrowingTextView.m in Sources */, + 6316FA6D1BE12A3E0050E441 /* UIRightImageButton.m in Sources */, + 63F1DF441BCE618E00EDED90 /* UIAddressTextField.m in Sources */, + D3EA540D1598528B0037DC6B /* ChatsListTableView.m in Sources */, D3EA5411159853750037DC6B /* UIChatCell.m in Sources */, - D3F26BF115986B73005F9CAB /* IncomingCallViewController.m in Sources */, - D31B4B21159876C0002E6C72 /* UICompositeViewController.m in Sources */, - D31AAF5E159B3919002C6B02 /* InCallTableViewController.m in Sources */, - D3211BB0159C4EF10098460B /* UIConferenceHeader.m in Sources */, - D32460E6159D9AAD00BA7F3A /* UITransparentView.m in Sources */, + D3F26BF115986B73005F9CAB /* CallIncomingView.m in Sources */, + D31B4B21159876C0002E6C72 /* UICompositeView.m in Sources */, + D31AAF5E159B3919002C6B02 /* CallPausedTableView.m in Sources */, D32B9DFC15A2F131000B6DEC /* FastAddressBook.m in Sources */, D3196D3E15A32BD8007FEEBA /* UITransferButton.m in Sources */, - D350F20E15A43BB100149E54 /* WizardViewController.m in Sources */, - D3F795D615A582810077328B /* ChatRoomViewController.m in Sources */, - D32B6E2915A5BC440033019F /* ChatRoomTableViewController.m in Sources */, - D3A8BB7015A6C7D500F96BE5 /* UIChatRoomCell.m in Sources */, - D3128FE115AABC7E00A2147A /* ContactDetailsViewController.m in Sources */, - D37C639515AADDAF009D0BAC /* UIContactDetailsHeader.m in Sources */, - D37C639B15AADEF6009D0BAC /* ContactDetailsTableViewController.m in Sources */, - 636316DE1A1DEF2F0009B839 /* UIButtonShrinkable.m in Sources */, - D3C6526715AC1A8F0092A874 /* UIEditableTableViewCell.m in Sources */, - D378906515AC373B00BD776C /* ContactDetailsLabelViewController.m in Sources */, - D3E8F68615ADE05B0065A226 /* UIContactDetailsFooter.m in Sources */, - C90FAA7915AF54E6002091CB /* HistoryDetailsViewController.m in Sources */, + D350F20E15A43BB100149E54 /* AssistantView.m in Sources */, + D3F795D615A582810077328B /* ChatConversationView.m in Sources */, + D32B6E2915A5BC440033019F /* ChatConversationTableView.m in Sources */, + D3A8BB7015A6C7D500F96BE5 /* UIChatBubbleTextCell.m in Sources */, + D3128FE115AABC7E00A2147A /* ContactDetailsView.m in Sources */, + D37C639B15AADEF6009D0BAC /* ContactDetailsTableView.m in Sources */, + 63E59A3F1ADE70D900646FB3 /* InAppProductsManager.m in Sources */, + D3C6526715AC1A8F0092A874 /* UIContactDetailsCell.m in Sources */, + 631348301B6F7B6600C6BDCB /* UIRoundBorderedButton.m in Sources */, + C90FAA7915AF54E6002091CB /* HistoryDetailsView.m in Sources */, 63FB30351A680E73008CA393 /* UIRoundedImageView.m in Sources */, - F066515517F9A02E0064280C /* UITransparentTVCell.m in Sources */, - D3F9A9EE15AF277E0045320F /* UACellBackgroundView.m in Sources */, + 635775251B6673EC00C8B704 /* HistoryDetailsTableView.m in Sources */, + 63C441C31BBC23ED0053DC5E /* UIAssistantTextField.m in Sources */, + 6346100F1B61409800548952 /* CallOutgoingView.m in Sources */, D35860D615B549B500513429 /* Utils.m in Sources */, D3F7998115BD32370018C273 /* TPMultiLayoutViewController.m in Sources */, D3807FBF15C28940005BE9BC /* DCRoundSwitch.m in Sources */, D3807FC115C28940005BE9BC /* DCRoundSwitchKnobLayer.m in Sources */, + 6306440E1BECB08500134C72 /* FirstLoginView.m in Sources */, D3807FC315C28940005BE9BC /* DCRoundSwitchOutlineLayer.m in Sources */, D3807FC515C28940005BE9BC /* DCRoundSwitchToggleLayer.m in Sources */, D3807FE815C2894A005BE9BC /* IASKAppSettingsViewController.m in Sources */, @@ -3999,25 +3503,22 @@ D3807FF015C2894A005BE9BC /* IASKSettingsStore.m in Sources */, D3807FF215C2894A005BE9BC /* IASKSettingsStoreFile.m in Sources */, D3807FF415C2894A005BE9BC /* IASKSettingsStoreUserDefaults.m in Sources */, + 639E9C801C0DB13D00019A75 /* UICheckBoxTableView.m in Sources */, D3807FF615C2894A005BE9BC /* IASKSpecifier.m in Sources */, D3807FF815C2894A005BE9BC /* IASKPSSliderSpecifierViewCell.m in Sources */, D3807FFA15C2894A005BE9BC /* IASKPSTextFieldSpecifierViewCell.m in Sources */, - 631C4FB719D2C3A6004BFE77 /* UIDigitButtonLongVoiceMail.m in Sources */, D3807FFC15C2894A005BE9BC /* IASKPSTitleValueSpecifierViewCell.m in Sources */, D3807FFE15C2894A005BE9BC /* IASKSlider.m in Sources */, D380800015C2894A005BE9BC /* IASKSwitch.m in Sources */, D380800215C2894A005BE9BC /* IASKTextField.m in Sources */, - D380800515C28A7A005BE9BC /* UILinphone.m in Sources */, D380801315C299D0005BE9BC /* ColorSpaceUtilites.m in Sources */, - D378AB2A15DCDB4A0098505D /* ImagePickerViewController.m in Sources */, - 22405F001601C19200B92522 /* ImageViewController.m in Sources */, - D3ED40191602172200BF332B /* HPGrowingTextView.m in Sources */, - D3ED401B1602172200BF332B /* HPTextViewInternal.m in Sources */, + 637157A11B283FE200C91677 /* FileTransferDelegate.m in Sources */, + D378AB2A15DCDB4A0098505D /* ImagePickerView.m in Sources */, + 22405F001601C19200B92522 /* ImageView.m in Sources */, + 63BC49E21BA2CDFC004EC273 /* UICallPausedCell.m in Sources */, D37EE162160377D7003608A6 /* DTActionSheet.m in Sources */, - D374D3FD16071762003D25FF /* ImageSharing.m in Sources */, - D35E91F4160CA10B0023116B /* UILinphoneTextField.m in Sources */, - D35E91F8160CA4FF0023116B /* UILinphoneButton.m in Sources */, D306459E1611EC2A00BB571E /* UILoadingImageView.m in Sources */, + 6381DA7D1C1AD5EA00DF3BBD /* UIBouncingView.m in Sources */, D37E3ECD1619C27A0087659A /* CAAnimation+Blocks.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4026,9 +3527,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - F08F119D19C0A65B007D70C2 /* NSObject+DTRuntime.m in Sources */, - F08F118F19C09C6B007D70C2 /* LinphoneTester_Tests.m in Sources */, - F08F11A019C0A6CB007D70C2 /* DTObjectBlockExecutor.m in Sources */, + 632DA24E1B43EEEF00EB356A /* Utils.m in Sources */, + 63058A3C1B4E822F00EFAE36 /* DTObjectBlockExecutor.m in Sources */, + 63058A3F1B4E823000EFAE36 /* NSObject+DTRuntime.m in Sources */, + 63058A3E1B4E822F00EFAE36 /* LinphoneTester_Tests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4036,11 +3538,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - F0BB8BE41936208100974404 /* AppDelegate.m in Sources */, - F84015C7193B4E34006ABAB5 /* LogsViewController.m in Sources */, - F0BB8BED1936208200974404 /* MasterViewController.m in Sources */, - F0BB8BE01936208100974404 /* main.m in Sources */, - F0BB8BF01936208200974404 /* DetailViewController.m in Sources */, + 63058A2D1B4E821E00EFAE36 /* main.m in Sources */, + 63058A241B4E821E00EFAE36 /* AppDelegate.m in Sources */, + 632DA24D1B43EE9400EB356A /* Utils.m in Sources */, + 63058A2A1B4E821E00EFAE36 /* DetailView.m in Sources */, + 63058A2E1B4E821E00EFAE36 /* MasterView.m in Sources */, + 63058A2C1B4E821E00EFAE36 /* LogsView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4048,36 +3551,31 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - F0A1CE081A6B056E001CA2BE /* ChatTester.m in Sources */, - F844AB141A93E3A200428306 /* ContactsTester.m in Sources */, - F85554481A6DA2F400A9F915 /* LinphoneTestCase.m in Sources */, - F0F952121A6AECD300254160 /* WizardTester.m in Sources */, + 630589EA1B4E810900EFAE36 /* LinphoneTestCase.m in Sources */, + 630589EB1B4E810900EFAE36 /* AssistantTester.m in Sources */, + 630589E71B4E810900EFAE36 /* ChatTester.m in Sources */, + 630589E81B4E810900EFAE36 /* ContactsTester.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 63058A4E1B4E832500EFAE36 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = KIF; + targetProxy = 63058A4D1B4E832500EFAE36 /* PBXContainerItemProxy */; + }; D3554ED515CA79B900478841 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = libXMLRPC; targetProxy = D3554ED415CA79B900478841 /* PBXContainerItemProxy */; }; - D3B90E1B15C2CBC800F64F8C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = NinePatch; - targetProxy = D3B90E1A15C2CBC800F64F8C /* PBXContainerItemProxy */; - }; F08F119219C09C6B007D70C2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = F0BB8BD41936208100974404 /* LinphoneTester */; + target = F0BB8BD41936208100974404 /* liblinphoneTester */; targetProxy = F08F119119C09C6B007D70C2 /* PBXContainerItemProxy */; }; - F0C773911A94827E00E0C486 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = KIF; - targetProxy = F0C773901A94827E00E0C486 /* PBXContainerItemProxy */; - }; F0F952071A6AEB1000254160 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 1D6058900D05DD3D006BFB54 /* linphone */; @@ -4086,52 +3584,123 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ - 2214783B1386A2030020F8B8 /* Localizable.strings */ = { + 63058A0F1B4E821E00EFAE36 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( - 2214783C1386A2030020F8B8 /* en */, - D381885815FE44A700C3EDCA /* fr */, - FD979F30169E84670022A8B4 /* ru */, - F0ADFCF91A78EB83004F1102 /* ar */, + 63058A101B4E821E00EFAE36 /* ar */, + 63058A1B1B4E821E00EFAE36 /* en */, ); - name = Localizable.strings; + name = InfoPlist.strings; sourceTree = ""; }; - 636316D31A1DEBCB0009B839 /* AboutViewController.xib */ = { + 63058A111B4E821E00EFAE36 /* Main_iPad.strings */ = { + isa = PBXVariantGroup; + children = ( + 63058A121B4E821E00EFAE36 /* ar */, + ); + name = Main_iPad.strings; + sourceTree = ""; + }; + 63058A131B4E821E00EFAE36 /* Main_iPhone.strings */ = { + isa = PBXVariantGroup; + children = ( + 63058A141B4E821E00EFAE36 /* ar */, + ); + name = Main_iPhone.strings; + sourceTree = ""; + }; + 63058A151B4E821E00EFAE36 /* Main_iPad.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 63058A161B4E821E00EFAE36 /* Base */, + ); + name = Main_iPad.storyboard; + sourceTree = ""; + }; + 63058A171B4E821E00EFAE36 /* Main_iPhone.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 63058A181B4E821E00EFAE36 /* Base */, + ); + name = Main_iPhone.storyboard; + sourceTree = ""; + }; + 63058A311B4E822F00EFAE36 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 63058A321B4E822F00EFAE36 /* ar */, + 63058A351B4E822F00EFAE36 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 63130FB01C1ED06900371918 /* SideMenuView~ipad.xib */ = { + isa = PBXVariantGroup; + children = ( + 63130FB11C1ED06900371918 /* Base */, + ); + name = "SideMenuView~ipad.xib"; + sourceTree = ""; + }; + 634610101B6140A500548952 /* CallOutgoingView.xib */ = { + isa = PBXVariantGroup; + children = ( + 634610111B6140A500548952 /* Base */, + ); + name = CallOutgoingView.xib; + sourceTree = ""; + }; + 636316D31A1DEBCB0009B839 /* AboutView.xib */ = { isa = PBXVariantGroup; children = ( 636316D21A1DEBCB0009B839 /* Base */, 63EF7FDC1A24B5810017A416 /* fr */, F0AF06F01A24BA760086C9C1 /* ar */, ); - name = AboutViewController.xib; + name = AboutView.xib; sourceTree = ""; }; - 636316D61A1DEC650009B839 /* SettingsViewController.xib */ = { + 636316D61A1DEC650009B839 /* SettingsView.xib */ = { isa = PBXVariantGroup; children = ( 636316D51A1DEC650009B839 /* Base */, F0AF070E1A24BA770086C9C1 /* ar */, ); - name = SettingsViewController.xib; + name = SettingsView.xib; sourceTree = ""; }; - 636316D71A1DECC90009B839 /* PhoneMainView.xib */ = { + 638F1A601C2021B2004B8E02 /* DialerView~ipad.xib */ = { isa = PBXVariantGroup; children = ( - 636316D81A1DECC90009B839 /* Base */, - F0AF070D1A24BA770086C9C1 /* ar */, + 638F1A611C2021B2004B8E02 /* Base */, ); - name = PhoneMainView.xib; + name = "DialerView~ipad.xib"; sourceTree = ""; }; - 639CEAFF1A1DF4D9004DE38F /* UIStateBar.xib */ = { + 638F1A861C2167C2004B8E02 /* CallView~ipad.xib */ = { + isa = PBXVariantGroup; + children = ( + 638F1A871C2167C2004B8E02 /* Base */, + ); + name = "CallView~ipad.xib"; + sourceTree = ""; + }; + 638F1A8F1C21993D004B8E02 /* UICompositeView~ipad.xib */ = { + isa = PBXVariantGroup; + children = ( + 638F1A901C21993D004B8E02 /* Base */, + ); + name = "UICompositeView~ipad.xib"; + sourceTree = ""; + }; + 639CEAFF1A1DF4D9004DE38F /* StatusBarView.xib */ = { isa = PBXVariantGroup; children = ( 639CEAFE1A1DF4D9004DE38F /* Base */, F0AF070C1A24BA770086C9C1 /* ar */, ); - name = UIStateBar.xib; + name = StatusBarView.xib; + path = LinphoneUI; sourceTree = ""; }; 639CEB021A1DF4E4004DE38F /* UIHistoryCell.xib */ = { @@ -4143,22 +3712,13 @@ name = UIHistoryCell.xib; sourceTree = ""; }; - 639CEB051A1DF4EB004DE38F /* UICompositeViewController.xib */ = { + 639CEB051A1DF4EB004DE38F /* UICompositeView.xib */ = { isa = PBXVariantGroup; children = ( 639CEB041A1DF4EB004DE38F /* Base */, F0AF07041A24BA770086C9C1 /* ar */, ); - name = UICompositeViewController.xib; - sourceTree = ""; - }; - 639CEB081A1DF4F1004DE38F /* UIChatRoomCell.xib */ = { - isa = PBXVariantGroup; - children = ( - 639CEB071A1DF4F1004DE38F /* Base */, - F0AF07031A24BA770086C9C1 /* ar */, - ); - name = UIChatRoomCell.xib; + name = UICompositeView.xib; sourceTree = ""; }; 639CEB0B1A1DF4FA004DE38F /* UIChatCell.xib */ = { @@ -4170,7 +3730,118 @@ name = UIChatCell.xib; sourceTree = ""; }; - D37EE11016035793003608A6 /* ImageViewController.xib */ = { + 639E9C951C0DB7BE00019A75 /* FirstLoginView.xib */ = { + isa = PBXVariantGroup; + children = ( + 639E9C941C0DB7BE00019A75 /* Base */, + ); + name = FirstLoginView.xib; + sourceTree = ""; + }; + 639E9C9C1C0DB7D300019A75 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 639E9C9B1C0DB7D300019A75 /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; + 639E9C9F1C0DB7DF00019A75 /* UICallPausedCell.xib */ = { + isa = PBXVariantGroup; + children = ( + 639E9C9E1C0DB7DF00019A75 /* Base */, + ); + name = UICallPausedCell.xib; + sourceTree = ""; + }; + 639E9CA21C0DB7E500019A75 /* UIChatBubblePhotoCell.xib */ = { + isa = PBXVariantGroup; + children = ( + 639E9CA11C0DB7E500019A75 /* Base */, + ); + name = UIChatBubblePhotoCell.xib; + sourceTree = ""; + }; + 639E9CA51C0DB7EA00019A75 /* UIChatBubbleTextCell.xib */ = { + isa = PBXVariantGroup; + children = ( + 639E9CA41C0DB7EA00019A75 /* Base */, + ); + name = UIChatBubbleTextCell.xib; + sourceTree = ""; + }; + 639E9CA81C0DB7F200019A75 /* UIChatCreateCell.xib */ = { + isa = PBXVariantGroup; + children = ( + 639E9CA71C0DB7F200019A75 /* Base */, + ); + name = UIChatCreateCell.xib; + sourceTree = ""; + }; + 639E9CAB1C0DB7FB00019A75 /* UIConfirmationDialog.xib */ = { + isa = PBXVariantGroup; + children = ( + 639E9CAA1C0DB7FB00019A75 /* Base */, + ); + name = UIConfirmationDialog.xib; + sourceTree = ""; + }; + 639E9CAE1C0DB80300019A75 /* UIContactDetailsCell.xib */ = { + isa = PBXVariantGroup; + children = ( + 639E9CAD1C0DB80300019A75 /* Base */, + ); + name = UIContactDetailsCell.xib; + sourceTree = ""; + }; + 639E9CB21C0DB83000019A75 /* SideMenuView.xib */ = { + isa = PBXVariantGroup; + children = ( + 639E9CB11C0DB83000019A75 /* Base */, + ); + name = SideMenuView.xib; + sourceTree = ""; + }; + 639E9CB31C0DB88200019A75 /* PhoneMainView.xib */ = { + isa = PBXVariantGroup; + children = ( + 639E9CB41C0DB88200019A75 /* Base */, + ); + name = PhoneMainView.xib; + sourceTree = ""; + }; + 63AADBC41B6A0FF200AA16FD /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 63AADBC51B6A0FF200AA16FD /* ar */, + 63AADBC61B6A0FF200AA16FD /* de */, + 63AADBC71B6A0FF200AA16FD /* en */, + 63AADBC81B6A0FF200AA16FD /* fr */, + 63AADBCB1B6A0FF200AA16FD /* ja */, + 63AADBDD1B6A0FF200AA16FD /* nl */, + 63AADBE11B6A0FF200AA16FD /* ru */, + 63AADBE71B6A0FF200AA16FD /* zh_TW */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 63B8D68E1BCBE65600C12B09 /* ChatConversationCreateView.xib */ = { + isa = PBXVariantGroup; + children = ( + 63B8D68D1BCBE65600C12B09 /* Base */, + ); + name = ChatConversationCreateView.xib; + sourceTree = ""; + }; + 63F1DF531BCE986A00EDED90 /* UICallConferenceCell.xib */ = { + isa = PBXVariantGroup; + children = ( + 63F1DF521BCE986A00EDED90 /* Base */, + ); + name = UICallConferenceCell.xib; + sourceTree = ""; + }; + D37EE11016035793003608A6 /* ImageView.xib */ = { isa = PBXVariantGroup; children = ( F09548221883F15400E8A69B /* Base */, @@ -4178,10 +3849,10 @@ F09548441883F52900E8A69B /* ru */, F0AF06FB1A24BA770086C9C1 /* ar */, ); - name = ImageViewController.xib; + name = ImageView.xib; sourceTree = ""; }; - D38187B015FE340100C3EDCA /* ChatRoomViewController.xib */ = { + D38187B015FE340100C3EDCA /* ChatConversationView.xib */ = { isa = PBXVariantGroup; children = ( F09548181883F15300E8A69B /* Base */, @@ -4189,10 +3860,10 @@ F09548321883F20A00E8A69B /* ru */, F0AF06F11A24BA760086C9C1 /* ar */, ); - name = ChatRoomViewController.xib; + name = ChatConversationView.xib; sourceTree = ""; }; - D38187B415FE340500C3EDCA /* ChatViewController.xib */ = { + D38187B415FE340500C3EDCA /* ChatsListView.xib */ = { isa = PBXVariantGroup; children = ( F09548191883F15300E8A69B /* Base */, @@ -4200,21 +3871,10 @@ F09548341883F25F00E8A69B /* ru */, F0AF06F21A24BA760086C9C1 /* ar */, ); - name = ChatViewController.xib; + name = ChatsListView.xib; sourceTree = ""; }; - D38187B815FE341B00C3EDCA /* ContactDetailsLabelViewController.xib */ = { - isa = PBXVariantGroup; - children = ( - F095481A1883F15300E8A69B /* Base */, - F09548351883F28100E8A69B /* fr */, - F09548361883F28400E8A69B /* ru */, - F0AF06F31A24BA760086C9C1 /* ar */, - ); - name = ContactDetailsLabelViewController.xib; - sourceTree = ""; - }; - D38187BC15FE342200C3EDCA /* ContactDetailsViewController.xib */ = { + D38187BC15FE342200C3EDCA /* ContactDetailsView.xib */ = { isa = PBXVariantGroup; children = ( F095481B1883F15300E8A69B /* Base */, @@ -4222,10 +3882,10 @@ F09548381883F29C00E8A69B /* ru */, F0AF06F41A24BA760086C9C1 /* ar */, ); - name = ContactDetailsViewController.xib; + name = ContactDetailsView.xib; sourceTree = ""; }; - D38187C015FE342800C3EDCA /* ContactsViewController.xib */ = { + D38187C015FE342800C3EDCA /* ContactsListView.xib */ = { isa = PBXVariantGroup; children = ( F095481C1883F15300E8A69B /* Base */, @@ -4233,10 +3893,10 @@ F095483A1883F2CA00E8A69B /* ru */, F0AF06F51A24BA760086C9C1 /* ar */, ); - name = ContactsViewController.xib; + name = ContactsListView.xib; sourceTree = ""; }; - D38187C415FE345B00C3EDCA /* DialerViewController.xib */ = { + D38187C415FE345B00C3EDCA /* DialerView.xib */ = { isa = PBXVariantGroup; children = ( F095481D1883F15300E8A69B /* Base */, @@ -4244,32 +3904,10 @@ F095483C1883F2E300E8A69B /* ru */, F0AF06F61A24BA760086C9C1 /* ar */, ); - name = DialerViewController.xib; + name = DialerView.xib; sourceTree = ""; }; - D38187C815FE345F00C3EDCA /* DialerViewController~ipad.xib */ = { - isa = PBXVariantGroup; - children = ( - F095481E1883F15300E8A69B /* Base */, - F095483D1883F49E00E8A69B /* fr */, - F095483E1883F4A200E8A69B /* ru */, - F0AF06F71A24BA760086C9C1 /* ar */, - ); - name = "DialerViewController~ipad.xib"; - sourceTree = ""; - }; - D38187CC15FE346400C3EDCA /* FirstLoginViewController.xib */ = { - isa = PBXVariantGroup; - children = ( - F095481F1883F15300E8A69B /* Base */, - F095483F1883F4B700E8A69B /* fr */, - F09548401883F4BC00E8A69B /* ru */, - F0AF06F81A24BA760086C9C1 /* ar */, - ); - name = FirstLoginViewController.xib; - sourceTree = ""; - }; - D38187D015FE346700C3EDCA /* HistoryDetailsViewController.xib */ = { + D38187D015FE346700C3EDCA /* HistoryDetailsView.xib */ = { isa = PBXVariantGroup; children = ( F09548201883F15400E8A69B /* Base */, @@ -4277,10 +3915,10 @@ 636316DB1A1DEDD80009B839 /* ru */, F0AF06F91A24BA760086C9C1 /* ar */, ); - name = HistoryDetailsViewController.xib; + name = HistoryDetailsView.xib; sourceTree = ""; }; - D38187D415FE346B00C3EDCA /* HistoryViewController.xib */ = { + D38187D415FE346B00C3EDCA /* HistoryListView.xib */ = { isa = PBXVariantGroup; children = ( F09548211883F15400E8A69B /* Base */, @@ -4288,10 +3926,10 @@ F09548421883F51B00E8A69B /* ru */, F0AF06FA1A24BA770086C9C1 /* ar */, ); - name = HistoryViewController.xib; + name = HistoryListView.xib; sourceTree = ""; }; - D38187DC15FE347700C3EDCA /* IncomingCallViewController.xib */ = { + D38187DC15FE347700C3EDCA /* CallIncomingView.xib */ = { isa = PBXVariantGroup; children = ( F09548241883F15400E8A69B /* Base */, @@ -4299,10 +3937,10 @@ F09548481883F55800E8A69B /* ru */, F0AF06FD1A24BA770086C9C1 /* ar */, ); - name = IncomingCallViewController.xib; + name = CallIncomingView.xib; sourceTree = ""; }; - D38187E015FE348A00C3EDCA /* WizardViewController.xib */ = { + D38187E015FE348A00C3EDCA /* AssistantView.xib */ = { isa = PBXVariantGroup; children = ( F095482E1883F15500E8A69B /* Base */, @@ -4310,54 +3948,10 @@ F095485A1883F67B00E8A69B /* ru */, F0AF070F1A24BA770086C9C1 /* ar */, ); - name = WizardViewController.xib; + name = AssistantView.xib; sourceTree = ""; }; - D38187E415FE349700C3EDCA /* UICallBar.xib */ = { - isa = PBXVariantGroup; - children = ( - F09548261883F15400E8A69B /* Base */, - F095484B1883F58E00E8A69B /* fr */, - F095484C1883F59200E8A69B /* ru */, - F0AF06FF1A24BA770086C9C1 /* ar */, - ); - name = UICallBar.xib; - sourceTree = ""; - }; - D38187E815FE349D00C3EDCA /* UICallBar~ipad.xib */ = { - isa = PBXVariantGroup; - children = ( - F09548271883F15400E8A69B /* Base */, - F095484D1883F5AF00E8A69B /* fr */, - F095484E1883F5B300E8A69B /* ru */, - F0AF07001A24BA770086C9C1 /* ar */, - ); - name = "UICallBar~ipad.xib"; - sourceTree = ""; - }; - D38187F315FE354000C3EDCA /* UIConferenceHeader.xib */ = { - isa = PBXVariantGroup; - children = ( - F09548291883F15400E8A69B /* Base */, - F095484F1883F5D500E8A69B /* fr */, - F09548501883F5D900E8A69B /* ru */, - F0AF07051A24BA770086C9C1 /* ar */, - ); - name = UIConferenceHeader.xib; - sourceTree = ""; - }; - D38187F715FE354700C3EDCA /* UIContactDetailsFooter.xib */ = { - isa = PBXVariantGroup; - children = ( - F095482A1883F15400E8A69B /* Base */, - F09548511883F5E300E8A69B /* fr */, - F09548521883F5E600E8A69B /* ru */, - F0AF07071A24BA770086C9C1 /* ar */, - ); - name = UIContactDetailsFooter.xib; - sourceTree = ""; - }; - D38187FB15FE355D00C3EDCA /* UIMainBar.xib */ = { + D38187FB15FE355D00C3EDCA /* TabBarView.xib */ = { isa = PBXVariantGroup; children = ( F095482C1883F15400E8A69B /* Base */, @@ -4365,43 +3959,11 @@ F09548561883F61600E8A69B /* ru */, F0AF070A1A24BA770086C9C1 /* ar */, ); - name = UIMainBar.xib; + name = TabBarView.xib; + path = LinphoneUI; sourceTree = ""; }; - D38187FF15FE356100C3EDCA /* UIMainBar~ipad.xib */ = { - isa = PBXVariantGroup; - children = ( - F095482D1883F15500E8A69B /* Base */, - F09548571883F66600E8A69B /* fr */, - F09548581883F66A00E8A69B /* ru */, - F0AF070B1A24BA770086C9C1 /* ar */, - ); - name = "UIMainBar~ipad.xib"; - sourceTree = ""; - }; - D381881415FE3F0B00C3EDCA /* UICallCell.xib */ = { - isa = PBXVariantGroup; - children = ( - F09548281883F15400E8A69B /* Base */, - 639CEB0C1A1DF528004DE38F /* fr */, - 639CEB0D1A1DF52C004DE38F /* ru */, - F0AF07011A24BA770086C9C1 /* ar */, - ); - name = UICallCell.xib; - sourceTree = ""; - }; - D381881815FE3F7F00C3EDCA /* UIContactDetailsHeader.xib */ = { - isa = PBXVariantGroup; - children = ( - F095482B1883F15400E8A69B /* Base */, - F09548531883F5F400E8A69B /* fr */, - F09548541883F5F700E8A69B /* ru */, - F0AF07081A24BA770086C9C1 /* ar */, - ); - name = UIContactDetailsHeader.xib; - sourceTree = ""; - }; - D381881C15FE3FCA00C3EDCA /* InCallViewController.xib */ = { + D381881C15FE3FCA00C3EDCA /* CallView.xib */ = { isa = PBXVariantGroup; children = ( F09548231883F15400E8A69B /* Base */, @@ -4409,10 +3971,10 @@ F09548461883F54200E8A69B /* ru */, F0AF06FC1A24BA770086C9C1 /* ar */, ); - name = InCallViewController.xib; + name = CallView.xib; sourceTree = ""; }; - D3D5126A160B3A8E00946DF8 /* WizardViews.xib */ = { + D3D5126A160B3A8E00946DF8 /* AssistantViewScreens.xib */ = { isa = PBXVariantGroup; children = ( F09548301883F15500E8A69B /* Base */, @@ -4420,29 +3982,7 @@ F095485E1883F6EA00E8A69B /* ru */, F0AF07111A24BA770086C9C1 /* ar */, ); - name = WizardViews.xib; - sourceTree = ""; - }; - D3D5126E160B3AD400946DF8 /* WizardViewController~ipad.xib */ = { - isa = PBXVariantGroup; - children = ( - F095482F1883F15500E8A69B /* Base */, - F095485B1883F68500E8A69B /* fr */, - F095485C1883F68800E8A69B /* ru */, - F0AF07101A24BA770086C9C1 /* ar */, - ); - name = "WizardViewController~ipad.xib"; - sourceTree = ""; - }; - D3D52A711614480700DEB00A /* IncomingCallViewController~ipad.xib */ = { - isa = PBXVariantGroup; - children = ( - F09548251883F15400E8A69B /* Base */, - F09548491883F56A00E8A69B /* fr */, - F095484A1883F56E00E8A69B /* ru */, - F0AF06FE1A24BA770086C9C1 /* ar */, - ); - name = "IncomingCallViewController~ipad.xib"; + name = AssistantViewScreens.xib; sourceTree = ""; }; F088488D19FF8C41007FFCF3 /* UIContactCell.xib */ = { @@ -4455,42 +3995,6 @@ name = UIContactCell.xib; sourceTree = ""; }; - F08F118B19C09C6B007D70C2 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - F08F118C19C09C6B007D70C2 /* en */, - F0AF07161A24BA780086C9C1 /* ar */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; - F0BB8BDC1936208100974404 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - F0BB8BDD1936208100974404 /* en */, - F0AF07151A24BA780086C9C1 /* ar */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; - F0BB8BE51936208100974404 /* Main_iPhone.storyboard */ = { - isa = PBXVariantGroup; - children = ( - F0BB8BE61936208100974404 /* Base */, - F0AF07131A24BA780086C9C1 /* ar */, - ); - name = Main_iPhone.storyboard; - sourceTree = ""; - }; - F0BB8BE81936208200974404 /* Main_iPad.storyboard */ = { - isa = PBXVariantGroup; - children = ( - F0BB8BE91936208200974404 /* Base */, - F0AF07121A24BA780086C9C1 /* ar */, - ); - name = Main_iPad.storyboard; - sourceTree = ""; - }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -4501,6 +4005,8 @@ ARCHS = "$(ARCHS_STANDARD)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_UNREACHABLE_CODE = NO; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COMPRESS_PNG_FILES = NO; @@ -4512,30 +4018,29 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = linphone_Prefix.pch; GCC_PREPROCESSOR_DEFINITIONS = ( - VIDEO_ENABLED, - HAVE_OPENH264, - HAVE_SILK, - HAVE_SSL, + USE_APN_DEV, DEBUG, ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; HEADER_SEARCH_PATHS = ( "$(SRCROOT)/liblinphone-sdk/apple-darwin/include", "$(SRCROOT)/Classes/Utils/NinePatch/", "$(SRCROOT)/Classes/Utils/XMLRPC/", ); INFOPLIST_FILE = "linphone-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; LIBRARY_SEARCH_PATHS = ( "$(BUILT_PRODUCTS_DIR)", "$(SRCROOT)/liblinphone-sdk/apple-darwin/lib", "$(SRCROOT)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", + "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); LINK_WITH_STANDARD_LIBRARIES = YES; ORDER_FILE = ""; OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_NAME = linphone; PROVISIONING_PROFILE = ""; SKIP_INSTALL = NO; @@ -4543,6 +4048,7 @@ WARNING_CFLAGS = ( "-Werror=objc-method-access", "-Werror=incomplete-implementation", + "-DLINPHONE_CAPABILITY_INAPP_PURCHASE=0", ); }; name = Debug; @@ -4558,7 +4064,9 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Distribution: jehan monnier"; + ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_THUMB_SUPPORT = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -4568,7 +4076,7 @@ GCC_WARN_UNUSED_FUNCTION = NO; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ""; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; LIBRARY_SEARCH_PATHS = ""; PROVISIONING_PROFILE = "0636A6EA-90EB-4D92-B707-19FC32F9A7CF"; SDKROOT = iphoneos; @@ -4585,6 +4093,8 @@ ARCHS = "$(ARCHS_STANDARD)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_UNREACHABLE_CODE = NO; CODE_SIGN_ENTITLEMENTS = ""; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -4596,29 +4106,26 @@ GCC_OPTIMIZATION_LEVEL = s; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = linphone_Prefix.pch; - GCC_PREPROCESSOR_DEFINITIONS = ( - VIDEO_ENABLED, - HAVE_SILK, - HAVE_SSL, - ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; HEADER_SEARCH_PATHS = ( "$(SRCROOT)/liblinphone-sdk/apple-darwin/include", "$(SRCROOT)/Classes/Utils/NinePatch/", "$(SRCROOT)/Classes/Utils/XMLRPC/", ); INFOPLIST_FILE = "linphone-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; LIBRARY_SEARCH_PATHS = ( "$(BUILT_PRODUCTS_DIR)", "$(SRCROOT)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", "$(SRCROOT)/liblinphone-sdk/apple-darwin/lib", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", + "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); LINK_WITH_STANDARD_LIBRARIES = YES; ORDER_FILE = ""; OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_NAME = linphone; PROVISIONING_PROFILE = ""; SKIP_INSTALL = NO; @@ -4626,6 +4133,7 @@ WARNING_CFLAGS = ( "-Werror=objc-method-access", "-Werror=incomplete-implementation", + "-DLINPHONE_CAPABILITY_INAPP_PURCHASE=0", ); }; name = DistributionAdhoc; @@ -4641,7 +4149,9 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; + ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_THUMB_SUPPORT = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -4651,7 +4161,7 @@ GCC_WARN_UNUSED_FUNCTION = NO; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ""; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; LIBRARY_SEARCH_PATHS = ""; PROVISIONING_PROFILE = ""; SDKROOT = iphoneos; @@ -4668,7 +4178,9 @@ ARCHS = "$(ARCHS_STANDARD)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - CODE_SIGN_IDENTITY = "iPhone Distribution"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_UNREACHABLE_CODE = NO; + CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COMPRESS_PNG_FILES = NO; COPY_PHASE_STRIP = NO; @@ -4678,29 +4190,27 @@ GCC_OPTIMIZATION_LEVEL = s; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = linphone_Prefix.pch; - GCC_PREPROCESSOR_DEFINITIONS = ( - VIDEO_ENABLED, - HAVE_SILK, - HAVE_SSL, - ); + GCC_PREPROCESSOR_DEFINITIONS = USE_APN_DEV; GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; HEADER_SEARCH_PATHS = ( "$(SRCROOT)/liblinphone-sdk/apple-darwin/include", "$(SRCROOT)/Classes/Utils/NinePatch/", "$(SRCROOT)/Classes/Utils/XMLRPC/", ); INFOPLIST_FILE = "linphone-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; LIBRARY_SEARCH_PATHS = ( "$(BUILT_PRODUCTS_DIR)", "$(SRCROOT)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", "$(SRCROOT)/liblinphone-sdk/apple-darwin/lib", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", + "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); LINK_WITH_STANDARD_LIBRARIES = YES; ORDER_FILE = ""; OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_NAME = linphone; PROVISIONING_PROFILE = ""; SKIP_INSTALL = NO; @@ -4708,6 +4218,7 @@ WARNING_CFLAGS = ( "-Werror=objc-method-access", "-Werror=incomplete-implementation", + "-DLINPHONE_CAPABILITY_INAPP_PURCHASE=0", ); }; name = Release; @@ -4723,7 +4234,9 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Distribution: jehan monnier"; + ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_THUMB_SUPPORT = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -4733,7 +4246,7 @@ GCC_WARN_UNUSED_FUNCTION = NO; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ""; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; LIBRARY_SEARCH_PATHS = ""; PROVISIONING_PROFILE = "C7F794BC-6D48-41F2-B37D-E1B1B1A40901"; SDKROOT = iphoneos; @@ -4750,6 +4263,8 @@ ARCHS = "$(ARCHS_STANDARD)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_UNREACHABLE_CODE = NO; CODE_SIGN_ENTITLEMENTS = ""; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -4761,29 +4276,26 @@ GCC_OPTIMIZATION_LEVEL = s; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = linphone_Prefix.pch; - GCC_PREPROCESSOR_DEFINITIONS = ( - VIDEO_ENABLED, - HAVE_SILK, - HAVE_SSL, - ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_TREAT_WARNINGS_AS_ERRORS = NO; + GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; HEADER_SEARCH_PATHS = ( "$(SRCROOT)/liblinphone-sdk/apple-darwin/include", "$(SRCROOT)/Classes/Utils/NinePatch/", "$(SRCROOT)/Classes/Utils/XMLRPC/", ); INFOPLIST_FILE = "linphone-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; LIBRARY_SEARCH_PATHS = ( "$(BUILT_PRODUCTS_DIR)", "$(SRCROOT)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", "$(SRCROOT)/liblinphone-sdk/apple-darwin/lib", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", + "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); LINK_WITH_STANDARD_LIBRARIES = YES; ORDER_FILE = ""; OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_NAME = linphone; PROVISIONING_PROFILE = ""; SKIP_INSTALL = NO; @@ -4791,6 +4303,7 @@ WARNING_CFLAGS = ( "-Werror=objc-method-access", "-Werror=incomplete-implementation", + "-DLINPHONE_CAPABILITY_INAPP_PURCHASE=0", ); }; name = Distribution; @@ -4806,7 +4319,10 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer: jehan monnier (E8MYPN2NXL)"; + ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_THUMB_SUPPORT = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -4816,14 +4332,14 @@ GCC_WARN_UNUSED_FUNCTION = NO; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ""; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; LIBRARY_SEARCH_PATHS = ""; - ONLY_ACTIVE_ARCH = NO; + ONLY_ACTIVE_ARCH = YES; PROVISIONING_PROFILE = "2AC0DC11-4546-47B6-8B8A-453CCA80903C"; SDKROOT = iphoneos; STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = dynamic; TARGETED_DEVICE_FAMILY = "1,2"; - VALID_ARCHS = armv7; + VALID_ARCHS = "arm64 armv7"; }; name = Debug; }; @@ -4831,7 +4347,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LinphoneTester.app/LinphoneTester"; + BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -4843,16 +4359,12 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - "$(DEVELOPER_FRAMEWORKS_DIR)", - ); + ENABLE_BITCODE = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "LinphoneTester Tests/LinphoneTester Tests-Prefix.pch"; + GCC_PREFIX_HEADER = "TestsLiblinphone/LinphoneTesterTests-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", @@ -4868,8 +4380,7 @@ Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, ); - INFOPLIST_FILE = "LinphoneTester Tests/LinphoneTester Tests-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + INFOPLIST_FILE = "TestsLiblinphone/LinphoneTesterTests-Info.plist"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", @@ -4878,7 +4389,7 @@ ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; - TEST_HOST = "$(BUNDLE_LOADER)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/liblinphoneTester.app/liblinphoneTester"; WRAPPER_EXTENSION = xctest; }; name = Debug; @@ -4887,7 +4398,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LinphoneTester.app/LinphoneTester"; + BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -4899,15 +4410,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - "$(DEVELOPER_FRAMEWORKS_DIR)", - ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "LinphoneTester Tests/LinphoneTester Tests-Prefix.pch"; + GCC_PREFIX_HEADER = "TestsLiblinphone/LinphoneTesterTests-Prefix.pch"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -4918,8 +4425,7 @@ Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, ); - INFOPLIST_FILE = "LinphoneTester Tests/LinphoneTester Tests-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + INFOPLIST_FILE = "TestsLiblinphone/LinphoneTesterTests-Info.plist"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", @@ -4927,7 +4433,7 @@ ); PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; - TEST_HOST = "$(BUNDLE_LOADER)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/liblinphoneTester.app/liblinphoneTester"; VALIDATE_PRODUCT = YES; WRAPPER_EXTENSION = xctest; }; @@ -4937,7 +4443,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LinphoneTester.app/LinphoneTester"; + BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -4949,15 +4455,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - "$(DEVELOPER_FRAMEWORKS_DIR)", - ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "LinphoneTester Tests/LinphoneTester Tests-Prefix.pch"; + GCC_PREFIX_HEADER = "TestsLiblinphone/LinphoneTesterTests-Prefix.pch"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -4968,8 +4470,7 @@ Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, ); - INFOPLIST_FILE = "LinphoneTester Tests/LinphoneTester Tests-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + INFOPLIST_FILE = "TestsLiblinphone/LinphoneTesterTests-Info.plist"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", @@ -4977,7 +4478,7 @@ ); PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; - TEST_HOST = "$(BUNDLE_LOADER)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/liblinphoneTester.app/liblinphoneTester"; VALIDATE_PRODUCT = YES; WRAPPER_EXTENSION = xctest; }; @@ -4987,7 +4488,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LinphoneTester.app/LinphoneTester"; + BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -4999,15 +4500,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - "$(DEVELOPER_FRAMEWORKS_DIR)", - ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "LinphoneTester Tests/LinphoneTester Tests-Prefix.pch"; + GCC_PREFIX_HEADER = "TestsLiblinphone/LinphoneTesterTests-Prefix.pch"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -5018,8 +4515,7 @@ Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, ); - INFOPLIST_FILE = "LinphoneTester Tests/LinphoneTester Tests-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + INFOPLIST_FILE = "TestsLiblinphone/LinphoneTesterTests-Info.plist"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", @@ -5027,7 +4523,7 @@ ); PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; - TEST_HOST = "$(BUNDLE_LOADER)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/liblinphoneTester.app/liblinphoneTester"; VALIDATE_PRODUCT = YES; WRAPPER_EXTENSION = xctest; }; @@ -5037,8 +4533,8 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + ASSETCATALOG_COMPILER_APPICON_NAME = TestAppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = TestLaunchImage; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -5050,6 +4546,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", @@ -5058,7 +4555,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "LinphoneTester/LinphoneTester-Prefix.pch"; + GCC_PREFIX_HEADER = "LiblinphoneTester/LinphoneTester-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", @@ -5074,17 +4571,17 @@ Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, ); - INFOPLIST_FILE = "LinphoneTester/LinphoneTester-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + INFOPLIST_FILE = "LiblinphoneTester/LinphoneTester-Info.plist"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.belledonne-communications.tester.liblinphoneTester"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; - TARGETED_DEVICE_FAMILY = 1; + TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; name = Debug; @@ -5093,8 +4590,8 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + ASSETCATALOG_COMPILER_APPICON_NAME = TestAppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = TestLaunchImage; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -5106,6 +4603,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = YES; ENABLE_NS_ASSERTIONS = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -5113,7 +4611,7 @@ ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "LinphoneTester/LinphoneTester-Prefix.pch"; + GCC_PREFIX_HEADER = "LiblinphoneTester/LinphoneTester-Prefix.pch"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -5124,16 +4622,16 @@ Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, ); - INFOPLIST_FILE = "LinphoneTester/LinphoneTester-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + INFOPLIST_FILE = "LiblinphoneTester/LinphoneTester-Info.plist"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); + PRODUCT_BUNDLE_IDENTIFIER = "com.belledonne-communications.tester.liblinphoneTester"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; - TARGETED_DEVICE_FAMILY = 1; + TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; WRAPPER_EXTENSION = app; }; @@ -5143,8 +4641,8 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + ASSETCATALOG_COMPILER_APPICON_NAME = TestAppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = TestLaunchImage; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -5156,6 +4654,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = YES; ENABLE_NS_ASSERTIONS = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -5163,7 +4662,7 @@ ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "LinphoneTester/LinphoneTester-Prefix.pch"; + GCC_PREFIX_HEADER = "LiblinphoneTester/LinphoneTester-Prefix.pch"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -5174,16 +4673,16 @@ Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, ); - INFOPLIST_FILE = "LinphoneTester/LinphoneTester-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + INFOPLIST_FILE = "LiblinphoneTester/LinphoneTester-Info.plist"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); + PRODUCT_BUNDLE_IDENTIFIER = "com.belledonne-communications.tester.liblinphoneTester"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; - TARGETED_DEVICE_FAMILY = 1; + TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; WRAPPER_EXTENSION = app; }; @@ -5193,8 +4692,8 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + ASSETCATALOG_COMPILER_APPICON_NAME = TestAppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = TestLaunchImage; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -5206,6 +4705,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = YES; ENABLE_NS_ASSERTIONS = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -5213,7 +4713,7 @@ ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "LinphoneTester/LinphoneTester-Prefix.pch"; + GCC_PREFIX_HEADER = "LiblinphoneTester/LinphoneTester-Prefix.pch"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -5224,16 +4724,16 @@ Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, ); - INFOPLIST_FILE = "LinphoneTester/LinphoneTester-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + INFOPLIST_FILE = "LiblinphoneTester/LinphoneTester-Info.plist"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); + PRODUCT_BUNDLE_IDENTIFIER = "com.belledonne-communications.tester.liblinphoneTester"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; - TARGETED_DEVICE_FAMILY = 1; + TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; WRAPPER_EXTENSION = app; }; @@ -5253,11 +4753,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - "$(DEVELOPER_FRAMEWORKS_DIR)", - ); + ENABLE_BITCODE = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -5272,10 +4768,16 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/liblinphone-sdk/apple-darwin/include", + "$(SRCROOT)/Classes/Utils/XMLRPC/", ); - INFOPLIST_FILE = KifTests/Info.plist; + INFOPLIST_FILE = TestsUI/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", + ); MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( "$(inherited)", "-framework", @@ -5302,12 +4804,8 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - "$(DEVELOPER_FRAMEWORKS_DIR)", - ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; @@ -5315,9 +4813,14 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/liblinphone-sdk/apple-darwin/include", + "$(SRCROOT)/Classes/Utils/XMLRPC/", ); - INFOPLIST_FILE = KifTests/Info.plist; + INFOPLIST_FILE = TestsUI/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", + ); MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( "$(inherited)", @@ -5346,12 +4849,8 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - "$(DEVELOPER_FRAMEWORKS_DIR)", - ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; @@ -5359,9 +4858,14 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/liblinphone-sdk/apple-darwin/include", + "$(SRCROOT)/Classes/Utils/XMLRPC/", ); - INFOPLIST_FILE = KifTests/Info.plist; + INFOPLIST_FILE = TestsUI/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", + ); MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( "$(inherited)", @@ -5390,12 +4894,8 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - "$(DEVELOPER_FRAMEWORKS_DIR)", - ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; @@ -5403,9 +4903,14 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/liblinphone-sdk/apple-darwin/include", + "$(SRCROOT)/Classes/Utils/XMLRPC/", ); - INFOPLIST_FILE = KifTests/Info.plist; + INFOPLIST_FILE = TestsUI/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/lib", + ); MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( "$(inherited)", @@ -5445,7 +4950,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - F08F119319C09C6B007D70C2 /* Build configuration list for PBXNativeTarget "LinphoneTester Tests" */ = { + F08F119319C09C6B007D70C2 /* Build configuration list for PBXNativeTarget "liblinphoneTesterTests" */ = { isa = XCConfigurationList; buildConfigurations = ( F08F119419C09C6B007D70C2 /* Debug */, @@ -5456,7 +4961,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - F0BB8C051936208200974404 /* Build configuration list for PBXNativeTarget "LinphoneTester" */ = { + F0BB8C051936208200974404 /* Build configuration list for PBXNativeTarget "liblinphoneTester" */ = { isa = XCConfigurationList; buildConfigurations = ( F0BB8C061936208200974404 /* Debug */, @@ -5467,7 +4972,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - F0F9520C1A6AEB1100254160 /* Build configuration list for PBXNativeTarget "KifTests" */ = { + F0F9520C1A6AEB1100254160 /* Build configuration list for PBXNativeTarget "linphoneTests" */ = { isa = XCConfigurationList; buildConfigurations = ( F0F952081A6AEB1000254160 /* Debug */, diff --git a/linphone.xcodeproj/xcshareddata/xcschemes/LinphoneTester.xcscheme b/linphone.xcodeproj/xcshareddata/xcschemes/LinphoneTester.xcscheme index 8e72f5ba4..0345d7d43 100644 --- a/linphone.xcodeproj/xcshareddata/xcschemes/LinphoneTester.xcscheme +++ b/linphone.xcodeproj/xcshareddata/xcschemes/LinphoneTester.xcscheme @@ -1,6 +1,6 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -43,27 +43,31 @@ + + - + @@ -71,17 +75,18 @@ - + diff --git a/linphone.xcodeproj/xcshareddata/xcschemes/linphone.xcscheme b/linphone.xcodeproj/xcshareddata/xcschemes/linphone.xcscheme index 1b8d88a1f..63e5f5d72 100644 --- a/linphone.xcodeproj/xcshareddata/xcschemes/linphone.xcscheme +++ b/linphone.xcodeproj/xcshareddata/xcschemes/linphone.xcscheme @@ -1,6 +1,6 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -62,17 +62,21 @@ ReferencedContainer = "container:linphone.xcodeproj"> + + - + - + #import #endif + +#import "Utils.h" diff --git a/main.m b/main.m index 26996ff51..8a2b569ff 100644 --- a/main.m +++ b/main.m @@ -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 programw; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ + */ #import #import "LinphoneAppDelegate.h" @@ -24,19 +24,18 @@ // Dump exception void uncaughtExceptionHandler(NSException *exception) { - NSLog(@"Crash: %@", exception); - NSLog(@"Stack Trace: %@", [exception callStackSymbols]); - // Internal error reporting -} + NSLog(@"Crash: %@", exception); + NSLog(@"Stack Trace: %@", [exception callStackSymbols]); + // Internal error reporting +}; #endif int main(int argc, char *argv[]) { #ifdef DEBUG - NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler); + NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler); #endif - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - int retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([LinphoneAppDelegate class])); - [pool release]; - return retVal; + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([LinphoneAppDelegate class])); + } } diff --git a/prepare.py b/prepare.py new file mode 100755 index 000000000..c356ed368 --- /dev/null +++ b/prepare.py @@ -0,0 +1,576 @@ +#!/usr/bin/env python + +############################################################################ +# prepare.py +# Copyright (C) 2015 Belledonne Communications, 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 argparse +import os +import re +import shutil +import tempfile +import sys +from logging import error, warning, info, INFO, basicConfig +from distutils.spawn import find_executable +from subprocess import Popen, PIPE +sys.dont_write_bytecode = True +sys.path.insert(0, 'submodules/cmake-builder') +try: + import prepare +except Exception as e: + error( + "Could not find prepare module: {}, probably missing submodules/cmake-builder? Try running:\n" + "git submodule sync && git submodule update --init --recursive".format(e)) + exit(1) + + +class IOSTarget(prepare.Target): + + def __init__(self, arch): + prepare.Target.__init__(self, 'ios-' + arch) + current_path = os.path.dirname(os.path.realpath(__file__)) + self.config_file = 'configs/config-ios-' + arch + '.cmake' + self.toolchain_file = 'toolchains/toolchain-ios-' + arch + '.cmake' + self.output = 'liblinphone-sdk/' + arch + '-apple-darwin.ios' + self.additional_args = [ + '-DCMAKE_INSTALL_MESSAGE=LAZY', + '-DLINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS=YES', + '-DLINPHONE_BUILDER_EXTERNAL_SOURCE_PATH=' + + current_path + '/submodules' + ] + + def clean(self): + if os.path.isdir('WORK'): + shutil.rmtree( + 'WORK', ignore_errors=False, onerror=self.handle_remove_read_only) + if os.path.isdir('liblinphone-sdk'): + shutil.rmtree( + 'liblinphone-sdk', ignore_errors=False, onerror=self.handle_remove_read_only) + + +class IOSi386Target(IOSTarget): + + def __init__(self): + IOSTarget.__init__(self, 'i386') + + +class IOSx8664Target(IOSTarget): + + def __init__(self): + IOSTarget.__init__(self, 'x86_64') + + +class IOSarmv7Target(IOSTarget): + + def __init__(self): + IOSTarget.__init__(self, 'armv7') + + +class IOSarm64Target(IOSTarget): + + def __init__(self): + IOSTarget.__init__(self, 'arm64') + + +targets = { + 'i386': IOSi386Target(), + 'x86_64': IOSx8664Target(), + 'armv7': IOSarmv7Target(), + 'arm64': IOSarm64Target() +} +archs_device = ['arm64', 'armv7'] +archs_simu = ['i386', 'x86_64'] +platforms = ['all', 'devices', 'simulators'] + archs_device + archs_simu + + +class PlatformListAction(argparse.Action): + + def __call__(self, parser, namespace, values, option_string=None): + if values: + for value in values: + if value not in platforms: + message = ("invalid platform: {0!r} (choose from {1})".format( + value, ', '.join([repr(platform) for platform in platforms]))) + raise argparse.ArgumentError(self, message) + setattr(namespace, self.dest, values) + + +def gpl_disclaimer(platforms): + cmakecache = 'WORK/ios-{arch}/cmake/CMakeCache.txt'.format(arch=platforms[0]) + gpl_third_parties_enabled = "ENABLE_GPL_THIRD_PARTIES:BOOL=YES" in open( + cmakecache).read() or "ENABLE_GPL_THIRD_PARTIES:BOOL=ON" in open(cmakecache).read() + + if gpl_third_parties_enabled: + warning("\n***************************************************************************" + "\n***************************************************************************" + "\n***** CAUTION, this liblinphone SDK is built using 3rd party GPL code *****" + "\n***** Even if you acquired a proprietary license from Belledonne *****" + "\n***** Communications, this SDK is GPL and GPL only. *****" + "\n***** To disable 3rd party gpl code, please use: *****" + "\n***** $ ./prepare.py -DENABLE_GPL_THIRD_PARTIES=NO *****" + "\n***************************************************************************" + "\n***************************************************************************") + else: + warning("\n***************************************************************************" + "\n***************************************************************************" + "\n***** Linphone SDK without 3rd party GPL software *****" + "\n***** If you acquired a proprietary license from Belledonne *****" + "\n***** Communications, this SDK can be used to create *****" + "\n***** a proprietary linphone-based application. *****" + "\n***************************************************************************" + "\n***************************************************************************") + + +def extract_from_xcode_project_with_regex(regex): + l = [] + f = open('linphone.xcodeproj/project.pbxproj', 'r') + lines = f.readlines() + f.close() + for line in lines: + m = regex.search(line) + if m is not None: + l += [m.group(1)] + return list(set(l)) + + +def extract_deployment_target(): + regex = re.compile("IPHONEOS_DEPLOYMENT_TARGET = (.*);") + return extract_from_xcode_project_with_regex(regex)[0] + + +def extract_libs_list(): + # name = libspeexdsp.a; path = "liblinphone-sdk/apple-darwin/lib/libspeexdsp.a"; sourceTree = ""; }; + regex = re.compile("name = \"*(lib\S+)\.a(\")*; path = \"liblinphone-sdk/apple-darwin/") + return extract_from_xcode_project_with_regex(regex) + + +missing_dependencies = {} + + +def check_is_installed(binary, prog=None, warn=True): + if not find_executable(binary): + if warn: + missing_dependencies[binary] = prog + # error("Could not find {}. Please install {}.".format(binary, prog)) + return False + return True + + +def detect_package_manager(): + if find_executable("brew"): + return "brew" + elif find_executable("port"): + return "sudo port" + else: + error( + "No package manager found. Please README or install brew using:\n\truby -e \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\"") + return "brew" + + +def check_tools(): + package_manager_info = {"brew-pkg-config": "pkg-config", + "sudo port-pkg-config": "pkgconfig", + "brew-binary-path": "/usr/local/bin/", + "sudo port-binary-path": "/opt/local/bin/" + } + reterr = 0 + + if " " in os.path.dirname(os.path.realpath(__file__)): + error("Invalid location: linphone-iphone path should not contain any spaces.") + reterr = 1 + + for prog in ["autoconf", "automake", "doxygen", "java", "nasm", "cmake", "wget", "yasm", "optipng"]: + reterr |= not check_is_installed(prog, prog) + + reterr |= not check_is_installed("pkg-config", package_manager_info[detect_package_manager() + "-pkg-config"]) + reterr |= not check_is_installed("ginstall", "coreutils") + reterr |= not check_is_installed("intltoolize", "intltool") + reterr |= not check_is_installed("convert", "imagemagick") + + if find_executable("nasm"): + nasm_output = Popen("nasm -f elf32".split(" "), stderr=PIPE, stdout=PIPE).stderr.read() + if "fatal: unrecognised output format" in nasm_output: + missing_dependencies["nasm"] = "nasm" + reterr = 1 + + if check_is_installed("libtoolize", warn=False): + if not check_is_installed("glibtoolize", "libtool"): + glibtoolize_path = find_executable("glibtoolize") + reterr = 1 + msg = "Please do a symbolic link from glibtoolize to libtoolize:\n\tln -s {} ${}" + error(msg.format(glibtoolize_path, glibtoolize_path.replace("glibtoolize", "libtoolize"))) + + # list all missing packages to install + if missing_dependencies: + error("The following binaries are missing: {}. Please install them using:\n\t{} install {}".format( + " ".join(missing_dependencies.keys()), + detect_package_manager(), + " ".join(missing_dependencies.values()))) + + devnull = open(os.devnull, 'wb') + # just ensure that JDK is installed - if not, it will automatically display a popup to user + p = Popen("java -version".split(" "), stderr=devnull, stdout=devnull) + p.wait() + if p.returncode != 0: + error("Please install Java JDK (not just JRE).") + reterr = 1 + + # needed by x264 + if not find_executable("gas-preprocessor.pl"): + error("""Could not find gas-preprocessor.pl, please install it: + wget --no-check-certificate https://raw.githubusercontent.com/FFmpeg/gas-preprocessor/master/gas-preprocessor.pl && \\ + chmod +x gas-preprocessor.pl && \\ + sudo mv gas-preprocessor.pl {}""".format(package_manager_info[detect_package_manager() + "-binary-path"])) + reterr = 1 + + if not os.path.isdir("submodules/linphone/mediastreamer2/src") or not os.path.isdir("submodules/linphone/oRTP/src"): + error("Missing some git submodules. Did you run:\n\tgit submodule update --init --recursive") + reterr = 1 + + p = Popen("xcrun --sdk iphoneos --show-sdk-path".split(" "), stdout=devnull, stderr=devnull) + p.wait() + if p.returncode != 0: + error("iOS SDK not found, please install Xcode from AppStore or equivalent.") + reterr = 1 + else: + xcode_version = int( + Popen("xcodebuild -version".split(" "), stdout=PIPE).stdout.read().split("\n")[0].split(" ")[1].split(".")[0]) + if xcode_version < 7: + sdk_platform_path = Popen( + "xcrun --sdk iphonesimulator --show-sdk-platform-path".split(" "), + stdout=PIPE, stderr=devnull).stdout.read()[:-1] + sdk_strings_path = "{}/{}".format(sdk_platform_path, "Developer/usr/bin/strings") + if not os.path.isfile(sdk_strings_path): + strings_path = find_executable("strings") + error("strings binary missing, please run:\n\tsudo ln -s {} {}".format(strings_path, sdk_strings_path)) + reterr = 1 + return reterr + + +def install_git_hook(): + git_hook_path = ".git{sep}hooks{sep}pre-commit".format(sep=os.sep) + if os.path.isdir(".git{sep}hooks".format(sep=os.sep)) and not os.path.isfile(git_hook_path): + info("Installing Git pre-commit hook") + shutil.copyfile(".git-pre-commit", git_hook_path) + os.chmod(git_hook_path, 0755) + + +def generate_makefile(platforms, generator): + arch_targets = "" + for arch in platforms: + arch_targets += """ +{arch}: {arch}-build + +{arch}-build: +\t{generator} WORK/ios-{arch}/cmake +\t@echo "Done" +""".format(arch=arch, generator=generator) + multiarch = "" + for arch in platforms[1:]: + multiarch += \ + """\tif test -f "$${arch}_path"; then \\ +\t\tall_paths=`echo $$all_paths $${arch}_path`; \\ +\t\tall_archs="$$all_archs,{arch}" ; \\ +\telse \\ +\t\techo "WARNING: archive `basename $$archive` exists in {first_arch} tree but does not exists in {arch} tree: $${arch}_path."; \\ +\tfi; \\ +""".format(first_arch=platforms[0], arch=arch) + makefile = """ +archs={archs} +LINPHONE_IPHONE_VERSION=$(shell git describe --always) + +.PHONY: all +.SILENT: sdk +all: build + +sdk: +\tarchives=`find liblinphone-sdk/{first_arch}-apple-darwin.ios -name *.a` && \\ +\trm -rf liblinphone-sdk/apple-darwin && \\ +\tmkdir -p liblinphone-sdk/apple-darwin && \\ +\tcp -rf liblinphone-sdk/{first_arch}-apple-darwin.ios/include liblinphone-sdk/apple-darwin/. && \\ +\tcp -rf liblinphone-sdk/{first_arch}-apple-darwin.ios/share liblinphone-sdk/apple-darwin/. && \\ +\tfor archive in $$archives ; do \\ +\t\tarmv7_path=`echo $$archive | sed -e "s/{first_arch}/armv7/"`; \\ +\t\tarm64_path=`echo $$archive | sed -e "s/{first_arch}/arm64/"`; \\ +\t\ti386_path=`echo $$archive | sed -e "s/{first_arch}/i386/"`; \\ +\t\tx86_64_path=`echo $$archive | sed -e "s/{first_arch}/x86_64/"`; \\ +\t\tdestpath=`echo $$archive | sed -e "s/-debug//" | sed -e "s/{first_arch}-//" | sed -e "s/\.ios//"`; \\ +\t\tall_paths=`echo $$archive`; \\ +\t\tall_archs="{first_arch}"; \\ +\t\tmkdir -p `dirname $$destpath`; \\ +\t\t{multiarch} \\ +\t\techo "[{archs}] Mixing `basename $$archive` in $$destpath"; \\ +\t\tlipo -create $$all_paths -output $$destpath; \\ +\tdone; \\ +\techo 'NOTE: the following libraries were STUBBED:'; \\ +\tcat WORK/ios-{first_arch}/Build/dummy_libraries/dummy_libraries.txt + +build: $(addsuffix -build, $(archs)) +\t$(MAKE) sdk + +ipa: build +\txcodebuild -configuration Release \\ +\t&& xcrun -sdk iphoneos PackageApplication -v build/Release-iphoneos/linphone.app -o $$PWD/linphone-iphone.ipa + +zipsdk: sdk +\techo "Generating SDK zip file for version $(LINPHONE_IPHONE_VERSION)" +\tzip -r liblinphone-iphone-sdk-$(LINPHONE_IPHONE_VERSION).zip \\ +\tliblinphone-sdk/apple-darwin \\ +\tliblinphone-tutorials \\ +\t-x liblinphone-tutorials/hello-world/build\* \\ +\t-x liblinphone-tutorials/hello-world/hello-world.xcodeproj/*.pbxuser \\ +\t-x liblinphone-tutorials/hello-world/hello-world.xcodeproj/*.mode1v3 + +pull-transifex: +\ttx pull -af + +push-transifex: +\t./Tools/i18n_generate_strings_files.sh && \\ +\ttx push -s -f --no-interactive + +zipres: +\t@tar -czf ios_assets.tar.gz Resources iTunesArtwork + +{arch_targets} + +help-prepare-options: +\t@echo "prepare.py was previously executed with the following options:" +\t@echo " {options}" + +help: help-prepare-options +\t@echo "" +\t@echo "(please read the README.md file first)" +\t@echo "" +\t@echo "Available architectures: {archs}" +\t@echo "" +\t@echo "Available targets:" +\t@echo "" +\t@echo " * all or build: builds all architectures and creates the liblinphone SDK" +\t@echo " * sdk: creates the liblinphone SDK. Use this only after a full build" +\t@echo " * zipsdk: generates a ZIP archive of liblinphone-sdk/apple-darwin containing the SDK. Use this only after SDK is built." +\t@echo " * zipres: creates a tar.gz file with all the resources (images)" +\t@echo "" +""".format(archs=' '.join(platforms), arch_opts='|'.join(platforms), + first_arch=platforms[0], options=' '.join(sys.argv), + arch_targets=arch_targets, + multiarch=multiarch, generator=generator) + f = open('Makefile', 'w') + f.write(makefile) + f.close() + gpl_disclaimer(platforms) + + +def list_features_with_args(debug, additional_args): + tmpdir = tempfile.mkdtemp(prefix="linphone-iphone") + tmptarget = IOSarm64Target() + tmptarget.abs_cmake_dir = tmpdir + + option_regex = re.compile("ENABLE_(.*):(.*)=(.*)") + options = {} + ended = True + build_type = 'Debug' if debug else 'Release' + + for line in Popen(tmptarget.cmake_command(build_type, False, True, additional_args, verbose=False), + cwd=tmpdir, shell=False, stdout=PIPE).stdout.readlines(): + match = option_regex.match(line) + if match is not None: + (name, typeof, value) = match.groups() + options["ENABLE_{}".format(name)] = value + ended &= (value == 'ON') + shutil.rmtree(tmpdir) + return (options, ended) + + +def list_features(debug, args): + additional_args = args + options = {} + info("Searching for available features...") + # We have to iterate multiple times to activate ALL options, so that options depending + # of others are also listed (cmake_dependent_option macro will not output options if + # prerequisite is not met) + while True: + (options, ended) = list_features_with_args(debug, additional_args) + if ended: + break + else: + additional_args = [] + # Activate ALL available options + for k in options.keys(): + additional_args.append("-D{}=ON".format(k)) + + # Now that we got the list of ALL available options, we must correct default values + # Step 1: all options are turned off by default + for x in options.keys(): + options[x] = 'OFF' + # Step 2: except options enabled when running with default args + (options_tmp, ended) = list_features_with_args(debug, args) + final_dict = dict(options.items() + options_tmp.items()) + + notice_features = "Here are available features:" + for k, v in final_dict.items(): + notice_features += "\n\t{}={}".format(k, v) + info(notice_features) + info("To enable some feature, please use -DENABLE_SOMEOPTION=ON (example: -DENABLE_OPUS=ON)") + info("Similarly, to disable some feature, please use -DENABLE_SOMEOPTION=OFF (example: -DENABLE_OPUS=OFF)") + + +def main(argv=None): + basicConfig(format="%(levelname)s: %(message)s", level=INFO) + + if argv is None: + argv = sys.argv + argparser = argparse.ArgumentParser( + description="Prepare build of Linphone and its dependencies.") + argparser.add_argument( + '-c', '-C', '--clean', help="Clean a previous build instead of preparing a build.", action='store_true') + argparser.add_argument( + '-d', '--debug', help="Prepare a debug build, eg. add debug symbols and use no optimizations.", action='store_true') + argparser.add_argument( + '-dv', '--debug-verbose', help="Activate ms_debug logs.", action='store_true') + argparser.add_argument( + '-f', '--force', help="Force preparation, even if working directory already exist.", action='store_true') + argparser.add_argument( + '--disable-gpl-third-parties', help="Disable GPL third parties such as FFMpeg, x264.", action='store_true') + argparser.add_argument( + '--enable-non-free-codecs', help="Enable non-free codecs such as OpenH264, MPEG4, etc.. Final application must comply with their respective license (see README.md).", action='store_true') + argparser.add_argument( + '--build-all-codecs', help="Build all codecs including non-free. Final application must comply with their respective license (see README.md).", action='store_true') + argparser.add_argument( + '-G', '--generator', help="CMake build system generator (default: Unix Makefiles, use cmake -h to get the complete list).", default='Unix Makefiles', dest='generator') + argparser.add_argument( + '-lf', '--list-features', help="List optional features and their default values.", action='store_true', dest='list_features') + argparser.add_argument( + '-t', '--tunnel', help="Enable Tunnel.", action='store_true') + argparser.add_argument('platform', nargs='*', action=PlatformListAction, default=[ + 'x86_64', 'devices'], help="The platform to build for (default is 'x86_64 devices'). Space separated architectures in list: {0}.".format(', '.join([repr(platform) for platform in platforms]))) + argparser.add_argument( + '-L', '--list-cmake-variables', help="(debug) List non-advanced CMake cache variables.", action='store_true', dest='list_cmake_variables') + + args, additional_args2 = argparser.parse_known_args() + + additional_args = [] + + additional_args += ["-G", args.generator] + + if check_tools() != 0: + return 1 + + additional_args += ["-DLINPHONE_IOS_DEPLOYMENT_TARGET=" + extract_deployment_target()] + additional_args += ["-DLINPHONE_BUILDER_DUMMY_LIBRARIES=" + ' '.join(extract_libs_list())] + if args.debug_verbose is True: + additional_args += ["-DENABLE_DEBUG_LOGS=YES"] + if args.enable_non_free_codecs is True: + additional_args += ["-DENABLE_NON_FREE_CODECS=YES"] + if args.build_all_codecs is True: + additional_args += ["-DENABLE_GPL_THIRD_PARTIES=YES"] + additional_args += ["-DENABLE_NON_FREE_CODECS=YES"] + additional_args += ["-DENABLE_AMRNB=YES"] + additional_args += ["-DENABLE_AMRWB=YES"] + additional_args += ["-DENABLE_G729=YES"] + additional_args += ["-DENABLE_GSM=YES"] + additional_args += ["-DENABLE_ILBC=YES"] + additional_args += ["-DENABLE_ISAC=YES"] + additional_args += ["-DENABLE_OPUS=YES"] + additional_args += ["-DENABLE_SILK=YES"] + additional_args += ["-DENABLE_SPEEX=YES"] + additional_args += ["-DENABLE_FFMPEG=YES"] + additional_args += ["-DENABLE_H263=YES"] + additional_args += ["-DENABLE_H263P=YES"] + additional_args += ["-DENABLE_MPEG4=YES"] + additional_args += ["-DENABLE_OPENH264=YES"] + additional_args += ["-DENABLE_VPX=YES"] + additional_args += ["-DENABLE_X264=YES"] + if args.disable_gpl_third_parties is True: + additional_args += ["-DENABLE_GPL_THIRD_PARTIES=NO"] + + if args.tunnel: + if not os.path.isdir("submodules/tunnel"): + info("Tunnel wanted but not found yet, trying to clone it...") + p = Popen("git clone gitosis@git.linphone.org:tunnel.git submodules/tunnel".split(" ")) + p.wait() + if p.returncode != 0: + error("Could not clone tunnel. Please see http://www.belledonne-communications.com/voiptunnel.html") + return 1 + warning("Tunnel enabled, disabling GPL third parties.") + additional_args += ["-DENABLE_TUNNEL=ON", "-DENABLE_GPL_THIRD_PARTIES=OFF"] + + # User's options are priority upon all automatic options + additional_args += additional_args2 + + if args.list_features: + list_features(args.debug, additional_args) + return 0 + + selected_platforms_dup = [] + for platform in args.platform: + if platform == 'all': + selected_platforms_dup += archs_device + archs_simu + elif platform == 'devices': + selected_platforms_dup += archs_device + elif platform == 'simulators': + selected_platforms_dup += archs_simu + else: + selected_platforms_dup += [platform] + # unify platforms but keep provided order + selected_platforms = [] + for x in selected_platforms_dup: + if x not in selected_platforms: + selected_platforms.append(x) + + if os.path.isdir('WORK') and not args.clean and not args.force: + warning("Working directory WORK already exists. Please remove it (option -C or -c) before re-executing CMake " + "to avoid conflicts between executions, or force execution (option -f) if you are aware of consequences.") + if os.path.isfile('Makefile'): + Popen("make help-prepare-options".split(" ")) + return 0 + + for platform in selected_platforms: + target = targets[platform] + + if args.clean: + target.clean() + else: + retcode = prepare.run(target, args.debug, False, args.list_cmake_variables, args.force, additional_args) + if retcode != 0: + return retcode + + if args.clean: + if os.path.isfile('Makefile'): + os.remove('Makefile') + elif selected_platforms: + install_git_hook() + + # only generated makefile if we are using Ninja or Makefile + if args.generator == 'Ninja': + if not check_is_installed("ninja", "it"): + return 1 + generate_makefile(selected_platforms, 'ninja -C') + elif args.generator == "Unix Makefiles": + generate_makefile(selected_platforms, '$(MAKE) -C') + elif args.generator == "Xcode": + info("You can now open Xcode project with: open WORK/cmake/Project.xcodeproj") + else: + info("Not generating meta-makefile for generator {}.".format(args.generator)) + + return 0 + +if __name__ == "__main__": + sys.exit(main()) diff --git a/submodules/MS2/MS2.xcodeproj/project.pbxproj b/submodules/MS2/MS2.xcodeproj/project.pbxproj new file mode 100644 index 000000000..4b01b2a7d --- /dev/null +++ b/submodules/MS2/MS2.xcodeproj/project.pbxproj @@ -0,0 +1,610 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + F03A97691AFA48E800651655 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F03A97681AFA48E800651655 /* main.m */; }; + F03A976C1AFA48E800651655 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F03A976B1AFA48E800651655 /* AppDelegate.m */; }; + F03A976F1AFA48E800651655 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F03A976E1AFA48E800651655 /* ViewController.m */; }; + F03A97721AFA48E800651655 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F03A97701AFA48E800651655 /* Main.storyboard */; }; + F03A97741AFA48E800651655 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F03A97731AFA48E800651655 /* Images.xcassets */; }; + F03A97771AFA48E800651655 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = F03A97751AFA48E800651655 /* LaunchScreen.xib */; }; + F03A97831AFA48E900651655 /* MS2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = F03A97821AFA48E900651655 /* MS2Tests.m */; }; + F03A97931AFA561900651655 /* libmsamr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A978D1AFA561900651655 /* libmsamr.a */; }; + F03A97941AFA561A00651655 /* libmsbcg729.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A978E1AFA561900651655 /* libmsbcg729.a */; }; + F03A97951AFA561A00651655 /* libmsilbc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A978F1AFA561900651655 /* libmsilbc.a */; }; + F03A97961AFA561A00651655 /* libmsopenh264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97901AFA561900651655 /* libmsopenh264.a */; }; + F03A97971AFA561A00651655 /* libmssilk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97911AFA561900651655 /* libmssilk.a */; }; + F03A97981AFA561A00651655 /* libmsx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97921AFA561900651655 /* libmsx264.a */; }; + F03A97AE1AFA563200651655 /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97991AFA563200651655 /* libavcodec.a */; }; + F03A97AF1AFA563200651655 /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A979A1AFA563200651655 /* libavutil.a */; }; + F03A97B01AFA563200651655 /* libbzrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A979B1AFA563200651655 /* libbzrtp.a */; }; + F03A97B11AFA563200651655 /* libgsm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A979C1AFA563200651655 /* libgsm.a */; }; + F03A97B21AFA563200651655 /* libilbc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A979D1AFA563200651655 /* libilbc.a */; }; + F03A97B31AFA563200651655 /* libmediastreamer_base.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A979E1AFA563200651655 /* libmediastreamer_base.a */; }; + F03A97B41AFA563200651655 /* libmediastreamer_voip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A979F1AFA563200651655 /* libmediastreamer_voip.a */; }; + F03A97B51AFA563200651655 /* libopencore-amrnb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97A01AFA563200651655 /* libopencore-amrnb.a */; }; + F03A97B61AFA563200651655 /* libopencore-amrwb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97A11AFA563200651655 /* libopencore-amrwb.a */; }; + F03A97B71AFA563200651655 /* libopenh264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97A21AFA563200651655 /* libopenh264.a */; }; + F03A97B81AFA563200651655 /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97A31AFA563200651655 /* libopus.a */; }; + F03A97B91AFA563200651655 /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97A41AFA563200651655 /* libortp.a */; }; + F03A97BA1AFA563200651655 /* libpolarssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97A51AFA563200651655 /* libpolarssl.a */; }; + F03A97BC1AFA563200651655 /* libspeex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97A71AFA563200651655 /* libspeex.a */; }; + F03A97BD1AFA563200651655 /* libspeexdsp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97A81AFA563200651655 /* libspeexdsp.a */; }; + F03A97BE1AFA563200651655 /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97A91AFA563200651655 /* libsrtp.a */; }; + F03A97BF1AFA563200651655 /* libswresample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97AA1AFA563200651655 /* libswresample.a */; }; + F03A97C01AFA563200651655 /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97AB1AFA563200651655 /* libswscale.a */; }; + F03A97C11AFA563200651655 /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97AC1AFA563200651655 /* libvpx.a */; }; + F03A97C21AFA563200651655 /* libx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97AD1AFA563200651655 /* libx264.a */; }; + F03A97C61AFA565000651655 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97C31AFA565000651655 /* AudioToolbox.framework */; }; + F03A97C71AFA565000651655 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97C41AFA565000651655 /* AVFoundation.framework */; }; + F03A97C81AFA565000651655 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97C51AFA565000651655 /* CoreAudio.framework */; }; + F03A97CA1AFA565C00651655 /* libxml2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97C91AFA565C00651655 /* libxml2.a */; }; + F03A97CC1AFA572600651655 /* libstdc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97CB1AFA572600651655 /* libstdc++.dylib */; }; + F03A97D81AFA580100651655 /* UITextField+DoneButton.m in Sources */ = {isa = PBXBuildFile; fileRef = F03A97D71AFA580100651655 /* UITextField+DoneButton.m */; }; + F03A97DA1AFA589E00651655 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97D91AFA589E00651655 /* Foundation.framework */; }; + F03A97DC1AFA58B600651655 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97DB1AFA58B600651655 /* UIKit.framework */; }; + F03A97E11AFA5B4A00651655 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F03A97E01AFA5B4A00651655 /* CoreMedia.framework */; }; + F03A97E31AFA64D200651655 /* nowebcamCIF.jpg in Resources */ = {isa = PBXBuildFile; fileRef = F03A97E21AFA64D200651655 /* nowebcamCIF.jpg */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + F03A977D1AFA48E900651655 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F03A975B1AFA48E800651655 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F03A97621AFA48E800651655; + remoteInfo = MS2; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + F03A97631AFA48E800651655 /* MS2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MS2.app; sourceTree = BUILT_PRODUCTS_DIR; }; + F03A97671AFA48E800651655 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F03A97681AFA48E800651655 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + F03A976A1AFA48E800651655 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + F03A976B1AFA48E800651655 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + F03A976D1AFA48E800651655 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + F03A976E1AFA48E800651655 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + F03A97711AFA48E800651655 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + F03A97731AFA48E800651655 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + F03A97761AFA48E800651655 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + F03A977C1AFA48E900651655 /* MS2Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MS2Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + F03A97811AFA48E900651655 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F03A97821AFA48E900651655 /* MS2Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MS2Tests.m; sourceTree = ""; }; + F03A978D1AFA561900651655 /* libmsamr.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmsamr.a; path = "../../../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmsamr.a"; sourceTree = ""; }; + F03A978E1AFA561900651655 /* libmsbcg729.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmsbcg729.a; path = "../../../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmsbcg729.a"; sourceTree = ""; }; + F03A978F1AFA561900651655 /* libmsilbc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmsilbc.a; path = "../../../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmsilbc.a"; sourceTree = ""; }; + F03A97901AFA561900651655 /* libmsopenh264.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmsopenh264.a; path = "../../../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmsopenh264.a"; sourceTree = ""; }; + F03A97911AFA561900651655 /* libmssilk.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmssilk.a; path = "../../../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmssilk.a"; sourceTree = ""; }; + F03A97921AFA561900651655 /* libmsx264.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmsx264.a; path = "../../../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmsx264.a"; sourceTree = ""; }; + F03A97991AFA563200651655 /* libavcodec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavcodec.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libavcodec.a"; sourceTree = ""; }; + F03A979A1AFA563200651655 /* libavutil.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavutil.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libavutil.a"; sourceTree = ""; }; + F03A979B1AFA563200651655 /* libbzrtp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbzrtp.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libbzrtp.a"; sourceTree = ""; }; + F03A979C1AFA563200651655 /* libgsm.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgsm.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libgsm.a"; sourceTree = ""; }; + F03A979D1AFA563200651655 /* libilbc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libilbc.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libilbc.a"; sourceTree = ""; }; + F03A979E1AFA563200651655 /* libmediastreamer_base.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmediastreamer_base.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libmediastreamer_base.a"; sourceTree = ""; }; + F03A979F1AFA563200651655 /* libmediastreamer_voip.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmediastreamer_voip.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libmediastreamer_voip.a"; sourceTree = ""; }; + F03A97A01AFA563200651655 /* libopencore-amrnb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libopencore-amrnb.a"; path = "../../../liblinphone-sdk/apple-darwin/lib/libopencore-amrnb.a"; sourceTree = ""; }; + F03A97A11AFA563200651655 /* libopencore-amrwb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libopencore-amrwb.a"; path = "../../../liblinphone-sdk/apple-darwin/lib/libopencore-amrwb.a"; sourceTree = ""; }; + F03A97A21AFA563200651655 /* libopenh264.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopenh264.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libopenh264.a"; sourceTree = ""; }; + F03A97A31AFA563200651655 /* libopus.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopus.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libopus.a"; sourceTree = ""; }; + F03A97A41AFA563200651655 /* libortp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libortp.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libortp.a"; sourceTree = ""; }; + F03A97A51AFA563200651655 /* libpolarssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpolarssl.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libpolarssl.a"; sourceTree = ""; }; + F03A97A71AFA563200651655 /* libspeex.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libspeex.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libspeex.a"; sourceTree = ""; }; + F03A97A81AFA563200651655 /* libspeexdsp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libspeexdsp.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libspeexdsp.a"; sourceTree = ""; }; + F03A97A91AFA563200651655 /* libsrtp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsrtp.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libsrtp.a"; sourceTree = ""; }; + F03A97AA1AFA563200651655 /* libswresample.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libswresample.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libswresample.a"; sourceTree = ""; }; + F03A97AB1AFA563200651655 /* libswscale.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libswscale.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libswscale.a"; sourceTree = ""; }; + F03A97AC1AFA563200651655 /* libvpx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvpx.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libvpx.a"; sourceTree = ""; }; + F03A97AD1AFA563200651655 /* libx264.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libx264.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libx264.a"; sourceTree = ""; }; + F03A97C31AFA565000651655 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + F03A97C41AFA565000651655 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + F03A97C51AFA565000651655 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; + F03A97C91AFA565C00651655 /* libxml2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libxml2.a; path = "../../../liblinphone-sdk/apple-darwin/lib/libxml2.a"; sourceTree = ""; }; + F03A97CB1AFA572600651655 /* libstdc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.dylib"; path = "usr/lib/libstdc++.dylib"; sourceTree = SDKROOT; }; + F03A97D61AFA580100651655 /* UITextField+DoneButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextField+DoneButton.h"; sourceTree = ""; }; + F03A97D71AFA580100651655 /* UITextField+DoneButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextField+DoneButton.m"; sourceTree = ""; }; + F03A97D91AFA589E00651655 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + F03A97DB1AFA58B600651655 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + F03A97E01AFA5B4A00651655 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; + F03A97E21AFA64D200651655 /* nowebcamCIF.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = nowebcamCIF.jpg; path = "../../../liblinphone-sdk/apple-darwin/share/images/nowebcamCIF.jpg"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + F03A97601AFA48E800651655 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F03A97E11AFA5B4A00651655 /* CoreMedia.framework in Frameworks */, + F03A97DC1AFA58B600651655 /* UIKit.framework in Frameworks */, + F03A97DA1AFA589E00651655 /* Foundation.framework in Frameworks */, + F03A97CC1AFA572600651655 /* libstdc++.dylib in Frameworks */, + F03A97C61AFA565000651655 /* AudioToolbox.framework in Frameworks */, + F03A97C71AFA565000651655 /* AVFoundation.framework in Frameworks */, + F03A97C81AFA565000651655 /* CoreAudio.framework in Frameworks */, + F03A97971AFA561A00651655 /* libmssilk.a in Frameworks */, + F03A97B61AFA563200651655 /* libopencore-amrwb.a in Frameworks */, + F03A97B91AFA563200651655 /* libortp.a in Frameworks */, + F03A97CA1AFA565C00651655 /* libxml2.a in Frameworks */, + F03A97981AFA561A00651655 /* libmsx264.a in Frameworks */, + F03A97B81AFA563200651655 /* libopus.a in Frameworks */, + F03A97B31AFA563200651655 /* libmediastreamer_base.a in Frameworks */, + F03A97B41AFA563200651655 /* libmediastreamer_voip.a in Frameworks */, + F03A97B21AFA563200651655 /* libilbc.a in Frameworks */, + F03A97931AFA561900651655 /* libmsamr.a in Frameworks */, + F03A97B11AFA563200651655 /* libgsm.a in Frameworks */, + F03A97C21AFA563200651655 /* libx264.a in Frameworks */, + F03A97951AFA561A00651655 /* libmsilbc.a in Frameworks */, + F03A97B71AFA563200651655 /* libopenh264.a in Frameworks */, + F03A97941AFA561A00651655 /* libmsbcg729.a in Frameworks */, + F03A97AE1AFA563200651655 /* libavcodec.a in Frameworks */, + F03A97B01AFA563200651655 /* libbzrtp.a in Frameworks */, + F03A97C01AFA563200651655 /* libswscale.a in Frameworks */, + F03A97BF1AFA563200651655 /* libswresample.a in Frameworks */, + F03A97C11AFA563200651655 /* libvpx.a in Frameworks */, + F03A97BC1AFA563200651655 /* libspeex.a in Frameworks */, + F03A97BE1AFA563200651655 /* libsrtp.a in Frameworks */, + F03A97B51AFA563200651655 /* libopencore-amrnb.a in Frameworks */, + F03A97AF1AFA563200651655 /* libavutil.a in Frameworks */, + F03A97961AFA561A00651655 /* libmsopenh264.a in Frameworks */, + F03A97BA1AFA563200651655 /* libpolarssl.a in Frameworks */, + F03A97BD1AFA563200651655 /* libspeexdsp.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F03A97791AFA48E900651655 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + F03A975A1AFA48E800651655 = { + isa = PBXGroup; + children = ( + F03A978C1AFA560800651655 /* Frameworks */, + F03A97651AFA48E800651655 /* MS2 */, + F03A977F1AFA48E900651655 /* MS2Tests */, + F03A97641AFA48E800651655 /* Products */, + ); + sourceTree = ""; + }; + F03A97641AFA48E800651655 /* Products */ = { + isa = PBXGroup; + children = ( + F03A97631AFA48E800651655 /* MS2.app */, + F03A977C1AFA48E900651655 /* MS2Tests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + F03A97651AFA48E800651655 /* MS2 */ = { + isa = PBXGroup; + children = ( + F03A976A1AFA48E800651655 /* AppDelegate.h */, + F03A976B1AFA48E800651655 /* AppDelegate.m */, + F03A976D1AFA48E800651655 /* ViewController.h */, + F03A976E1AFA48E800651655 /* ViewController.m */, + F03A97E21AFA64D200651655 /* nowebcamCIF.jpg */, + F03A97D61AFA580100651655 /* UITextField+DoneButton.h */, + F03A97D71AFA580100651655 /* UITextField+DoneButton.m */, + F03A97701AFA48E800651655 /* Main.storyboard */, + F03A97731AFA48E800651655 /* Images.xcassets */, + F03A97751AFA48E800651655 /* LaunchScreen.xib */, + F03A97661AFA48E800651655 /* Supporting Files */, + ); + path = MS2; + sourceTree = ""; + }; + F03A97661AFA48E800651655 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + F03A97671AFA48E800651655 /* Info.plist */, + F03A97681AFA48E800651655 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + F03A977F1AFA48E900651655 /* MS2Tests */ = { + isa = PBXGroup; + children = ( + F03A97821AFA48E900651655 /* MS2Tests.m */, + F03A97801AFA48E900651655 /* Supporting Files */, + ); + path = MS2Tests; + sourceTree = ""; + }; + F03A97801AFA48E900651655 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + F03A97811AFA48E900651655 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + F03A978C1AFA560800651655 /* Frameworks */ = { + isa = PBXGroup; + children = ( + F03A97E01AFA5B4A00651655 /* CoreMedia.framework */, + F03A97DB1AFA58B600651655 /* UIKit.framework */, + F03A97D91AFA589E00651655 /* Foundation.framework */, + F03A97CB1AFA572600651655 /* libstdc++.dylib */, + F03A97C31AFA565000651655 /* AudioToolbox.framework */, + F03A97C41AFA565000651655 /* AVFoundation.framework */, + F03A97C51AFA565000651655 /* CoreAudio.framework */, + F03A978D1AFA561900651655 /* libmsamr.a */, + F03A978E1AFA561900651655 /* libmsbcg729.a */, + F03A97991AFA563200651655 /* libavcodec.a */, + F03A979A1AFA563200651655 /* libavutil.a */, + F03A979B1AFA563200651655 /* libbzrtp.a */, + F03A979C1AFA563200651655 /* libgsm.a */, + F03A979D1AFA563200651655 /* libilbc.a */, + F03A979E1AFA563200651655 /* libmediastreamer_base.a */, + F03A979F1AFA563200651655 /* libmediastreamer_voip.a */, + F03A97A01AFA563200651655 /* libopencore-amrnb.a */, + F03A97A11AFA563200651655 /* libopencore-amrwb.a */, + F03A97C91AFA565C00651655 /* libxml2.a */, + F03A97A21AFA563200651655 /* libopenh264.a */, + F03A97A31AFA563200651655 /* libopus.a */, + F03A97A41AFA563200651655 /* libortp.a */, + F03A97A51AFA563200651655 /* libpolarssl.a */, + F03A97A71AFA563200651655 /* libspeex.a */, + F03A97A81AFA563200651655 /* libspeexdsp.a */, + F03A97A91AFA563200651655 /* libsrtp.a */, + F03A97AA1AFA563200651655 /* libswresample.a */, + F03A97AB1AFA563200651655 /* libswscale.a */, + F03A97AC1AFA563200651655 /* libvpx.a */, + F03A97AD1AFA563200651655 /* libx264.a */, + F03A978F1AFA561900651655 /* libmsilbc.a */, + F03A97901AFA561900651655 /* libmsopenh264.a */, + F03A97911AFA561900651655 /* libmssilk.a */, + F03A97921AFA561900651655 /* libmsx264.a */, + ); + name = Frameworks; + path = MS2; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + F03A97621AFA48E800651655 /* MS2 */ = { + isa = PBXNativeTarget; + buildConfigurationList = F03A97861AFA48E900651655 /* Build configuration list for PBXNativeTarget "MS2" */; + buildPhases = ( + F03A975F1AFA48E800651655 /* Sources */, + F03A97601AFA48E800651655 /* Frameworks */, + F03A97611AFA48E800651655 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MS2; + productName = MS2; + productReference = F03A97631AFA48E800651655 /* MS2.app */; + productType = "com.apple.product-type.application"; + }; + F03A977B1AFA48E900651655 /* MS2Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = F03A97891AFA48E900651655 /* Build configuration list for PBXNativeTarget "MS2Tests" */; + buildPhases = ( + F03A97781AFA48E900651655 /* Sources */, + F03A97791AFA48E900651655 /* Frameworks */, + F03A977A1AFA48E900651655 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + F03A977E1AFA48E900651655 /* PBXTargetDependency */, + ); + name = MS2Tests; + productName = MS2Tests; + productReference = F03A977C1AFA48E900651655 /* MS2Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + F03A975B1AFA48E800651655 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Belldonne Communications"; + TargetAttributes = { + F03A97621AFA48E800651655 = { + CreatedOnToolsVersion = 6.3; + }; + F03A977B1AFA48E900651655 = { + CreatedOnToolsVersion = 6.3; + TestTargetID = F03A97621AFA48E800651655; + }; + }; + }; + buildConfigurationList = F03A975E1AFA48E800651655 /* Build configuration list for PBXProject "MS2" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = F03A975A1AFA48E800651655; + productRefGroup = F03A97641AFA48E800651655 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + F03A97621AFA48E800651655 /* MS2 */, + F03A977B1AFA48E900651655 /* MS2Tests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + F03A97611AFA48E800651655 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F03A97E31AFA64D200651655 /* nowebcamCIF.jpg in Resources */, + F03A97721AFA48E800651655 /* Main.storyboard in Resources */, + F03A97771AFA48E800651655 /* LaunchScreen.xib in Resources */, + F03A97741AFA48E800651655 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F03A977A1AFA48E900651655 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + F03A975F1AFA48E800651655 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F03A976F1AFA48E800651655 /* ViewController.m in Sources */, + F03A976C1AFA48E800651655 /* AppDelegate.m in Sources */, + F03A97691AFA48E800651655 /* main.m in Sources */, + F03A97D81AFA580100651655 /* UITextField+DoneButton.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F03A97781AFA48E900651655 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F03A97831AFA48E900651655 /* MS2Tests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + F03A977E1AFA48E900651655 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F03A97621AFA48E800651655 /* MS2 */; + targetProxy = F03A977D1AFA48E900651655 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + F03A97701AFA48E800651655 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + F03A97711AFA48E800651655 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + F03A97751AFA48E800651655 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + F03A97761AFA48E800651655 /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + F03A97841AFA48E900651655 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F03A97851AFA48E900651655 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + F03A97871AFA48E900651655 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + "$(SRCROOT)/../../liblinphone-sdk/apple-darwin/include", + ); + INFOPLIST_FILE = MS2/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "/Users/guillaume/Dev/linphone-iphone/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", + "/Users/guillaume/Dev/linphone-iphone/liblinphone-sdk/apple-darwin/lib", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + F03A97881AFA48E900651655 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + "$(SRCROOT)/../../liblinphone-sdk/apple-darwin/include", + ); + INFOPLIST_FILE = MS2/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "/Users/guillaume/Dev/linphone-iphone/liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", + "/Users/guillaume/Dev/linphone-iphone/liblinphone-sdk/apple-darwin/lib", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + F03A978A1AFA48E900651655 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = MS2Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MS2.app/MS2"; + }; + name = Debug; + }; + F03A978B1AFA48E900651655 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = MS2Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MS2.app/MS2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + F03A975E1AFA48E800651655 /* Build configuration list for PBXProject "MS2" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F03A97841AFA48E900651655 /* Debug */, + F03A97851AFA48E900651655 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F03A97861AFA48E900651655 /* Build configuration list for PBXNativeTarget "MS2" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F03A97871AFA48E900651655 /* Debug */, + F03A97881AFA48E900651655 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F03A97891AFA48E900651655 /* Build configuration list for PBXNativeTarget "MS2Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F03A978A1AFA48E900651655 /* Debug */, + F03A978B1AFA48E900651655 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = F03A975B1AFA48E800651655 /* Project object */; +} diff --git a/submodules/MS2/MS2.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/submodules/MS2/MS2.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..2f155d3fc --- /dev/null +++ b/submodules/MS2/MS2.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/submodules/MS2/MS2/AppDelegate.h b/submodules/MS2/MS2/AppDelegate.h new file mode 100644 index 000000000..c9c5caa48 --- /dev/null +++ b/submodules/MS2/MS2/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// MS2 +// +// Created by guillaume on 06/05/2015. +// Copyright (c) 2015 Belldonne Communications. All rights reserved. +// + +#import + +@interface AppDelegate : UIResponder + +@property(strong, nonatomic) UIWindow *window; + +@end diff --git a/submodules/MS2/MS2/AppDelegate.m b/submodules/MS2/MS2/AppDelegate.m new file mode 100644 index 000000000..d81acddfc --- /dev/null +++ b/submodules/MS2/MS2/AppDelegate.m @@ -0,0 +1,52 @@ +// +// AppDelegate.m +// MS2 +// +// Created by guillaume on 06/05/2015. +// Copyright (c) 2015 Belldonne Communications. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of + // temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application + // and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use + // this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application + // state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: + // when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes + // made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application + // was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also + // applicationDidEnterBackground:. +} + +@end diff --git a/submodules/MS2/MS2/Base.lproj/LaunchScreen.xib b/submodules/MS2/MS2/Base.lproj/LaunchScreen.xib new file mode 100644 index 000000000..a3cbf860c --- /dev/null +++ b/submodules/MS2/MS2/Base.lproj/LaunchScreen.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/submodules/MS2/MS2/Base.lproj/Main.storyboard b/submodules/MS2/MS2/Base.lproj/Main.storyboard new file mode 100644 index 000000000..a8ce1fb77 --- /dev/null +++ b/submodules/MS2/MS2/Base.lproj/Main.storyboard @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/submodules/MS2/MS2/Images.xcassets/AppIcon.appiconset/Contents.json b/submodules/MS2/MS2/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..36d2c80d8 --- /dev/null +++ b/submodules/MS2/MS2/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/submodules/MS2/MS2/Info.plist b/submodules/MS2/MS2/Info.plist new file mode 100644 index 000000000..a088afae2 --- /dev/null +++ b/submodules/MS2/MS2/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + com.belledonne-communications.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/submodules/MS2/MS2/UITextField+DoneButton.h b/submodules/MS2/MS2/UITextField+DoneButton.h new file mode 100644 index 000000000..f1199f33c --- /dev/null +++ b/submodules/MS2/MS2/UITextField+DoneButton.h @@ -0,0 +1,13 @@ +// +// UITextField+DoneButton.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 14/10/14. +// +// + +#import + +@interface UITextField (DoneButton) +- (void)addDoneButton; +@end diff --git a/submodules/MS2/MS2/UITextField+DoneButton.m b/submodules/MS2/MS2/UITextField+DoneButton.m new file mode 100644 index 000000000..3e667ed29 --- /dev/null +++ b/submodules/MS2/MS2/UITextField+DoneButton.m @@ -0,0 +1,42 @@ +// +// UITextField+DoneButton.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 14/10/14. +// +// + +#import "UITextField+DoneButton.h" + +@implementation UITextField (DoneButton) + +- (void)addDoneButton { + // actually on iPad there is a done button + UIToolbar *numberToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 50)]; + numberToolbar.items = [NSArray + arrayWithObjects:[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Cancel", nil) + style:UIBarButtonItemStyleBordered + target:self + action:@selector(cancelNumberPad)], + [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace + target:nil + action:nil], + [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Done", nil) + style:UIBarButtonItemStyleDone + target:self + action:@selector(doneWithNumberPad)], + nil]; + [numberToolbar sizeToFit]; + + self.inputAccessoryView = numberToolbar; +} + +- (void)cancelNumberPad { + [self resignFirstResponder]; + self.text = @""; +} + +- (void)doneWithNumberPad { + [self resignFirstResponder]; +} +@end diff --git a/submodules/MS2/MS2/ViewController.h b/submodules/MS2/MS2/ViewController.h new file mode 100644 index 000000000..342c76cdb --- /dev/null +++ b/submodules/MS2/MS2/ViewController.h @@ -0,0 +1,24 @@ +// +// ViewController.h +// MS2 +// +// Created by guillaume on 06/05/2015. +// Copyright (c) 2015 Belldonne Communications. All rights reserved. +// + +#import + +@interface ViewController : UIViewController + +- (IBAction)onStartStreamsClick:(id)sender; +- (IBAction)changeCamUp:(id)sender; +- (IBAction)changeCamDown:(id)sender; + +@property(weak, nonatomic) IBOutlet UIView *remoteView; +@property(weak, nonatomic) IBOutlet UIView *localView; +@property(weak, nonatomic) IBOutlet UIButton *startStreamLabel; + +@property(weak, nonatomic) IBOutlet UILabel *infoLabel; +@property(weak, nonatomic) IBOutlet UILabel *bandwidthLabel; + +@end diff --git a/submodules/MS2/MS2/ViewController.m b/submodules/MS2/MS2/ViewController.m new file mode 100644 index 000000000..8b47190d4 --- /dev/null +++ b/submodules/MS2/MS2/ViewController.m @@ -0,0 +1,151 @@ +// +// ViewController.m +// MS2 +// +// Created by guillaume on 06/05/2015. +// Copyright (c) 2015 Belldonne Communications. All rights reserved. +// + +#import "ViewController.h" +#include +#include + +#import "mediastreamer2/mediastream.h" +#import "oRTP/rtpsession.h" +#import "UITextField+DoneButton.h" +extern void libmsopenh264_init(); + +@interface ViewController () { + + MSWebCam *videoCam; + MSWebCam *noCam; + MSFilter *noWebCamFilter; + MSFilter *videoCamFilter; + + RtpProfile *profile; + VideoStream *currentStream; + IceSession *iceSession; + PayloadType *vp8_pt; +} +@end + +@implementation ViewController +#define CAM_NAME "AV Capture: com.apple.avfoundation.avcapturedevice.built-in_video:1" + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view, typically from a nib. + + ortp_init(); + ortp_set_log_level_mask(ORTP_DEBUG | ORTP_MESSAGE | ORTP_WARNING | ORTP_ERROR | ORTP_FATAL); + ms_init(); + libmsopenh264_init(); /*no plugin on IOS/Android */ + + NSString *nowebFile = @"nowebcamCIF.jpg"; + NSString *path = [[NSBundle mainBundle] pathForResource:[nowebFile stringByDeletingPathExtension] + ofType:[nowebFile pathExtension]]; + ms_static_image_set_default_image([path UTF8String]); + + noCam = ms_web_cam_manager_get_cam(ms_web_cam_manager_get(), "StaticImage: Static picture"); + videoCam = ms_web_cam_manager_get_cam(ms_web_cam_manager_get(), CAM_NAME); + + noWebCamFilter = ms_web_cam_create_reader(noCam); + videoCamFilter = ms_web_cam_create_reader(videoCam); + + currentStream = NULL; + profile = rtp_profile_clone_full(&av_profile); + rtp_profile_set_payload(profile, 103, &payload_type_vp8); + + vp8_pt = payload_type_clone(rtp_profile_get_payload(profile, 103)); + + // Enable AVPF + PayloadTypeAvpfParams avpf_params; + payload_type_set_flag(vp8_pt, PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED); + avpf_params.features = + PAYLOAD_TYPE_AVPF_FIR | PAYLOAD_TYPE_AVPF_PLI | PAYLOAD_TYPE_AVPF_SLI | PAYLOAD_TYPE_AVPF_RPSI; + avpf_params.trr_interval = 3000; + payload_type_set_avpf_params(vp8_pt, avpf_params); + + vp8_pt->normal_bitrate = 500000; + + [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(timer:) userInfo:nil repeats:TRUE]; + [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(infoTimer:) userInfo:nil repeats:TRUE]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (void)updateInfo { + if (currentStream == NULL) { + self.infoLabel.text = @"No stream"; + self.bandwidthLabel.text = @""; + return; + } + const MSWebCam *currentCam = video_stream_get_camera(currentStream); + if (currentCam) + self.infoLabel.text = [NSString stringWithFormat:@"Stream running, current cam: %s", currentCam->name]; + else + self.infoLabel.text = @"No Webcam ?!"; + + MediaStream *ms = (MediaStream *)currentStream; + float upload = rtp_session_get_rtp_send_bandwidth(ms->sessions.rtp_session); + float download = rtp_session_get_rtp_recv_bandwidth(ms->sessions.rtp_session); + + self.bandwidthLabel.text = + [NSString stringWithFormat:@"Upload: %f kbit/s, Download: %f kbit/s", upload / 1000.0, download / 1000.0]; +} + +#pragma mark - Timer callbacks +- (void)timer:(NSTimer *)timer { + if (currentStream) { + media_stream_iterate((MediaStream *)currentStream); + } +} + +- (void)infoTimer:(NSTimer *)timer { + [self updateInfo]; +} + +#pragma mark - Actions + +- (IBAction)onStartStreamsClick:(id)sender { + if (currentStream) { + VideoStream *stream = currentStream; + currentStream = NULL; + video_stream_stop_keep_source(stream); + [self.startStreamLabel setTitle:@"Start streams" forState:UIControlStateNormal]; + + } else { + VideoStream *stream = video_stream_new(3456, 3457, FALSE); + video_stream_set_native_window_id(stream, (unsigned long)self.remoteView); + video_stream_set_native_preview_window_id(stream, (unsigned long)self.localView); + video_stream_start_with_source(stream, profile, "127.0.0.1", 3456, "127.0.0.1", 3457, 103, 30, noCam, + noWebCamFilter); + currentStream = stream; + [self.startStreamLabel setTitle:@"Stop streams" forState:UIControlStateNormal]; + [self updateInfo]; + } +} + +- (IBAction)changeCamUp:(id)sender { + if (currentStream == NULL) + return; + + NSLog(@"Restore static cam (%p)", noWebCamFilter); + video_stream_change_source_filter(currentStream, noCam, noWebCamFilter, TRUE); + + [self updateInfo]; +} + +- (IBAction)changeCamDown:(id)sender { + if (currentStream == NULL) { + return; + } + NSLog(@"Use real camera (%p)", videoCamFilter); + video_stream_change_source_filter(currentStream, videoCam, videoCamFilter, TRUE); + [self updateInfo]; +} + +@end diff --git a/submodules/MS2/MS2/main.m b/submodules/MS2/MS2/main.m new file mode 100644 index 000000000..de777a601 --- /dev/null +++ b/submodules/MS2/MS2/main.m @@ -0,0 +1,16 @@ +// +// main.m +// MS2 +// +// Created by guillaume on 06/05/2015. +// Copyright (c) 2015 Belldonne Communications. All rights reserved. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char *argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/submodules/MS2/MS2Tests/Info.plist b/submodules/MS2/MS2Tests/Info.plist new file mode 100644 index 000000000..157a12536 --- /dev/null +++ b/submodules/MS2/MS2Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + com.belledonne-communications.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/submodules/MS2/MS2Tests/MS2Tests.m b/submodules/MS2/MS2Tests/MS2Tests.m new file mode 100644 index 000000000..1e63b7689 --- /dev/null +++ b/submodules/MS2/MS2Tests/MS2Tests.m @@ -0,0 +1,40 @@ +// +// MS2Tests.m +// MS2Tests +// +// Created by guillaume on 06/05/2015. +// Copyright (c) 2015 Belldonne Communications. All rights reserved. +// + +#import +#import + +@interface MS2Tests : XCTestCase + +@end + +@implementation MS2Tests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + XCTAssert(YES, @"Pass"); +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/submodules/MS2/README.md b/submodules/MS2/README.md new file mode 100644 index 000000000..22279c7ba --- /dev/null +++ b/submodules/MS2/README.md @@ -0,0 +1,10 @@ +## Simple example of MediaStreamer 2 usage + +This Xcode project is a simple local (not using the network) example of use of the MediaStreamer2 API. **This project only works on a real device with a camera onboard: running it on the simulator will not work**. + +It requires first that you compile the liblinphone SDK into the `submodules/build` directory. Please read theroot directory README for instructions on how to build this SDK. + +After that, simply open the MS2.xcodeproj file with Xcode and press the Run button on the top. + +You will be presented with a munimal UI that lets you start a streaming session, and switch rapidly between a static image and the live image coming from the camera sensor of the device. + diff --git a/submodules/bcg729 b/submodules/bcg729 index 0a58e95c1..06d0bfe52 160000 --- a/submodules/bcg729 +++ b/submodules/bcg729 @@ -1 +1 @@ -Subproject commit 0a58e95c1d7f7da9035456f2b1bcfa832bfd2d7e +Subproject commit 06d0bfe525d7ba0246020408ecb62d13b7e4c868 diff --git a/submodules/belle-sip b/submodules/belle-sip index e5e0590db..bdf7594a8 160000 --- a/submodules/belle-sip +++ b/submodules/belle-sip @@ -1 +1 @@ -Subproject commit e5e0590db8917ccbf5631ec42022bb9f8e03b064 +Subproject commit bdf7594a81c7c5058b1c4fd1a9cd460bb4666ae7 diff --git a/submodules/binaries/libdummy.a b/submodules/binaries/libdummy.a deleted file mode 100644 index a4910d080..000000000 Binary files a/submodules/binaries/libdummy.a and /dev/null differ diff --git a/submodules/binaries/libvpx-armv7.a b/submodules/binaries/libvpx-armv7.a deleted file mode 100644 index 888bdc235..000000000 Binary files a/submodules/binaries/libvpx-armv7.a and /dev/null differ diff --git a/submodules/binaries/libvpx-armv7s.a b/submodules/binaries/libvpx-armv7s.a deleted file mode 100644 index c36d5f299..000000000 Binary files a/submodules/binaries/libvpx-armv7s.a and /dev/null differ diff --git a/submodules/binaries/libvpx-i386.a b/submodules/binaries/libvpx-i386.a deleted file mode 100644 index 6d8042248..000000000 Binary files a/submodules/binaries/libvpx-i386.a and /dev/null differ diff --git a/submodules/binaries/why.txt b/submodules/binaries/why.txt deleted file mode 100644 index 5325fecad..000000000 --- a/submodules/binaries/why.txt +++ /dev/null @@ -1,17 +0,0 @@ -Notes: - -This directory is here because some of our dependencies compile incorrecly -(or not at all) with the compilers that Apple ships with its newer Xcode versions. - -You'll find here the reasons why certain libs are furnished pre-compiled. - -Additionaly, the libdummy.a is an empty library created to stub the tunnel extension. - -= Libvpx = - -Binary version compiled with XCode 5.0, with the patch suggested here for -garbage video fix: https://code.google.com/p/webm/issues/detail?id=603#c45 - -Compiles OK on XCode 5.1 but results in a crash in-app. -Bug is here: https://code.google.com/p/webm/issues/detail?id=737 - diff --git a/submodules/build/Makefile b/submodules/build/Makefile index e2e83ff3a..b081e82c4 100644 --- a/submodules/build/Makefile +++ b/submodules/build/Makefile @@ -19,158 +19,13 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ############################################################################ -enable_gpl_third_parties=yes -enable_zrtp=yes -enable_ffmpeg=no -enable_opus=yes -enable_debug=no - -# Checks -CHECK_MSG=$(shell ../../Tools/check_tools.sh) - -ifneq ($(CHECK_MSG),) - $(error Some tools are missing.) -endif - - -TUNNEL_AVAILABLE=$(shell git submodule status ../tunnel 2>/dev/null 1>/dev/null && echo yes) -ifneq ($(TUNNEL_AVAILABLE),) - enable_tunnel=yes - enable_gpl_third_parties=no -else - enable_tunnel=no -endif - - -.NOTPARALLEL all: check_options build warning - -# check that the selected options are correct -CHECKOPT_MSG := "" - -ifeq ($(enable_gpl_third_parties)$(enable_ffmpeg),noyes) -# ffmpeg is not compatible with no GPL. - enable_ffmpeg:=no -endif - -ifneq ($(CHECKOPT_MSG),"") -check_options: - @echo $(CHECKOPT_MSG) -else -check_options: -endif - -# setup footer - -ifeq ($(enable_gpl_third_parties),yes) -warning: - @echo - @echo "***************************************************************************" - @echo "***************************************************************************" - @echo "*****CAUTION, this liblinphone SDK is built using 3rd party GPL code ******" - @echo "*****Even if you acquired a proprietary license from Belledonne ******" - @echo "*****Communications, this SDK is GPL and GPL only. ******" - @echo "*****To disable 3rd party gpl code, please use: ******" - @echo "*****$ make enable_gpl_third_parties=no ******" - @echo "***************************************************************************" - @echo "***************************************************************************" -else -warning: - @echo - @echo "*****************************************************************" - @echo "*****************************************************************" - @echo "*****Linphone SDK without 3rd party GPL software ******" - @echo "*****If you acquired a proprietary license from Belledonne ******" - @echo "*****Communications, this SDK can be used to create ******" - @echo "*****a proprietary linphone-based application. ******" - @echo "*****************************************************************" - @echo "*****************************************************************" -endif - -LINPHONE_OPTIONS=enable_gpl_third_parties=$(enable_gpl_third_parties) \ - enable_zrtp=$(enable_zrtp) enable_opus=$(enable_opus) \ - enable_debug=$(enable_debug) enable_ffmpeg=$(enable_ffmpeg) enable_tunnel=$(enable_tunnel) - - -armv7-%: - make -f builder-iphone-os.mk $(LINPHONE_OPTIONS) $* - -arm64-%: - make -f builder-iphone-os.mk host=aarch64-apple-darwin $(LINPHONE_OPTIONS) $* V=1 VERBOSE=1 - -simu-%: - make -f builder-iphone-simulator.mk $(LINPHONE_OPTIONS) $* - -arm64: - make -f builder-iphone-os.mk host=aarch64-apple-darwin $(LINPHONE_OPTIONS) V=1 VERBOSE=1 - - -# sends the target after 'broadcast_' to all sub-architectures (armv7, simu, arm64) -broadcast_%: - @echo "Broadcasting target '$*' to all sub-architectures" - make -f builder-iphone-simulator.mk $(LINPHONE_OPTIONS) $* \ - && make -f builder-iphone-os.mk $(LINPHONE_OPTIONS) $* \ - && make -f builder-iphone-os.mk host=aarch64-apple-darwin $(LINPHONE_OPTIONS) $* - -build-% clean-% veryclean-%: - make -f builder-iphone-simulator.mk $(LINPHONE_OPTIONS) $@ \ - && make -f builder-iphone-os.mk $(LINPHONE_OPTIONS) $@ \ - && make -f builder-iphone-os.mk host=aarch64-apple-darwin $(LINPHONE_OPTIONS) $@ - -sdk: - make -f builder-iphone-os.mk delivery-sdk - -libs: - make -f builder-iphone-os.mk multi-arch - -download-sdk: - make -f builder-iphone-os.mk download-sdk - -build: broadcast_all libs - -ipa: build broadcast_ipa - -clean: broadcast_clean - -veryclean: broadcast_veryclean - -list-packages: - @make -f builder-iphone-os.mk list-packages - -pull-transifex: - cd ../../ && tx pull -af - -push-transifex: - cd ../../ && ./Tools/generate_strings_files.sh && tx push -s -t -f --no-interactive - -zipres: - @tar -C ../.. -czf ../../ios_assets.tar.gz Resources iTunesArtwork - @echo Archive 'ios_assets.tar.gz' placed in root directory - -help: - @echo "(please read the README file first)" - @echo "Available architectures: armv7, simu" - @echo "Available targets:" - @echo "" - @echo " * all : builds all architectures and creates the liblinphone sdk" - @echo " * ipa : builds all, creates the SDK, then builds an IPA of the Linphone-iphone application" - @echo " * clean : clean all packages for all architectures" - @echo " * veryclean : completely clean all packages for all architectures" - @echo " * zipres : creates a tar.gz file with all the resources (images)" - @echo "" - @echo "=== Advanced usage ===" - @echo "" - @echo " * list-packages : lists the packages that you can build" - @echo "" - @echo " * build-[package] : builds the package for all architectures" - @echo " * clean-[package] : clean the package for all architectures" - @echo " * veryclean-[package] : completely clean the package for all architectures" - @echo "" - @echo " * armv7-build-[package] : builds a package for the armv7 architecture" - @echo " * simu-build-[package] : builds a package for the simulator architecture" - @echo "" - @echo " * [arch]-clean-[package] : clean the package for the selected architecture" - @echo " * [arch]-veryclean-[package] : completely clean the package for the selected architecture" - @echo "" - @echo " * sdk : re-add all generated libraries to the SDK. Use this only after a full build." - @echo " * libs : after a rebuild of a subpackage, will mix the new libs in liblinphone-sdk/apple-darwin directory" +all: + @echo "*******************************************************************************" + @echo "This makefile is deprecated. Please see README.md for compilation instructions. Here are some equivalents:" + @echo "Equivalent of make is: cd ../../ && ./prepare.py && make" + @echo "Equivalent of make enable_gpl_third_parties=no is: cd ../../ && ./prepare.py -DENABLE_GPL_THIRD_PARTIES=NO && make" + @echo "Equivalent of make enable_debug=yes is: cd ../../ && ./prepare.py -d && make" + @echo "Equivalent of make enable_i386=yes is: cd ../../ && ./prepare.py all && make" + @echo "Equivalent of make enable_zrpt=yes enable_opus=yes enable_ffmpeg is: cd ../../ && ./prepare.py -DENABLE_ZRTP=YES -DENABLE_OPUS=YES -DENABLE_FFMPEG=YES && make" + @echo "*******************************************************************************" diff --git a/submodules/build/Makefile.xcode4.4 b/submodules/build/Makefile.xcode4.4 deleted file mode 100644 index 276688bb4..000000000 --- a/submodules/build/Makefile.xcode4.4 +++ /dev/null @@ -1,81 +0,0 @@ -############################################################################ -# Makefile -# Copyright (C) 2009 Belledonne Communications,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. -# -############################################################################ -enable_gpl_third_parties=yes -enable_zrtp=no - -.NOTPARALLEL all: check_options build warning -ifeq ($(enable_gpl_third_parties)$(enable_zrtp),noyes) -check_options: - @echo "ZRTP is not available in non-gpl build." - @exit -1 -else -check_options: - -endif - -ifeq ($(enable_gpl_third_parties),yes) -warning: - @echo - @echo "*****************************************************************" - @echo "*****************************************************************" - @echo "*****CAUTION, this liblinphone SDK is built using GPL code ******" - @echo "*****To disable gpl code, use make enable_gpl_third_parties=no***" - @echo "*****************************************************************" - @echo "*****************************************************************" -else -warning: - @echo - @echo "*****************************************************************" - @echo "*****************************************************************" - @echo "*****linphone SDK without GPL code ******" - @echo "*****************************************************************" - @echo "*****************************************************************" -endif - -LINPHONE_OPTIONS=enable_gpl_third_parties=$(enable_gpl_third_parties) enable_zrtp=$(enable_zrtp) - -build: - make -f builder-iphone-os.mk host=armv6-apple-darwin $(LINPHONE_OPTIONS) all \ - && make -f builder-iphone-simulator.mk $(LINPHONE_OPTIONS) all \ - && make -f builder-iphone-os.mk host=armv7-apple-darwin $(LINPHONE_OPTIONS) all \ - && make -f builder-iphone-os.mk delivery-sdk - -ipa: build - make -f builder-iphone-simulator.mk ipa \ - && make -f builder-iphone-os.mk host=armv6-apple-darwin ipa \ - && make -f builder-iphone-os.mk host=armv7-apple-darwin ipa - -clean: - make -f builder-iphone-simulator.mk clean \ - && make -f builder-iphone-os.mk host=armv6-apple-darwin clean \ - && make -f builder-iphone-os.mk host=armv7-apple-darwin clean - -clean-makefile: - make -f builder-iphone-simulator.mk clean-makefile \ - && make -f builder-iphone-os.mk host=armv6-apple-darwin clean-makefile \ - && make -f builder-iphone-os.mk host=armv7-apple-darwin clean-makefile - -veryclean: - make -f builder-iphone-simulator.mk veryclean \ - && make -f builder-iphone-os.mk host=armv6-apple-darwin veryclean \ - && make -f builder-iphone-os.mk host=armv7-apple-darwin veryclean - diff --git a/submodules/build/builder-iphone-os.mk b/submodules/build/builder-iphone-os.mk deleted file mode 100644 index 879da6690..000000000 --- a/submodules/build/builder-iphone-os.mk +++ /dev/null @@ -1,278 +0,0 @@ -############################################################################ -# builder-generic.mk -# Copyright (C) 2009 Belledonne Communications,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. -# -############################################################################ - -host?=armv7-apple-darwin -config_site:=iphone-config.site -library_mode:= --disable-shared --enable-static -linphone_configure_controls = \ - --with-readline=none \ - --enable-gtk_ui=no \ - --enable-console_ui=no \ - --enable-bellesip \ - --with-gsm=$(prefix) \ - --with-srtp=$(prefix) \ - --with-antlr=$(prefix) \ - --disable-strict \ - --disable-nls \ - --disable-theora \ - --disable-sdl \ - --disable-x11 \ - --disable-tutorials \ - --disable-tools \ - --enable-msg-storage=yes \ - --with-polarssl=$(prefix) \ - --enable-dtls - - -#path -BUILDER_SRC_DIR?=$(shell pwd)/../ -ifeq ($(enable_debug),yes) -BUILDER_BUILD_DIR?=$(shell pwd)/../build-$(host)-debug -linphone_configure_controls += CFLAGS="-g" -prefix?=$(BUILDER_SRC_DIR)/../liblinphone-sdk/$(host)-debug -else -BUILDER_BUILD_DIR?=$(shell pwd)/../build-$(host) -prefix?=$(BUILDER_SRC_DIR)/../liblinphone-sdk/$(host) -endif - -LINPHONE_SRC_DIR=$(BUILDER_SRC_DIR)/linphone -LINPHONE_BUILD_DIR=$(BUILDER_BUILD_DIR)/linphone -LINPHONE_IPHONE_VERSION=$(shell git describe --always) - -# list of the submodules to build, the order is important -MEDIASTREAMER_PLUGINS := msilbc \ - libilbc \ - msamr \ - mssilk \ - msx264 \ - msopenh264 \ - msbcg729 -# TODO: add mswebrtc when it is commatible again - - -SUBMODULES_LIST := polarssl - -ifeq ($(enable_tunnel),yes) -SUBMODULES_LIST += tunnel -endif - -SUBMODULES_LIST += libantlr \ - cunit \ - belle-sip \ - srtp \ - speex \ - libgsm \ - libvpx \ - libxml2 \ - bzrtp \ - ffmpeg \ - opus - -# build linphone (which depends on submodules) and then the plugins -all: build-linphone $(addprefix build-,$(MEDIASTREAMER_PLUGINS)) - - - -#################################################################### -# setup the switches that might trigger a linphone recompilation -#################################################################### - -enable_gpl_third_parties?=yes -enable_ffmpeg?=yes -enable_zrtp?=yes - -SWITCHES:= - -ifeq ($(enable_zrtp), yes) - linphone_configure_controls+= --enable-zrtp - SWITCHES += enable_zrtp -else - linphone_configure_controls+= --disable-zrtp - SWITCHES += disable_zrtp -endif - -ifeq ($(enable_tunnel), yes) - linphone_configure_controls+= --enable-tunnel - SWITCHES += enable_tunnel -else - linphone_configure_controls+= --disable-tunnel - SWITCHES += disable_tunnel -endif - -ifeq ($(enable_gpl_third_parties),yes) - SWITCHES+= enable_gpl_third_parties - - ifeq ($(enable_ffmpeg), yes) - linphone_configure_controls+= --enable-ffmpeg - SWITCHES += enable_ffmpeg - else - linphone_configure_controls+= --disable-ffmpeg - SWITCHES += disable_ffmpeg - endif - -else # !enable gpl - linphone_configure_controls+= --disable-ffmpeg - SWITCHES += disable_gpl_third_parties disable_ffmpeg -endif - -SWITCHES := $(addprefix $(LINPHONE_BUILD_DIR)/,$(SWITCHES)) - -mode_switch_check: $(SWITCHES) -#generic rule to force recompilation of linphone if some options require it -$(LINPHONE_BUILD_DIR)/enable_% $(LINPHONE_BUILD_DIR)/disable_%: - mkdir -p $(LINPHONE_BUILD_DIR) - cd $(LINPHONE_BUILD_DIR) && rm -f *able_$* - touch $@ - cd $(LINPHONE_BUILD_DIR) && rm -f Makefile && rm -f oRTP/Makefile && rm -f mediastreamer2/Makefile - -#################################################################### -# Base rules: -#################################################################### - - -clean-makefile: clean-makefile-linphone -clean: clean-linphone -init: - mkdir -p $(prefix)/include - mkdir -p $(prefix)/lib/pkgconfig - -veryclean: veryclean-linphone - rm -rf $(BUILDER_BUILD_DIR) - -list-packages: - @echo "Submodules:" - @echo "$(addprefix \nbuild-,$(SUBMODULES_LIST))" - @echo "\nPlugins: " - @echo "$(addprefix \nbuild-,$(MEDIASTREAMER_PLUGINS))" - -#################################################################### -# Linphone compilation -#################################################################### - -build-submodules: $(addprefix build-,$(SUBMODULES_LIST)) - -.NOTPARALLEL build-linphone: init build-submodules mode_switch_check $(LINPHONE_BUILD_DIR)/Makefile - cd $(LINPHONE_BUILD_DIR) && \ - export PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig && \ - export CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) && \ - make newdate && make all && make install - mkdir -p $(prefix)/share/linphone/tutorials && cp -f $(LINPHONE_SRC_DIR)/coreapi/help/*.c $(prefix)/share/linphone/tutorials/ - -clean-linphone: $(addprefix clean-,$(SUBMODULES_LIST)) $(addprefix clean-,$(MEDIASTREAMER_PLUGINS)) - cd $(LINPHONE_BUILD_DIR) && make clean - -veryclean-linphone: $(addprefix veryclean-,$(SUBMODULES_LIST)) $(addprefix veryclean-,$(MEDIASTREAMER_PLUGINS)) -#-cd $(LINPHONE_BUILD_DIR) && make distclean - -cd $(LINPHONE_SRC_DIR) && rm -f configure - -clean-makefile-linphone: $(addprefix clean-makefile-,$(SUBMODULES_LIST)) $(addprefix clean-makefile-,$(MEDIASTREAMER_PLUGINS)) - cd $(LINPHONE_BUILD_DIR) && rm -f Makefile && rm -f oRTP/Makefile && rm -f mediastreamer2/Makefile - - -$(LINPHONE_SRC_DIR)/configure: - cd $(LINPHONE_SRC_DIR) && ./autogen.sh - -$(LINPHONE_BUILD_DIR)/Makefile: $(LINPHONE_SRC_DIR)/configure - mkdir -p $(LINPHONE_BUILD_DIR) - @echo -e "\033[1mPKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(LINPHONE_SRC_DIR)/configure -prefix=$(prefix) --host=$(host) ${library_mode} \ - ${linphone_configure_controls}\033[0m" - cd $(LINPHONE_BUILD_DIR) && \ - PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(LINPHONE_SRC_DIR)/configure -prefix=$(prefix) --host=$(host) ${library_mode} \ - ${linphone_configure_controls} - - -#libphone only (asume dependencies are met) -build-liblinphone: $(LINPHONE_BUILD_DIR)/Makefile - cd $(LINPHONE_BUILD_DIR) && export PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig export CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) make newdate && make && make install - -clean-makefile-liblinphone: - cd $(LINPHONE_BUILD_DIR) && rm -f Makefile && rm -f oRTP/Makefile && rm -f mediastreamer2/Makefile - -clean-liblinphone: - cd $(LINPHONE_BUILD_DIR) && make clean - - -include builders.d/*.mk - -#################################################################### -# sdk generation and distribution -#################################################################### - -multi-arch: - arm_archives=`find $(prefix) -name *.a` ;\ - mkdir -p $(prefix)/../apple-darwin; \ - cp -rf $(prefix)/include $(prefix)/../apple-darwin/. ; \ - cp -rf $(prefix)/share $(prefix)/../apple-darwin/. ; \ - for archive in $$arm_archives ; do \ - i386_path=`echo $$archive | sed -e "s/armv7/i386/"` ;\ - arm64_path=`echo $$archive | sed -e "s/armv7/aarch64/"` ;\ - if test ! -f "$$arm64_path"; then \ - arm64_path= ; \ - fi; \ - destpath=`echo $$archive | sed -e "s/-debug//"` ;\ - destpath=`echo $$destpath | sed -e "s/armv7-//"` ;\ - if test -f "$$i386_path"; then \ - echo "Mixing $$archive into $$destpath"; \ - mkdir -p `dirname $$destpath` ; \ - lipo -create $$archive $$arm64_path $$i386_path -output $$destpath; \ - else \ - echo "WARNING: archive `basename $$archive` exists in arm tree but does not exists in i386 tree."; \ - fi \ - done - if ! test -f $(prefix)/../apple-darwin/lib/libtunnel.a ; then \ - cp -f $(BUILDER_SRC_DIR)/../submodules/binaries/libdummy.a $(prefix)/../apple-darwin/lib/libtunnel.a ; \ - fi - - -delivery-sdk: multi-arch - echo "Generating SDK zip file for version $(LINPHONE_IPHONE_VERSION)" - cd $(BUILDER_SRC_DIR)/../ \ - && zip -r $(BUILDER_SRC_DIR)/liblinphone-iphone-sdk-$(LINPHONE_IPHONE_VERSION).zip \ - liblinphone-sdk/apple-darwin \ - liblinphone-tutorials \ - -x liblinphone-tutorials/hello-world/build\* \ - -x liblinphone-tutorials/hello-world/hello-world.xcodeproj/*.pbxuser \ - -x liblinphone-tutorials/hello-world/hello-world.xcodeproj/*.mode1v3 - -download-sdk: - @echo "Downloading the latest binary SDK" - cd $(BUILDER_SRC_DIR)/../ - rm -fr liblinphone-iphone-sdk-latest* - wget http://linphone.org/snapshots/ios/liblinphone-iphone-sdk-latest.zip - unzip -o -q liblinphone-iphone-sdk-latest.zip - rm -fr ../../liblinphone-sdk/ - mv liblinphone-sdk ../.. - -.PHONY delivery: - cd $(BUILDER_SRC_DIR)/../../ \ - && zip -r $(BUILDER_SRC_DIR)/linphone-iphone.zip \ - linphone-iphone \ - -x linphone-iphone/build\* \ - --exclude linphone-iphone/.git\* --exclude \*.[od] --exclude \*.so.\* --exclude \*.a --exclude linphone-iphone/liblinphone-sdk/apple-darwin/\* --exclude \*.lo - -ipa: - cd $(BUILDER_SRC_DIR)/../ \ - && xcodebuild -configuration Release \ - && xcrun -sdk iphoneos PackageApplication -v build/Release-iphoneos/linphone.app -o $(BUILDER_SRC_DIR)/../linphone-iphone.ipa - diff --git a/submodules/build/builder-iphone-simulator.mk b/submodules/build/builder-iphone-simulator.mk deleted file mode 100644 index ea2363be5..000000000 --- a/submodules/build/builder-iphone-simulator.mk +++ /dev/null @@ -1,24 +0,0 @@ -############################################################################ -# builder-iphone-simulator.mk -# Copyright (C) 2009 Belledonne Communications,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. -# -############################################################################ -host:=i386-apple-darwin -include builder-iphone-os.mk - diff --git a/submodules/build/builders.d/belle-sip.mk b/submodules/build/builders.d/belle-sip.mk deleted file mode 100644 index 085472d54..000000000 --- a/submodules/build/builders.d/belle-sip.mk +++ /dev/null @@ -1,43 +0,0 @@ -############################################################################ -# belle-sip.mk -# Copyright (C) 2013 Belledonne Communications,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. -# -############################################################################ -belle-sip_dir?=belle-sip -$(BUILDER_SRC_DIR)/$(belle-sip_dir)/configure: - cd $(BUILDER_SRC_DIR)/$(belle-sip_dir) && ./autogen.sh - -$(BUILDER_BUILD_DIR)/$(belle-sip_dir)/Makefile: $(BUILDER_SRC_DIR)/$(belle-sip_dir)/configure - mkdir -p $(BUILDER_BUILD_DIR)/$(belle-sip_dir) - cd $(BUILDER_BUILD_DIR)/$(belle-sip_dir)/ \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(BUILDER_SRC_DIR)/$(belle-sip_dir)/configure --prefix=$(prefix) --host=$(host) ${library_mode} --enable-tls --enable-tunnel --with-polarssl=$(prefix) - -build-belle-sip: $(BUILDER_BUILD_DIR)/$(belle-sip_dir)/Makefile - cd $(BUILDER_BUILD_DIR)/$(belle-sip_dir) && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) make && make install - -clean-belle-sip: - cd $(BUILDER_BUILD_DIR)/$(belle-sip_dir) && make clean - -veryclean-belle-sip: - -cd $(BUILDER_BUILD_DIR)/$(belle-sip_dir) && make distclean - rm -f $(BUILDER_SRC_DIR)/$(belle-sip_dir)/configure - -clean-makefile-belle-sip: - cd $(BUILDER_BUILD_DIR)/$(belle-sip_dir) && rm -f Makefile diff --git a/submodules/build/builders.d/cunit.mk b/submodules/build/builders.d/cunit.mk deleted file mode 100644 index ae09401c0..000000000 --- a/submodules/build/builders.d/cunit.mk +++ /dev/null @@ -1,39 +0,0 @@ -cunit_dir?=cunit - -SRC_DIR=$(BUILDER_SRC_DIR) -BUILD_DIR=$(BUILDER_BUILD_DIR) - - -$(SRC_DIR)/$(cunit_dir)/configure $(SRC_DIR)/$(cunit_dir)/autogened: - cd $(SRC_DIR)/$(cunit_dir) \ - && ./autogen.sh \ - && touch autogened - -$(BUILD_DIR)/$(cunit_dir)/rsynced: $(SRC_DIR)/$(cunit_dir)/configure $(SRC_DIR)/$(cunit_dir)/autogened - mkdir -p $(BUILD_DIR)/$(cunit_dir) - cd $(BUILD_DIR)/$(cunit_dir)/ \ - && rsync -rvLpgoc --exclude ".git" $(SRC_DIR)/$(cunit_dir)/* . \ - && touch $(BUILD_DIR)/$(cunit_dir)/rsynced - -$(BUILD_DIR)/$(cunit_dir)/Makefile: $(BUILD_DIR)/$(cunit_dir)/rsynced - mkdir -p $(BUILD_DIR)/$(cunit_dir) - cd $(BUILD_DIR)/$(cunit_dir) \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(SRC_DIR)/build/$(config_site) \ - $(SRC_DIR)/$(cunit_dir)/configure --prefix=$(prefix) --host=$(host) ${library_mode} - -build-cunit: $(BUILD_DIR)/$(cunit_dir)/Makefile - cd $(BUILD_DIR)/${cunit_dir} \ - && host_alias=$(host) \ - && . $(SRC_DIR)/build/$(config_site) \ - && make V=1 \ - && make install V=1 - -clean-cunit: - -cd $(BUILD_DIR)/$(cunit_dir) && make clean - -veryclean-cunit: - -rm -rf $(BUILD_DIR)/$(cunit_dir) - -rm -f $(SRC_DIR)/$(cunit_dir)/autogened - -clean-makefile-cunit: veryclean-cunit - diff --git a/submodules/build/builders.d/ffmpeg.mk b/submodules/build/builders.d/ffmpeg.mk deleted file mode 100644 index be68d05ea..000000000 --- a/submodules/build/builders.d/ffmpeg.mk +++ /dev/null @@ -1,55 +0,0 @@ -ffmpeg_configure_options=\ - --disable-mmx \ - --enable-cross-compile \ - --disable-ffprobe --disable-ffserver --disable-avdevice --disable-doc \ - --disable-avfilter --disable-network \ - --disable-everything --enable-decoder=mjpeg --enable-encoder=mjpeg --enable-decoder=mpeg4 --enable-encoder=mpeg4 \ - --enable-decoder=h264 --disable-avformat --enable-pic\ - --enable-decoder=h263p --enable-encoder=h263p --enable-decoder=h263 --enable-encoder=h263 \ - --cross-prefix=$$SDK_BIN_PATH/ \ - --sysroot=$$SYSROOT_PATH --arch=$$ARCH \ - --enable-static --disable-shared --target-os=darwin \ - --extra-cflags="-w $$COMMON_FLAGS" --extra-ldflags="$$COMMON_FLAGS" \ - --disable-iconv \ - --ar="$$AR" \ - --nm="$$NM" \ - --cc="$$CC" - -# --as=$(BUILDER_SRC_DIR)/externals/x264/extras/gas-preprocessor.pl - -#--sysinclude=PATH location of cross-build system headers -ifneq (,$(findstring armv6,$(host))) - ffmpeg_configure_options+= --cpu=arm1176jzf-s --disable-armv5te --enable-armv6 --enable-armv6t2 -endif - -ifneq (,$(findstring armv7,$(host))) - ffmpeg_configure_options+= --enable-neon --cpu=cortex-a8 --disable-armv5te --enable-armv6 --enable-armv6t2 -endif - -ffmpeg_dir?=externals/ffmpeg -$(BUILDER_SRC_DIR)/$(ffmpeg_dir)/patched : - cd $(BUILDER_SRC_DIR)/$(ffmpeg_dir) \ - && git apply $(BUILDER_SRC_DIR)/build/builders.d/ffmpeg.patch \ - && touch $(BUILDER_SRC_DIR)/$(ffmpeg_dir)/patched - -$(BUILDER_BUILD_DIR)/$(ffmpeg_dir)/config.mak: - mkdir -p $(BUILDER_BUILD_DIR)/$(ffmpeg_dir) - cd $(BUILDER_BUILD_DIR)/$(ffmpeg_dir)/ \ - && host_alias=${host} . $(BUILDER_SRC_DIR)/build/$(config_site) \ - && $(BUILDER_SRC_DIR)/$(ffmpeg_dir)/configure --prefix=$(prefix) $(ffmpeg_configure_options) - -build-ffmpeg: $(BUILDER_BUILD_DIR)/$(ffmpeg_dir)/config.mak - cd $(BUILDER_BUILD_DIR)/$(ffmpeg_dir) \ - && host_alias=${host} . $(BUILDER_SRC_DIR)/build/$(config_site) \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig make RANLIB="$$RANLIB" && make RANLIB="$$RANLIB" install - -clean-ffmpeg: - -cd $(BUILDER_BUILD_DIR)/$(ffmpeg_dir) && make clean - -veryclean-ffmpeg: - -cd $(BUILDER_BUILD_DIR)/$(ffmpeg_dir) && make distclean - rm -rf $(BUILDER_BUILD_DIR)/$(ffmpeg_dir) - -clean-makefile-ffmpeg: - cd $(BUILDER_BUILD_DIR)/$(ffmpeg_dir) && rm -f config.mak - diff --git a/submodules/build/builders.d/gsm.mk b/submodules/build/builders.d/gsm.mk deleted file mode 100644 index ce686b064..000000000 --- a/submodules/build/builders.d/gsm.mk +++ /dev/null @@ -1,29 +0,0 @@ - -#GSM - -gsm_dir?=externals/gsm - -#GSM build is a bit different: since there is only a Makefile, -#we must force CC to contains CFLAGS to compile all architectures -#as expected -build-libgsm: - cp -rf $(BUILDER_SRC_DIR)/$(gsm_dir) $(BUILDER_BUILD_DIR)/$(gsm_dir) - rm -rf $(BUILDER_BUILD_DIR)/$(gsm_dir)/gsm/.git $(BUILDER_BUILD_DIR)/$(gsm_dir)/.git - rm -f $(prefix)/lib/libgsm.a - rm -rf $(prefix)/include/gsm - cd $(BUILDER_BUILD_DIR)/$(gsm_dir)\ - && mkdir -p $(prefix)/include/gsm \ - && host_alias=$(host) . $(BUILDER_SRC_DIR)/build/$(config_site) \ - && make install \ - CC="$${CC} $${COMMON_FLAGS} -w" \ - INSTALL_ROOT=$(prefix) \ - GSM_INSTALL_INC=$(prefix)/include/gsm - -clean-libgsm: - cd $(BUILDER_BUILD_DIR)/$(gsm_dir)\ - && make clean - -veryclean-libgsm: - -rm -rf $(BUILD_DIR)/$(gsm_dir) - - diff --git a/submodules/build/builders.d/libantlr3c.mk b/submodules/build/builders.d/libantlr3c.mk deleted file mode 100644 index da1cf08f6..000000000 --- a/submodules/build/builders.d/libantlr3c.mk +++ /dev/null @@ -1,43 +0,0 @@ -############################################################################ -# libantlr.mk -# Copyright (C) 2013 Belledonne Communications,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. -# -############################################################################ -libantlr_dir?=externals/antlr3/runtime/C -$(BUILDER_SRC_DIR)/$(libantlr_dir)/configure: - cd $(BUILDER_SRC_DIR)/$(libantlr_dir) && ./autogen.sh - -$(BUILDER_BUILD_DIR)/$(libantlr_dir)/Makefile: $(BUILDER_SRC_DIR)/$(libantlr_dir)/configure - mkdir -p $(BUILDER_BUILD_DIR)/$(libantlr_dir) - cd $(BUILDER_BUILD_DIR)/$(libantlr_dir)/ \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(BUILDER_SRC_DIR)/$(libantlr_dir)/configure -prefix=$(prefix) --host=$(host) ${library_mode} - -build-libantlr: $(BUILDER_BUILD_DIR)/$(libantlr_dir)/Makefile - cd $(BUILDER_BUILD_DIR)/$(libantlr_dir) && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) make && make install - -clean-libantlr: - cd $(BUILDER_BUILD_DIR)/$(libantlr_dir) && make clean - -veryclean-libantlr: - -cd $(BUILDER_BUILD_DIR)/$(libantlr_dir) && make distclean - rm -f $(BUILDER_SRC_DIR)/$(libantlr_dir)/configure - -clean-makefile-libantlr: - cd $(BUILDER_BUILD_DIR)/$(libantlr_dir) && rm -f Makefile diff --git a/submodules/build/builders.d/libilbc.mk b/submodules/build/builders.d/libilbc.mk deleted file mode 100644 index 2f6b4414a..000000000 --- a/submodules/build/builders.d/libilbc.mk +++ /dev/null @@ -1,27 +0,0 @@ - -# libilbc - - -LIBILBC_SRC_DIR:=$(BUILDER_SRC_DIR)/libilbc-rfc3951 -LIBILBC_BUILD_DIR:=$(BUILDER_BUILD_DIR)/libilbc-rfc3951 - -$(LIBILBC_SRC_DIR)/configure: - cd $(LIBILBC_SRC_DIR) && ./autogen.sh - -$(LIBILBC_BUILD_DIR)/Makefile: $(LIBILBC_SRC_DIR)/configure - mkdir -p $(LIBILBC_BUILD_DIR) - cd $(LIBILBC_BUILD_DIR) && \ - PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(LIBILBC_SRC_DIR)/configure -prefix=$(prefix) --host=$(host) $(library_mode) - -build-libilbc: $(LIBILBC_BUILD_DIR)/Makefile - cd $(LIBILBC_BUILD_DIR) && make && make install - -clean-libilbc: - cd $(LIBILBC_BUILD_DIR) && make clean - -veryclean-libilbc: - -cd $(LIBILBC_BUILD_DIR) && make distclean - -clean-makefile-libilbc: - cd $(LIBILBC_BUILD_DIR) && rm -f Makefile diff --git a/submodules/build/builders.d/libvpx.mk b/submodules/build/builders.d/libvpx.mk deleted file mode 100644 index 98e398061..000000000 --- a/submodules/build/builders.d/libvpx.mk +++ /dev/null @@ -1,92 +0,0 @@ - - -# /!\ Unset compiler env variable is set by user to avoid error in configure such as: -# 1) Requested extra CFLAGS '-fno-strict-aliasing' not supported by compiler -# OR -# 2) Unable to invoke compiler -unexport CC - -libvpx_dir?=externals/libvpx - -libvpx_configure_options=\ - --enable-static --disable-shared \ - --disable-examples --disable-unit-tests \ - --enable-realtime-only --enable-spatial-resampling \ - --enable-vp8 --enable-multithread --disable-vp9 - - -ifeq ($(enable_debug),yes) - libvpx_configure_options += --enable-debug -endif - -take_binary= - -# force take binary, it seems libvpx was fixed since http://git.chromium.org/gitweb/?p=webm/libvpx.git;a=commit;h=33df6d1fc1d268b4901b74b4141f83594266f041 -force_non_binary_libvpx=1 - -ifneq (,$(findstring armv6,$(host))) - libvpx_configure_options+= --target=armv6-darwin-gcc --cpu=arm1176jzf-s -else ifneq (,$(findstring armv7s,$(host))) - libvpx_configure_options+= --target=armv7s-darwin-gcc - take_binary = armv7s -else ifneq (,$(findstring armv7,$(host))) - libvpx_configure_options+= --target=armv7-darwin-gcc - take_binary = armv7 -else ifneq (,$(findstring aarch64,$(host))) - libvpx_configure_options+= --target=arm64-darwin-gcc - take_binary = arm64 -else - libvpx_configure_options+= --target=x86-darwin10-gcc - take_binary = i386 -endif - -ifeq ($(LINPHONE_CCACHE),ccache) - libvpx_configure_options+= --enable-ccache -endif - - - -all_p+=armv7-darwin-gcc #neon Cortex-A8 - -ifeq ($(force_non_binary_libvpx),1) -take_binary= -libvpx_configure_options+= --extra-cflags="-fno-strict-aliasing" -endif - -$(BUILDER_SRC_DIR)/$(libvpx_dir)/patched.stamp: - cd $(BUILDER_SRC_DIR)/$(libvpx_dir) \ - && git apply $(BUILDER_SRC_DIR)/build/builders.d/libvpx.patch \ - && touch $@ - - -$(BUILDER_BUILD_DIR)/$(libvpx_dir)/config.mk: $(BUILDER_SRC_DIR)/$(libvpx_dir)/patched.stamp - mkdir -p $(BUILDER_BUILD_DIR)/$(libvpx_dir) - cd $(BUILDER_BUILD_DIR)/$(libvpx_dir)/ \ - && host_alias=${host} . $(BUILDER_SRC_DIR)/build/$(config_site) \ - && export all_platforms="${all_p}" && $(BUILDER_SRC_DIR)/$(libvpx_dir)/configure --prefix=$(prefix) --sdk-path=$$SDK_BIN_PATH/../../ --libc=$$SYSROOT_PATH $(libvpx_configure_options) - -build-libvpx: $(BUILDER_BUILD_DIR)/$(libvpx_dir)/config.mk - cd $(BUILDER_BUILD_DIR)/$(libvpx_dir) \ - && host_alias=${host} . $(BUILDER_SRC_DIR)/build/$(config_site) \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) make && make install -ifeq ($(force_non_binary_libvpx),1) - @echo "\033[01;32m DON'T get BINARY version of libvpx for $(take_binary), because 'force_non_binary_libvpx' is 1 \033[0m" -endif -ifneq (,$(take_binary)) -# sometimes when clang gets updated we have to take binary version of libvpx for ARM because the compiler introduces bugs in optimized assembly - @echo "\033[01;32m Getting BINARY version of libvpx for $(take_binary) \033[0m" - cp $(BUILDER_SRC_DIR)/binaries/libvpx-$(take_binary).a $(prefix)/lib/libvpx.a -endif - -clean-libvpx: - cd $(BUILDER_BUILD_DIR)/$(libvpx_dir) && make clean - -veryclean-libvpx: - -cd $(BUILDER_BUILD_DIR)/$(libvpx_dir) && make distclean - cd $(BUILDER_SRC_DIR)/$(libvpx_dir) \ - && git clean -f && git reset --hard && rm -f patched.stamp - rm -rf $(BUILDER_BUILD_DIR)/$(libvpx_dir) - -clean-makefile-libvpx: - cd $(BUILDER_BUILD_DIR)/$(libvpx_dir) && rm -f config.mak - diff --git a/submodules/build/builders.d/libvpx.patch b/submodules/build/builders.d/libvpx.patch deleted file mode 100644 index a0bb55045..000000000 --- a/submodules/build/builders.d/libvpx.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c -index 5aa274d..9eee377 100644 ---- a/vp8/vp8_dx_iface.c -+++ b/vp8/vp8_dx_iface.c -@@ -327,14 +327,6 @@ static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx, - unsigned int resolution_change = 0; - unsigned int w, h; - -- if (data == NULL && data_sz == 0) { -- ctx->flushed = 1; -- return VPX_CODEC_OK; -- } -- -- /* Reset flushed when receiving a valid frame */ -- ctx->flushed = 0; -- - /* Update the input fragment data */ - if(update_fragments(ctx, data, data_sz, &res) <= 0) - return res; diff --git a/submodules/build/builders.d/libxml2.mk b/submodules/build/builders.d/libxml2.mk deleted file mode 100644 index ce7c72135..000000000 --- a/submodules/build/builders.d/libxml2.mk +++ /dev/null @@ -1,62 +0,0 @@ -############################################################################ -# libxml2.mk -# Copyright (C) 2013 Belledonne Communications,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. -# -############################################################################ -libxml2_dir?=externals/libxml2 - -libxml2_configure_options= --enable-static --disable-shared -libxml2_configure_options+= --disable-rebuild-docs --enable-rebuild-docs=no --with-iconv=no --with-python=no --with-zlib=no - -$(BUILDER_SRC_DIR)/$(libxml2_dir)/patched.stamp: - cd $(BUILDER_SRC_DIR)/$(libxml2_dir) \ - && git apply $(BUILDER_SRC_DIR)/build/builders.d/libxml2.patch \ - && touch $@ - -$(BUILDER_SRC_DIR)/$(libxml2_dir)/configure: $(BUILDER_SRC_DIR)/$(libxml2_dir)/patched.stamp - @echo -e "\033[01;32m Running autogen for libxml2 in $(BUILDER_SRC_DIR)/$(libxml2_dir) \033[0m" - cd $(BUILDER_SRC_DIR)/$(libxml2_dir) \ - && PKG_CONFIG_PATH=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) NOCONFIGURE=1 \ - $(BUILDER_SRC_DIR)/$(libxml2_dir)/autogen.sh -prefix=$(prefix) --host=$(host) ${library_mode} - -$(BUILDER_BUILD_DIR)/$(libxml2_dir)/Makefile: $(BUILDER_SRC_DIR)/$(libxml2_dir)/configure - @echo -e "\033[01;32m Running configure in $(BUILDER_BUILD_DIR)/$(libxml2_dir) \033[0m" - mkdir -p $(BUILDER_BUILD_DIR)/$(libxml2_dir) - cd $(BUILDER_BUILD_DIR)/$(libxml2_dir) \ - && PKG_CONFIG_PATH=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(BUILDER_SRC_DIR)/$(libxml2_dir)/configure -prefix=$(prefix) --host=$(host) ${library_mode} ${libxml2_configure_options} CFLAGS=-w - -build-libxml2: $(BUILDER_BUILD_DIR)/$(libxml2_dir)/Makefile - @echo -e "\033[01;32m building libxml2 \033[0m" - cd $(BUILDER_BUILD_DIR)/$(libxml2_dir) \ - && PKG_CONFIG_PATH=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - make && make install - -clean-libxml2: - -cd $(BUILDER_BUILD_DIR)/$(libxml2_dir) && make clean - -veryclean-libxml2: - -cd $(BUILDER_BUILD_DIR)/$(libxml2_dir) && make distclean - rm -f $(BUILDER_SRC_DIR)/$(libxml2_dir)/configure - cd $(BUILDER_SRC_DIR)/$(libxml2_dir) \ - && git checkout configure.in \ - && rm -f patched.stamp - -clean-makefile-libxml2: - -cd $(BUILDER_BUILD_DIR)/$(libxml2_dir) && rm -f Makefile diff --git a/submodules/build/builders.d/libxml2.patch b/submodules/build/builders.d/libxml2.patch deleted file mode 100644 index eb2ac3cd9..000000000 --- a/submodules/build/builders.d/libxml2.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/configure.in b/configure.in -index 0fb4983..a5f86ca 100644 ---- a/configure.in -+++ b/configure.in -@@ -1,7 +1,7 @@ - dnl Process this file with autoconf to produce a configure script. - AC_PREREQ(2.59) - AC_INIT(entities.c) --AM_CONFIG_HEADER(config.h) -+AC_CONFIG_HEADERS(config.h) - AC_CONFIG_MACRO_DIR([m4]) - AC_CANONICAL_HOST - diff --git a/submodules/build/builders.d/msamr.mk b/submodules/build/builders.d/msamr.mk deleted file mode 100644 index d5dbf097a..000000000 --- a/submodules/build/builders.d/msamr.mk +++ /dev/null @@ -1,50 +0,0 @@ -############################################################################ -# msamr.mk -# Copyright (C) 2011 Belledonne Communications,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. -# -############################################################################ -msamr_dir?=msamr - -configure-options= -ifeq ($(LINPHONE_CCACHE), ccache) - configure-options+= --disable-strict -endif - - -$(BUILDER_SRC_DIR)/$(msamr_dir)/configure: - cd $(BUILDER_SRC_DIR)/$(msamr_dir) && ./autogen.sh - -$(BUILDER_BUILD_DIR)/$(msamr_dir)/Makefile: $(BUILDER_SRC_DIR)/$(msamr_dir)/configure - mkdir -p $(BUILDER_BUILD_DIR)/$(msamr_dir) - cd $(BUILDER_BUILD_DIR)/$(msamr_dir)/ \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(BUILDER_SRC_DIR)/$(msamr_dir)/configure -prefix=$(prefix) --host=$(host) ${library_mode} ${configure-options} - -build-msamr: build-opencore-amr $(BUILDER_BUILD_DIR)/$(msamr_dir)/Makefile - cd $(BUILDER_BUILD_DIR)/$(msamr_dir) && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) make && make install - -clean-msamr: clean-opencore-amr - cd $(BUILDER_BUILD_DIR)/$(msamr_dir) && make clean - -veryclean-msamr: veryclean-opencore-amr - -cd $(BUILDER_BUILD_DIR)/$(msamr_dir) && make distclean - rm -f $(BUILDER_SRC_DIR)/$(msamr_dir)/configure - -clean-makefile-msamr: clean-makefile-opencore-amr - cd $(BUILDER_BUILD_DIR)/$(msamr_dir) && rm -f Makefile diff --git a/submodules/build/builders.d/msbcg729.mk b/submodules/build/builders.d/msbcg729.mk deleted file mode 100644 index d90d88ec3..000000000 --- a/submodules/build/builders.d/msbcg729.mk +++ /dev/null @@ -1,66 +0,0 @@ -############################################################################ -# msbcg729.mk -# Copyright (C) 2011 Belledonne Communications,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. -# -############################################################################ -msbcg729_dir?=bcg729 -enable_bcg729?=yes - -configure-options= -ifeq ($(LINPHONE_CCACHE), ccache) - configure-options+= --disable-strict -endif - -$(BUILDER_SRC_DIR)/$(msbcg729_dir)/configure: - @echo -e "\033[01;32m Running autogen for msbcg729 in $(BUILDER_SRC_DIR)/$(msbcg729_dir) \033[0m" - cd $(BUILDER_SRC_DIR)/$(msbcg729_dir) && ./autogen.sh - -$(BUILDER_BUILD_DIR)/$(msbcg729_dir)/Makefile: $(BUILDER_SRC_DIR)/$(msbcg729_dir)/configure - @echo -e "\033[01;32m Running configure in $(BUILDER_BUILD_DIR)/$(msbcg729_dir) \033[0m" - mkdir -p $(BUILDER_BUILD_DIR)/$(msbcg729_dir) - cd $(BUILDER_BUILD_DIR)/$(msbcg729_dir)/ \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(BUILDER_SRC_DIR)/$(msbcg729_dir)/configure -prefix=$(prefix) --host=$(host) ${library_mode} \ - --enable-static ${configure-options} - -ifeq ($(enable_bcg729),yes) - -build-msbcg729: $(BUILDER_BUILD_DIR)/$(msbcg729_dir)/Makefile - @echo -e "\033[01;32m building bcg729 \033[0m" - cd $(BUILDER_BUILD_DIR)/$(msbcg729_dir) \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig \ - CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - make -j1 && make install - - -else -build-msbcg729: - @echo "G729 is disabled" - -endif - -clean-msbcg729: - -cd $(BUILDER_BUILD_DIR)/$(msbcg729_dir) && make clean - -veryclean-msbcg729: - -cd $(BUILDER_BUILD_DIR)/$(msbcg729_dir) && make distclean - rm -f $(BUILDER_SRC_DIR)/$(msbcg729_dir)/configure - -clean-makefile-msbcg729: - -cd $(BUILDER_BUILD_DIR)/$(msbcg729_dir) && rm -f Makefile diff --git a/submodules/build/builders.d/msilbc.mk b/submodules/build/builders.d/msilbc.mk deleted file mode 100644 index ce4d63bcd..000000000 --- a/submodules/build/builders.d/msilbc.mk +++ /dev/null @@ -1,29 +0,0 @@ - -# msilbc plugin - -msilbc_dir?=msilbc - -MSILBC_SRC_DIR:=$(BUILDER_SRC_DIR)/$(msilbc_dir) -MSILBC_BUILD_DIR:=$(BUILDER_BUILD_DIR)/$(msilbc_dir) - -$(MSILBC_SRC_DIR)/configure: - cd $(MSILBC_SRC_DIR) && ./autogen.sh - -$(MSILBC_BUILD_DIR)/Makefile: $(MSILBC_SRC_DIR)/configure - mkdir -p $(MSILBC_BUILD_DIR) - cd $(MSILBC_BUILD_DIR) && \ - PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(MSILBC_SRC_DIR)/configure -prefix=$(prefix) --host=$(host) $(library_mode) - -build-msilbc: build-libilbc $(MSILBC_BUILD_DIR)/Makefile - cd $(MSILBC_BUILD_DIR) && make && make install - -clean-msilbc: - cd $(MSILBC_BUILD_DIR) && make clean - -veryclean-msilbc: -# -cd $(MSILBC_BUILD_DIR) && make distclean - -cd $(MSILBC_SRC_DIR) && rm configure - -clean-makefile-msilbc: - cd $(MSILBC_BUILD_DIR) && rm -f Makefile \ No newline at end of file diff --git a/submodules/build/builders.d/msopenh264.mk b/submodules/build/builders.d/msopenh264.mk deleted file mode 100644 index 7421c3319..000000000 --- a/submodules/build/builders.d/msopenh264.mk +++ /dev/null @@ -1,44 +0,0 @@ -############################################################################ -# msopenh264.mk -# Copyright (C) 2011 Belledonne Communications,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. -# -############################################################################ -msopenh264_dir?=msopenh264 -$(BUILDER_SRC_DIR)/$(msopenh264_dir)/configure: - cd $(BUILDER_SRC_DIR)/$(msopenh264_dir) && ./autogen.sh - -$(BUILDER_BUILD_DIR)/$(msopenh264_dir)/Makefile: $(BUILDER_SRC_DIR)/$(msopenh264_dir)/configure - mkdir -p $(BUILDER_BUILD_DIR)/$(msopenh264_dir) - cd $(BUILDER_BUILD_DIR)/$(msopenh264_dir)/ \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(BUILDER_SRC_DIR)/$(msopenh264_dir)/configure -prefix=$(prefix) --host=$(host) ${library_mode} - -build-msopenh264: build-openh264 $(BUILDER_BUILD_DIR)/$(msopenh264_dir)/Makefile - cd $(BUILDER_BUILD_DIR)/$(msopenh264_dir) && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) make && make install - -clean-msopenh264: clean-openh264 - cd $(BUILDER_BUILD_DIR)/$(msopenh264_dir) && make clean - -veryclean-msopenh264: veryclean-openh264 - -cd $(BUILDER_BUILD_DIR)/$(msopenh264_dir) && make distclean - -cd $(BUILDER_SRC_DIR)/$(msopenh264_dir) && rm -f configure - -clean-makefile-msopenh264: clean-makefile-openh264 - cd $(BUILDER_BUILD_DIR)/$(msopenh264_dir) && rm -f Makefile - diff --git a/submodules/build/builders.d/mssilk.mk b/submodules/build/builders.d/mssilk.mk deleted file mode 100644 index bbde3fad7..000000000 --- a/submodules/build/builders.d/mssilk.mk +++ /dev/null @@ -1,70 +0,0 @@ -############################################################################ -# mssilk.mk -# Copyright (C) 2011 Belledonne Communications,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. -# -############################################################################ -mssilk_dir?=mssilk -enable_silk?=yes - -configure-options= -ifeq ($(LINPHONE_CCACHE), ccache) - configure-options+= --disable-strict -endif - -$(BUILDER_SRC_DIR)/$(mssilk_dir)/configure: - @echo -e "\033[01;32m Running autogen for mssilk in $(BUILDER_SRC_DIR)/$(mssilk_dir) \033[0m" - cd $(BUILDER_SRC_DIR)/$(mssilk_dir) && ./autogen.sh - -$(BUILDER_BUILD_DIR)/$(mssilk_dir)/Makefile: $(BUILDER_SRC_DIR)/$(mssilk_dir)/configure - @echo -e "\033[01;32m Running configure in $(BUILDER_BUILD_DIR)/$(mssilk_dir) \033[0m" - mkdir -p $(BUILDER_BUILD_DIR)/$(mssilk_dir) - cd $(BUILDER_BUILD_DIR)/$(mssilk_dir)/ \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(BUILDER_SRC_DIR)/$(mssilk_dir)/configure -prefix=$(prefix) --host=$(host) ${library_mode} \ - --enable-static ${configure-options} - -ifeq ($(enable_silk),yes) - -build-mssilk: $(BUILDER_BUILD_DIR)/$(mssilk_dir)/Makefile - @echo -e "\033[01;32m building silk \033[0m" - cd $(BUILDER_BUILD_DIR)/$(mssilk_dir) \ - && PKG_CONFIG_PATH=$(prefix)/lib/pkgconfig \ - CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - make -j1 && make install -ifeq ($(host),armv7-apple-darwin) - echo -e "\033[01;32m Getting BINARY version of silk for armV7 \033[0m" - cp $(BUILDER_SRC_DIR)/$(mssilk_dir)/ios_bin/armv7/libSKP_SILK_SDK.a $(prefix)/lib/ -endif - -else - -build-mssilk: - echo "SILK is disabled" - -endif # enable_silk - -clean-mssilk: - -cd $(BUILDER_BUILD_DIR)/$(mssilk_dir) && make clean - -veryclean-mssilk: - -cd $(BUILDER_BUILD_DIR)/$(mssilk_dir) && make distclean - rm -f $(BUILDER_SRC_DIR)/$(mssilk_dir)/configure - -clean-makefile-mssilk: - -cd $(BUILDER_BUILD_DIR)/$(mssilk_dir) && rm -f Makefile diff --git a/submodules/build/builders.d/mswebrtc.mk b/submodules/build/builders.d/mswebrtc.mk deleted file mode 100644 index 9bf7450f7..000000000 --- a/submodules/build/builders.d/mswebrtc.mk +++ /dev/null @@ -1,46 +0,0 @@ -############################################################################ -# mswebrtc.mk -# Copyright (C) 2014 Belledonne Communications,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. -# -############################################################################ -mswebrtc_dir?=mswebrtc - - - -$(BUILDER_SRC_DIR)/$(mswebrtc_dir)/configure: - cd $(BUILDER_SRC_DIR)/$(mswebrtc_dir) && ./autogen.sh - -$(BUILDER_BUILD_DIR)/$(mswebrtc_dir)/Makefile: $(BUILDER_SRC_DIR)/$(mswebrtc_dir)/configure - mkdir -p $(BUILDER_BUILD_DIR)/$(mswebrtc_dir) - cd $(BUILDER_BUILD_DIR)/$(mswebrtc_dir)/ \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(BUILDER_SRC_DIR)/$(mswebrtc_dir)/configure -prefix=$(prefix) --host=$(host) ${library_mode} --disable-aec CFLAGS="-Wno-error" - -build-mswebrtc: $(BUILDER_BUILD_DIR)/$(mswebrtc_dir)/Makefile - cd $(BUILDER_BUILD_DIR)/$(mswebrtc_dir) && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) make && make install - -clean-mswebrtc: - cd $(BUILDER_BUILD_DIR)/$(mswebrtc_dir) && make clean - -veryclean-mswebrtc: - -cd $(BUILDER_BUILD_DIR)/$(mswebrtc_dir) && make distclean - -cd $(BUILDER_SRC_DIR)/$(mswebrtc_dir) && rm -f configure - -clean-makefile-mswebrtc: - cd $(BUILDER_BUILD_DIR)/$(mswebrtc_dir) && rm -f Makefile diff --git a/submodules/build/builders.d/msx264.mk b/submodules/build/builders.d/msx264.mk deleted file mode 100644 index ce0b727c0..000000000 --- a/submodules/build/builders.d/msx264.mk +++ /dev/null @@ -1,49 +0,0 @@ -############################################################################ -# msx264.mk -# Copyright (C) 2011 Belledonne Communications,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. -# -############################################################################ -msx264_dir?=msx264 - -configure-options= -ifeq ($(LINPHONE_CCACHE), ccache) - configure-options+= --disable-strict -endif - -$(BUILDER_SRC_DIR)/$(msx264_dir)/configure: - cd $(BUILDER_SRC_DIR)/$(msx264_dir) && ./autogen.sh - -$(BUILDER_BUILD_DIR)/$(msx264_dir)/Makefile: $(BUILDER_SRC_DIR)/$(msx264_dir)/configure - mkdir -p $(BUILDER_BUILD_DIR)/$(msx264_dir) - cd $(BUILDER_BUILD_DIR)/$(msx264_dir)/ \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(BUILDER_SRC_DIR)/$(msx264_dir)/configure -prefix=$(prefix) --host=$(host) ${library_mode} ${configure-options} - -build-msx264: build-x264 $(BUILDER_BUILD_DIR)/$(msx264_dir)/Makefile - cd $(BUILDER_BUILD_DIR)/$(msx264_dir) && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) make && make install - -clean-msx264: clean-x264 - cd $(BUILDER_BUILD_DIR)/$(msx264_dir) && make clean - -veryclean-msx264: veryclean-x264 - -cd $(BUILDER_BUILD_DIR)/$(msx264_dir) && make distclean - -cd $(BUILDER_SRC_DIR)/$(msx264_dir) && rm -f configure - -clean-makefile-msx264: clean-makefile-x264 - cd $(BUILDER_BUILD_DIR)/$(msx264_dir) && rm -f Makefile diff --git a/submodules/build/builders.d/opencore-amr.mk b/submodules/build/builders.d/opencore-amr.mk deleted file mode 100644 index ba415c7ed..000000000 --- a/submodules/build/builders.d/opencore-amr.mk +++ /dev/null @@ -1,48 +0,0 @@ -############################################################################ -# opencore-amr.mk -# Copyright (C) 2011 Belledonne Communications,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. -# -############################################################################ - -opencore-amr_dir?=externals/opencore-amr - -$(BUILDER_SRC_DIR)/$(opencore-amr_dir)/autoreconf.stamp: $(BUILDER_SRC_DIR)/$(opencore-amr_dir)/configure.ac - cd $(BUILDER_SRC_DIR)/$(opencore-amr_dir) \ - && libtoolize --copy --force \ - && aclocal -I m4 \ - && automake --add-missing --force-missing --copy && autoreconf && touch autoreconf.stamp - -$(BUILDER_BUILD_DIR)/$(opencore-amr_dir)/Makefile: $(BUILDER_SRC_DIR)/$(opencore-amr_dir)/autoreconf.stamp - mkdir -p $(BUILDER_BUILD_DIR)/$(opencore-amr_dir) - cd $(BUILDER_BUILD_DIR)/$(opencore-amr_dir)/ \ - && CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(BUILDER_SRC_DIR)/$(opencore-amr_dir)/configure -prefix=$(prefix) --host=$(host) ${library_mode} ${opencore-amr-configure-option} - -build-opencore-amr: $(BUILDER_BUILD_DIR)/$(opencore-amr_dir)/Makefile - cd $(BUILDER_BUILD_DIR)/$(opencore-amr_dir) && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) make && make install - -clean-opencore-amr: - cd $(BUILDER_BUILD_DIR)/$(opencore-amr_dir) && make clean - -veryclean-opencore-amr: - -cd $(BUILDER_BUILD_DIR)/$(opencore-amr_dir) && make distclean - -rm -rf $(BUILDER_BUILD_DIR)/$(opencore-amr_dir) - -clean-makefile-opencore-amr: - cd $(BUILDER_BUILD_DIR)/$(opencore-amr_dir) && rm -f Makefile diff --git a/submodules/build/builders.d/openh264-permissive.patch b/submodules/build/builders.d/openh264-permissive.patch deleted file mode 100644 index bff18b6ce..000000000 --- a/submodules/build/builders.d/openh264-permissive.patch +++ /dev/null @@ -1,40 +0,0 @@ -commit 6b3de978d928b6c0baec3305c9803c21a4367d0c -Author: Simon Morlat -Date: Tue Apr 15 15:19:37 2014 +0200 - - permissive mode: allow reference frames to be used even if there were lost slices. - -diff --git a/codec/decoder/core/src/manage_dec_ref.cpp b/codec/decoder/core/src/manage_dec_ref.cpp -index dcf61ca..5582ec9 100644 ---- a/codec/decoder/core/src/manage_dec_ref.cpp -+++ b/codec/decoder/core/src/manage_dec_ref.cpp -@@ -165,6 +165,7 @@ int32_t WelsReorderRefList (PWelsDecoderContext pCtx) { - && (pSliceHeader->iSpsId != ppRefList[i]->iSpsId)) { //check; - WelsLog (pCtx, WELS_LOG_WARNING, "WelsReorderRefList()-1::::BASE LAYER::::iSpsId:%d, ref_sps_id:%d\n", - pSliceHeader->iSpsId, ppRefList[i]->iSpsId); -+ return ERR_NONE; - pCtx->iErrorCode = dsNoParamSets; //cross-IDR reference frame selection, SHOULD request IDR.-- - return ERR_INFO_REFERENCE_PIC_LOST; - } else { - -commit a1f3b95ad18d0788c2c803fac80e78d6365673ce -Author: Simon Morlat -Date: Tue Apr 15 17:54:58 2014 +0200 - - permissive mode (2) - -diff --git a/codec/decoder/core/src/decoder_core.cpp b/codec/decoder/core/src/decoder_core.cpp -index a14e971..e742dbf 100644 ---- a/codec/decoder/core/src/decoder_core.cpp -+++ b/codec/decoder/core/src/decoder_core.cpp -@@ -1738,8 +1738,8 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int3 - if ((iLastIdD < 0) || //case 1: first layer - (iLastIdD == iCurrIdD)) { //case 2: same uiDId - InitDqLayerInfo (dq_cur, &pLayerInfo, pNalCur, pCtx->pDec); -- -- if (!dq_cur->sLayerInfo.pSps->bGapsInFrameNumValueAllowedFlag) { -+ if (0){ -+ //if (!dq_cur->sLayerInfo.pSps->bGapsInFrameNumValueAllowedFlag) { - const bool kbIdrFlag = dq_cur->sLayerInfo.sNalHeaderExt.bIdrFlag - || (dq_cur->sLayerInfo.sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR); - // Subclause 8.2.5.2 Decoding process for gaps in frame_num diff --git a/submodules/build/builders.d/openh264.mk b/submodules/build/builders.d/openh264.mk deleted file mode 100644 index 63210cdde..000000000 --- a/submodules/build/builders.d/openh264.mk +++ /dev/null @@ -1,62 +0,0 @@ -############################################################################ -# openh264.mk -# Copyright (C) 2011 Belledonne Communications,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. -# -############################################################################ - -ifneq (,$(findstring i386-,$(host))) - ARCH=i386 -endif -ifneq (,$(findstring armv7-,$(host))) - ARCH=armv7 -endif -ifneq (,$(findstring aarch64-,$(host))) - ARCH=arm64 -endif - -openh264_dir?=externals/openh264 - -$(BUILDER_SRC_DIR)/$(openh264_dir)/openh264-permissive.patch.stamp: - cd $(BUILDER_SRC_DIR)/$(openh264_dir) \ - && patch -p1 < $(BUILDER_SRC_DIR)/build/builders.d/openh264-permissive.patch - touch $(BUILDER_SRC_DIR)/$(openh264_dir)/openh264-permissive.patch.stamp - -patch-openh264: $(BUILDER_SRC_DIR)/$(openh264_dir)/openh264-permissive.patch.stamp - -update-openh264: patch-openh264 - mkdir -p $(BUILDER_BUILD_DIR)/$(openh264_dir) \ - && cd $(BUILDER_BUILD_DIR)/$(openh264_dir)/ \ - && rsync -rvLpgoc --exclude ".git" $(BUILDER_SRC_DIR)/$(openh264_dir)/* . - -make-target-%: - cd $(BUILDER_BUILD_DIR)/$(openh264_dir) \ - && echo ===== OpenH264: make $* ===== \ - && make CC="xcrun clang" CXX="xcrun clang++" AR="xcrun ar" LD="xcrun clang" RANLIB="xcrun ranlib" OS=ios ARCH=$(ARCH) PREFIX=$(prefix) $* - -build-openh264: update-openh264 make-target-libraries make-target-install - -clean-openh264: - cd $(BUILDER_BUILD_DIR)/$(openh264_dir) \ - && make clean OS=ios ARCH=$(ARCH) - -veryclean-openh264: - cd $(BUILDER_SRC_DIR)/$(openh264_dir)/ \ - && git clean -f && git reset --hard \ - && rm -rf $(BUILDER_BUILD_DIR)/$(openh264_dir) - diff --git a/submodules/build/builders.d/openssl.mk b/submodules/build/builders.d/openssl.mk deleted file mode 100644 index 8ecea393d..000000000 --- a/submodules/build/builders.d/openssl.mk +++ /dev/null @@ -1,40 +0,0 @@ -openssl_version=1.0.1c -OPENSSL_BUILD_DIR?=$(BUILDER_BUILD_DIR)/externals/openssl - -ifneq (,$(findstring mingw,$(host))) - CONFIGURE_OPTION := mingw - MAKE_PARAMS:= CC=i586-mingw32msvc-gcc RANLIB=i586-mingw32msvc-ranlib -endif - -$(OPENSSL_BUILD_DIR)/Configure: - mkdir -p $(BUILDER_BUILD_DIR)/externals \ - && cd $(BUILDER_BUILD_DIR)/externals \ - && rm -rf openssl \ - && wget ftp://sunsite.cnlab-switch.ch/mirror/openssl/source/openssl-$(openssl_version).tar.gz \ - && tar xvzf openssl-$(openssl_version).tar.gz \ - && rm -f openssl-$(openssl_version).tar.gz \ - && mv openssl-$(openssl_version) openssl \ - && cd openssl && patch -p0 < $(BUILDER_SRC_DIR)/build/builders.d/openssl.patch - -$(OPENSSL_BUILD_DIR)/Makefile: $(OPENSSL_BUILD_DIR)/Configure - cd $(OPENSSL_BUILD_DIR) \ - && host_alias=${host} . $(BUILDER_SRC_DIR)/build/$(config_site) \ - && ./Configure --prefix=$(prefix) --cross-compile-prefix=$$SDK_BIN_PATH/ BSD-generic32 no-asm - -build-openssl: $(OPENSSL_BUILD_DIR)/Makefile - cd $(OPENSSL_BUILD_DIR) && host_alias=${host} . $(BUILDER_SRC_DIR)/build/$(config_site) \ - && make CC="$$CC" AR="$$AR r" RANLIB="$$RANLIB" build_crypto build_ssl libcrypto.pc libssl.pc\ - && cp -r include $(prefix)/ \ - && cp lib*.a $(prefix)/lib \ - && cp libcrypto.pc $(prefix)/lib/pkgconfig/. \ - && cp libssl.pc $(prefix)/lib/pkgconfig/. \ - -clean-openssl: - cd $(OPENSSL_BUILD_DIR) && make clean - -clean-makefile-openssl: - touch $(OPENSSL_BUILD_DIR)/Configure - -veryclean-openssl: - rm -rf $(OPENSSL_BUILD_DIR) - diff --git a/submodules/build/builders.d/openssl.patch b/submodules/build/builders.d/openssl.patch deleted file mode 100644 index d4013d0e4..000000000 --- a/submodules/build/builders.d/openssl.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- crypto/ui/ui_openssl.c.ori 2011-03-18 18:09:26.000000000 +0100 -+++ crypto/ui/ui_openssl.c 2011-03-18 18:09:44.000000000 +0100 -@@ -404,7 +404,7 @@ - return 1; - } - --static volatile sig_atomic_t intr_signal; -+static volatile int intr_signal; - #endif - - static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) diff --git a/submodules/build/builders.d/opus.mk b/submodules/build/builders.d/opus.mk deleted file mode 100644 index 54d816d22..000000000 --- a/submodules/build/builders.d/opus.mk +++ /dev/null @@ -1,69 +0,0 @@ -############################################################################ -# opus.mk -# Copyright (C) 2013 Belledonne Communications,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. -# -############################################################################ -opus_dir?=externals/opus -enable_opus?=yes - -libopus_configure_options=--disable-extra-programs --disable-doc -ifneq (,$(findstring armv7,$(host))) - libopus_configure_options+= --enable-fixed-point -endif -ifneq (,$(findstring armv7s,$(host))) - libopus_configure_options+= --enable-fixed-point -endif - -$(BUILDER_SRC_DIR)/$(opus_dir)/configure: - @echo -e "\033[01;32m Running autogen for msopus in $(BUILDER_SRC_DIR)/$(opus_dir) \033[0m" - cd $(BUILDER_SRC_DIR)/$(opus_dir) && ./autogen.sh - -$(BUILDER_BUILD_DIR)/$(opus_dir)/Makefile: $(BUILDER_SRC_DIR)/$(opus_dir)/configure - @echo -e "\033[01;32m Running configure in $(BUILDER_BUILD_DIR)/$(opus_dir) \033[0m" - mkdir -p $(BUILDER_BUILD_DIR)/$(opus_dir) - cd $(BUILDER_BUILD_DIR)/$(opus_dir)/ \ - && PKG_CONFIG_PATH=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(BUILDER_SRC_DIR)/$(opus_dir)/configure -prefix=$(prefix) --host=$(host) ${library_mode} \ - ${libopus_configure_options} - -ifeq ($(enable_opus),yes) - -build-opus: $(BUILDER_BUILD_DIR)/$(opus_dir)/Makefile - @echo -e "\033[01;32m building opus \033[0m" - cd $(BUILDER_BUILD_DIR)/$(opus_dir) \ - && PKG_CONFIG_PATH=$(prefix)/lib/pkgconfig \ - CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - make && make install - - -else -build-opus: - @echo "opus is disabled" - -endif - -clean-opus: - -cd $(BUILDER_BUILD_DIR)/$(opus_dir) && make clean - -veryclean-opus: - -cd $(BUILDER_BUILD_DIR)/$(opus_dir) && make distclean - rm -f $(BUILDER_SRC_DIR)/$(opus_dir)/configure - -clean-makefile-opus: - -cd $(BUILDER_BUILD_DIR)/$(opus_dir) && rm -f Makefile diff --git a/submodules/build/builders.d/polarssl.mk b/submodules/build/builders.d/polarssl.mk deleted file mode 100644 index 3aabf5fc5..000000000 --- a/submodules/build/builders.d/polarssl.mk +++ /dev/null @@ -1,27 +0,0 @@ -polarssl_dir?=externals/polarssl - -SRC_DIR=$(BUILDER_SRC_DIR) -BUILD_DIR=$(BUILDER_BUILD_DIR) - - -$(SRC_DIR)/$(polarssl_dir)/configure: - cd $(SRC_DIR)/$(polarssl_dir) && ./autogen.sh - -$(BUILD_DIR)/$(polarssl_dir)/Makefile: $(SRC_DIR)/$(polarssl_dir)/configure - mkdir -p $(BUILD_DIR)/$(polarssl_dir) - cd $(BUILD_DIR)/$(polarssl_dir) \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(SRC_DIR)/build/$(config_site) \ - $(SRC_DIR)/$(polarssl_dir)/configure --prefix=$(prefix) --host=$(host) ${library_mode} - -build-polarssl: $(BUILD_DIR)/$(polarssl_dir)/Makefile - cd $(BUILD_DIR)/${polarssl_dir} && \ - host_alias=$(host) PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(SRC_DIR)/build/$(config_site) make && make install - -clean-polarssl: - -cd $(BUILD_DIR)/$(polarssl_dir) && make clean - -veryclean-polarssl: - -rm -rf $(BUILD_DIR)/$(polarssl_dir) - -clean-makefile-polarssl: veryclean-polarssl - diff --git a/submodules/build/builders.d/speex.mk b/submodules/build/builders.d/speex.mk deleted file mode 100644 index 04a4aed30..000000000 --- a/submodules/build/builders.d/speex.mk +++ /dev/null @@ -1,43 +0,0 @@ -#speex - -speex_dir=externals/speex - - -ifeq (,$(findstring i386,$(host))) - CFLAGS := $(CFLAGS) -marm - SPEEX_CONFIGURE_OPTION := --disable-float-api --enable-fixed-point -endif - -ifneq (,$(findstring armv7,$(host))) - SPEEX_CONFIGURE_OPTION += --enable-armv7neon-asm --enable-arm5e-asm -endif -ifneq (,$(findstring aarch64,$(host))) - SPEEX_CONFIGURE_OPTION += --enable-armv7neon-asm -endif - -ifeq ($(enable_debug),yes) - CFLAGS := $(CFLAGS) -g - SPEEX_CONFIGURE_OPTION += --enable-debug -endif - -$(BUILDER_SRC_DIR)/$(speex_dir)/configure: - cd $(BUILDER_SRC_DIR)/$(speex_dir) && ./autogen.sh - -$(BUILDER_BUILD_DIR)/$(speex_dir)/Makefile: $(BUILDER_SRC_DIR)/$(speex_dir)/configure - mkdir -p $(BUILDER_BUILD_DIR)/$(speex_dir) - cd $(BUILDER_BUILD_DIR)/$(speex_dir)/\ - && CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) CFLAGS="$(CFLAGS) -O2" \ - $(BUILDER_SRC_DIR)/$(speex_dir)/configure -prefix=$(prefix) --host=$(host) ${library_mode} --disable-ogg $(SPEEX_CONFIGURE_OPTION) - -build-speex: $(BUILDER_BUILD_DIR)/$(speex_dir)/Makefile - cd $(BUILDER_BUILD_DIR)/$(speex_dir) && make && make install - -clean-speex: - cd $(BUILDER_BUILD_DIR)/$(speex_dir) && make clean - -veryclean-speex: -# -cd $(BUILDER_BUILD_DIR)/$(speex_dir) && make distclean - -rm -f $(BUILDER_SRC_DIR)/$(speex_dir)/configure - -clean-makefile-speex: - cd $(BUILDER_BUILD_DIR)/$(speex_dir) && rm -f Makefile diff --git a/submodules/build/builders.d/srtp.mk b/submodules/build/builders.d/srtp.mk deleted file mode 100644 index ee2d6c92a..000000000 --- a/submodules/build/builders.d/srtp.mk +++ /dev/null @@ -1,26 +0,0 @@ -srtp_dir?=externals/srtp - -$(BUILDER_SRC_DIR)/$(srtp_dir)/configure: $(BUILDER_SRC_DIR)/$(srtp_dir)/configure.in - cd $(BUILDER_SRC_DIR)/$(srtp_dir) \ - && autoconf -$(BUILDER_BUILD_DIR)/$(srtp_dir)/Makefile: $(BUILDER_SRC_DIR)/$(srtp_dir)/configure $(BUILDER_SRC_DIR)/$(srtp_dir)/Makefile.in - mkdir -p $(BUILDER_BUILD_DIR)/$(srtp_dir) - cd $(BUILDER_BUILD_DIR)/$(srtp_dir)/\ - && CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(BUILDER_SRC_DIR)/$(srtp_dir)/configure -prefix=$(prefix) --host=$(host) ${library_mode} - -build-srtp: $(BUILDER_BUILD_DIR)/$(srtp_dir)/Makefile - host_alias=$(host) && . /$(BUILDER_SRC_DIR)/build/$(config_site) && \ - cd $(BUILDER_BUILD_DIR)/$(srtp_dir) && make libsrtp.a AR="$$AR" && make install - -clean-srtp: - -cd $(BUILDER_BUILD_DIR)/$(srtp_dir) && make clean - -veryclean-srtp: - -cd $(BUILDER_BUILD_DIR)/$(srtp_dir) && make distclean - -rm -rf $(BUILDER_BUILD_DIR)/$(srtp_dir) - -rm -f $(BUILDER_SRC_DIR)/$(srtp_dir)/configure - -clean-makefile-srtp: - -cd $(BUILDER_BUILD_DIR)/$(srtp_dir) && rm -f Makefile - diff --git a/submodules/build/builders.d/srtp.patch b/submodules/build/builders.d/srtp.patch deleted file mode 100644 index c3d127b13..000000000 --- a/submodules/build/builders.d/srtp.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -rupN ../srtp_old/crypto/cipher/aes_icm.c ./crypto/cipher/aes_icm.c ---- ../srtp_old/crypto/cipher/aes_icm.c 2006-03-16 18:11:29.000000000 +0100 -+++ ./crypto/cipher/aes_icm.c 2011-09-06 10:19:16.000000000 +0200 -@@ -281,7 +281,7 @@ aes_icm_set_iv(aes_icm_ctx_t *c, void *i - * this is an internal, hopefully inlined function - */ - --inline void -+static void - aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) { - /* fill buffer with new keystream */ - v128_copy(&c->keystream_buffer, &c->counter); -diff -rupN ../srtp_old/crypto/math/datatypes.c ./crypto/math/datatypes.c ---- ../srtp_old/crypto/math/datatypes.c 2005-10-08 18:38:06.000000000 +0200 -+++ ./crypto/math/datatypes.c 2011-09-06 10:02:55.000000000 +0200 -@@ -124,7 +124,7 @@ octet_string_hex_string(const void *s, i - return bit_string; - } - --inline int -+static int - hex_char_to_nibble(uint8_t c) { - switch(c) { - case ('0'): return 0x0; diff --git a/submodules/build/builders.d/tunnel.mk b/submodules/build/builders.d/tunnel.mk deleted file mode 100644 index 6f07fb2c2..000000000 --- a/submodules/build/builders.d/tunnel.mk +++ /dev/null @@ -1,28 +0,0 @@ -TUNNEL_SRC_DIR?=$(BUILDER_SRC_DIR)/tunnel -TUNNEL_BUILD_DIR?=$(BUILDER_BUILD_DIR)/tunnel - -#############################TUNNEL############################ -$(TUNNEL_SRC_DIR)/configure: - cd $(TUNNEL_SRC_DIR) && ./autogen.sh - -$(TUNNEL_BUILD_DIR)/Makefile: $(TUNNEL_SRC_DIR)/configure - mkdir -p $(TUNNEL_BUILD_DIR) \ - && cd $(TUNNEL_BUILD_DIR) \ - && CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) PKG_CONFIG_PATH=$(prefix)/lib/pkgconfig \ - $(TUNNEL_SRC_DIR)/configure -prefix=$(prefix) --host=$(host) --enable-polarssl --with-polarssl=$(prefix) --disable-servers ${library_mode} - -build-tunnel: $(TUNNEL_BUILD_DIR)/Makefile - cd $(TUNNEL_BUILD_DIR) \ - && host_alias=$(host) . $(BUILDER_SRC_DIR)/build/$(config_site) \ - && make RANLIB="$$RANLIB" && make install - -clean-tunnel: - cd $(TUNNEL_BUILD_DIR) && make clean - -veryclean-tunnel: - rm -f $(TUNNEL_SRC_DIR)/configure - -clean-makefile-tunnel: - cd $(TUNNEL_BUILD_DIR) && rm -f Makefile - - diff --git a/submodules/build/builders.d/x264.mk b/submodules/build/builders.d/x264.mk deleted file mode 100644 index 21c8638e9..000000000 --- a/submodules/build/builders.d/x264.mk +++ /dev/null @@ -1,73 +0,0 @@ -############################################################################ -# x264.mk -# Copyright (C) 2011 Belledonne Communications,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. -# -############################################################################ - -#--enable-static is mandatory otherwise the lib is not installed - -x264-configure-option= \ - --host=$(host)\ - --enable-static --enable-pic \ - --cross-prefix=$$SDK_BIN_PATH/ \ - --extra-ldflags="$$COMMON_FLAGS" - - -XCFLAGS:=$$COMMON_FLAGS - - -ifneq (,$(findstring armv7,$(host))) - XCFLAGS+= -mfpu=neon -mfloat-abi=softfp -endif - -x264-configure-option+= --extra-cflags="${XCFLAGS}" - -x264_dir?=externals/x264 -$(BUILDER_SRC_DIR)/$(x264_dir)/patched: - cd $(BUILDER_SRC_DIR)/$(x264_dir) \ - && git apply $(BUILDER_SRC_DIR)/build/builders.d/x264.patch \ - && touch $(BUILDER_SRC_DIR)/$(x264_dir)/patched - -$(BUILDER_BUILD_DIR)/$(x264_dir)/configure: $(BUILDER_SRC_DIR)/$(x264_dir)/patched - mkdir -p $(BUILDER_BUILD_DIR)/$(x264_dir) - cd $(BUILDER_BUILD_DIR)/$(x264_dir)/ \ - && rsync -rvLpgoc --exclude ".git" $(BUILDER_SRC_DIR)/$(x264_dir)/* . - -$(BUILDER_BUILD_DIR)/$(x264_dir)/config.mak: $(BUILDER_BUILD_DIR)/$(x264_dir)/configure - cd $(BUILDER_BUILD_DIR)/$(x264_dir)/ \ - && host_alias=$(host) . $(BUILDER_SRC_DIR)/build/$(config_site) \ - && CC="$$CC" STRINGS="$$STRINGS" ./configure --prefix=$(prefix) $(x264-configure-option) - -build-x264: $(BUILDER_BUILD_DIR)/$(x264_dir)/config.mak - cd $(BUILDER_BUILD_DIR)/$(x264_dir) \ - && host_alias=$(host) . $(BUILDER_SRC_DIR)/build/$(config_site) \ - && make STRIP="$$STRIP" AR="$$AR -r " RANLIB="$$RANLIB" CC="$$CC" STRINGS="$$STRINGS" && make STRIP="$$STRIP" AR="$$AR" RANLIB="$$RANLIB" STRINGS="$$STRINGS" install - -clean-x264: - cd $(BUILDER_BUILD_DIR)/$(x264_dir) && make clean - -veryclean-x264: - -cd $(BUILDER_BUILD_DIR)/$(x264_dir) && make distclean - cd $(BUILDER_SRC_DIR)/$(x264_dir)/ \ - && git clean -f && git reset --hard \ - && rm -f patched - rm -rf $(BUILDER_BUILD_DIR)/$(x264_dir) - -clean-makefile-x264: - cd $(BUILDER_BUILD_DIR)/$(x264_dir) && rm -f config.mak diff --git a/submodules/build/builders.d/x264.patch b/submodules/build/builders.d/x264.patch deleted file mode 100644 index 62bd0789e..000000000 --- a/submodules/build/builders.d/x264.patch +++ /dev/null @@ -1,149 +0,0 @@ -diff --git a/common/arm/cpu-a.S b/common/arm/cpu-a.S -index a459553..bc91505 100644 ---- a/common/arm/cpu-a.S -+++ b/common/arm/cpu-a.S -@@ -26,7 +26,7 @@ - #include "asm.S" - - .fpu neon --.align -+// .align - - // done in gas because .fpu neon overrides the refusal to assemble - // instructions the selected -march/-mcpu doesn't support -@@ -95,7 +95,7 @@ average_loop: - sub r2, r2, r1 - cmpgt r2, #30 << 3 // assume context switch if it took over 30 cycles - addle r3, r3, r2 -- subles ip, ip, #1 -+ suble ip, ip, #1 - bgt average_loop - - // disable counters if we enabled them -diff --git a/common/arm/mc-a.S b/common/arm/mc-a.S -index 507bbba..d5554be 100644 ---- a/common/arm/mc-a.S -+++ b/common/arm/mc-a.S -@@ -166,7 +166,7 @@ function x264_pixel_avg_\w\()x\h\()_neon - ldr ip, [sp, #8] - push {r4-r6,lr} - cmp ip, #32 -- ldrd r4, [sp, #16] -+ ldrd r4, r5, [sp, #16] - mov lr, #\h - beq x264_pixel_avg_w\w\()_neon - rsbs r6, ip, #64 -@@ -446,7 +446,7 @@ avg2_w20_loop: - .ifc \type, full - ldr lr, [r4, #32] // denom - .endif -- ldrd r4, [r4, #32+4] // scale, offset -+ ldrd r4, r5, [r4, #32+4] // scale, offset - vdup.16 q0, r4 - vdup.16 q1, r5 - .ifc \type, full -@@ -815,7 +815,7 @@ copy_w16_aligned_loop: - // int dx, int dy, int i_width, int i_height ); - function x264_mc_chroma_neon - push {r4-r6, lr} -- ldrd r4, [sp, #16] -+ ldrd r4, r5, [sp, #16] - ldr r6, [sp, #24] - - asr lr, r5, #3 -@@ -1271,8 +1271,8 @@ filter_h_loop: - function x264_frame_init_lowres_core_neon - push {r4-r10,lr} - vpush {d8-d15} -- ldrd r4, [sp, #96] -- ldrd r6, [sp, #104] -+ ldrd r4, r5, [sp, #96] -+ ldrd r6, r7, [sp, #104] - ldr lr, [sp, #112] - sub r10, r6, r7 // dst_stride - width - and r10, r10, #~15 -diff --git a/common/arm/pixel-a.S b/common/arm/pixel-a.S -index 8bce3b6..0784ae6 100644 ---- a/common/arm/pixel-a.S -+++ b/common/arm/pixel-a.S -@@ -328,9 +328,9 @@ SAD_FUNC_DUAL 16, 16 - function x264_pixel_sad_x\x\()_\w\()x\h\()_neon - push {r6-r7,lr} - .if \x == 3 -- ldrd r6, [sp, #12] -+ ldrd r6, r7, [sp, #12] - .else -- ldrd r6, [sp, #16] -+ ldrd r6, r7, [sp, #16] - ldr r12, [sp, #12] - .endif - mov lr, #FENC_STRIDE -@@ -596,7 +596,7 @@ function x264_pixel_var2_8x8_neon - vadd.s32 d1, d2, d3 - vpadd.s32 d0, d0, d1 - -- vmov.32 r0, r1, d0 -+ vmov r0, r1, d0 - vst1.32 {d0[1]}, [ip,:32] - mul r0, r0, r0 - sub r0, r1, r0, lsr #6 -diff --git a/common/arm/predict-a.S b/common/arm/predict-a.S -index af65bd7..8cdaf50 100644 ---- a/common/arm/predict-a.S -+++ b/common/arm/predict-a.S -@@ -181,9 +181,9 @@ function x264_predict_4x4_ddl_neon - - function x264_predict_8x8_dc_neon - mov ip, #0 -- ldrd r2, [r1, #8] -+ ldrd r2, r3, [r1, #8] - push {r4-r5,lr} -- ldrd r4, [r1, #16] -+ ldrd r4, r5, [r1, #16] - lsl r3, r3, #8 - ldrb lr, [r1, #7] - usad8 r2, r2, ip -diff --git a/common/arm/quant-a.S b/common/arm/quant-a.S -index e851562..c159f9e 100644 ---- a/common/arm/quant-a.S -+++ b/common/arm/quant-a.S -@@ -271,7 +271,7 @@ dequant_4x4_dc_rshift: - - // int coeff_last( int16_t *l ) - function x264_coeff_last4_arm -- ldrd r2, [r0] -+ ldrd r2, r3, [r0] - subs r0, r3, #0 - movne r0, #2 - movne r2, r3 -@@ -300,7 +300,7 @@ function x264_coeff_last\size\()_neon - - subs r1, ip, r1, lsr #2 - addge r0, r1, #\size - 8 -- sublts r0, r3, r0, lsr #2 -+ sublt r0, r3, r0, lsr #2 - movlt r0, #0 - bx lr - .endfunc -@@ -349,7 +349,7 @@ function x264_coeff_last64_neon - - subs r1, ip, r1 - addge r0, r1, #32 -- sublts r0, ip, r0 -+ sublt r0, ip, r0 - movlt r0, #0 - bx lr - .endfunc -diff --git a/configure b/configure -index 250b0ac..af69d44 100755 ---- a/configure -+++ b/configure -@@ -456,7 +456,7 @@ case $host_os in - ;; - darwin*) - SYS="MACOSX" -- CFLAGS="$CFLAGS -falign-loops=16" -+ CFLAGS="$CFLAGS" - libm="-lm" - if [ "$pic" = "no" ]; then - cc_check "" -mdynamic-no-pic && CFLAGS="$CFLAGS -mdynamic-no-pic" diff --git a/submodules/build/builders.d/zrtp.mk b/submodules/build/builders.d/zrtp.mk deleted file mode 100644 index db08fc9a4..000000000 --- a/submodules/build/builders.d/zrtp.mk +++ /dev/null @@ -1,66 +0,0 @@ -############################################################################ -# zrtp.mk -# Copyright (C) 2014 Belledonne Communications,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. -# -############################################################################ -bzrtp_dir?=bzrtp -enable_zrtp?=yes - -configure-options= -ifeq ($(LINPHONE_CCACHE), ccache) - configure-options+= --disable-strict -endif - -$(BUILDER_SRC_DIR)/$(bzrtp_dir)/configure: - @echo -e "\033[01;32m Running autogen for bzrtp in $(BUILDER_SRC_DIR)/$(bzrtp_dir) \033[0m" - cd $(BUILDER_SRC_DIR)/$(bzrtp_dir) && ./autogen.sh - -$(BUILDER_BUILD_DIR)/$(bzrtp_dir)/Makefile: $(BUILDER_SRC_DIR)/$(bzrtp_dir)/configure - @echo -e "\033[01;32m Running configure in $(BUILDER_BUILD_DIR)/$(bzrtp_dir) \033[0m" - mkdir -p $(BUILDER_BUILD_DIR)/$(bzrtp_dir) - cd $(BUILDER_BUILD_DIR)/$(bzrtp_dir)/ \ - && host_alias=${host} . $(BUILDER_SRC_DIR)/build/$(config_site) \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - $(BUILDER_SRC_DIR)/$(bzrtp_dir)/configure -prefix=$(prefix) --host=$(host) ${library_mode} \ - --enable-static ${configure-options} - -ifeq ($(enable_zrtp),yes) - -build-bzrtp: $(BUILDER_BUILD_DIR)/$(bzrtp_dir)/Makefile - @echo -e "\033[01;32m building bzrtp \033[0m" - cd $(BUILDER_BUILD_DIR)/$(bzrtp_dir) \ - && PKG_CONFIG_LIBDIR=$(prefix)/lib/pkgconfig \ - CONFIG_SITE=$(BUILDER_SRC_DIR)/build/$(config_site) \ - make -j1 && make install - -else -build-bzrtp: - @echo "ZRTP is disabled" - -endif - -clean-bzrtp: - -cd $(BUILDER_BUILD_DIR)/$(bzrtp_dir) && make clean - -veryclean-bzrtp: - -cd $(BUILDER_BUILD_DIR)/$(bzrtp_dir) && make distclean - rm -f $(BUILDER_SRC_DIR)/$(bzrtp_dir)/configure - -clean-makefile-bzrtp: - -cd $(BUILDER_BUILD_DIR)/$(bzrtp_dir) && rm -f Makefile diff --git a/submodules/build/iphone-config.site b/submodules/build/iphone-config.site deleted file mode 100644 index 95812fc57..000000000 --- a/submodules/build/iphone-config.site +++ /dev/null @@ -1,71 +0,0 @@ -# -*- shell-script -*- - -SDK_VERSION_MAJOR=5 -SDK_VERSION=5.0 -MCPU="" -CLANG_TARGET_SPECIFIER=miphoneos-version-min -if test "${host_alias}" = "i386-apple-darwin" ; then - PLATFORM=Simulator - ARCH=i386 - CMAKE_OPTS="-DCMAKE_SYSTEM_PROCESSOR=i386" - MCPU="" - CLANG_TARGET_SPECIFIER=mios-simulator-version-min -elif test "${host_alias}" = "armv7-apple-darwin" ; then - ARCH=armv7 - PLATFORM=OS - CMAKE_OPTS="-DCMAKE_SYSTEM_PROCESSOR=arm" - MCPU="-mcpu=cortex-a8" -elif test "${host_alias}" = "aarch64-apple-darwin" ; then - ARCH=arm64 - PLATFORM=OS - CMAKE_OPTS="-DCMAKE_SYSTEM_PROCESSOR=aarch64" -else - echo "bad host ${host_alias} must be either i386-apple-darwin or arm[v7,64]-apple-darwin" - exit -fi -echo "Loading config.site for iPhone platform=${PLATFORM} version=${SDK_VERSION}" -XCODE_DEV_PATH=`xcode-select -print-path` -#new path with Xcode 4.3: -if test -d ${XCODE_DEV_PATH}/Platforms/iPhone${PLATFORM}.platform/Developer/SDKs ; then - SDK_PATH_LIST=`ls -drt ${XCODE_DEV_PATH}/Platforms/iPhone${PLATFORM}.platform/Developer/SDKs/iPhone${PLATFORM}*` - SDK_BIN_PATH=${XCODE_DEV_PATH}/Platforms/iPhone${PLATFORM}.platform/Developer/usr/bin -else - SDK_PATH_LIST=`ls -drt /Developer/Platforms/iPhone${PLATFORM}.platform/Developer/SDKs/iPhone${PLATFORM}*` - SDK_BIN_PATH=/Developer/Platforms/iPhone${PLATFORM}.platform/Developer/usr/bin -fi - -for SYSROOT_PATH in $SDK_PATH_LIST ; do echo $SYSROOT_PATH ; done ; -echo "Selecting SDK path = ${SYSROOT_PATH}" - -COMMON_FLAGS=" -arch ${ARCH} ${MCPU} -isysroot ${SYSROOT_PATH} -${CLANG_TARGET_SPECIFIER}=${SDK_VERSION} -DTARGET_OS_IPHONE=1 -D__IOS -fms-extensions" - -#workaround for polarssl conflicting symbols - -COMMON_FLAGS="$COMMON_FLAGS -Dsha256=polarssl_sha256" - -# silence clang unused operators. This is temporary, we should find a way to compile 3rd party with correct flags :( -COMMON_FLAGS="-Qunused-arguments -Wno-unknown-warning-option -Wno-unused-command-line-argument-hard-error-in-future $COMMON_FLAGS" - -# you can use ccache to speed up build, in which case just define LINPHONE_CCACHE to 'ccache' -if test "$LINPHONE_CCACHE" = "ccache" ; then - # ccache doesn't like some options - COMMON_FLAGS="$COMMON_FLAGS -Wno-variadic-macros -Wno-pointer-arith -Wno-return-type -Wno-tautological-compare -Wno-unused-function -Wno-error" -fi - -CC="xcrun $LINPHONE_CCACHE clang" -OBJC="xcrun $LINPHONE_CCACHE clang" -CXX="xcrun $LINPHONE_CCACHE clang++" -LD="xcrun ld" -AR="xcrun ar" -RANLIB="xcrun ranlib" -STRIP="xcrun strip" -NM="xcrun nm" - -LDFLAGS="-arch ${ARCH}" -CFLAGS="$COMMON_FLAGS -std=c99" -CPPFLAGS="$COMMON_FLAGS -Dasm=__asm" -OBJCFLAGS="$COMMON_FLAGS -std=c99 -x objective-c -fexceptions -gdwarf-2 -fobjc-abi-version=2 -fobjc-legacy-dispatch" -#Force install script to use -C so that header files don't get re-written if not changed. -INSTALL_DATA="ginstall -C" - - diff --git a/submodules/build/iphone-toolchain.cmake b/submodules/build/iphone-toolchain.cmake deleted file mode 100644 index d7add3c91..000000000 --- a/submodules/build/iphone-toolchain.cmake +++ /dev/null @@ -1,6 +0,0 @@ -SET (CMAKE_SYSTEM_NAME "Generic") -SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -SET (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - - diff --git a/submodules/bzrtp b/submodules/bzrtp index 0948658db..4c9fc9539 160000 --- a/submodules/bzrtp +++ b/submodules/bzrtp @@ -1 +1 @@ -Subproject commit 0948658db85a7c9933ed2d39a159239d9ee5c734 +Subproject commit 4c9fc9539a06483da62938e8ae0ea48b18d026e6 diff --git a/submodules/cmake-builder b/submodules/cmake-builder new file mode 160000 index 000000000..b458a004e --- /dev/null +++ b/submodules/cmake-builder @@ -0,0 +1 @@ +Subproject commit b458a004e736f17e059741f067bc754adee3cb88 diff --git a/submodules/cunit b/submodules/cunit index 9aa6142d2..0a0a9c60f 160000 --- a/submodules/cunit +++ b/submodules/cunit @@ -1 +1 @@ -Subproject commit 9aa6142d267197c92b579ff82bc84ea7f0f5c35d +Subproject commit 0a0a9c60f5a1b899ae26b705fa5224ef25377982 diff --git a/submodules/externals/antlr3 b/submodules/externals/antlr3 index 489f375fb..311b6764e 160000 --- a/submodules/externals/antlr3 +++ b/submodules/externals/antlr3 @@ -1 +1 @@ -Subproject commit 489f375fb391cb70d82b56f509c39cbf7fa0b706 +Subproject commit 311b6764e3f440db43617296ff856f7ec07bfdef diff --git a/submodules/externals/ffmpeg b/submodules/externals/ffmpeg index 2b8b2ba19..644296e73 160000 --- a/submodules/externals/ffmpeg +++ b/submodules/externals/ffmpeg @@ -1 +1 @@ -Subproject commit 2b8b2ba19fe0ca6594cb09439b9ead2c328a79d8 +Subproject commit 644296e736ee219cd02f7b7d7b7b4c7c5a464217 diff --git a/submodules/externals/gsm b/submodules/externals/gsm index 405fb3856..b6b379963 160000 --- a/submodules/externals/gsm +++ b/submodules/externals/gsm @@ -1 +1 @@ -Subproject commit 405fb3856f0b9e902dcb159ec6a3409ba6e78476 +Subproject commit b6b37996357ae9d9596b8ee227f33744889d895c diff --git a/submodules/externals/libvpx b/submodules/externals/libvpx index 7621a19aa..62e8660f6 160000 --- a/submodules/externals/libvpx +++ b/submodules/externals/libvpx @@ -1 +1 @@ -Subproject commit 7621a19aa53c7b26b4bf4ba30f2c7f65f8503f9d +Subproject commit 62e8660f60361f36752c214ac3de17d061b45a98 diff --git a/submodules/externals/opencore-amr b/submodules/externals/opencore-amr deleted file mode 160000 index cf4409e03..000000000 --- a/submodules/externals/opencore-amr +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cf4409e03ec56b1cd85a2f9532f58bc1fa9db274 diff --git a/submodules/externals/openh264 b/submodules/externals/openh264 index c13bfe640..3a75956fb 160000 --- a/submodules/externals/openh264 +++ b/submodules/externals/openh264 @@ -1 +1 @@ -Subproject commit c13bfe6407252f64610b0c2c9aa0737054dcd71e +Subproject commit 3a75956fb2584cca84a95ba1fcbc72fa2c91f98d diff --git a/submodules/externals/polarssl b/submodules/externals/polarssl index ab2f403a3..3b7c2443e 160000 --- a/submodules/externals/polarssl +++ b/submodules/externals/polarssl @@ -1 +1 @@ -Subproject commit ab2f403a3e0ec91257f0e943129c0eec272f34e8 +Subproject commit 3b7c2443e75e51b7af67a3e5dcb3771ae3120ff3 diff --git a/submodules/externals/speex b/submodules/externals/speex index f0bbb55db..6a8d5c8df 160000 --- a/submodules/externals/speex +++ b/submodules/externals/speex @@ -1 +1 @@ -Subproject commit f0bbb55db823234366993ce4b64f2b14ab025260 +Subproject commit 6a8d5c8dff15afb04e1c71be3f7e4e051992494b diff --git a/submodules/externals/srtp b/submodules/externals/srtp index 4338c102f..4caa4843b 160000 --- a/submodules/externals/srtp +++ b/submodules/externals/srtp @@ -1 +1 @@ -Subproject commit 4338c102f5a4b8f89b7019ed66fb456e3e3359ae +Subproject commit 4caa4843b4bfc54be596d309b5d00a81a35e3276 diff --git a/submodules/externals/vo-amrwbenc b/submodules/externals/vo-amrwbenc new file mode 160000 index 000000000..080af7540 --- /dev/null +++ b/submodules/externals/vo-amrwbenc @@ -0,0 +1 @@ +Subproject commit 080af7540562e4adfbd3312837fe5fc6771c4cd0 diff --git a/submodules/externals/x264 b/submodules/externals/x264 index 3f516c523..1840d2a6d 160000 --- a/submodules/externals/x264 +++ b/submodules/externals/x264 @@ -1 +1 @@ -Subproject commit 3f516c5238d0c536ea03c8e5334d231facf9f31b +Subproject commit 1840d2a6de0e832d5c770e0810bcaf5c5ca7a7ff diff --git a/submodules/libilbc-rfc3951 b/submodules/libilbc-rfc3951 deleted file mode 160000 index 488f21593..000000000 --- a/submodules/libilbc-rfc3951 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 488f2159378d2c1956135604736dfddaeb947ef5 diff --git a/submodules/liblinphone.xcodeproj/project.pbxproj b/submodules/liblinphone.xcodeproj/project.pbxproj index 80bc18154..604868bd2 100644 --- a/submodules/liblinphone.xcodeproj/project.pbxproj +++ b/submodules/liblinphone.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 0F3BFC991BFCC7A10025B8DF /* libmswebrtc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0F3BFC981BFCC7A00025B8DF /* libmswebrtc.a */; }; 1561A554178D9C68006B4B2F /* ioshardware.h in Headers */ = {isa = PBXBuildFile; fileRef = 1561A553178D9C68006B4B2F /* ioshardware.h */; }; 1561A555178D9C71006B4B2F /* ioshardware.m in Sources */ = {isa = PBXBuildFile; fileRef = 1561A551178D98E2006B4B2F /* ioshardware.m */; }; 2206D2D3177AC70900C40726 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2206D2C6177AC70900C40726 /* InfoPlist.strings */; }; @@ -86,7 +87,6 @@ 225D64481521BFA6008B2E81 /* msvolume.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5D811F6CF7600621220 /* msvolume.h */; }; 225D64491521BFA6008B2E81 /* mswebcam.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5D911F6CF7600621220 /* mswebcam.h */; }; 225D644A1521BFA6008B2E81 /* rfc3984.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5DA11F6CF7600621220 /* rfc3984.h */; }; - 225D644B1521BFA6008B2E81 /* waveheader.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5DB11F6CF7600621220 /* waveheader.h */; }; 225D64531521BFA6008B2E81 /* b64.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA6A511F6CF9F00621220 /* b64.h */; }; 225D64541521BFA6008B2E81 /* event.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA6A611F6CF9F00621220 /* event.h */; }; 225D64551521BFA6008B2E81 /* ortp.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA6A911F6CF9F00621220 /* ortp.h */; }; @@ -109,7 +109,6 @@ 225D64671521BFA6008B2E81 /* utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA6F311F6CF9F00621220 /* utils.h */; }; 225D64811521BFA6008B2E81 /* zrtp.h in Headers */ = {isa = PBXBuildFile; fileRef = 7014533B13FA7ECA00A01D86 /* zrtp.h */; }; 225D64F21521BFA6008B2E81 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; }; - 225D64F31521BFA6008B2E81 /* libSKP_SILK_SDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2211DBA0147660BB00DEE054 /* libSKP_SILK_SDK.a */; }; 225D64FC1521C009008B2E81 /* liblinphone_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* liblinphone_Prefix.pch */; }; 225D64FD1521C009008B2E81 /* allfilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5BE11F6CF7600621220 /* allfilters.h */; }; 225D64FE1521C009008B2E81 /* dsptools.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5BF11F6CF7600621220 /* dsptools.h */; }; @@ -138,7 +137,6 @@ 225D65151521C009008B2E81 /* msvolume.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5D811F6CF7600621220 /* msvolume.h */; }; 225D65161521C009008B2E81 /* mswebcam.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5D911F6CF7600621220 /* mswebcam.h */; }; 225D65171521C009008B2E81 /* rfc3984.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5DA11F6CF7600621220 /* rfc3984.h */; }; - 225D65181521C009008B2E81 /* waveheader.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5DB11F6CF7600621220 /* waveheader.h */; }; 225D65201521C009008B2E81 /* b64.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA6A511F6CF9F00621220 /* b64.h */; }; 225D65211521C009008B2E81 /* event.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA6A611F6CF9F00621220 /* event.h */; }; 225D65221521C009008B2E81 /* ortp.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA6A911F6CF9F00621220 /* ortp.h */; }; @@ -215,7 +213,6 @@ 22C8D05D1769F8FF00DAFB4E /* msvolume.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5D811F6CF7600621220 /* msvolume.h */; }; 22C8D05E1769F8FF00DAFB4E /* mswebcam.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5D911F6CF7600621220 /* mswebcam.h */; }; 22C8D05F1769F8FF00DAFB4E /* rfc3984.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5DA11F6CF7600621220 /* rfc3984.h */; }; - 22C8D0601769F8FF00DAFB4E /* waveheader.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA5DB11F6CF7600621220 /* waveheader.h */; }; 22C8D0611769F8FF00DAFB4E /* b64.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA6A511F6CF9F00621220 /* b64.h */; }; 22C8D0621769F8FF00DAFB4E /* event.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA6A611F6CF9F00621220 /* event.h */; }; 22C8D0631769F8FF00DAFB4E /* ortp.h in Headers */ = {isa = PBXBuildFile; fileRef = 222CA6A911F6CF9F00621220 /* ortp.h */; }; @@ -320,11 +317,13 @@ 22C8D0DF1769F8FF00DAFB4E /* speexec.c in Sources */ = {isa = PBXBuildFile; fileRef = 22D07CE416F3BFCB009F2C9E /* speexec.c */; }; 22C8D0E01769F8FF00DAFB4E /* msopus.c in Sources */ = {isa = PBXBuildFile; fileRef = 22AF73BD1753E83700BE8398 /* msopus.c */; }; 22C8D0E21769F8FF00DAFB4E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; }; - 22C8D0E31769F8FF00DAFB4E /* libSKP_SILK_SDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2211DBA0147660BB00DEE054 /* libSKP_SILK_SDK.a */; }; 22C8D0ED176A079600DAFB4E /* aac-eld.c in Sources */ = {isa = PBXBuildFile; fileRef = 22C8D0EC176A079600DAFB4E /* aac-eld.c */; }; 22DD19C113A8D7FA0018ECD4 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22DD19C013A8D7FA0018ECD4 /* UIKit.framework */; }; 22DD19C213A8D7FA0018ECD4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; }; 22DD19C413A8D7FA0018ECD4 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22DD19C313A8D7FA0018ECD4 /* CoreGraphics.framework */; }; + 630DCF691BBAC06400A0DDC8 /* msvideopresets.c in Sources */ = {isa = PBXBuildFile; fileRef = 630DCF661BBAC05100A0DDC8 /* msvideopresets.c */; }; + 630DCF6C1BBAC08200A0DDC8 /* rfc4103_textstream.c in Sources */ = {isa = PBXBuildFile; fileRef = 630DCF6A1BBAC08200A0DDC8 /* rfc4103_textstream.c */; }; + 630DCF6D1BBAC08200A0DDC8 /* video_preset_high_fps.c in Sources */ = {isa = PBXBuildFile; fileRef = 630DCF6B1BBAC08200A0DDC8 /* video_preset_high_fps.c */; }; 7066FC0A13E830B800EFC6DC /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7066FC0913E830B800EFC6DC /* libvpx.a */; }; 70E542EE13E147C7002BA2C0 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542ED13E147C7002BA2C0 /* OpenGLES.framework */; }; 70E542F113E147CE002BA2C0 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542F013E147CE002BA2C0 /* QuartzCore.framework */; }; @@ -344,6 +343,9 @@ F02538F919794908002C30F3 /* flowcontrol.c in Sources */ = {isa = PBXBuildFile; fileRef = F02538F819794908002C30F3 /* flowcontrol.c */; }; F02538FB1979491B002C30F3 /* videostarter.c in Sources */ = {isa = PBXBuildFile; fileRef = F02538FA1979491B002C30F3 /* videostarter.c */; }; F0340ADD1A6D13BD002E4BF1 /* ms_srtp.c in Sources */ = {isa = PBXBuildFile; fileRef = F0340ADC1A6D13BD002E4BF1 /* ms_srtp.c */; }; + F03A96E81AFA157800651655 /* bc_completion in Resources */ = {isa = PBXBuildFile; fileRef = F03A96E51AFA157800651655 /* bc_completion */; }; + F03A96E91AFA157800651655 /* bc_tester_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F03A96E61AFA157800651655 /* bc_tester_utils.c */; }; + F03A96EA1AFA174400651655 /* bc_tester_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F03A96E61AFA157800651655 /* bc_tester_utils.c */; }; F0497F021A1652F100B67112 /* mediastreamer2_neon_tester.c in Sources */ = {isa = PBXBuildFile; fileRef = F0ED9B981A164D7200A788CE /* mediastreamer2_neon_tester.c */; }; F0497F0E1A1B4C1700B67112 /* mediastreamer2_tester_ios.m in Sources */ = {isa = PBXBuildFile; fileRef = F0497F0D1A1B4C1700B67112 /* mediastreamer2_tester_ios.m */; }; F0497F131A1C9E9C00B67112 /* mediastreamViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2206D2CA177AC70900C40726 /* mediastreamViewController.xib */; }; @@ -359,7 +361,6 @@ F0BA0A8E1A24D4DE00F68203 /* nowebcam.c in Sources */ = {isa = PBXBuildFile; fileRef = 223CA84016D9268D00EF1BEC /* nowebcam.c */; }; F0ED99131A16456500A788CE /* libcunit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F0ED99121A16456500A788CE /* libcunit.a */; }; F0ED99361A1645C200A788CE /* Makefile.am in Resources */ = {isa = PBXBuildFile; fileRef = F0ED99171A1645C200A788CE /* Makefile.am */; }; - F0ED99371A1645C200A788CE /* Makefile.in in Resources */ = {isa = PBXBuildFile; fileRef = F0ED99181A1645C200A788CE /* Makefile.in */; }; F0ED99421A1645C200A788CE /* arpeggio_8000_mono.wav in Resources */ = {isa = PBXBuildFile; fileRef = F0ED99261A1645C200A788CE /* arpeggio_8000_mono.wav */; }; F0ED99431A1645C200A788CE /* bird_44100_stereo.wav in Resources */ = {isa = PBXBuildFile; fileRef = F0ED99271A1645C200A788CE /* bird_44100_stereo.wav */; }; F0ED99441A1645C200A788CE /* chimes_48000_stereo.wav in Resources */ = {isa = PBXBuildFile; fileRef = F0ED99281A1645C200A788CE /* chimes_48000_stereo.wav */; }; @@ -417,7 +418,6 @@ F0ED99881A16464D00A788CE /* nylon_48000_mono.wav in Resources */ = {isa = PBXBuildFile; fileRef = F0ED99321A1645C200A788CE /* nylon_48000_mono.wav */; }; F0ED99891A16464D00A788CE /* hello8000.wav in Resources */ = {isa = PBXBuildFile; fileRef = F0ED992C1A1645C200A788CE /* hello8000.wav */; }; F0ED998A1A16464D00A788CE /* laserrocket_16000_mono.wav in Resources */ = {isa = PBXBuildFile; fileRef = F0ED99311A1645C200A788CE /* laserrocket_16000_mono.wav */; }; - F0ED998B1A16464D00A788CE /* Makefile.in in Resources */ = {isa = PBXBuildFile; fileRef = F0ED99181A1645C200A788CE /* Makefile.in */; }; F0ED998C1A16464D00A788CE /* chimes_48000_stereo.wav in Resources */ = {isa = PBXBuildFile; fileRef = F0ED99281A1645C200A788CE /* chimes_48000_stereo.wav */; }; F0ED998D1A16464D00A788CE /* Makefile.am in Resources */ = {isa = PBXBuildFile; fileRef = F0ED99171A1645C200A788CE /* Makefile.am */; }; F0ED998E1A16464D00A788CE /* bird_44100_stereo.wav in Resources */ = {isa = PBXBuildFile; fileRef = F0ED99271A1645C200A788CE /* bird_44100_stereo.wav */; }; @@ -514,6 +514,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 0F3BFC961BFCC7420025B8DF /* liblinphone-sdk */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "liblinphone-sdk"; path = "../liblinphone-sdk"; sourceTree = ""; }; + 0F3BFC981BFCC7A00025B8DF /* libmswebrtc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmswebrtc.a; path = "../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmswebrtc.a"; sourceTree = ""; }; 1561A551178D98E2006B4B2F /* ioshardware.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ioshardware.m; sourceTree = ""; }; 1561A553178D9C68006B4B2F /* ioshardware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ioshardware.h; sourceTree = ""; }; 2203127413A249F70049A2ED /* filter-template.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "filter-template.c"; sourceTree = ""; }; @@ -538,7 +540,6 @@ 220ED1A613A9040700AC21E0 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 220ED1A813A9041800AC21E0 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; 2211DB9E14765CEC00DEE054 /* libmssilk.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmssilk.a; path = "../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmssilk.a"; sourceTree = ""; }; - 2211DBA0147660BB00DEE054 /* libSKP_SILK_SDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSKP_SILK_SDK.a; path = "../liblinphone-sdk/apple-darwin/lib/libSKP_SILK_SDK.a"; sourceTree = ""; }; 221DCB6A153584410025E54D /* yuv2rgb.fs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = yuv2rgb.fs; sourceTree = ""; }; 221DCB6B153584410025E54D /* yuv2rgb.vs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = yuv2rgb.vs; sourceTree = ""; }; 221F589913AB4EEE00D603C9 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; @@ -577,10 +578,8 @@ 222CA5D811F6CF7600621220 /* msvolume.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msvolume.h; sourceTree = ""; }; 222CA5D911F6CF7600621220 /* mswebcam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mswebcam.h; sourceTree = ""; }; 222CA5DA11F6CF7600621220 /* rfc3984.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rfc3984.h; sourceTree = ""; }; - 222CA5DB11F6CF7600621220 /* waveheader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = waveheader.h; sourceTree = ""; }; 222CA5DD11F6CF7600621220 /* .gitignore */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; 222CA5F911F6CF7600621220 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = ""; }; - 222CA5FA11F6CF7600621220 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = ""; }; 222CA6A011F6CF9E00621220 /* .gitignore */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; 222CA6A111F6CF9E00621220 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = ""; }; 222CA6A211F6CF9F00621220 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = ""; }; @@ -736,6 +735,9 @@ 22DD19BE13A8D7FA0018ECD4 /* mediastream.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = mediastream.app; sourceTree = BUILT_PRODUCTS_DIR; }; 22DD19C013A8D7FA0018ECD4 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 22DD19C313A8D7FA0018ECD4 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 630DCF661BBAC05100A0DDC8 /* msvideopresets.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = msvideopresets.c; path = linphone/mediastreamer2/src/base/msvideopresets.c; sourceTree = SOURCE_ROOT; }; + 630DCF6A1BBAC08200A0DDC8 /* rfc4103_textstream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rfc4103_textstream.c; sourceTree = ""; }; + 630DCF6B1BBAC08200A0DDC8 /* video_preset_high_fps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = video_preset_high_fps.c; sourceTree = ""; }; 7014533B13FA7ECA00A01D86 /* zrtp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zrtp.h; sourceTree = ""; }; 7066FC0913E830B800EFC6DC /* libvpx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvpx.a; path = "../liblinphone-sdk/apple-darwin/lib/libvpx.a"; sourceTree = ""; }; 70E542ED13E147C7002BA2C0 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; @@ -762,6 +764,9 @@ F02538F819794908002C30F3 /* flowcontrol.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = flowcontrol.c; sourceTree = ""; }; F02538FA1979491B002C30F3 /* videostarter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = videostarter.c; sourceTree = ""; }; F0340ADC1A6D13BD002E4BF1 /* ms_srtp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ms_srtp.c; sourceTree = ""; }; + F03A96E51AFA157800651655 /* bc_completion */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = bc_completion; sourceTree = ""; }; + F03A96E61AFA157800651655 /* bc_tester_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bc_tester_utils.c; sourceTree = ""; }; + F03A96E71AFA157800651655 /* bc_tester_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bc_tester_utils.h; sourceTree = ""; }; F0497F0D1A1B4C1700B67112 /* mediastreamer2_tester_ios.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = mediastreamer2_tester_ios.m; sourceTree = ""; }; F0497F151A1C9F8700B67112 /* mediastream-tester-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "mediastream-tester-Info.plist"; sourceTree = ""; }; F04D51ED1A08E638004DD530 /* common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = common.c; path = tools/common.c; sourceTree = ""; }; @@ -772,7 +777,6 @@ F08272D91A7F898200BB6004 /* zrtp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zrtp.c; sourceTree = ""; }; F0ED99121A16456500A788CE /* libcunit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcunit.a; path = "../liblinphone-sdk/apple-darwin/lib/libcunit.a"; sourceTree = ""; }; F0ED99171A1645C200A788CE /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.am; sourceTree = ""; }; - F0ED99181A1645C200A788CE /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Makefile.in; sourceTree = ""; }; F0ED991A1A1645C200A788CE /* mediastreamer2_adaptive_tester.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mediastreamer2_adaptive_tester.c; sourceTree = ""; }; F0ED991B1A1645C200A788CE /* mediastreamer2_audio_stream_tester.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mediastreamer2_audio_stream_tester.c; sourceTree = ""; }; F0ED991C1A1645C200A788CE /* mediastreamer2_basic_audio_tester.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mediastreamer2_basic_audio_tester.c; sourceTree = ""; }; @@ -811,7 +815,6 @@ buildActionMask = 2147483647; files = ( 225D64F21521BFA6008B2E81 /* Foundation.framework in Frameworks */, - 225D64F31521BFA6008B2E81 /* libSKP_SILK_SDK.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -828,7 +831,6 @@ buildActionMask = 2147483647; files = ( 22C8D0E21769F8FF00DAFB4E /* Foundation.framework in Frameworks */, - 22C8D0E31769F8FF00DAFB4E /* libSKP_SILK_SDK.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -836,6 +838,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 0F3BFC991BFCC7A10025B8DF /* libmswebrtc.a in Frameworks */, 2206D2DE177ACD3800C40726 /* libmediastreamer_voip.a in Frameworks */, 22AF73C01753F3E100BE8398 /* libopus.a in Frameworks */, 225D65CD1521C19A008B2E81 /* libortp.a in Frameworks */, @@ -1030,7 +1033,6 @@ 222CA5D811F6CF7600621220 /* msvolume.h */, 222CA5D911F6CF7600621220 /* mswebcam.h */, 222CA5DA11F6CF7600621220 /* rfc3984.h */, - 222CA5DB11F6CF7600621220 /* waveheader.h */, ); path = mediastreamer2; sourceTree = ""; @@ -1043,7 +1045,6 @@ 2252935A12F6CA4700DD9BFB /* ec-calibrator.c */, 2203127413A249F70049A2ED /* filter-template.c */, 221DCB6A153584410025E54D /* yuv2rgb.fs */, - 222CA5FA11F6CF7600621220 /* Makefile.in */, 221DCB6B153584410025E54D /* yuv2rgb.vs */, 223CA7EF16D9268D00EF1BEC /* audiofilters */, 223CA81116D9268D00EF1BEC /* base */, @@ -1245,6 +1246,9 @@ 223CA84E16D9268D00EF1BEC /* voip */ = { isa = PBXGroup; children = ( + 630DCF6A1BBAC08200A0DDC8 /* rfc4103_textstream.c */, + 630DCF6B1BBAC08200A0DDC8 /* video_preset_high_fps.c */, + 630DCF661BBAC05100A0DDC8 /* msvideopresets.c */, 223CA84F16D9268D00EF1BEC /* audioconference.c */, 223CA85016D9268D00EF1BEC /* audiostream.c */, 223CA85116D9268D00EF1BEC /* bitratecontrol.c */, @@ -1320,12 +1324,22 @@ path = crypto; sourceTree = ""; }; + F03A96E41AFA157800651655 /* common */ = { + isa = PBXGroup; + children = ( + F03A96E51AFA157800651655 /* bc_completion */, + F03A96E61AFA157800651655 /* bc_tester_utils.c */, + F03A96E71AFA157800651655 /* bc_tester_utils.h */, + ); + path = common; + sourceTree = ""; + }; F0ED99161A1645C200A788CE /* tester */ = { isa = PBXGroup; children = ( + F03A96E41AFA157800651655 /* common */, F01223BC1A1E4827008D16BA /* sounds */, F0ED99171A1645C200A788CE /* Makefile.am */, - F0ED99181A1645C200A788CE /* Makefile.in */, F0ED991A1A1645C200A788CE /* mediastreamer2_adaptive_tester.c */, F0ED991B1A1645C200A788CE /* mediastreamer2_audio_stream_tester.c */, F0ED991C1A1645C200A788CE /* mediastreamer2_basic_audio_tester.c */, @@ -1369,11 +1383,12 @@ F0ED99521A1645CD00A788CE /* Frameworks */ = { isa = PBXGroup; children = ( + 0F3BFC981BFCC7A00025B8DF /* libmswebrtc.a */, + 0F3BFC961BFCC7420025B8DF /* liblinphone-sdk */, AACBBE490F95108600F1A2B1 /* Foundation.framework */, 22DD19C013A8D7FA0018ECD4 /* UIKit.framework */, 22DD19C313A8D7FA0018ECD4 /* CoreGraphics.framework */, 22AF73BF1753F3E100BE8398 /* libopus.a */, - 2211DBA0147660BB00DEE054 /* libSKP_SILK_SDK.a */, 2211DB9E14765CEC00DEE054 /* libmssilk.a */, 7066FC0913E830B800EFC6DC /* libvpx.a */, 70E542F013E147CE002BA2C0 /* QuartzCore.framework */, @@ -1435,7 +1450,6 @@ 225D64481521BFA6008B2E81 /* msvolume.h in Headers */, 225D64491521BFA6008B2E81 /* mswebcam.h in Headers */, 225D644A1521BFA6008B2E81 /* rfc3984.h in Headers */, - 225D644B1521BFA6008B2E81 /* waveheader.h in Headers */, 225D64531521BFA6008B2E81 /* b64.h in Headers */, 225D64541521BFA6008B2E81 /* event.h in Headers */, 225D64551521BFA6008B2E81 /* ortp.h in Headers */, @@ -1512,7 +1526,6 @@ 225D65151521C009008B2E81 /* msvolume.h in Headers */, 225D65161521C009008B2E81 /* mswebcam.h in Headers */, 225D65171521C009008B2E81 /* rfc3984.h in Headers */, - 225D65181521C009008B2E81 /* waveheader.h in Headers */, 225D65201521C009008B2E81 /* b64.h in Headers */, 225D65211521C009008B2E81 /* event.h in Headers */, 225D65221521C009008B2E81 /* ortp.h in Headers */, @@ -1569,7 +1582,6 @@ 22C8D05D1769F8FF00DAFB4E /* msvolume.h in Headers */, 22C8D05E1769F8FF00DAFB4E /* mswebcam.h in Headers */, 22C8D05F1769F8FF00DAFB4E /* rfc3984.h in Headers */, - 22C8D0601769F8FF00DAFB4E /* waveheader.h in Headers */, 22C8D0611769F8FF00DAFB4E /* b64.h in Headers */, 22C8D0621769F8FF00DAFB4E /* event.h in Headers */, 22C8D0631769F8FF00DAFB4E /* ortp.h in Headers */, @@ -1785,7 +1797,6 @@ F0ED994E1A1645C200A788CE /* nylon_48000_mono.wav in Resources */, F0ED99481A1645C200A788CE /* hello8000.wav in Resources */, F0ED994D1A1645C200A788CE /* laserrocket_16000_mono.wav in Resources */, - F0ED99371A1645C200A788CE /* Makefile.in in Resources */, F0ED99441A1645C200A788CE /* chimes_48000_stereo.wav in Resources */, F0ED99361A1645C200A788CE /* Makefile.am in Resources */, F0ED99431A1645C200A788CE /* bird_44100_stereo.wav in Resources */, @@ -1822,8 +1833,8 @@ F0ED99891A16464D00A788CE /* hello8000.wav in Resources */, F0497F141A1C9EA000B67112 /* MainWindow.xib in Resources */, F0ED998A1A16464D00A788CE /* laserrocket_16000_mono.wav in Resources */, - F0ED998B1A16464D00A788CE /* Makefile.in in Resources */, F0ED998C1A16464D00A788CE /* chimes_48000_stereo.wav in Resources */, + F03A96E81AFA157800651655 /* bc_completion in Resources */, F0ED998D1A16464D00A788CE /* Makefile.am in Resources */, F0ED998E1A16464D00A788CE /* bird_44100_stereo.wav in Resources */, F0ED99901A16464D00A788CE /* hello8000-1s.wav in Resources */, @@ -1898,6 +1909,7 @@ files = ( 22C8D0991769F8FF00DAFB4E /* filter-template.c in Sources */, 22C8D09A1769F8FF00DAFB4E /* yuv2rgb.fs in Sources */, + 630DCF691BBAC06400A0DDC8 /* msvideopresets.c in Sources */, 22C8D09B1769F8FF00DAFB4E /* yuv2rgb.vs in Sources */, F02538F919794908002C30F3 /* flowcontrol.c in Sources */, 22C8D09C1769F8FF00DAFB4E /* alaw.c in Sources */, @@ -1961,6 +1973,7 @@ 22C8D0D81769F8FF00DAFB4E /* msvoip.c in Sources */, 22C8D0D91769F8FF00DAFB4E /* qosanalyzer.c in Sources */, 22C8D0DA1769F8FF00DAFB4E /* qualityindicator.c in Sources */, + 630DCF6D1BBAC08200A0DDC8 /* video_preset_high_fps.c in Sources */, 22C8D0DB1769F8FF00DAFB4E /* rfc3984.c in Sources */, 22C8D0DC1769F8FF00DAFB4E /* ringstream.c in Sources */, 22C8D0DD1769F8FF00DAFB4E /* scaler.c in Sources */, @@ -1970,6 +1983,7 @@ 22C8D0E01769F8FF00DAFB4E /* msopus.c in Sources */, 22C8D0ED176A079600DAFB4E /* aac-eld.c in Sources */, 1561A555178D9C71006B4B2F /* ioshardware.m in Sources */, + 630DCF6C1BBAC08200A0DDC8 /* rfc4103_textstream.c in Sources */, F08272D71A7F895400BB6004 /* stun.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1992,6 +2006,7 @@ F01223D91A1F29AB008D16BA /* mediastream_tester_Tests.m in Sources */, F0BA0A8E1A24D4DE00F68203 /* nowebcam.c in Sources */, F01223E41A1F29D6008D16BA /* DTObjectBlockExecutor.m in Sources */, + F03A96EA1AFA174400651655 /* bc_tester_utils.c in Sources */, F01223E51A1F29D6008D16BA /* NSObject+DTRuntime.m in Sources */, F0BA0A8D1A24D4C900F68203 /* mediastreamer2_tester.c in Sources */, ); @@ -2001,6 +2016,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F03A96E91AFA157800651655 /* bc_tester_utils.c in Sources */, F0ED99591A16464D00A788CE /* mediastreamer2_adaptive_tester.c in Sources */, F0ED995A1A16464D00A788CE /* mediastreamer2_basic_audio_tester.c in Sources */, F0ED995B1A16464D00A788CE /* mediastreamer2_player_tester.c in Sources */, @@ -2090,6 +2106,7 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD)"; + ENABLE_BITCODE = NO; GCC_C_LANGUAGE_STANDARD = c99; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -2116,6 +2133,7 @@ "POSIXTIMER_INTERVAL=10000", ); GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( linphone/mediastreamer2/build/iphone, @@ -2126,6 +2144,8 @@ externals/exosip/include, externals/speex/include, ); + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; SDKROOT = iphoneos; VALID_ARCHS = "arm64 armv7"; @@ -2136,6 +2156,7 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD)"; + ENABLE_BITCODE = NO; GCC_C_LANGUAGE_STANDARD = c99; GCC_PREPROCESSOR_DEFINITIONS = ( "_BYTE_ORDER=_LITTLE_ENDIAN", @@ -2162,6 +2183,7 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( linphone/mediastreamer2/build/iphone, @@ -2172,6 +2194,7 @@ externals/exosip/include, externals/speex/include, ); + IPHONEOS_DEPLOYMENT_TARGET = 6.0; OTHER_LDFLAGS = "-ObjC"; SDKROOT = iphoneos; VALID_ARCHS = "arm64 armv7"; @@ -2211,6 +2234,7 @@ HAVE_LIBSWSCALE_SWSCALE_H, TARGET_OS_IPHONE, MS2_FILTERS, + HAVE_NON_FREE_CODECS, ); GCC_THUMB_SUPPORT = NO; GCC_UNROLL_LOOPS = NO; @@ -2267,6 +2291,7 @@ HAVE_LIBSWSCALE_SWSCALE_H, TARGET_OS_IPHONE, MS2_FILTERS, + HAVE_NON_FREE_CODECS, ); GCC_THUMB_SUPPORT = NO; GCC_UNROLL_LOOPS = NO; @@ -2323,6 +2348,7 @@ HAVE_LIBSWSCALE_SWSCALE_H, TARGET_OS_IPHONE, MS2_FILTERS, + HAVE_NON_FREE_CODECS, ); GCC_THUMB_SUPPORT = NO; GCC_UNROLL_LOOPS = NO; @@ -2521,6 +2547,7 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD)"; + ENABLE_BITCODE = NO; GCC_C_LANGUAGE_STANDARD = c99; GCC_PREPROCESSOR_DEFINITIONS = ( "_BYTE_ORDER=_LITTLE_ENDIAN", @@ -2547,6 +2574,7 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( linphone/mediastreamer2/build/iphone, @@ -2557,6 +2585,7 @@ externals/exosip/include, externals/speex/include, ); + IPHONEOS_DEPLOYMENT_TARGET = 6.0; OTHER_LDFLAGS = "-ObjC"; SDKROOT = iphoneos; VALID_ARCHS = "arm64 armv7"; @@ -2573,6 +2602,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "linphone/mediastreamer2/tools/ios/mediastream-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = ( + HAVE_WEBRTC, HAVE_SILK, "_BYTE_ORDER=_LITTLE_ENDIAN", ORTP_INET6, @@ -2598,13 +2628,11 @@ GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_FILE = "$(SRCROOT)/linphone/mediastreamer2/tools/ios/mediastream-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/../liblinphone-sdk/apple-darwin/lib", "$(SRCROOT)/../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); - ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -2648,6 +2676,7 @@ MS2_FILTERS, HAVE_FUN_avcodec_open2, HAVE_FUN_avcodec_get_context_defaults3, + HAVE_NON_FREE_CODECS, ); GCC_THUMB_SUPPORT = NO; GCC_UNROLL_LOOPS = NO; @@ -2705,6 +2734,7 @@ MS2_FILTERS, HAVE_FUN_avcodec_open2, HAVE_FUN_avcodec_get_context_defaults3, + HAVE_NON_FREE_CODECS, ); GCC_THUMB_SUPPORT = NO; GCC_UNROLL_LOOPS = NO; @@ -2762,6 +2792,7 @@ MS2_FILTERS, HAVE_FUN_avcodec_open2, HAVE_FUN_avcodec_get_context_defaults3, + HAVE_NON_FREE_CODECS, ); GCC_THUMB_SUPPORT = NO; GCC_UNROLL_LOOPS = NO; @@ -2798,6 +2829,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "linphone/mediastreamer2/tools/ios/mediastream-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = ( + HAVE_WEBRTC, HAVE_SILK, "_BYTE_ORDER=_LITTLE_ENDIAN", ORTP_INET6, @@ -2823,13 +2855,11 @@ GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_FILE = "$(SRCROOT)/linphone/mediastreamer2/tools/ios/mediastream-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/../liblinphone-sdk/apple-darwin/lib", "$(SRCROOT)/../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); - ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; WRAPPER_EXTENSION = app; @@ -2846,6 +2876,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "linphone/mediastreamer2/tools/ios/mediastream-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = ( + HAVE_WEBRTC, HAVE_SILK, "_BYTE_ORDER=_LITTLE_ENDIAN", ORTP_INET6, @@ -2871,13 +2902,11 @@ GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_FILE = "$(SRCROOT)/linphone/mediastreamer2/tools/ios/mediastream-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/../liblinphone-sdk/apple-darwin/lib", "$(SRCROOT)/../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); - ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -2932,10 +2961,8 @@ "$(SRCROOT)/../liblinphone-sdk/apple-darwin/include", ); INFOPLIST_FILE = "mediastream-tester Tests/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/mediastream-tester.app/mediastream-tester"; }; @@ -2980,7 +3007,6 @@ "$(SRCROOT)/../liblinphone-sdk/apple-darwin/include", ); INFOPLIST_FILE = "mediastream-tester Tests/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -3028,7 +3054,6 @@ "$(SRCROOT)/../liblinphone-sdk/apple-darwin/include", ); INFOPLIST_FILE = "mediastream-tester Tests/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -3086,13 +3111,11 @@ "$(SRCROOT)/externals/speex", ); INFOPLIST_FILE = "$(SRCROOT)/linphone/mediastreamer2/tools/ios/mediastream-tester-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.1; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/../liblinphone-sdk/apple-darwin/lib", "$(SRCROOT)/../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); - ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = "mediastream-tester"; PROVISIONING_PROFILE = ""; SKIP_INSTALL = YES; @@ -3148,13 +3171,11 @@ "$(SRCROOT)/externals/speex", ); INFOPLIST_FILE = "$(SRCROOT)/linphone/mediastreamer2/tools/ios/mediastream-tester-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.1; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/../liblinphone-sdk/apple-darwin/lib", "$(SRCROOT)/../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); - ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; PRODUCT_NAME = "mediastream-tester"; PROVISIONING_PROFILE = ""; @@ -3212,13 +3233,11 @@ "$(SRCROOT)/externals/speex", ); INFOPLIST_FILE = "$(SRCROOT)/linphone/mediastreamer2/tools/ios/mediastream-tester-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.1; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/../liblinphone-sdk/apple-darwin/lib", "$(SRCROOT)/../liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins", ); - ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; PRODUCT_NAME = "mediastream-tester"; PROVISIONING_PROFILE = ""; diff --git a/submodules/liblinphone.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/submodules/liblinphone.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..163a8192b --- /dev/null +++ b/submodules/liblinphone.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/submodules/liblinphone.xcodeproj/project.xcworkspace/xcshareddata/liblinphone.xccheckout b/submodules/liblinphone.xcodeproj/project.xcworkspace/xcshareddata/liblinphone.xccheckout new file mode 100644 index 000000000..6d49aa287 --- /dev/null +++ b/submodules/liblinphone.xcodeproj/project.xcworkspace/xcshareddata/liblinphone.xccheckout @@ -0,0 +1,53 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 9A1D1003-FB23-4CFA-98EE-023D9D0776DB + IDESourceControlProjectName + liblinphone + IDESourceControlProjectOriginsDictionary + + 0D7533C70B3E77874DB4DC9E2131A9B1895C2C86 + git.linphone.org:linphone-iphone.git + B9A509D4F3D25560F565CB53A09A75E2140C5232 + git://git.linphone.org/mediastreamer2.git + + IDESourceControlProjectPath + submodules/liblinphone.xcodeproj + IDESourceControlProjectRelativeInstallPathDictionary + + 0D7533C70B3E77874DB4DC9E2131A9B1895C2C86 + ../../.. + B9A509D4F3D25560F565CB53A09A75E2140C5232 + ../../..submodules/linphone/mediastreamer2 + + IDESourceControlProjectURL + git.linphone.org:linphone-iphone.git + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + 0D7533C70B3E77874DB4DC9E2131A9B1895C2C86 + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + 0D7533C70B3E77874DB4DC9E2131A9B1895C2C86 + IDESourceControlWCCName + linphone-iphone + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + B9A509D4F3D25560F565CB53A09A75E2140C5232 + IDESourceControlWCCName + mediastreamer2 + + + + diff --git a/submodules/linphone b/submodules/linphone index 2c7b9f2cf..0d2723fae 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 2c7b9f2cf256baaa7905eb2825c5db5fd19bb149 +Subproject commit 0d2723fae84f812c8d8bb7daaee9b91ca57958b5 diff --git a/submodules/mediastream-tester Tests/DTObjectBlockExecutor.m b/submodules/mediastream-tester Tests/DTObjectBlockExecutor.m deleted file mode 100644 index 4e9dfd0fd..000000000 --- a/submodules/mediastream-tester Tests/DTObjectBlockExecutor.m +++ /dev/null @@ -1,30 +0,0 @@ -// -// DTObjectBlockExecutor.m -// DTFoundation -// -// Created by Oliver Drobnik on 12.02.13. -// Copyright (c) 2013 Cocoanetics. All rights reserved. -// - -#import "DTObjectBlockExecutor.h" - - -@implementation DTObjectBlockExecutor - -+ (id)blockExecutorWithDeallocBlock:(void(^)())block -{ - DTObjectBlockExecutor *executor = [[DTObjectBlockExecutor alloc] init]; - executor.deallocBlock = block; // copy - return executor; -} - -- (void)dealloc -{ - if (_deallocBlock) - { - _deallocBlock(); - _deallocBlock = nil; - } -} - -@end diff --git a/submodules/mediastream-tester Tests/NSObject+DTRuntime.m b/submodules/mediastream-tester Tests/NSObject+DTRuntime.m deleted file mode 100644 index 54e69ec07..000000000 --- a/submodules/mediastream-tester Tests/NSObject+DTRuntime.m +++ /dev/null @@ -1,101 +0,0 @@ -// -// NSObject_DTRuntime.h -// DTFoundation -// -// Created by Oliver Drobnik on 4/25/12. -// Copyright (c) 2012 Cocoanetics. All rights reserved. -// - -#import -#import "DTObjectBlockExecutor.h" - -@implementation NSObject (DTRuntime) - -static char DTRuntimeDeallocBlocks; - -#pragma mark - Blocks - -- (void)addDeallocBlock:(void(^)())block -{ - // don't accept NULL block - NSParameterAssert(block); - - NSMutableArray *deallocBlocks = objc_getAssociatedObject(self, &DTRuntimeDeallocBlocks); - - // add array of dealloc blocks if not existing yet - if (!deallocBlocks) - { - deallocBlocks = [[NSMutableArray alloc] init]; - - objc_setAssociatedObject(self, &DTRuntimeDeallocBlocks, deallocBlocks, OBJC_ASSOCIATION_RETAIN); - } - - DTObjectBlockExecutor *executor = [DTObjectBlockExecutor blockExecutorWithDeallocBlock:block]; - - [deallocBlocks addObject:executor]; -} - -+ (BOOL)addInstanceMethodWithSelectorName:(NSString *)selectorName block:(void(^)(id))block -{ - // don't accept nil name - NSParameterAssert(selectorName); - - // don't accept NULL block - NSParameterAssert(block); - - // See http://stackoverflow.com/questions/6357663/casting-a-block-to-a-void-for-dynamic-class-method-resolution - -#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_7 - void *impBlockForIMP = (void *)objc_unretainedPointer(block); -#else - id impBlockForIMP = (__bridge id)objc_unretainedPointer(block); -#endif - - IMP myIMP = imp_implementationWithBlock(impBlockForIMP); - - SEL selector = NSSelectorFromString(selectorName); - return class_addMethod(self, selector, myIMP, "v@:"); -} - -#pragma mark - Method Swizzling - -+ (void)swizzleMethod:(SEL)selector withMethod:(SEL)otherSelector -{ - // my own class is being targetted - Class c = [self class]; - - // get the methods from the selectors - Method originalMethod = class_getInstanceMethod(c, selector); - Method otherMethod = class_getInstanceMethod(c, otherSelector); - - if (class_addMethod(c, selector, method_getImplementation(otherMethod), method_getTypeEncoding(otherMethod))) - { - class_replaceMethod(c, otherSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); - } - else - { - method_exchangeImplementations(originalMethod, otherMethod); - } -} - -+ (void)swizzleClassMethod:(SEL)selector withMethod:(SEL)otherSelector -{ - // my own class is being targetted - Class c = [self class]; - - // get the methods from the selectors - Method originalMethod = class_getClassMethod(c, selector); - Method otherMethod = class_getClassMethod(c, otherSelector); - -// if (class_addMethod(c, selector, method_getImplementation(otherMethod), method_getTypeEncoding(otherMethod))) -// { -// class_replaceMethod(c, otherSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); -// } -// else -// { - method_exchangeImplementations(originalMethod, otherMethod); -// } - -} - -@end diff --git a/submodules/mediastream-tester Tests/mediastream_tester_Tests.m b/submodules/mediastream-tester Tests/mediastream_tester_Tests.m deleted file mode 100644 index 53c7f5322..000000000 --- a/submodules/mediastream-tester Tests/mediastream_tester_Tests.m +++ /dev/null @@ -1,96 +0,0 @@ -// -// mediastream_tester_Tests.m -// mediastream-tester Tests -// -// Created by guillaume on 21/11/2014. -// -// - -#import -#import -#import "NSObject+DTRuntime.h" - -#include "mediastreamer2_tester.h" - -@interface mediastream_tester_Tests : XCTestCase -@property (nonatomic,retain) NSString* bundlePath; -@property (nonatomic,retain) NSString* documentPath; -@property (nonatomic,retain) NSString* staticImagePath; -@end - -@implementation mediastream_tester_Tests - -+ (NSArray*)skippedSuites { - NSArray* skipped_suites = @[]; - return skipped_suites; -} - -+ (NSString*)safeifyTestString:(NSString*)testString{ - NSArray* invalidChars= @[@"[", @"]", @" ", @"-", @"."]; - NSString* safeString = testString; - - for (NSString* c in invalidChars) { - safeString = [safeString stringByReplacingOccurrencesOfString:c withString:@"_"]; - } - return safeString; -} - -+ (void)initialize { - mediastreamer2_tester_init(); - ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); - - int count = mediastreamer2_tester_nb_test_suites(); - for (int i=0; i +#import "DTObjectBlockExecutor.h" + +@implementation NSObject (DTRuntime) + +static char DTRuntimeDeallocBlocks; + +#pragma mark - Blocks + +- (void)addDeallocBlock:(void (^)())block { + // don't accept NULL block + NSParameterAssert(block); + + NSMutableArray *deallocBlocks = objc_getAssociatedObject(self, &DTRuntimeDeallocBlocks); + + // add array of dealloc blocks if not existing yet + if (!deallocBlocks) { + deallocBlocks = [[NSMutableArray alloc] init]; + + objc_setAssociatedObject(self, &DTRuntimeDeallocBlocks, deallocBlocks, OBJC_ASSOCIATION_RETAIN); + } + + DTObjectBlockExecutor *executor = [DTObjectBlockExecutor blockExecutorWithDeallocBlock:block]; + + [deallocBlocks addObject:executor]; +} + ++ (BOOL)addInstanceMethodWithSelectorName:(NSString *)selectorName block:(void (^)(id))block { + // don't accept nil name + NSParameterAssert(selectorName); + + // don't accept NULL block + NSParameterAssert(block); + +// See http://stackoverflow.com/questions/6357663/casting-a-block-to-a-void-for-dynamic-class-method-resolution + +#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_7 + void *impBlockForIMP = (void *)objc_unretainedPointer(block); +#else + id impBlockForIMP = (__bridge id)objc_unretainedPointer(block); +#endif + + IMP myIMP = imp_implementationWithBlock(impBlockForIMP); + + SEL selector = NSSelectorFromString(selectorName); + return class_addMethod(self, selector, myIMP, "v@:"); +} + +#pragma mark - Method Swizzling + ++ (void)swizzleMethod:(SEL)selector withMethod:(SEL)otherSelector { + // my own class is being targetted + Class c = [self class]; + + // get the methods from the selectors + Method originalMethod = class_getInstanceMethod(c, selector); + Method otherMethod = class_getInstanceMethod(c, otherSelector); + + if (class_addMethod(c, selector, method_getImplementation(otherMethod), method_getTypeEncoding(otherMethod))) { + class_replaceMethod(c, otherSelector, method_getImplementation(originalMethod), + method_getTypeEncoding(originalMethod)); + } else { + method_exchangeImplementations(originalMethod, otherMethod); + } +} + ++ (void)swizzleClassMethod:(SEL)selector withMethod:(SEL)otherSelector { + // my own class is being targetted + Class c = [self class]; + + // get the methods from the selectors + Method originalMethod = class_getClassMethod(c, selector); + Method otherMethod = class_getClassMethod(c, otherSelector); + + // if (class_addMethod(c, selector, method_getImplementation(otherMethod), method_getTypeEncoding(otherMethod))) + // { + // class_replaceMethod(c, otherSelector, method_getImplementation(originalMethod), + // method_getTypeEncoding(originalMethod)); + // } + // else + // { + method_exchangeImplementations(originalMethod, otherMethod); + // } +} + +@end diff --git a/submodules/mediastream-testerTests/mediastream_tester_Tests.m b/submodules/mediastream-testerTests/mediastream_tester_Tests.m new file mode 100644 index 000000000..f6883a56f --- /dev/null +++ b/submodules/mediastream-testerTests/mediastream_tester_Tests.m @@ -0,0 +1,107 @@ +// +// mediastream_tester_Tests.m +// mediastream-tester Tests +// +// Created by guillaume on 21/11/2014. +// +// + +#import +#import +#include "ortp.h" +#import "NSObject+DTRuntime.h" + +#include "mediastreamer2_tester.h" + +@interface mediastream_tester_Tests : XCTestCase +@property(nonatomic, retain) NSString *bundlePath; +@property(nonatomic, retain) NSString *documentPath; +@property(nonatomic, retain) NSString *staticImagePath; +@end + +@implementation mediastream_tester_Tests + ++ (NSArray *)skippedSuites { + NSArray *skipped_suites = @[]; + return skipped_suites; +} + ++ (NSString *)safeifyTestString:(NSString *)testString { + NSArray *invalidChars = @[ @"[", @"]", @" ", @"-", @"." ]; + NSString *safeString = testString; + + for (NSString *c in invalidChars) { + safeString = [safeString stringByReplacingOccurrencesOfString:c withString:@"_"]; + } + return safeString; +} + +static void log_handler(int lev, const char *fmt, va_list args) { + va_list cap; + va_copy(cap, args); + /* Otherwise, we must use stdio to avoid log formatting (for autocompletion etc.) */ + vfprintf(lev == ORTP_ERROR ? stderr : stdout, fmt, cap); + fprintf(lev == ORTP_ERROR ? stderr : stdout, "\n"); + va_end(cap); +} + ++ (void)initialize { + bc_tester_init(log_handler, ORTP_MESSAGE, ORTP_ERROR); + ortp_set_log_level_mask(ORTP_MESSAGE | ORTP_WARNING | ORTP_ERROR | ORTP_FATAL); + + int count = bc_tester_nb_suites(); + for (int i = 0; i < count; i++) { + const char *suite = bc_tester_suite_name(i); + + int test_count = bc_tester_nb_tests(suite); + for (int k = 0; k < test_count; k++) { + const char *test = bc_tester_test_name(suite, k); + NSString *sSuite = [NSString stringWithUTF8String:suite]; + NSString *sTest = [NSString stringWithUTF8String:test]; + + if ([[mediastream_tester_Tests skippedSuites] containsObject:sSuite]) + continue; + + // prepend test_ so that it gets found by introspection + NSString *safesTest = [self safeifyTestString:sTest]; + NSString *safesSuite = [self safeifyTestString:sSuite]; + NSString *selectorName = [NSString stringWithFormat:@"test_%@__%@", safesSuite, safesTest]; + NSLog(@"Adding test: %@", selectorName); + [mediastream_tester_Tests addInstanceMethodWithSelectorName:selectorName + block:^(mediastream_tester_Tests *myself) { + [myself testForSuite:sSuite andTest:sTest]; + }]; + } + } +} + +- (void)setUp { + [super setUp]; + self.bundlePath = [[NSBundle mainBundle] bundlePath]; + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + self.documentPath = [paths objectAtIndex:0]; + self.staticImagePath = [[self.bundlePath stringByAppendingString:@"/"] stringByAppendingString:@"nowebcamCIF.jpg"]; + + NSLog(@"Bundle path: %@", self.bundlePath); + NSLog(@"Document path: %@", self.documentPath); + + bc_tester_writable_dir_prefix = [self.documentPath UTF8String]; + bc_tester_read_dir_prefix = [self.bundlePath UTF8String]; + + ms_static_image_set_default_image([self.staticImagePath UTF8String]); + + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testForSuite:(NSString *)suite andTest:(NSString *)test { + NSLog(@"Launching test %@ from suite %@", test, suite); + XCTAssertFalse(bc_tester_run_tests([suite UTF8String], [test UTF8String]), @"Suite '%@' / Test '%@' failed", suite, + test); +} + +@end diff --git a/submodules/msamr b/submodules/msamr index eb17e35a2..e56ef9f86 160000 --- a/submodules/msamr +++ b/submodules/msamr @@ -1 +1 @@ -Subproject commit eb17e35a22301db309b51bd9d458fb00972bd4c3 +Subproject commit e56ef9f86989bafa9a0e808ed4b34c2264c6e10d diff --git a/submodules/msilbc b/submodules/msilbc deleted file mode 160000 index afe533687..000000000 --- a/submodules/msilbc +++ /dev/null @@ -1 +0,0 @@ -Subproject commit afe5336871be478f54e794d4f649e2c1f18dcaff diff --git a/submodules/msopenh264 b/submodules/msopenh264 index 6c2cf04b5..78ed115b5 160000 --- a/submodules/msopenh264 +++ b/submodules/msopenh264 @@ -1 +1 @@ -Subproject commit 6c2cf04b56b226be7bbc4f0ebe47fe937806ac73 +Subproject commit 78ed115b583ee43473f982d370d85d2f86754dac diff --git a/submodules/mssilk b/submodules/mssilk index dcb4798df..49306ca45 160000 --- a/submodules/mssilk +++ b/submodules/mssilk @@ -1 +1 @@ -Subproject commit dcb4798df328186b3d177d10af5145aafed8352e +Subproject commit 49306ca4566480e08a0b64f1323bfc9f354d41bf diff --git a/submodules/mswebrtc b/submodules/mswebrtc index 5a55409dd..5787ddda7 160000 --- a/submodules/mswebrtc +++ b/submodules/mswebrtc @@ -1 +1 @@ -Subproject commit 5a55409ddce8bc35163662231dae475488dfce75 +Subproject commit 5787ddda77a8292898670ab8bd3d48e6e51ccfaa diff --git a/submodules/msx264 b/submodules/msx264 index 05b55211c..2e9b11b82 160000 --- a/submodules/msx264 +++ b/submodules/msx264 @@ -1 +1 @@ -Subproject commit 05b55211c6fe7eebef485a00a60c66cbe1394907 +Subproject commit 2e9b11b8255a305adcc8e94ff3f77b6a2c08418e