diff --git a/.gitlab-ci-files/job-linux-desktop-archlinux-latest.yml b/.gitlab-ci-files/job-linux-desktop-archlinux-latest.yml new file mode 100644 index 000000000..32983798e --- /dev/null +++ b/.gitlab-ci-files/job-linux-desktop-archlinux-latest.yml @@ -0,0 +1,80 @@ + +job-archlinux-latest-makefile-gcc: + + tags: [ "docker-archlinux-latest" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-archlinux:latest + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Unix Makefiles + CC: gcc + CXX: g++ + extends: .job-linux-desktop + + +job-archlinux-latest-makefile-clang: + + tags: [ "docker-archlinux-latest" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-archlinux:latest + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Unix Makefiles + CC: clang + CXX: clang++ + extends: .job-linux-desktop + + +################################################# +# Ninja +################################################# + + +job-archlinux-latest-ninja-gcc: + + tags: [ "docker-archlinux-latest" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-archlinux:latest + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Ninja + CC: gcc + CXX: g++ + extends: .job-linux-desktop + + +job-archlinux-latest-ninja-gcc-novideo: + + tags: [ "docker-archlinux-latest" ] + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_OPTIONS: -DENABLE_VIDEO=NO + extends: job-archlinux-latest-ninja-gcc + + +job-archlinux-latest-ninja-clang: + + tags: [ "docker-archlinux-latest" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-archlinux:latest + variables: + CMAKE_GENERATOR: Ninja + CC: clang + CXX: clang++ + extends: .job-linux-desktop + + +job-archlinux-latest-ninja-clang-novideo: + + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_OPTIONS: -DENABLE_VIDEO=NO + extends: job-archlinux-latest-ninja-clang + + diff --git a/.gitlab-ci-files/job-linux-desktop-centos7.yml b/.gitlab-ci-files/job-linux-desktop-centos7.yml new file mode 100644 index 000000000..ac2916a3f --- /dev/null +++ b/.gitlab-ci-files/job-linux-desktop-centos7.yml @@ -0,0 +1,80 @@ +job-centos7-makefile-gcc: + + tags: [ "docker-centos7" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-centos:7 + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Unix Makefiles + CC: gcc + CXX: g++ + extends: .job-linux-desktop + + +job-centos7-makefile-clang: + + tags: [ "docker-centos7" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-centos:7 + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Unix Makefiles + CC: clang + CXX: clang++ + extends: .job-linux-desktop + + +################################################# +# Ninja +################################################# + + +job-centos7-ninja-gcc: + + tags: [ "docker-centos7" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-centos:7 + variables: + CMAKE_GENERATOR: Ninja + CC: gcc + CXX: g++ + extends: .job-linux-desktop + + +job-centos7-ninja-gcc-novideo: + + tags: [ "docker-centos7" ] + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_OPTIONS: -DENABLE_VIDEO=NO + extends: job-centos7-ninja-gcc + + +job-centos7-ninja-clang: + + tags: [ "docker-centos7" ] + only: + variables: + - $NIGHTLY_MASTER + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-centos:7 + variables: + CMAKE_GENERATOR: Ninja + CC: clang + CXX: clang++ + CMAKE_OPTIONS: -DENABLE_LIME=ON + extends: .job-linux-desktop + + +job-centos7-ninja-clang-novideo: + + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_OPTIONS: -DENABLE_VIDEO=NO + extends: job-centos7-ninja-clang + + diff --git a/.gitlab-ci-files/job-linux-desktop-debian10.yml b/.gitlab-ci-files/job-linux-desktop-debian10.yml new file mode 100644 index 000000000..c5a6dad4d --- /dev/null +++ b/.gitlab-ci-files/job-linux-desktop-debian10.yml @@ -0,0 +1,100 @@ +################################################# +# Makefile +################################################# + + +job-debian10-makefile-gcc: + + tags: [ "docker-debian10" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:10 + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Unix Makefiles + CC: gcc + CXX: g++ + ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS + extends: .job-linux-desktop + + +job-debian10-makefile-clang: + + tags: [ "docker-debian10" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:10 + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Unix Makefiles + CC: clang + CXX: clang++ + ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS + extends: .job-linux-desktop + + +################################################# +# Ninja +################################################# + + +job-debian10-ninja-gcc: + + tags: [ "docker-debian10" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:10 + variables: + CMAKE_GENERATOR: Ninja + CC: gcc + CXX: g++ + extends: .job-linux-desktop + + +job-debian10-ninja-gcc-novideo: + + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_OPTIONS: -DENABLE_VIDEO=NO + extends: job-debian10-ninja-gcc + + +job-debian10-ninja-gcc-smallsdk: + + only: + variables: + - $NIGHTLY_MASTER + + variables: + CMAKE_OPTIONS: -DENABLE_VIDEO=NO -DENABLE_ADVANCED_IM=NO -DENABLE_DB_STORAGE=NO + extends: job-debian10-ninja-gcc + + +job-debian10-ninja-clang: + + tags: [ "docker-debian10" ] + only: + variables: + - $NIGHTLY_MASTER + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:10 + variables: + CMAKE_OPTIONS: -DENABLE_DOC=ON + CMAKE_GENERATOR: Ninja + CC: clang + CXX: clang++ + extends: .job-linux-desktop + + +job-debian10-ninja-clang-novideo: + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_OPTIONS: -DENABLE_VIDEO=NO + extends: job-debian10-ninja-clang + +################################################# +# TESTS +################################################# + + diff --git a/.gitlab-ci-files/job-linux-desktop-debian8.yml b/.gitlab-ci-files/job-linux-desktop-debian8.yml new file mode 100644 index 000000000..b4419a0f3 --- /dev/null +++ b/.gitlab-ci-files/job-linux-desktop-debian8.yml @@ -0,0 +1,57 @@ +################################################# +# Makefile +################################################# + + +job-debian8-makefile-gcc: + + tags: [ "docker-debian8" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:8 + variables: + CMAKE_GENERATOR: Unix Makefiles + CC: gcc + CXX: g++ + ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS + LBC_NODEBUG_OPTIONS: -- -j$MAKEFILE_JOBS + extends: .job-linux-desktop + + +job-debian8-makefile-clang: + + tags: [ "docker-debian8" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:8 + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Unix Makefiles + CC: clang + CXX: clang++ + ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS + LBC_NODEBUG_OPTIONS: -- -j$MAKEFILE_JOBS + extends: .job-linux-desktop + +################################################# +# Ninja +################################################# + +#job-debian8-ninja-gcc: +# +# tags: [ "docker-debian8" ] +# image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:8 +# variables: +# CMAKE_GENERATOR: Ninja +# CC: gcc +# CXX: g++ +# extends: .job-linux-desktop + + +#job-debian8-ninja-clang: +# +# tags: [ "docker-debian8" ] +# image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:8 +# variables: +# CMAKE_GENERATOR: Ninja +# CC: clang +# CXX: clang++ +# extends: .job-linux-desktop diff --git a/.gitlab-ci-files/job-linux-desktop-debian9.yml b/.gitlab-ci-files/job-linux-desktop-debian9.yml new file mode 100644 index 000000000..d31676749 --- /dev/null +++ b/.gitlab-ci-files/job-linux-desktop-debian9.yml @@ -0,0 +1,87 @@ + +job-debian9-makefile-gcc: + + tags: [ "docker-debian9" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:9 + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Unix Makefiles + CC: gcc + CXX: g++ + ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS + extends: .job-linux-desktop + + +job-debian9-makefile-clang: + + tags: [ "docker-debian9" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:9 + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Unix Makefiles + CC: clang + CXX: clang++ + ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS + extends: .job-linux-desktop + + +################################################# +# Ninja +################################################# + + +job-debian9-ninja-gcc: + + tags: [ "docker-debian9" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:9 + variables: + CMAKE_GENERATOR: Ninja + CC: gcc + CXX: g++ + extends: .job-linux-desktop + + +job-debian9-ninja-gcc-novideo: + + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_OPTIONS: -DENABLE_VIDEO=NO + extends: job-debian9-ninja-gcc + + +job-debian9-ninja-gcc-smallsdk: + + variables: + CMAKE_OPTIONS: -DENABLE_VIDEO=NO -DENABLE_ADVANCED_IM=NO -DENABLE_DB_STORAGE=NO + extends: job-debian9-ninja-gcc + + +job-debian9-ninja-clang: + + tags: [ "docker-debian9" ] + only: + variables: + - $NIGHTLY_MASTER + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:9 + variables: + CMAKE_OPTIONS: -DENABLE_DOC=ON + CMAKE_GENERATOR: Ninja + CC: clang + CXX: clang++ + extends: .job-linux-desktop + + +job-debian9-ninja-clang-novideo: + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_OPTIONS: -DENABLE_VIDEO=NO + extends: job-debian9-ninja-clang + diff --git a/.gitlab-ci-files/job-linux-desktop-ubuntu-rolling.yml b/.gitlab-ci-files/job-linux-desktop-ubuntu-rolling.yml new file mode 100644 index 000000000..3af96dae4 --- /dev/null +++ b/.gitlab-ci-files/job-linux-desktop-ubuntu-rolling.yml @@ -0,0 +1,82 @@ +################################################# +# Makefile +################################################# + + +job-ubuntu-rolling-makefile-gcc: + + tags: [ "docker-ubuntu-rolling" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:rolling + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Unix Makefiles + CC: gcc + CXX: g++ + ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS + extends: .job-linux-desktop + + +job-ubuntu-rolling-makefile-clang: + + tags: [ "docker-ubuntu-rolling" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:rolling + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Unix Makefiles + CC: clang + CXX: clang++ + ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS + extends: .job-linux-desktop + + +################################################# +# Ninja +################################################# + + +job-ubuntu-rolling-ninja-gcc: + + tags: [ "docker-ubuntu-rolling" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:rolling + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Ninja + CC: gcc + CXX: g++ + extends: .job-linux-desktop + + +job-ubuntu-rolling-ninja-gcc-novideo: + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_OPTIONS: -DENABLE_VIDEO=NO + extends: job-ubuntu-rolling-ninja-gcc + + +job-ubuntu-rolling-ninja-clang: + tags: [ "docker-ubuntu-rolling" ] + image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:rolling + variables: + CMAKE_GENERATOR: Ninja + CC: clang + CXX: clang++ + extends: .job-linux-desktop + + +job-ubuntu-rolling-ninja-clang-novideo: + + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_OPTIONS: -DENABLE_VIDEO=NO + extends: job-ubuntu-rolling-ninja-clang + diff --git a/.gitlab-ci-files/job-linux-desktop.yml b/.gitlab-ci-files/job-linux-desktop.yml new file mode 100644 index 000000000..12c37efe9 --- /dev/null +++ b/.gitlab-ci-files/job-linux-desktop.yml @@ -0,0 +1,43 @@ +################################################# +# BUILD +################################################# + +.job-linux-desktop: + + stage: build + extends: .linux-prepare + + script: + - export CC=$CC + - export CXX=$CXX + - mkdir -p build-desktop/OUTPUT + - export + - echo $CMAKE_GENERATOR + - echo $DEFAULT_LINUX_CMAKE_OPTIONS + - echo $CMAKE_OPTIONS + - echo $CMAKE_SANITIZER_OPTIONS +# SDK Building + - mkdir -p linphone-sdk/build-sdk + - cd linphone-sdk/build-sdk + - cmake .. -G "$CMAKE_GENERATOR" -DLINPHONESDK_PLATFORM=Desktop $DEFAULT_LINUX_CMAKE_OPTIONS $CMAKE_OPTIONS $SCHEDULE_CMAKE_OPTIONS $CMAKE_SANITIZER_OPTIONS + - cmake --build . --target sdk $LBC_NODEBUG_OPTIONS + - cd ../../submodules/externals/minizip +# Minizip submodule Building + - mkdir -p build-minizip + - cd build-minizip + - cmake .. -G "$CMAKE_GENERATOR" $DEFAULT_LINUX_CMAKE_OPTIONS $CMAKE_OPTIONS $SCHEDULE_CMAKE_OPTIONS $CMAKE_SANITIZER_OPTIONS -DCMAKE_INSTALL_PREFIX=OUTPUT -DCMAKE_PREFIX_PATH="../../../linphone-sdk/build-sdk/linphone-sdk/desktop" + - cmake --build . --target all $LBC_NODEBUG_OPTIONS + - cmake --build . --target install +# Desktop Building + - cd ../../../../build-desktop + - cmake .. -G "$CMAKE_GENERATOR" $DEFAULT_LINUX_CMAKE_OPTIONS $CMAKE_OPTIONS $SCHEDULE_CMAKE_OPTIONS $CMAKE_SANITIZER_OPTIONS -DCMAKE_INSTALL_PREFIX=OUTPUT -DCMAKE_PREFIX_PATH="linphone-sdk/build-sdk/linphone-sdk/desktop;submodules/externals/minizip/build-minizip/OUTPUT" + - cmake --build . --target all -- $ADDITIONAL_BUILD_OPTIONS + - cmake --build . --target install -- $ADDITIONAL_BUILD_OPTIONS + + artifacts: + paths: + - build-desktop/OUTPUT + - linphone-sdk/build-sdk/linphone-sdk/desktop + - submodules/externals/minizip/build-minizip/OUTPUT + expire_in: 1 week + diff --git a/.gitlab-ci-files/job-linux-prepare.yml b/.gitlab-ci-files/job-linux-prepare.yml new file mode 100644 index 000000000..932b0ff8d --- /dev/null +++ b/.gitlab-ci-files/job-linux-prepare.yml @@ -0,0 +1,34 @@ +.linux-prepare: + + cache: + key: $CI_JOB_NAME + paths: + - ccache/ + + extends: .job-prepare + + before_script: + ## + ## If a TUNNEL_USER_KEY is defined then start ssh-agent and add the key + ## + - if ! [ -z ${TUNNEL_USER_KEY+x} ]; then eval $(ssh-agent -s); fi + - if ! [ -z ${TUNNEL_USER_KEY+x} ]; then echo "$TUNNEL_USER_KEY" | tr -d '\r' | ssh-add - > /dev/null; fi + - if ! [ -z ${TUNNEL_USER_KEY+x} ]; then mkdir -p ~/.ssh && chmod 700 ~/.ssh; fi + - if ! [ -z ${TUNNEL_USER_KEY+x} ]; then echo -e "Host gitlab.linphone.org\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config; fi + + ## + ## Then configure ccache + ## + - mkdir -p ccache + - echo "max_size = $CCACHE_SIZE" > ccache/ccache.conf + - echo $CCACHE_SIZE + - echo ${PWD}/ccache + - export CCACHE_BASEDIR=${PWD} + - export CCACHE_DIR=${PWD}/ccache + - ccache -s + + after_script: + - if ! [ -z ${TUNNEL_USER_KEY+x} ]; then rm -rf ~/.ssh || true; fi + - export CCACHE_DIR=${PWD}/ccache + - ccache -s + diff --git a/.gitlab-ci-files/job-macosx-desktop.yml b/.gitlab-ci-files/job-macosx-desktop.yml new file mode 100644 index 000000000..3c8054cd0 --- /dev/null +++ b/.gitlab-ci-files/job-macosx-desktop.yml @@ -0,0 +1,105 @@ + +.job-macosx-desktop: + + stage: build + + tags: [ "macosx" ] + + script: + - ccache -s + - export Qt5_DIR=/usr/local/opt/qt/lib/cmake + - export PATH=$PATH:/usr/local/opt/qt/bin + - if [ -d "build-desktop" ]; then rm -rf build-desktop; fi; + - mkdir -p build-desktop/OUTPUT + - cd linphone-sdk +#SDK Building + - if [ -d "build-sdk" ]; then rm -rf build-sdk; fi; + - mkdir -p build-sdk + - cd build-sdk + - echo $CMAKE_GENERATOR + - echo $DEFAULT_MACOS_CMAKE_OPTIONS + - echo $CMAKE_OPTIONS + - echo $ADDITIONAL_BUILD_OPTIONS + - cmake .. -G "$CMAKE_GENERATOR" -DLINPHONESDK_PLATFORM=Desktop $DEFAULT_MACOS_CMAKE_OPTIONS $XCODE_OPTIONS $CMAKE_OPTIONS + - cmake --build . $LBC_NODEBUG_OPTIONS + - cd ../../submodules/externals/minizip +# Minizip submodule Building + - if [ -d "build-minizip" ]; then rm -rf build-minizip; fi; + - mkdir -p build-minizip + - cd build-minizip + - cmake .. -G "$CMAKE_GENERATOR" $DEFAULT_MACOS_CMAKE_OPTIONS $XCODE_OPTIONS $CMAKE_OPTIONS -DCMAKE_INSTALL_PREFIX=OUTPUT -DCMAKE_PREFIX_PATH="../../../linphone-sdk/build-sdk/linphone-sdk/desktop" + - cmake --build . --target all $LBC_NODEBUG_OPTIONS + - cmake --build . --target install +# Desktop Building + - cd ../../../../build-desktop + - cmake .. -G "$CMAKE_GENERATOR" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 $DEFAULT_MACOS_CMAKE_OPTIONS $XCODE_OPTIONS $CMAKE_OPTIONS -DCMAKE_INSTALL_PREFIX=OUTPUT -DCMAKE_PREFIX_PATH="linphone-sdk/build-sdk/linphone-sdk/desktop;submodules/externals/minizip/build-minizip/OUTPUT" + - cmake --build . --target all -- $ADDITIONAL_BUILD_OPTIONS +# - codesign --verbose -s "$MACOS_SIGNING_IDENTITY" WORK/desktop/Build/linphone_package/Linphone-*.dmg +# - cmake --build . --target install -- $ADDITIONAL_BUILD_OPTIONS + - ccache -s + + artifacts: + paths: + - build-desktop/OUTPUT + - linphone-sdk/build-sdk/linphone-sdk/desktop + - submodules/externals/minizip/build-minizip/OUTPUT + expire_in: 1 week + + + +################################################# +# Makefile +################################################# + + +job-macosx-makefile: + + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_GENERATOR: Unix Makefiles + ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS + extends: .job-macosx-desktop + + +################################################# +# Ninja +################################################# + + +job-macosx-ninja: + + variables: + CMAKE_GENERATOR: Ninja + CMAKE_OPTIONS: -DENABLE_UNIT_TESTS=ON + extends: .job-macosx-desktop + + +job-macosx-ninja-novideo: + + only: + variables: + - $NIGHTLY_MASTER + variables: + CMAKE_OPTIONS: -DENABLE_VIDEO=NO + extends: job-macosx-ninja + + +################################################# +# XCode +################################################# + + +job-macosx-xcode: + extends: .job-macosx-desktop + variables: + XCODE_OPTIONS: -DLINPHONESDK_MACOS_BASE_URL=$MACOS_SNAPSHOTS_URL + CMAKE_GENERATOR: Xcode + ADDITIONAL_BUILD_OPTIONS: -IDEBuildOperationMaxNumberOfConcurrentCompileTasks=$MAX_NUMBER_TASK + + only: + variables: + - $NIGHTLY_MASTER + - $DEPLOY_RUN_MACOSX + diff --git a/.gitlab-ci-files/job-windows-desktop.yml b/.gitlab-ci-files/job-windows-desktop.yml new file mode 100644 index 000000000..f984a2c00 --- /dev/null +++ b/.gitlab-ci-files/job-windows-desktop.yml @@ -0,0 +1,174 @@ +################################################# +# BUILD +################################################# + + + +################################################# +# VS2015 +################################################# +#Wedo not need vs2015 anymore + +#job-windows-vs2015: +# +# extends: .job-prepare +# stage: build +# tags: [ "windows" ] +# except: +# refs: +# - feature/peioMergeCi +# +# except: +# variables: +# - $DEPLOY_RUN_ANDROID +# - $DEPLOY_RUN_IOS +# variables: +# CMAKE_OPTIONS: -DENABLE_LIME_X3DH=NO +# +# script: +# - mkdir build-desktop +# - cd build-desktop +# - cmake .. -G "Visual Studio 14 2015" -DLINPHONESDK_PLATFORM=Desktop -DCMAKE_BUILD_TYPE=Release %DEFAULT_CMAKE_OPTIONS% %CMAKE_OPTIONS% +# - cmake --build . --target sdk --config Release -- /maxcpucount + +#job-windows-vs2015-novideo: +# +# only: +# - schedules +# except: +# variables: +# - $DEPLOY_RUN_ANDROID +# - $FAST_LINUX_TESTS +# variables: +# CMAKE_OPTIONS: -DENABLE_VIDEO=NO +# extends: job-windows-vs2015 + +.job-windows-vs2017: + extends: .job-prepare + stage: build + tags: [ "windows" ] + + variables: + CMAKE_OPTIONS: -DENABLE_LIME_X3DH=NO -DENABLE_UNIT_TESTS=ON + + script: + - SET Qt5_DIR=C:\Qt\5.12.6\msvc2017\lib\cmake + - IF EXIST build-desktop RMDIR /S /Q build-desktop + - mkdir build-desktop + - cd build-desktop + - mkdir OUTPUT +#SDK Building + - cd ../linphone-sdk + #handling the case of previous job cancellation + - IF EXIST build-sdkdesktop RMDIR /S /Q build-sdkdesktop + - mkdir build-sdk + - cd build-sdk + #we launch the msvc-cl wrapper located in python scripts folder + #this wrapper relays only needed calls to the real compiler + #cache stats display + - C:\PROGRA~1\Python37\Scripts\cl -s + - cmake .. -G "Visual Studio 15 2017" -DLINPHONESDK_PLATFORM=Desktop -DENABLE_CSHARP_WRAPPER=YES -DCMAKE_BUILD_TYPE=Release %DEFAULT_WINDOWS_CMAKE_OPTIONS% %CMAKE_OPTIONS% + - cmake --build . --target sdk --config Release %LBC_NODEBUG_OPTIONS% -- /maxcpucount /nodeReuse:true /p:TrackFileAccess=false + - cd ../../submodules/externals/minizip +# Minizip submodule Building + - IF EXIST build-minizip RMDIR /S /Q build-minizip + - mkdir build-minizip + - cd build-minizip + - cmake .. -G "Visual Studio 15 2017" -DCMAKE_BUILD_TYPE=Release %DEFAULT_WINDOWS_CMAKE_OPTIONS% %CMAKE_OPTIONS% -DCMAKE_INSTALL_PREFIX=OUTPUT -DCMAKE_PREFIX_PATH="../../../linphone-sdk/build-sdk/linphone-sdk/desktop" + - cmake --build . --target all_build --config Release %LBC_NODEBUG_OPTIONS% -- /maxcpucount /nodeReuse:true /p:TrackFileAccess=false + - cmake --build . --target install --config Release %LBC_NODEBUG_OPTIONS% -- /maxcpucount /nodeReuse:true /p:TrackFileAccess=false +# Desktop Building + - cd ../../../../build-desktop + - cmake .. -G "Visual Studio 15 2017" -DENABLE_CSHARP_WRAPPER=YES -DCMAKE_BUILD_TYPE=Release %DEFAULT_WINDOWS_CMAKE_OPTIONS% %CMAKE_OPTIONS% -DCMAKE_INSTALL_PREFIX=OUTPUT -DCMAKE_PREFIX_PATH="linphone-sdk/build-sdk/linphone-sdk/desktop;submodules/externals/minizip/build-minizip/OUTPUT" + - cmake --build . --target all_build --config Release -- /maxcpucount /nodeReuse:true /p:TrackFileAccess=false + - cmake --build . --target install --config Release -- /maxcpucount /nodeReuse:true /p:TrackFileAccess=false + - C:\PROGRA~1\Python37\Scripts\cl -s + + artifacts: + paths: + - build-desktop\OUTPUT + - linphone-sdk\build-sdk\linphone-sdk\desktop + - submodules\externals\minizip\build-minizip\OUTPUT + expire_in: 1 week + +.job-windows-vs2017-scheduled: + extends: .job-windows-vs2017 + + only: + variables: + - $NIGHTLY_MASTER + - $NIGHTLY_RELEASE + - $PACKAGE_RUN_WINDOWS + before_script: + #cache disabled on scheduled builds since we dot not need the fastest build + - set "CLCACHE_DISABLE=1" + + +job-windows-vs2017: + extends: .job-windows-vs2017 + except: + refs: + - schedules + +job-windows-vs2017-scheduled: + extends: .job-windows-vs2017-scheduled + +job-windows-vs2017-novideo: + extends: .job-windows-vs2017-scheduled + variables: + CMAKE_OPTIONS: -DENABLE_LIME_X3DH=NO -DENABLE_VIDEO=NO + +################################################# +# PACKAGE +################################################# + +#Remove . when packaging process is ready to use +.job-windows-vs2017-package: + stage: package + tags: [ "windows" ] + dependencies: + - job-windows-vs2017-scheduled + only: + variables: + - $NIGHTLY_MASTER + - $PACKAGE_RUN_WINDOWS + + script: + - cd build-desktop/OUTPUT + - IF EXIST deploy RMDIR /S /Q deploy + - mkdir deploy + - copy bin\linphone.exe deploy /Y + - xcopy ..\..\linphone-sdk\build-sdk\linphone-sdk\desktop\bin\*.dll deploy /C /Y + - xcopy ..\..\submodules\externals\minizip\build-minizip\OUTPUT\bin\*.dll deploy /C /Y + + + - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" + - cd build-desktop + - chdir > chdir_sdk.temp + - set /p OUTPUT_SDK_BUILD= chdir_wrapper.temp + - set /p OUTPUT_WRAPPER_BUILD= describe.temp + - set /p DESCRIBE= ${LINPHONE_LIBRARIES}") +message("LINPHONECXX : ${LINPHONECXX_INCLUDE_DIRS} => ${LINPHONECXX_LIBRARIES}") + set(SOURCES src/app/App.cpp src/app/AppController.cpp @@ -162,6 +162,7 @@ set(SOURCES src/components/timeline/TimelineModel.cpp src/components/url-handlers/UrlHandlers.cpp src/utils/LinphoneUtils.cpp + src/utils/MediastreamerUtils.cpp src/utils/QExifImageHeader.cpp src/utils/Utils.cpp ) @@ -221,6 +222,7 @@ set(HEADERS src/components/timeline/TimelineModel.hpp src/components/url-handlers/UrlHandlers.hpp src/utils/LinphoneUtils.hpp + src/utils/MediastreamerUtils.hpp src/utils/QExifImageHeader.hpp src/utils/Utils.hpp ) @@ -288,7 +290,6 @@ endfunction () # Force absolute paths. PREPEND(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/") PREPEND(HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/") -PREPEND(QRC_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/") # ------------------------------------------------------------------------------ # Compute QML files list. @@ -319,7 +320,7 @@ if (NOT WIN32) check_qml DEPENDS ${QML_SOURCES} COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tools/check_qml_syntax" ) -endif () +endif() execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/tools/private/pre-commit" @@ -343,23 +344,26 @@ find_package(Qt5 COMPONENTS ${QT5_PACKAGES} REQUIRED) find_package(Qt5 COMPONENTS ${QT5_PACKAGES_OPTIONAL} QUIET) if (CMAKE_INSTALL_RPATH) + #Retrieve lib path from a know QT executable get_target_property(LUPDATE_PATH Qt5::lupdate LOCATION) get_filename_component(LUPDATE_PATH "${LUPDATE_PATH}" DIRECTORY) get_filename_component(QT_PATH "${LUPDATE_PATH}/../lib" ABSOLUTE) list(APPEND CMAKE_INSTALL_RPATH "${QT_PATH}") endif () - # Add languages support. add_subdirectory(${LANGUAGES_DIRECTORY}) -list(APPEND QRC_RESOURCES "${CMAKE_CURRENT_BINARY_DIR}/${LANGUAGES_DIRECTORY}/${I18N_FILENAME}") -# Add qrc. (images, qml, translations...) -qt5_add_resources(RESOURCES ${QRC_RESOURCES}) +list(APPEND SOURCES "${CMAKE_CURRENT_BINARY_DIR}/${LANGUAGES_DIRECTORY}/${I18N_FILENAME}") # Build. -add_library(${APP_LIBRARY} OBJECT ${SOURCES} ${HEADERS} ${RESOURCES} ${QML_SOURCES}) +#add_library(${APP_LIBRARY} OBJECT ${SOURCES} ${HEADERS} ${RESOURCES} ${QML_SOURCES}) +add_library(${APP_LIBRARY} OBJECT ${SOURCES} ${HEADERS} ${QML_SOURCES} ${QRC_RESOURCES}) set_property(TARGET ${APP_LIBRARY} PROPERTY POSITION_INDEPENDENT_CODE ON) +#Turn on automatic resources compilation by cmake +#Instead of excplicitely calling qt5_add_resources +set_property(TARGET ${APP_LIBRARY} PROPERTY AUTORCC ON) + bc_git_version(${TARGET_NAME} ${PROJECT_VERSION}) add_dependencies(${APP_LIBRARY} ${TARGET_NAME}-git-version) add_dependencies(${APP_LIBRARY} update_translations) @@ -370,13 +374,9 @@ else () add_executable(${TARGET_NAME} $ ${MAIN_FILE}) endif () -if (NOT WIN32) - add_dependencies(update_translations check_qml) -endif () set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${EXECUTABLE_NAME}") - -set(INCLUDED_DIRECTORIES "${LINPHONECXX_INCLUDE_DIRS}" "${BELCARD_INCLUDE_DIRS}" "${BCTOOLBOX_INCLUDE_DIRS}" "${MEDIASTREAMER2_INCLUDE_DIRS}" "${MINIZIP_INCLUDE_DIRS}") -set(LIBRARIES ${BCTOOLBOX_CORE_LIBRARIES} ${BELCARD_LIBRARIES} ${LINPHONECXX_LIBRARIES} ${MINIZIP_LIBRARIES}) +set(INCLUDED_DIRECTORIES "${LINPHONECXX_INCLUDE_DIRS}" "${LINPHONE_INCLUDE_DIRS}" "${BELCARD_INCLUDE_DIRS}" "${BCTOOLBOX_INCLUDE_DIRS}" "${MEDIASTREAMER2_INCLUDE_DIRS}" "${MINIZIP_INCLUDE_DIRS}") +set(LIBRARIES ${BCTOOLBOX_CORE_LIBRARIES} ${BELCARD_LIBRARIES} ${LINPHONE_LIBRARIES} ${LINPHONECXX_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES} ${ORTP_LIBRARIES} ${MINIZIP_LIBRARIES} ${OPUS_LIBRARIES}) foreach (package ${QT5_PACKAGES}) list(APPEND INCLUDED_DIRECTORIES "${Qt5${package}_INCLUDE_DIRS}") @@ -402,6 +402,7 @@ endforeach () if (APPLE) list(APPEND LIBRARIES "-framework Cocoa -framework IOKit") +# -framework linphone") #This doesn't work yet endif () target_include_directories(${APP_LIBRARY} SYSTEM PRIVATE ${INCLUDED_DIRECTORIES}) @@ -409,6 +410,7 @@ target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${INCLUDED_DIRECTORIES} target_link_libraries(${TARGET_NAME} ${LIBRARIES}) + foreach (target ${TARGET_NAME}) install(TARGETS ${target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} diff --git a/README.md b/README.md index 20f6bc054..be471cf59 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,12 @@ Linphone is a free VoIP and video softphone based on the SIP protocol. ## Getting started +Installing dependencies: + +apt-get install libqt53dcore5:amd64 libqt53dextras5:amd64 libqt53dinput5:amd64 libqt53dlogic5:amd64 libqt53dquick5:amd64 libqt53dquickextras5:amd64 libqt53dquickinput5:amd64 libqt53dquickrender5:amd64 libqt53drender5:amd64 libqt5concurrent5:amd64 libqt5core5a:amd64 libqt5dbus5:amd64 libqt5designer5:amd64 libqt5designercomponents5:amd64 libqt5gui5:amd64 libqt5help5:amd64 libqt5multimedia5:amd64 libqt5multimedia5-plugins:amd64 libqt5multimediawidgets5:amd64 libqt5network5:amd64 libqt5opengl5:amd64 libqt5opengl5-dev:amd64 libqt5positioning5:amd64 libqt5printsupport5:amd64 libqt5qml5:amd64 libqt5quick5:amd64 libqt5quickcontrols2-5:amd64 libqt5quickparticles5:amd64 libqt5quicktemplates2-5:amd64 libqt5quicktest5:amd64 libqt5quickwidgets5:amd64 libqt5script5:amd64 libqt5scripttools5:amd64 libqt5sensors5:amd64 libqt5serialport5:amd64 libqt5sql5:amd64 libqt5sql5-sqlite:amd64 libqt5svg5:amd64 libqt5svg5-dev:amd64 libqt5test5:amd64 libqt5webchannel5:amd64 libqt5webengine-data libqt5webenginecore5:amd64 libqt5webenginewidgets5:amd64 libqt5webkit5:amd64 libqt5widgets5:amd64 libqt5x11extras5:amd64 libqt5xml5:amd64 libqt5xmlpatterns5:amd64 qt5-default:amd64 qt5-doc qt5-gtk-platformtheme:amd64 qt5-qmake:amd64 qt5-qmltooling-plugins:amd64 + + + Here are the general instructions to build linphone for desktop. The specific instructions for each build platform is described just below. 1. Install some build tools: `CMake`, `Python` and `Qt5` (_5.9 or newer_). `C++11` support is required! @@ -68,7 +74,7 @@ Before you install packages with Brew, you may have to change directories permis 3. Open a Windows command line (cmd.exe) in the current directory and run: - python prepare.py -G "Visual Studio 14 2015" -DENABLE_DOC=OFF + python prepare.py -G "Visual Studio 15 2017" -DENABLE_DOC=OFF 4. Run the following command in the root directory of linphone-desktop: diff --git a/assets/images/warning.svg b/assets/images/warning.svg new file mode 100644 index 000000000..57e2692d2 --- /dev/null +++ b/assets/images/warning.svg @@ -0,0 +1,90 @@ + + + + + + image/svg+xml + + chat_error + + + + + + chat_error + Created with Sketch. + + + + + + + + + + + + + diff --git a/assets/languages/CMakeLists.txt b/assets/languages/CMakeLists.txt index 4cc03146b..ee53ddf74 100644 --- a/assets/languages/CMakeLists.txt +++ b/assets/languages/CMakeLists.txt @@ -11,40 +11,75 @@ set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM true) # Build languages resource file. set(TS_FILES) -set(I18N_CONTENT "\n\n \n") -foreach (lang ${LANGUAGES}) - list(APPEND TS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${lang}.ts") +set(QM_FILES) +set(QM_FILES_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}") +set(I18N_CONTENT "\n\n \n") +foreach (lang ${LANGUAGES}) # Note: the below `languages/` path is not the same as the `${LANGUAGES_DIRECTORY}` value. # It's the symbolic path used by the linphone binary in the qrc model. # This path is used in `app.cpp`. set(I18N_CONTENT "${I18N_CONTENT} ${lang}.qm\n") -endforeach () + + list(APPEND TS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${lang}.ts") + list(APPEND TARGET_TS_FILES "${CMAKE_CURRENT_BINARY_DIR}/${lang}.ts") + list(APPEND QM_FILES "${CMAKE_CURRENT_BINARY_DIR}/${lang}.qm") +endforeach() + set(I18N_CONTENT "${I18N_CONTENT} \n\n") file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${I18N_FILENAME}" "${I18N_CONTENT}") -# Create `qm` files from `ts` files. -qt5_create_translation(QM_FILES ${TS_FILES} ${SOURCES} ${HEADERS} ${QML_SOURCES} OPTIONS -no-obsolete) +#Files or directories to inspect for translations references +set(TRANSLATION_SOURCES) +list(APPEND TRANSLATION_SOURCES "${PROJECT_SOURCE_DIR}/src") +list(APPEND TRANSLATION_SOURCES "${PROJECT_SOURCE_DIR}/ui") -# Workaround: Create empty files for some cmake versions. Otherwise, the qm rules can't be used. -foreach (qm ${QM_FILES}) - if (NOT EXISTS "${qm}") - file(GENERATE OUTPUT "${qm}" CONTENT "") - endif () -endforeach () +if (WIN32) + foreach (lang ${LANGUAGES}) + file(READ "${CMAKE_CURRENT_SOURCE_DIR}/${lang}.ts" content) + set(cleanedContent) + string(REPLACE "\r" "" cleanedContent "${content}") + file(WRITE "${CMAKE_CURRENT_SOURCE_DIR}/${lang}.ts" "${cleanedContent}") + endforeach() +endif() -# Update translations. +set(LUPDATE_OPTIONS "-no-obsolete") +set(LRELEASE_OPTIONS "") + +#Clean existing generated file to force re-creation +file(REMOVE ${QM_FILES}) +file(REMOVE ${TARGET_TS_FILES}) + +add_custom_command(OUTPUT ${TARGET_TS_FILES} + COMMAND ${Qt5_LUPDATE_EXECUTABLE} + ARGS ${LUPDATE_OPTIONS} ${TRANSLATION_SOURCES} -ts ${TS_FILES} + COMMAND ${CMAKE_COMMAND} -E copy ${TS_FILES} ${CMAKE_CURRENT_BINARY_DIR} + VERBATIM + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Updating translation source files (ts)..." +) + +add_custom_command(OUTPUT ${QM_FILES} + COMMAND ${Qt5_LRELEASE_EXECUTABLE} + ARGS ${TARGET_TS_FILES} ${LRELEASE_OPTIONS} + DEPENDS ${TARGET_TS_FILES} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + VERBATIM + COMMENT "Creating compiled translation files (qm)..." +) + +#The dependency on custom_command Output is important add_custom_target(update_translations - COMMAND ${CMAKE_COMMAND} "-DLANGUAGES=\"${LANGUAGES}\"" -P "${CMAKE_CURRENT_SOURCE_DIR}/clean_translations.cmake" DEPENDS ${QM_FILES} - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" ) # Remove `*.qm` when `clean` is called. set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${QM_FILES}") -# Command to just remove `.qm` files. -add_custom_target(remove_qm_files - COMMAND ${CMAKE_COMMAND} -E remove ${QM_FILES} -) +# Workaround: Create empty files for some cmake versions. Otherwise, the qm rules can't be used. +# foreach (qm ${QM_FILES}) +# if (NOT EXISTS "${qm}") +# file(GENERATE OUTPUT "${qm}" CONTENT "") +# endif() +# endforeach() diff --git a/assets/languages/clean_translations.cmake b/assets/languages/clean_translations.cmake deleted file mode 100644 index 9ea330505..000000000 --- a/assets/languages/clean_translations.cmake +++ /dev/null @@ -1,12 +0,0 @@ -# ============================================================================== -# assets/languages/clean_translations.cmake -# ============================================================================== - -if (WIN32) - foreach (lang ${LANGUAGES}) - file(READ "${lang}.ts" content) - set(cleanedContent) - string(REPLACE "\r" "" cleanedContent "${content}") - file(WRITE "${lang}.ts" "${cleanedContent}") - endforeach () -endif () diff --git a/assets/languages/de.ts b/assets/languages/de.ts index 2d1e5063b..9dbe9c305 100644 --- a/assets/languages/de.ts +++ b/assets/languages/de.ts @@ -615,6 +615,10 @@ Server URL ist nicht konfiguriert. abortEditDescriptionText Möchten Sie die Änderungen an diesem Kontakt verwerfen? + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ Server URL ist nicht konfiguriert. removeAllEntriesDescription Möchten Sie diese Historie wirklich löschen? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -958,6 +974,10 @@ Server URL ist nicht konfiguriert. smartSearchBarTooltip Verwenden das intelligente Suchfeld um Audio- und Videocalls zu starten, Nachrichten zu senden oder Kontakt hinzuzufügen. Geben Sie die SIP-Adresse oder Username Ihres Kontaktes ein. + + newConferenceButton + + MainWindowMenuBar @@ -1152,6 +1172,22 @@ Server URL ist nicht konfiguriert. showAudioCodecsLabel + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat @@ -1255,6 +1291,10 @@ Server URL ist nicht konfiguriert. callPauseEnabledLabel + + encryptionMandatoryLabel + + SettingsNetwork diff --git a/assets/languages/en.ts b/assets/languages/en.ts index 3cc3924b5..1d054dbf6 100644 --- a/assets/languages/en.ts +++ b/assets/languages/en.ts @@ -615,6 +615,10 @@ Server url not configured. abortEditDescriptionText Are you sure you want to cancel the contact modification? + + tooltipShowConversation + Show conversation + Contacts @@ -657,6 +661,18 @@ Server url not configured. removeAllEntriesDescription Are you sure you want to clean this history? + + tooltipContactEdit + Edit contact + + + tooltipContactAdd + Add contact + + + cleanHistory + Delete history + CreateAppSipAccount @@ -963,6 +979,10 @@ Click here: <a href="%1">%1</a> calls, send a message or add a new contact. Just enter your friend's SIP address or username. + + newConferenceButton + Start conference call + MainWindowMenuBar @@ -1157,6 +1177,22 @@ your friend's SIP address or username. showAudioCodecsLabel Show audio codecs + + playbackGainLabel + Playback gain + + + captureGainLabel + Capture gain + + + audioTestLabel + Capture level + + + audioSettingsInCallWarning + Audio call in progress: some settings are not available. + SettingsCallsChat @@ -1260,6 +1296,10 @@ your friend's SIP address or username. callPauseEnabledLabel Call pause enabled + + encryptionMandatoryLabel + Encrytion is mandatory + SettingsNetwork diff --git a/assets/languages/fr.ts b/assets/languages/fr.ts deleted file mode 100644 index c23fdb9a6..000000000 --- a/assets/languages/fr.ts +++ /dev/null @@ -1,1817 +0,0 @@ - - - About - - ok - - - - - ActivateAppSipAccountWithEmail - - activateAppSipAccount - - - - confirmAction - - - - activationSteps - - - - - ActivateAppSipAccountWithPhoneNumber - - activateAppSipAccount - - - - confirmAction - - - - activationSteps - - - - - App - - commandLineOptionVerbose - - - - commandLineOptionConfig - - - - applicationDescription - - - - commandLineOptionIconified - - - - commandLineOptionConfigArg - - - - commandLineOptionHelp - - - - commandLineOptionVersion - - - - commandLineOptionCliHelp - - - - commandLineDescription - - - - restore - - - - quit - - - - settings - - - - about - - - - - AssistantAbstractView - - back - - - - - AssistantHome - - useAppSipAccount - - - - useOtherSipAccount - - - - fetchRemoteConfiguration - - - - homeTitle - - - - homeDescription - - - - createAppSipAccount - - - - - AssistantModel - - loginWithUsernameFailed - - - - usernameStatusTooShort - - - - usernameStatusTooLong - - - - usernameStatusInvalidCharacters - - - - usernameStatusInvalid - - - - passwordStatusTooShort - - - - passwordStatusTooLong - - - - passwordStatusInvalidCharacters - - - - passwordStatusMissingCharacters - - - - requestFailed - - - - emailStatusMalformed - - - - emailStatusMalformedInvalidCharacters - - - - cannotSendSms - - - - accountAlreadyExists - - - - smsActivationFailed - - - - emailActivationFailed - - - - phoneNumberStatusInvalid - - - - phoneNumberStatusTooShort - - - - phoneNumberStatusTooLong - - - - phoneNumberStatusInvalidCountryCode - - - - loginWithPhoneNumberFailed - - - - unableToAddAccount - - - - - AuthenticationRequest - - cancel - - - - confirm - - - - identityLabel - - - - passwordLabel - - - - authenticationRequestDescription - - - - userIdLabel - - - - realmLabel - - - - - CallModel - - callStatsCodec - - - - callStatsUploadBandwidth - - - - callStatsDownloadBandwidth - - - - callStatsEstimatedDownloadBandwidth - - - - callStatsIceState - - - - callStatsIpFamily - - - - callStatsSenderLossRate - - - - callStatsReceiverLossRate - - - - callStatsJitterBuffer - - - - callStatsSentVideoDefinition - - - - callStatsReceivedVideoDefinition - - - - iceStateNotActivated - - - - iceStateFailed - - - - iceStateInProgress - - - - iceStateReflexiveConnection - - - - iceStateHostConnection - - - - iceStateRelayConnection - - - - iceStateInvalid - - - - callErrorDeclined - - - - callErrorNotFound - - - - callErrorBusy - - - - callErrorNotAcceptable - - - - callStatsReceivedFramerate - - - - callStatsSentFramerate - - - - - CallSipAddress - - cancel - - - - callSipAddressDescription - - - - - CallStatistics - - audioStatsLabel - - - - videoStatsLabel - - - - - CallTransfer - - cancel - - - - callTransferDescription - - - - - Calls - - acceptAudioCall - - - - acceptVideoCall - - - - terminateCall - - - - resumeCall - - - - transferCall - - - - callPause - - - - - CallsWindow - - callsTitle - - - - acceptClosingDescription - - - - - Chat - - newMessagePlaceholder - - - - noFileTransferUrl - - - - isComposing - - - - - Cli - - appCliDescription - - - - uriCommandLineSyntax - - - - cliCommandLineSyntax - - - - commandsName - - - - showFunctionDescription - - - - callFunctionDescription - - - - initiateConferenceFunctionDescription - - - - joinConferenceFunctionDescription - - - - joinConferenceAsFunctionDescription - - - - - CodecsViewer - - codecMime - - - - codecEncoderDescription - - - - codecEncoderClockRate - - - - codecBitrate - - - - codecRecvFmtp - - - - codecStatus - - - - - Conference - - conferenceTitle - - - - - ConferenceControls - - conference - - - - - ConferenceManager - - conferenceManagerDescription - - - - cancel - - - - confirm - - - - - ConfirmDialog - - cancel - - - - confirm - - - - - ContactEdit - - removeContactDescription - - - - sipAccounts - - - - address - - - - emails - - - - webSites - - - - avatarChooserTitle - - - - companies - - - - save - - - - cancel - - - - sipAccountsPlaceholder - - - - companiesPlaceholder - - - - emailsPlaceholder - - - - webSitesPlaceholder - - - - street - - - - postalCode - - - - country - - - - locality - - - - abortEditDescriptionText - - - - - Contacts - - searchContactPlaceholder - - - - selectAllContacts - - - - selectConnectedContacts - - - - addContact - - - - removeContactDescription - - - - - Conversation - - displayCallsAndMessages - - - - displayCalls - - - - displayMessages - - - - removeAllEntriesDescription - - - - - CreateAppSipAccount - - createAppSipAccountDescription - - - - createAppSipAccountTitle - - - - withPhoneNumber - - - - withEmailAddress - - - - - CreateAppSipAccountWithEmail - - createAppSipAccountTitle - - - - confirmAction - - - - usernameLabel - - - - emailLabel - - - - passwordLabel - - - - passwordConfirmationLabel - - - - passwordConfirmationError - - - - quitWarning - - - - displayNameLabel - - - - - CreateAppSipAccountWithPhoneNumber - - createAppSipAccountTitle - - - - countryLabel - - - - phoneNumberLabel - - - - usernameLabel - - - - displayNameLabel - - - - confirmAction - - - - quitWarning - - - - - DroppableTextArea - - fileChooserTitle - - - - dropYourAttachment - - - - attachmentTooltip - - - - - Event - - incomingCall - - - - outgoingCall - - - - declinedIncomingCall - - - - declinedOutgoingCall - - - - endedCall - - - - missedIncomingCall - - - - missedOutgoingCall - - - - - FetchRemoteConfiguration - - confirmAction - - - - fetchRemoteConfigurationTitle - - - - urlLabel - - - - remoteProvisioningError - - - - remoteProvisioningUpdateDescription - - - - - Home - - howToDescription - - - - howToTitle - - - - inviteDescription - - - - inviteTitle - - - - accountAssistantDescription - - - - accountAssistantTitle - - - - assistantButton - - - - showTooltips - - - - inviteButton - - - - - Incall - - acceptVideoDescription - - - - pendingRequestLabel - - - - securedStringFormat - - - - callNotSecured - - - - takeSnapshotLabel - - - - startRecordingLabel - - - - stopRecordingLabel - - - - - IncallFullscreenWindow - - takeSnapshotLabel - - - - startRecordingLabel - - - - stopRecordingLabel - - - - - InviteFriends - - enterEmailLabel - - - - messageLabel - - - - cancel - - - - confirm - - - - inviteFriendsTitle - - - - defaultMessage - - - - defaultSubject - - - - forcedMessage - - - - - MainWindow - - mainSearchBarPlaceholder - - - - homeEntry - - - - contactsEntry - - - - autoAnswerStatus - - - - smartSearchBarTooltip - - - - - MainWindowMenuBar - - settings - - - - about - - - - quit - - - - - ManageAccounts - - ok - - - - selectPresenceLabel - - - - selectAccountLabel - - - - - Message - - menuCopy - - - - menuPlayMe - - - - - MultimediaParameters - - ok - - - - - Notifier - - newVersionAvailable - - - - newFileMessage - - - - - OnlineInstallerDialog - - confirm - - - - onlineInstallerExtractingDescription - - - - onlineInstallerDownloadingDescription - - - - onlineInstallerFinishedDescription - - - - onlineInstallerFailedDescription - - - - - OutgoingMessage - - messageError - - - - messageRead - - - - messageDelivered - - - - - Presence - - presenceOnline - - - - presenceBusy - - - - presenceDoNotDisturb - - - - presenceOffline - - - - - SettingsAdvanced - - logsTitle - - - - logsFolderLabel - - - - sendLogs - - - - logsUploadUrlLabel - - - - logsUploadFailed - - - - logsEnabledLabel - - - - cleanLogs - - - - cleanLogsDescription - - - - developerSettingsTitle - - - - developerSettingsEnabledLabel - - - - - SettingsAudio - - audioTitle - - - - playbackDeviceLabel - - - - captureDeviceLabel - - - - ringerDeviceLabel - - - - ringLabel - - - - echoCancellationLabel - - - - audioCodecsTitle - - - - showAudioCodecsLabel - - - - - SettingsCallsChat - - fileServerLabel - - - - encryptWithLimeLabel - - - - limeDisabled - - - - limeRequired - - - - limePreferred - - - - chatTitle - - - - callsTitle - - - - encryptionLabel - - - - noEncryption - - - - autoAnswerLabel - - - - autoAnswerDelayLabel - - - - autoAnswerWithVideoLabel - - - - chatEnabledLabel - - - - callRecorderEnabledLabel - - - - chatNotificationSoundEnabledLabel - - - - chatNotificationSoundLabel - - - - conferenceEnabledLabel - - - - contactsTitle - - - - contactsEnabledLabel - - - - muteMicrophoneEnabledLabel - - - - outgoingCallsEnabledLabel - - - - showTelKeypadAutomaticallyLabel - - - - automaticallyRecordCallsLabel - - - - keepCallsWindowInBackgroundLabel - - - - callPauseEnabledLabel - - - - - SettingsNetwork - - sendDtmfsLabel - - - - allowIpV6Label - - - - transportTitle - - - - natAndFirewallTitle - - - - enableIceLabel - - - - stunServerLabel - - - - enableTurnLabel - - - - turnUserLabel - - - - turnPasswordLabel - - - - networkProtocolAndPortsTitle - - - - sipUdpPortLabel - - - - sipTcpPortLabel - - - - audioRtpUdpPortLabel - - - - videoRtpUdpPortLabel - - - - portHeader - - - - randomPortHeader - - - - enabledPortHeader - - - - dscpFieldsTitle - - - - sipFieldLabel - - - - audioRtpStreamFieldLabel - - - - videoRtpStreamFieldLabel - - - - bandwidthControlTitle - - - - downloadSpeedLimitLabel - - - - uploadSpeedLimitLabel - - - - enableAdaptiveRateControlLabel - - - - presenceTitle - - - - rlsUriLabel - - - - rlsUriAuto - - - - rlsUriDisabled - - - - showNetworkSettingsLabel - - - - generalTitle - - - - - SettingsSipAccounts - - defaultIdentityTitle - - - - defaultUsernameLabel - - - - defaultSipAddressLabel - - - - proxyAccountsTitle - - - - eraseAllPasswords - - - - addAccount - - - - editHeader - - - - deleteHeader - - - - deleteAccountDescription - - - - eraseAllPasswordsDescription - - - - defaultDisplayNameLabel - - - - assistantTitle - - - - createAppSipAccountEnabledLabel - - - - useAppSipAccountEnabledLabel - - - - useOtherSipAccountEnabledLabel - - - - fetchRemoteConfigurationEnabledLabel - - - - assistantSupportsPhoneNumbersLabel - - - - - SettingsSipAccountsEdit - - sipAddressLabel - - - - transportLabel - - - - serverAddressLabel - - - - registrationDurationLabel - - - - routeLabel - - - - contactParamsLabel - - - - publishPresenceLabel - - - - avpfIntervalLabel - - - - registerEnabledLabel - - - - avpfEnabledLabel - - - - cancel - - - - confirm - - - - invalidSipAddress - - - - invalidServerAddress - - - - invalidRoute - - - - enableIceLabel - - - - stunServerLabel - - - - enableTurnLabel - - - - turnUserLabel - - - - turnPasswordLabel - - - - natAndFirewallTitle - - - - mainSipAccountSettingsTitle - - - - - SettingsUi - - pathsTitle - - - - savedScreenshotsLabel - - - - savedCallsLabel - - - - languagesTitle - - - - languagesLabel - - - - systemLocale - - - - cleanAvatars - - - - cleanAvatarsDescription - - - - downloadLabel - - - - setLocaleDescription - - - - otherTitle - - - - exitOnCloseLabel - - - - dataTitle - - - - autoStartLabel - - - - - SettingsVideo - - videoInputDeviceLabel - - - - videoFramerateLabel - - - - videoCaptureTitle - - - - videoPresetLabel - - - - presetDefault - - - - presetHighFps - - - - presetCustom - - - - videoSizeLabel - - - - videoCodecsTitle - - - - showCameraPreview - - - - showVideoCodecsLabel - - - - - SettingsVideoPreview - - confirm - - - - - SettingsWindow - - settingsTitle - - - - sipAccountsTab - - - - audioTab - - - - videoTab - - - - callsAndChatTab - - - - networkTab - - - - uiTab - - - - validButton - - - - uiAdvanced - - - - - SmartSearchBar - - addContact - - - - - Timeline - - timelineTitle - - - - - UseAppSipAccount - - confirmAction - - - - useAppSipAccountTitle - - - - useUsernameToLogin - - - - quitWarning - - - - - UseAppSipAccountWithPhoneNumber - - countryLabel - - - - phoneNumberLabel - - - - - UseAppSipAccountWithUsername - - usernameLabel - - - - passwordLabel - - - - - UseOtherSipAccount - - confirmAction - - - - useOtherSipAccountTitle - - - - usernameLabel - - - - displayNameLabel - - - - sipDomainLabel - - - - passwordLabel - - - - transportLabel - - - - addOtherSipAccountError - - - - - ZrtpTokenAuthentication - - confirmSas - - - - codeA - - - - codeB - - - - deny - - - - accept - - - - - linphone-utils - - downloadCodecDescription - - - - \ No newline at end of file diff --git a/assets/languages/fr_FR.ts b/assets/languages/fr_FR.ts index c78c5c2ca..25529b4ac 100644 --- a/assets/languages/fr_FR.ts +++ b/assets/languages/fr_FR.ts @@ -615,6 +615,10 @@ Url du serveur non configurée. abortEditDescriptionText Êtes-vous sûr de vouloir annuler l'édition du contact ? + + tooltipShowConversation + Allez à la conversation + Contacts @@ -657,6 +661,18 @@ Url du serveur non configurée. removeAllEntriesDescription Êtes-vous sûr de vouloir supprimer cet historique ? + + tooltipContactEdit + Editer le contact + + + tooltipContactAdd + Ajouter le contact + + + cleanHistory + Supprimer l'historique + CreateAppSipAccount @@ -961,6 +977,10 @@ Cliquez ici : <a href="%1">%1</a> smartSearchBarTooltip Utilisez la barre de recherche intelligente pour lancer des appels audio et vidéo, envoyer un message ou ajouter un contact. Entrez simplement l'adresse SIP ou le nom d'utilisateur de votre contact. + + newConferenceButton + Démarrer une conférence + MainWindowMenuBar @@ -1155,6 +1175,22 @@ Cliquez ici : <a href="%1">%1</a> showAudioCodecsLabel Afficher les codecs audio + + playbackGainLabel + Gain de lecture + + + captureGainLabel + Gain de capture + + + audioTestLabel + Niveau micro + + + audioSettingsInCallWarning + Appel en cours: certains paramètres sont inaccessibles + SettingsCallsChat @@ -1258,6 +1294,10 @@ Cliquez ici : <a href="%1">%1</a> callPauseEnabledLabel Autoriser la mise en pause + + encryptionMandatoryLabel + Chiffrement obligatoire + SettingsNetwork diff --git a/assets/languages/ja.ts b/assets/languages/ja.ts index 24a044b1f..8e373ed24 100644 --- a/assets/languages/ja.ts +++ b/assets/languages/ja.ts @@ -615,6 +615,10 @@ abortEditDescriptionText + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ removeAllEntriesDescription 履歴をクリアしてよろしいですか? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -958,6 +974,10 @@ smartSearchBarTooltip + + newConferenceButton + + MainWindowMenuBar @@ -1152,6 +1172,22 @@ showAudioCodecsLabel + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat @@ -1255,6 +1291,10 @@ callPauseEnabledLabel + + encryptionMandatoryLabel + + SettingsNetwork diff --git a/assets/languages/lt.ts b/assets/languages/lt.ts index bd0cbe16d..e29a5cfe8 100644 --- a/assets/languages/lt.ts +++ b/assets/languages/lt.ts @@ -615,6 +615,10 @@ Nesukonfigūruotas serverio url. abortEditDescriptionText + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ Nesukonfigūruotas serverio url. removeAllEntriesDescription Ar tikrai norite išvalyti šią istoriją? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -963,6 +979,10 @@ Spustelėkite čia: <a href="%1">%1</a> garso ir vaizdo skambučius, siųsti žinutę ar pridėti naują kontaktą. Tiesiog, įveskite savo draugo SIP adresą ar naudotojo vardą. + + newConferenceButton + + MainWindowMenuBar @@ -1157,6 +1177,22 @@ Tiesiog, įveskite savo draugo SIP adresą ar naudotojo vardą. showAudioCodecsLabel Rodyti garso kodekus + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat @@ -1260,6 +1296,10 @@ Tiesiog, įveskite savo draugo SIP adresą ar naudotojo vardą. callPauseEnabledLabel + + encryptionMandatoryLabel + + SettingsNetwork diff --git a/assets/languages/pt_BR.ts b/assets/languages/pt_BR.ts index 645dda685..7a86f5c89 100644 --- a/assets/languages/pt_BR.ts +++ b/assets/languages/pt_BR.ts @@ -615,6 +615,10 @@ URL do servidor não configurado. abortEditDescriptionText Tem certeza de que deseja cancelar a modificação do contato? + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ URL do servidor não configurado. removeAllEntriesDescription Tem certeza de que deseja limpar este histórico? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -963,6 +979,10 @@ Click aqui: <a href="%1">%1</a> enviar uma mensagem ou adicionar um novo contato. Basta entrar o endereço SIP ou nome de usuário do seu amigo. + + newConferenceButton + + MainWindowMenuBar @@ -1157,6 +1177,22 @@ o endereço SIP ou nome de usuário do seu amigo. showAudioCodecsLabel Mostrar codecs de áudio + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat @@ -1260,6 +1296,10 @@ o endereço SIP ou nome de usuário do seu amigo. callPauseEnabledLabel Habilitada pausa na chamada. + + encryptionMandatoryLabel + + SettingsNetwork diff --git a/assets/languages/ru.ts b/assets/languages/ru.ts index d0218f306..9d70f67fe 100644 --- a/assets/languages/ru.ts +++ b/assets/languages/ru.ts @@ -615,6 +615,10 @@ abortEditDescriptionText Вы уверены, что хотите отменить изменение контакта? + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ removeAllEntriesDescription Вы уверены, что хотите очистить эту историю? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -961,6 +977,10 @@ smartSearchBarTooltip Используйте умную поисковую строку, чтобы сразу начать аудио или видео вызов, отправить сообщение или добавить новый контакт. Просто введите SIP адрес или имя пользователя вашего контакта. + + newConferenceButton + + MainWindowMenuBar @@ -1155,6 +1175,22 @@ showAudioCodecsLabel Показать Аудио кодаки + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat @@ -1258,6 +1294,10 @@ callPauseEnabledLabel Вызов поставлен на паузу + + encryptionMandatoryLabel + + SettingsNetwork diff --git a/assets/languages/sv.ts b/assets/languages/sv.ts index 4642646ca..40c734e53 100644 --- a/assets/languages/sv.ts +++ b/assets/languages/sv.ts @@ -615,6 +615,10 @@ Serverwebbadressen är inte konfigurerad. abortEditDescriptionText Är du säker på att du vill avbryta kontaktändringen? + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ Serverwebbadressen är inte konfigurerad. removeAllEntriesDescription Är du säker på att du vill rensa den här historiken? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -961,6 +977,10 @@ Klicka här: <a href="%1">%1</a> smartSearchBarTooltip + + newConferenceButton + + MainWindowMenuBar @@ -1155,6 +1175,22 @@ Klicka här: <a href="%1">%1</a> showAudioCodecsLabel Visa ljudkodek + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat @@ -1258,6 +1294,10 @@ Klicka här: <a href="%1">%1</a> callPauseEnabledLabel Samtals paus aktiverad + + encryptionMandatoryLabel + + SettingsNetwork diff --git a/assets/languages/tr.ts b/assets/languages/tr.ts index f07b5b2da..c04518e43 100644 --- a/assets/languages/tr.ts +++ b/assets/languages/tr.ts @@ -615,6 +615,10 @@ Sunucu url'si yapılandırılmadı. abortEditDescriptionText Kişi düzenlemesini iptal etmek istediğinize emin misiniz? + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ Sunucu url'si yapılandırılmadı. removeAllEntriesDescription Bu geçmişi temizlemek istediğinize emin misiniz? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -963,6 +979,10 @@ Buraya tıklayın: <a href="%1">%1</a> eklemek için akıllı arama çubuğunu kullanın. Yalnızca arkadaşınızın SIP adresini veya kullanıcı adını girin. + + newConferenceButton + + MainWindowMenuBar @@ -1157,6 +1177,22 @@ arkadaşınızın SIP adresini veya kullanıcı adını girin. showAudioCodecsLabel Ses çözücüleri göster + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat @@ -1260,6 +1296,10 @@ arkadaşınızın SIP adresini veya kullanıcı adını girin. callPauseEnabledLabel Çağrı duraklatma etkin + + encryptionMandatoryLabel + + SettingsNetwork diff --git a/cmake_builder/CMakeLists.txt b/cmake_builder/CMakeLists.txt index 3c036264e..41882eb8e 100644 --- a/cmake_builder/CMakeLists.txt +++ b/cmake_builder/CMakeLists.txt @@ -23,6 +23,6 @@ lcb_define_target("linphoneqt" "linphone" "ms2plugins") -if (NOT WIN32 AND NOT APPLE) - lcb_blacklist_dependencies("turbo-jpeg") # turbo-jpeg is already provided by Qt5 so do not build it. -endif () +#if (NOT WIN32 AND NOT APPLE) +# lcb_blacklist_dependencies("turbojpeg") # turbo-jpeg is already provided by Qt5 so do not build it. +#endif () diff --git a/create_appimage.sh b/create_appimage.sh new file mode 100755 index 000000000..371ca0778 --- /dev/null +++ b/create_appimage.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +APP_NAME="linphone" + +BIN_SOURCE_DIR="OUTPUT/desktop" + +WORK_DIR="OUTPUT/AppDir/usr" + +mkdir -p "${WORK_DIR}" + +cp -rfv "${BIN_SOURCE_DIR}"/* "${WORK_DIR}" + +./AppImage/linuxdeployqt-continuous-x86_64.AppImage "${WORK_DIR}/bin/${APP_NAME}" -appimage -bundle-non-qt-libs -verbose=2 diff --git a/linphone-sdk b/linphone-sdk index 44380577a..b3dbedd10 160000 --- a/linphone-sdk +++ b/linphone-sdk @@ -1 +1 @@ -Subproject commit 44380577a36e41c5e9226328dac64e7b27c4d0fc +Subproject commit b3dbedd109f9d4357f5b73410a132c11c2660b58 diff --git a/resources.qrc b/resources.qrc index bd49023b3..400e612f3 100644 --- a/resources.qrc +++ b/resources.qrc @@ -199,6 +199,7 @@ assets/images/video_call_hovered.svg assets/images/video_call_normal.svg assets/images/video_call_pressed.svg + assets/images/warning.svg ui/modules/Common/Animations/BusyIndicator.qml ui/modules/Common/Constants/Constants.qml ui/modules/Common/Dialog/ConfirmDialog.qml diff --git a/src/app/logger/Logger.cpp b/src/app/logger/Logger.cpp index c71463425..092065511 100644 --- a/src/app/logger/Logger.cpp +++ b/src/app/logger/Logger.cpp @@ -202,7 +202,7 @@ void Logger::init (const shared_ptr &config) { { shared_ptr loggingService = mInstance->mLoggingService = linphone::LoggingService::get(); loggingService->setLogLevel(linphone::LogLevel::Message); - loggingService->setListener(make_shared(mInstance)); + loggingService->addListener(make_shared(mInstance)); } linphone::Core::setLogCollectionPath(Utils::appStringToCoreString(folder)); diff --git a/src/app/main.cpp b/src/app/main.cpp index 8b936d4ae..5719f2f33 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -28,7 +28,10 @@ int main (int argc, char *argv[]) { AppController controller(argc, argv); App *app = controller.getApp(); if (app->isSecondary()) - return EXIT_SUCCESS; + { + qInfo() << QStringLiteral("Running secondary app success. Kill it now."); + return EXIT_SUCCESS; + } qInfo() << QStringLiteral("Running app..."); diff --git a/src/app/paths/Paths.cpp b/src/app/paths/Paths.cpp index 51143c108..5554a4676 100644 --- a/src/app/paths/Paths.cpp +++ b/src/app/paths/Paths.cpp @@ -108,15 +108,23 @@ static inline QDir getAppPackageDir () { QDir dir(QCoreApplication::applicationDirPath()); if (dir.dirName() == QLatin1String("MacOS")) { dir.cdUp(); - dir.cd("Resources"); + if (!dir.cd("Resources")) + { + dir.mkdir("Resources"); + dir.cd("Resources"); + } } else dir.cdUp(); return dir; } -static inline QString getAppPackageDataDirPath () { +static inline QString getAppPackageDataDirPath() { QDir dir = getAppPackageDir(); - dir.cd("share"); + if (!dir.cd("share")) + { + dir.mkdir("share"); + dir.cd("share"); + } return dir.absolutePath(); } diff --git a/src/app/single-application/SingleApplication.cpp b/src/app/single-application/SingleApplication.cpp index 5d76ee692..38a5f4465 100644 --- a/src/app/single-application/SingleApplication.cpp +++ b/src/app/single-application/SingleApplication.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef Q_OS_UNIX #include @@ -167,8 +168,10 @@ void SingleApplicationPrivate::startPrimary (bool resetMemory) { if (resetMemory) { inst->primary = true; inst->secondary = 0; + inst->primaryId = q_ptr->applicationPid(); } else { inst->primary = true; + inst->primaryId = q_ptr->applicationPid(); } memory->unlock(); @@ -344,10 +347,10 @@ SingleApplication::SingleApplication (int &argc, char *argv[], bool allowSeconda // Attempt to attach to the memory segment if (d->memory->attach()) { d->memory->lock(); - + InstancesInfo *inst = static_cast(d->memory->data()); - if (!inst->primary) { + if (!inst->primary || !Utils::processExists(inst->primaryId)) { // Check if there is not a primary instance and if there is, is it still running? d->startPrimary(false); d->memory->unlock(); return; diff --git a/src/app/single-application/SingleApplicationPrivate.hpp b/src/app/single-application/SingleApplicationPrivate.hpp index a425fa76d..c7ffe1ea2 100644 --- a/src/app/single-application/SingleApplicationPrivate.hpp +++ b/src/app/single-application/SingleApplicationPrivate.hpp @@ -44,6 +44,7 @@ struct InstancesInfo { bool primary; quint32 secondary; + quint64 primaryId; }; class SingleApplicationPrivate : public QObject { diff --git a/src/components/assistant/AssistantModel.cpp b/src/components/assistant/AssistantModel.cpp index 9bb8f3e11..918e31e53 100644 --- a/src/components/assistant/AssistantModel.cpp +++ b/src/components/assistant/AssistantModel.cpp @@ -150,7 +150,7 @@ AssistantModel::AssistantModel (QObject *parent) : QObject(parent) { mAccountCreator = core->createAccountCreator( core->getConfig()->getString("assistant", "xmlrpc_url", DefaultXmlrpcUri) ); - mAccountCreator->setListener(mHandlers); + mAccountCreator->addListener(mHandlers); } // ----------------------------------------------------------------------------- diff --git a/src/components/call/CallModel.cpp b/src/components/call/CallModel.cpp index 6fba9a6d6..f98b7adce 100644 --- a/src/components/call/CallModel.cpp +++ b/src/components/call/CallModel.cpp @@ -33,6 +33,7 @@ #include "components/settings/AccountSettingsModel.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/LinphoneUtils.hpp" +#include "utils/MediastreamerUtils.hpp" #include "utils/Utils.hpp" #include "CallModel.hpp" @@ -469,11 +470,11 @@ float CallModel::getQuality () const { // ----------------------------------------------------------------------------- float CallModel::getSpeakerVu () const { - return LinphoneUtils::computeVu(mCall->getPlayVolume()); + return MediastreamerUtils::computeVu(mCall->getPlayVolume()); } float CallModel::getMicroVu () const { - return LinphoneUtils::computeVu(mCall->getRecordVolume()); + return MediastreamerUtils::computeVu(mCall->getRecordVolume()); } // ----------------------------------------------------------------------------- diff --git a/src/components/chat/ChatModel.cpp b/src/components/chat/ChatModel.cpp index ebba5d24f..78f7a55cf 100644 --- a/src/components/chat/ChatModel.cpp +++ b/src/components/chat/ChatModel.cpp @@ -409,7 +409,7 @@ void ChatModel::removeAllEntries () { void ChatModel::sendMessage (const QString &message) { shared_ptr _message = mChatRoom->createMessage(Utils::appStringToCoreString(message)); - _message->setListener(mMessageHandlers); + _message->addListener(mMessageHandlers); insertMessageAtEnd(_message); mChatRoom->sendChatMessage(_message); @@ -435,7 +435,7 @@ void ChatModel::resendMessage (int id) { case MessageStatusFileTransferError: case MessageStatusNotDelivered: { shared_ptr message = static_pointer_cast(entry.second); - message->setListener(mMessageHandlers); + message->addListener(mMessageHandlers); message->resend(); break; @@ -473,7 +473,7 @@ void ChatModel::sendFileMessage (const QString &path) { shared_ptr message = mChatRoom->createFileTransferMessage(content); message->setFileTransferFilepath(Utils::appStringToCoreString(path)); - message->setListener(mMessageHandlers); + message->addListener(mMessageHandlers); createThumbnail(message); @@ -518,7 +518,7 @@ void ChatModel::downloadFile (int id) { } message->setFileTransferFilepath(Utils::appStringToCoreString(safeFilePath)); - message->setListener(mMessageHandlers); + message->addListener(mMessageHandlers); if (!message->downloadFile()) qWarning() << QStringLiteral("Unable to download file of entry %1.").arg(id); diff --git a/src/components/conference/ConferenceModel.cpp b/src/components/conference/ConferenceModel.cpp index 8d3638654..74a276320 100644 --- a/src/components/conference/ConferenceModel.cpp +++ b/src/components/conference/ConferenceModel.cpp @@ -28,6 +28,7 @@ #include "components/core/CoreManager.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/LinphoneUtils.hpp" +#include "utils/MediastreamerUtils.hpp" #include "utils/Utils.hpp" #include "ConferenceModel.hpp" @@ -128,7 +129,7 @@ bool ConferenceModel::getRecording () const { // ----------------------------------------------------------------------------- float ConferenceModel::getMicroVu () const { - return LinphoneUtils::computeVu( + return MediastreamerUtils::computeVu( CoreManager::getInstance()->getCore()->getConferenceLocalInputVolume() ); } diff --git a/src/components/core/CoreHandlers.cpp b/src/components/core/CoreHandlers.cpp index c046f15fe..417765d1c 100644 --- a/src/components/core/CoreHandlers.cpp +++ b/src/components/core/CoreHandlers.cpp @@ -125,6 +125,11 @@ void CoreHandlers::onCallStatsUpdated ( call->getData("call-model").updateStats(stats); } +void CoreHandlers::onCallCreated(const shared_ptr &, + const shared_ptr &call) { + emit callCreated(call); +} + void CoreHandlers::onGlobalStateChanged ( const shared_ptr &, linphone::GlobalState gstate, diff --git a/src/components/core/CoreHandlers.hpp b/src/components/core/CoreHandlers.hpp index ed8da73e0..bdb377d91 100644 --- a/src/components/core/CoreHandlers.hpp +++ b/src/components/core/CoreHandlers.hpp @@ -46,6 +46,7 @@ signals: void callStateChanged (const std::shared_ptr &call, linphone::Call::State state); void callTransferFailed (const std::shared_ptr &call); void callTransferSucceeded (const std::shared_ptr &call); + void callCreated(const std::shared_ptr & call); void coreStarted (); void isComposingChanged (const std::shared_ptr &chatRoom); void logsUploadStateChanged (linphone::Core::LogCollectionUploadState state, const std::string &info); @@ -87,6 +88,11 @@ private: const std::shared_ptr &stats ) override; + void onCallCreated( + const std::shared_ptr & lc, + const std::shared_ptr & call + ) override; + void onGlobalStateChanged ( const std::shared_ptr &core, linphone::GlobalState gstate, diff --git a/src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp b/src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp index e03fa5d3d..078ec2a70 100644 --- a/src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp +++ b/src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp @@ -66,7 +66,7 @@ void AbstractEventCountNotifier::internalnotifyEventCount () { n = n > 99 ? 99 : n; notifyEventCount(CoreManager::getInstance()->getSettingsModel()->getChatEnabled() ? n : 0); - emit eventCountChanged(mUnreadMessageCount); + emit eventCountChanged(n); } // ----------------------------------------------------------------------------- diff --git a/src/components/settings/SettingsModel.cpp b/src/components/settings/SettingsModel.cpp index d30b75155..57f9a4f9e 100644 --- a/src/components/settings/SettingsModel.cpp +++ b/src/components/settings/SettingsModel.cpp @@ -22,11 +22,14 @@ #include +#include +#include + #include "app/logger/Logger.hpp" #include "app/paths/Paths.hpp" #include "components/core/CoreManager.hpp" #include "utils/Utils.hpp" - +#include "utils/MediastreamerUtils.hpp" #include "SettingsModel.hpp" // ============================================================================= @@ -34,287 +37,424 @@ using namespace std; namespace { - constexpr char DefaultRlsUri[] = "sips:rls@sip.linphone.org"; - constexpr char DefaultLogsEmail[] = "linphone-desktop@belledonne-communications.com"; + constexpr char DefaultRlsUri[] = "sips:rls@sip.linphone.org"; + constexpr char DefaultLogsEmail[] = "linphone-desktop@belledonne-communications.com"; } const string SettingsModel::UiSection("ui"); SettingsModel::SettingsModel (QObject *parent) : QObject(parent) { - mConfig = CoreManager::getInstance()->getCore()->getConfig(); - configureRlsUri(); + CoreManager *coreManager = CoreManager::getInstance(); + mConfig = coreManager->getCore()->getConfig(); + + QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::callCreated, + this, &SettingsModel::handleCallCreated); + QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::callStateChanged, + this, &SettingsModel::handleCallStateChanged); + configureRlsUri(); +} + +void SettingsModel::settingsWindowClosing(void) { + onSettingsTabChanged(-1); +} + +//Provides tabbar per-tab setup/teardown mecanism for specific settings views +void SettingsModel::onSettingsTabChanged(int idx) { + int prevIdx = mCurrentSettingsTab; + mCurrentSettingsTab = idx; + + switch (prevIdx) { + case 0://sip + break; + case 1://audio + closeAudioSettings(); + break; + case 2://video + break; + case 3://call + break; + case 4://ui + break; + case 5://advanced + break; + default: + break; + } + switch (idx) { + case 0://sip + break; + case 1://audio + accessAudioSettings(); + break; + case 2://video + accessVideoSettings(); + break; + case 3://call + break; + case 4://ui + break; + case 5://advanced + break; + default: + break; + } } // ============================================================================= // Assistant. // ============================================================================= - bool SettingsModel::getUseAppSipAccountEnabled () const { - return !!mConfig->getInt(UiSection, "use_app_sip_account_enabled", 1); - } +bool SettingsModel::getUseAppSipAccountEnabled () const { + return !!mConfig->getInt(UiSection, "use_app_sip_account_enabled", 1); +} - void SettingsModel::setUseAppSipAccountEnabled (bool status) { - mConfig->setInt(UiSection, "use_app_sip_account_enabled", status); - emit useAppSipAccountEnabledChanged(status); - } +void SettingsModel::setUseAppSipAccountEnabled (bool status) { + mConfig->setInt(UiSection, "use_app_sip_account_enabled", status); + emit useAppSipAccountEnabledChanged(status); +} - bool SettingsModel::getUseOtherSipAccountEnabled () const { - return !!mConfig->getInt(UiSection, "use_other_sip_account_enabled", 1); - } +bool SettingsModel::getUseOtherSipAccountEnabled () const { + return !!mConfig->getInt(UiSection, "use_other_sip_account_enabled", 1); +} - void SettingsModel::setUseOtherSipAccountEnabled (bool status) { - mConfig->setInt(UiSection, "use_other_sip_account_enabled", status); - emit useOtherSipAccountEnabledChanged(status); - } +void SettingsModel::setUseOtherSipAccountEnabled (bool status) { + mConfig->setInt(UiSection, "use_other_sip_account_enabled", status); + emit useOtherSipAccountEnabledChanged(status); +} - bool SettingsModel::getCreateAppSipAccountEnabled () const { - return !!mConfig->getInt(UiSection, "create_app_sip_account_enabled", 1); - } +bool SettingsModel::getCreateAppSipAccountEnabled () const { + return !!mConfig->getInt(UiSection, "create_app_sip_account_enabled", 1); +} - void SettingsModel::setCreateAppSipAccountEnabled (bool status) { - mConfig->setInt(UiSection, "create_app_sip_account_enabled", status); - emit createAppSipAccountEnabledChanged(status); - } +void SettingsModel::setCreateAppSipAccountEnabled (bool status) { + mConfig->setInt(UiSection, "create_app_sip_account_enabled", status); + emit createAppSipAccountEnabledChanged(status); +} - bool SettingsModel::getFetchRemoteConfigurationEnabled () const { - return !!mConfig->getInt(UiSection, "fetch_remote_configuration_enabled", 1); - } +bool SettingsModel::getFetchRemoteConfigurationEnabled () const { + return !!mConfig->getInt(UiSection, "fetch_remote_configuration_enabled", 1); +} - void SettingsModel::setFetchRemoteConfigurationEnabled (bool status) { - mConfig->setInt(UiSection, "fetch_remote_configuration_enabled", status); - emit fetchRemoteConfigurationEnabledChanged(status); - } +void SettingsModel::setFetchRemoteConfigurationEnabled (bool status) { + mConfig->setInt(UiSection, "fetch_remote_configuration_enabled", status); + emit fetchRemoteConfigurationEnabledChanged(status); +} - // --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- - bool SettingsModel::getAssistantSupportsPhoneNumbers () const { - return !!mConfig->getInt(UiSection, "assistant_supports_phone_numbers", 1); - } +bool SettingsModel::getAssistantSupportsPhoneNumbers () const { + return !!mConfig->getInt(UiSection, "assistant_supports_phone_numbers", 1); +} - void SettingsModel::setAssistantSupportsPhoneNumbers (bool status) { - mConfig->setInt(UiSection, "assistant_supports_phone_numbers", status); - emit assistantSupportsPhoneNumbersChanged(status); - } +void SettingsModel::setAssistantSupportsPhoneNumbers (bool status) { + mConfig->setInt(UiSection, "assistant_supports_phone_numbers", status); + emit assistantSupportsPhoneNumbersChanged(status); +} // ============================================================================= // Audio. // ============================================================================= +void SettingsModel::createCaptureGraph() { + if (mSimpleCaptureGraph) { + delete mSimpleCaptureGraph; + mSimpleCaptureGraph = nullptr; + } + if (!mSimpleCaptureGraph) { + mSimpleCaptureGraph = + new MediastreamerUtils::SimpleCaptureGraph(Utils::appStringToCoreString(getCaptureDevice()), + Utils::appStringToCoreString(getPlaybackDevice())); + } + mSimpleCaptureGraph->start(); + emit captureGraphRunningChanged(getCaptureGraphRunning()); +} + +//Force a call on the 'detect' method of all audio filters, updating new or removed devices +void SettingsModel::accessAudioSettings() { + CoreManager::getInstance()->getCore()->reloadSoundDevices(); + emit captureDevicesChanged(getCaptureDevices()); + emit playbackDevicesChanged(getPlaybackDevices()); + emit playbackDeviceChanged(getPlaybackDevice()); + emit captureDeviceChanged(getCaptureDevice()); + emit ringerDeviceChanged(getRingerDevice()); + + if (!getIsInCall()) { + createCaptureGraph(); + } +} + +void SettingsModel::closeAudioSettings() { + if (mSimpleCaptureGraph) { + if (mSimpleCaptureGraph->isRunning()) { + mSimpleCaptureGraph->stop(); + } + delete mSimpleCaptureGraph; + mSimpleCaptureGraph = nullptr; + } + emit captureGraphRunningChanged(getCaptureGraphRunning()); +} + +bool SettingsModel::getCaptureGraphRunning() { + return mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning() && !getIsInCall(); +} + +float SettingsModel::getMicVolume() { + float v = 0.0; + + if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { + v = mSimpleCaptureGraph->getCaptureVolume(); + } + return v; +} + +float SettingsModel::getPlaybackGain() const { + float dbGain = CoreManager::getInstance()->getCore()->getPlaybackGainDb(); + return MediastreamerUtils::dbToLinear(dbGain); +} + +void SettingsModel::setPlaybackGain(float gain) { + if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { + mSimpleCaptureGraph->setPlaybackGain(gain); + } +} + +float SettingsModel::getCaptureGain() const { + float dbGain = CoreManager::getInstance()->getCore()->getMicGainDb(); + return MediastreamerUtils::dbToLinear(dbGain); +} + +void SettingsModel::setCaptureGain(float gain) { + if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { + mSimpleCaptureGraph->setCaptureGain(gain); + } +} + QStringList SettingsModel::getCaptureDevices () const { - shared_ptr core = CoreManager::getInstance()->getCore(); - QStringList list; + shared_ptr core = CoreManager::getInstance()->getCore(); + QStringList list; - for (const auto &device : core->getSoundDevicesList()) { - if (core->soundDeviceCanCapture(device)) - list << Utils::coreStringToAppString(device); - } - - return list; + for (const auto &device : core->getSoundDevicesList()) { + if (core->soundDeviceCanCapture(device)) + list << Utils::coreStringToAppString(device); + } + return list; } QStringList SettingsModel::getPlaybackDevices () const { - shared_ptr core = CoreManager::getInstance()->getCore(); - QStringList list; + shared_ptr core = CoreManager::getInstance()->getCore(); + QStringList list; - for (const auto &device : core->getSoundDevicesList()) - if (core->soundDeviceCanPlayback(device)) - list << Utils::coreStringToAppString(device); + for (const auto &device : core->getSoundDevicesList()) { + if (core->soundDeviceCanPlayback(device)) { + list << Utils::coreStringToAppString(device); + } + } - return list; + return list; } // ----------------------------------------------------------------------------- QString SettingsModel::getCaptureDevice () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getCaptureDevice() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getCaptureDevice() + ); } void SettingsModel::setCaptureDevice (const QString &device) { - CoreManager::getInstance()->getCore()->setCaptureDevice( - Utils::appStringToCoreString(device) - ); - emit captureDeviceChanged(device); + CoreManager::getInstance()->getCore()->setCaptureDevice( + Utils::appStringToCoreString(device) + ); + emit captureDeviceChanged(device); + if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { + createCaptureGraph(); + } } // ----------------------------------------------------------------------------- QString SettingsModel::getPlaybackDevice () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getPlaybackDevice() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getPlaybackDevice() + ); } void SettingsModel::setPlaybackDevice (const QString &device) { - CoreManager::getInstance()->getCore()->setPlaybackDevice( - Utils::appStringToCoreString(device) - ); - emit playbackDeviceChanged(device); + CoreManager::getInstance()->getCore()->setPlaybackDevice( + Utils::appStringToCoreString(device) + ); + emit playbackDeviceChanged(device); } // ----------------------------------------------------------------------------- QString SettingsModel::getRingerDevice () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getRingerDevice() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getRingerDevice() + ); } void SettingsModel::setRingerDevice (const QString &device) { - CoreManager::getInstance()->getCore()->setRingerDevice( - Utils::appStringToCoreString(device) - ); - emit ringerDeviceChanged(device); + CoreManager::getInstance()->getCore()->setRingerDevice( + Utils::appStringToCoreString(device) + ); + emit ringerDeviceChanged(device); } // ----------------------------------------------------------------------------- QString SettingsModel::getRingPath () const { - return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getRing()); + return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getRing()); } void SettingsModel::setRingPath (const QString &path) { - QString cleanedPath = QDir::cleanPath(path); + QString cleanedPath = QDir::cleanPath(path); - CoreManager::getInstance()->getCore()->setRing( - Utils::appStringToCoreString(cleanedPath) - ); + CoreManager::getInstance()->getCore()->setRing( + Utils::appStringToCoreString(cleanedPath) + ); - emit ringPathChanged(cleanedPath); + emit ringPathChanged(cleanedPath); } // ----------------------------------------------------------------------------- bool SettingsModel::getEchoCancellationEnabled () const { - return CoreManager::getInstance()->getCore()->echoCancellationEnabled(); + return CoreManager::getInstance()->getCore()->echoCancellationEnabled(); } void SettingsModel::setEchoCancellationEnabled (bool status) { - CoreManager::getInstance()->getCore()->enableEchoCancellation(status); - emit echoCancellationEnabledChanged(status); + CoreManager::getInstance()->getCore()->enableEchoCancellation(status); + emit echoCancellationEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getShowAudioCodecs () const { - return !!mConfig->getInt(UiSection, "show_audio_codecs", 1); + return !!mConfig->getInt(UiSection, "show_audio_codecs", 1); } void SettingsModel::setShowAudioCodecs (bool status) { - mConfig->setInt(UiSection, "show_audio_codecs", status); - emit showAudioCodecsChanged(status); + mConfig->setInt(UiSection, "show_audio_codecs", status); + emit showAudioCodecsChanged(status); } + // ============================================================================= // Video. // ============================================================================= +//Force a call on the 'detect' method of all video filters, updating new or removed devices +void SettingsModel::accessVideoSettings() { + CoreManager::getInstance()->getCore()->reloadVideoDevices(); + emit videoDevicesChanged(getVideoDevices()); +} + QStringList SettingsModel::getVideoDevices () const { - QStringList list; + QStringList list; - for (const auto &device : CoreManager::getInstance()->getCore()->getVideoDevicesList()) - list << Utils::coreStringToAppString(device); + for (const auto &device : CoreManager::getInstance()->getCore()->getVideoDevicesList()) + list << Utils::coreStringToAppString(device); - return list; + return list; } // ----------------------------------------------------------------------------- QString SettingsModel::getVideoDevice () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getVideoDevice() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getVideoDevice() + ); } void SettingsModel::setVideoDevice (const QString &device) { - CoreManager::getInstance()->getCore()->setVideoDevice( - Utils::appStringToCoreString(device) - ); - emit videoDeviceChanged(device); + CoreManager::getInstance()->getCore()->setVideoDevice( + Utils::appStringToCoreString(device) + ); + emit videoDeviceChanged(device); } // ----------------------------------------------------------------------------- QString SettingsModel::getVideoPreset () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getVideoPreset() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getVideoPreset() + ); } void SettingsModel::setVideoPreset (const QString &preset) { - CoreManager::getInstance()->getCore()->setVideoPreset( - Utils::appStringToCoreString(preset) - ); - emit videoPresetChanged(preset); + CoreManager::getInstance()->getCore()->setVideoPreset( + Utils::appStringToCoreString(preset) + ); + emit videoPresetChanged(preset); } // ----------------------------------------------------------------------------- int SettingsModel::getVideoFramerate () const { - return int(CoreManager::getInstance()->getCore()->getPreferredFramerate()); + return int(CoreManager::getInstance()->getCore()->getPreferredFramerate()); } void SettingsModel::setVideoFramerate (int framerate) { - CoreManager::getInstance()->getCore()->setPreferredFramerate(float(framerate)); - emit videoFramerateChanged(framerate); + CoreManager::getInstance()->getCore()->setPreferredFramerate(float(framerate)); + emit videoFramerateChanged(framerate); } // ----------------------------------------------------------------------------- static inline QVariantMap createMapFromVideoDefinition (const shared_ptr &definition) { - QVariantMap map; + QVariantMap map; - if (!definition) { - Q_ASSERT(!CoreManager::getInstance()->getCore()->videoSupported()); + if (!definition) { + Q_ASSERT(!CoreManager::getInstance()->getCore()->videoSupported()); - map["name"] = QStringLiteral("Bad EGG"); - map["width"] = QStringLiteral("?????"); - map["height"] = QStringLiteral("?????"); + map["name"] = QStringLiteral("Bad EGG"); + map["width"] = QStringLiteral("?????"); + map["height"] = QStringLiteral("?????"); - return map; - } + return map; + } - map["name"] = Utils::coreStringToAppString(definition->getName()); - map["width"] = definition->getWidth(); - map["height"] = definition->getHeight(); - map["__definition"] = QVariant::fromValue(definition); + map["name"] = Utils::coreStringToAppString(definition->getName()); + map["width"] = definition->getWidth(); + map["height"] = definition->getHeight(); + map["__definition"] = QVariant::fromValue(definition); - return map; + return map; } QVariantList SettingsModel::getSupportedVideoDefinitions () const { - QVariantList list; - for (const auto &definition : linphone::Factory::get()->getSupportedVideoDefinitions()) - list << createMapFromVideoDefinition(definition); - return list; + QVariantList list; + for (const auto &definition : linphone::Factory::get()->getSupportedVideoDefinitions()) + list << createMapFromVideoDefinition(definition); + return list; } QVariantMap SettingsModel::getVideoDefinition () const { - return createMapFromVideoDefinition(CoreManager::getInstance()->getCore()->getPreferredVideoDefinition()); + return createMapFromVideoDefinition(CoreManager::getInstance()->getCore()->getPreferredVideoDefinition()); } void SettingsModel::setVideoDefinition (const QVariantMap &definition) { - CoreManager::getInstance()->getCore()->setPreferredVideoDefinition( - definition.value("__definition").value>()->clone() - ); + CoreManager::getInstance()->getCore()->setPreferredVideoDefinition( + definition.value("__definition").value>()->clone() + ); - emit videoDefinitionChanged(definition); + emit videoDefinitionChanged(definition); } bool SettingsModel::getVideoSupported () const { - return CoreManager::getInstance()->getCore()->videoSupported(); + return CoreManager::getInstance()->getCore()->videoSupported(); } // ----------------------------------------------------------------------------- bool SettingsModel::getShowVideoCodecs () const { - return !!mConfig->getInt(UiSection, "show_video_codecs", 1); + return !!mConfig->getInt(UiSection, "show_video_codecs", 1); } void SettingsModel::setShowVideoCodecs (bool status) { - mConfig->setInt(UiSection, "show_video_codecs", status); - emit showVideoCodecsChanged(status); + mConfig->setInt(UiSection, "show_video_codecs", status); + emit showVideoCodecsChanged(status); } // ============================================================================= @@ -322,253 +462,274 @@ void SettingsModel::setShowVideoCodecs (bool status) { // ============================================================================= bool SettingsModel::getAutoAnswerStatus () const { - return !!mConfig->getInt(UiSection, "auto_answer", 0); + return !!mConfig->getInt(UiSection, "auto_answer", 0); } void SettingsModel::setAutoAnswerStatus (bool status) { - mConfig->setInt(UiSection, "auto_answer", status); - emit autoAnswerStatusChanged(status); + mConfig->setInt(UiSection, "auto_answer", status); + emit autoAnswerStatusChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getAutoAnswerVideoStatus () const { - return !!mConfig->getInt(UiSection, "auto_answer_with_video", 0); + return !!mConfig->getInt(UiSection, "auto_answer_with_video", 0); } void SettingsModel::setAutoAnswerVideoStatus (bool status) { - mConfig->setInt(UiSection, "auto_answer_with_video", status); - emit autoAnswerVideoStatusChanged(status); + mConfig->setInt(UiSection, "auto_answer_with_video", status); + emit autoAnswerVideoStatusChanged(status); } // ----------------------------------------------------------------------------- int SettingsModel::getAutoAnswerDelay () const { - return mConfig->getInt(UiSection, "auto_answer_delay", 0); + return mConfig->getInt(UiSection, "auto_answer_delay", 0); } void SettingsModel::setAutoAnswerDelay (int delay) { - mConfig->setInt(UiSection, "auto_answer_delay", delay); - emit autoAnswerDelayChanged(delay); + mConfig->setInt(UiSection, "auto_answer_delay", delay); + emit autoAnswerDelayChanged(delay); } // ----------------------------------------------------------------------------- bool SettingsModel::getShowTelKeypadAutomatically () const { - return !!mConfig->getInt(UiSection, "show_tel_keypad_automatically", 0); + return !!mConfig->getInt(UiSection, "show_tel_keypad_automatically", 0); } void SettingsModel::setShowTelKeypadAutomatically (bool status) { - mConfig->setInt(UiSection, "show_tel_keypad_automatically", status); - emit showTelKeypadAutomaticallyChanged(status); + mConfig->setInt(UiSection, "show_tel_keypad_automatically", status); + emit showTelKeypadAutomaticallyChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getKeepCallsWindowInBackground () const { - return !!mConfig->getInt(UiSection, "keep_calls_window_in_background", 0); + return !!mConfig->getInt(UiSection, "keep_calls_window_in_background", 0); } void SettingsModel::setKeepCallsWindowInBackground (bool status) { - mConfig->setInt(UiSection, "keep_calls_window_in_background", status); - emit keepCallsWindowInBackgroundChanged(status); + mConfig->setInt(UiSection, "keep_calls_window_in_background", status); + emit keepCallsWindowInBackgroundChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getOutgoingCallsEnabled () const { - return !!mConfig->getInt(UiSection, "outgoing_calls_enabled", 1); + return !!mConfig->getInt(UiSection, "outgoing_calls_enabled", 1); } void SettingsModel::setOutgoingCallsEnabled (bool status) { - mConfig->setInt(UiSection, "outgoing_calls_enabled", status); - emit outgoingCallsEnabledChanged(status); + mConfig->setInt(UiSection, "outgoing_calls_enabled", status); + emit outgoingCallsEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getCallRecorderEnabled () const { - return !!mConfig->getInt(UiSection, "call_recorder_enabled", 1); + return !!mConfig->getInt(UiSection, "call_recorder_enabled", 1); } void SettingsModel::setCallRecorderEnabled (bool status) { - mConfig->setInt(UiSection, "call_recorder_enabled", status); - emit callRecorderEnabledChanged(status); + mConfig->setInt(UiSection, "call_recorder_enabled", status); + emit callRecorderEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getAutomaticallyRecordCalls () const { - return !!mConfig->getInt(UiSection, "automatically_record_calls", 0); + return !!mConfig->getInt(UiSection, "automatically_record_calls", 0); } void SettingsModel::setAutomaticallyRecordCalls (bool status) { - mConfig->setInt(UiSection, "automatically_record_calls", status); - emit automaticallyRecordCallsChanged(status); + mConfig->setInt(UiSection, "automatically_record_calls", status); + emit automaticallyRecordCallsChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getCallPauseEnabled () const { - return !!mConfig->getInt(UiSection, "call_pause_enabled", 1); + return !!mConfig->getInt(UiSection, "call_pause_enabled", 1); } void SettingsModel::setCallPauseEnabled (bool status) { - mConfig->setInt(UiSection, "call_pause_enabled", status); - emit callPauseEnabledChanged(status); + mConfig->setInt(UiSection, "call_pause_enabled", status); + emit callPauseEnabledChanged(status); } bool SettingsModel::getMuteMicrophoneEnabled () const { - return !!mConfig->getInt(UiSection, "mute_microphone_enabled", 1); + return !!mConfig->getInt(UiSection, "mute_microphone_enabled", 1); } void SettingsModel::setMuteMicrophoneEnabled (bool status) { - mConfig->setInt(UiSection, "mute_microphone_enabled", status); - emit muteMicrophoneEnabledChanged(status); + mConfig->setInt(UiSection, "mute_microphone_enabled", status); + emit muteMicrophoneEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getChatEnabled () const { - return !!mConfig->getInt(UiSection, "chat_enabled", 1); + return !!mConfig->getInt(UiSection, "chat_enabled", 1); } void SettingsModel::setChatEnabled (bool status) { - mConfig->setInt(UiSection, "chat_enabled", status); - emit chatEnabledChanged(status); + mConfig->setInt(UiSection, "chat_enabled", status); + emit chatEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getConferenceEnabled () const { - return !!mConfig->getInt(UiSection, "conference_enabled", 1); + return !!mConfig->getInt(UiSection, "conference_enabled", 1); } void SettingsModel::setConferenceEnabled (bool status) { - mConfig->setInt(UiSection, "conference_enabled", status); - emit conferenceEnabledChanged(status); + mConfig->setInt(UiSection, "conference_enabled", status); + emit conferenceEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getChatNotificationSoundEnabled () const { - return !!mConfig->getInt(UiSection, "chat_sound_notification_enabled", 1); + return !!mConfig->getInt(UiSection, "chat_sound_notification_enabled", 1); } void SettingsModel::setChatNotificationSoundEnabled (bool status) { - mConfig->setInt(UiSection, "chat_sound_notification_enabled", status); - emit chatNotificationSoundEnabledChanged(status); + mConfig->setInt(UiSection, "chat_sound_notification_enabled", status); + emit chatNotificationSoundEnabledChanged(status); } // ----------------------------------------------------------------------------- QString SettingsModel::getChatNotificationSoundPath () const { - static const string defaultFile = linphone::Factory::get()->getSoundResourcesDir() + "/incoming_chat.wav"; - return Utils::coreStringToAppString(mConfig->getString(UiSection, "chat_sound_notification_file", defaultFile)); + static const string defaultFile = linphone::Factory::get()->getSoundResourcesDir() + "/incoming_chat.wav"; + return Utils::coreStringToAppString(mConfig->getString(UiSection, "chat_sound_notification_file", defaultFile)); } void SettingsModel::setChatNotificationSoundPath (const QString &path) { - QString cleanedPath = QDir::cleanPath(path); - mConfig->setString(UiSection, "chat_sound_notification_file", Utils::appStringToCoreString(cleanedPath)); - emit chatNotificationSoundPathChanged(cleanedPath); + QString cleanedPath = QDir::cleanPath(path); + mConfig->setString(UiSection, "chat_sound_notification_file", Utils::appStringToCoreString(cleanedPath)); + emit chatNotificationSoundPathChanged(cleanedPath); } // ----------------------------------------------------------------------------- QString SettingsModel::getFileTransferUrl () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getFileTransferServer() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getFileTransferServer() + ); } void SettingsModel::setFileTransferUrl (const QString &url) { - CoreManager::getInstance()->getCore()->setFileTransferServer( - Utils::appStringToCoreString(url) - ); - emit fileTransferUrlChanged(url); + CoreManager::getInstance()->getCore()->setFileTransferServer( + Utils::appStringToCoreString(url) + ); + emit fileTransferUrlChanged(url); } // ----------------------------------------------------------------------------- bool SettingsModel::getLimeIsSupported () const { - return CoreManager::getInstance()->getCore()->limeAvailable(); + return CoreManager::getInstance()->getCore()->limeAvailable(); } // ----------------------------------------------------------------------------- static inline QVariant buildEncryptionDescription (SettingsModel::MediaEncryption encryption, const char *description) { - return QVariantList() << encryption << description; + return QVariantList() << encryption << description; } QVariantList SettingsModel::getSupportedMediaEncryptions () const { - shared_ptr core = CoreManager::getInstance()->getCore(); - QVariantList list; + shared_ptr core = CoreManager::getInstance()->getCore(); + QVariantList list; - if (core->mediaEncryptionSupported(linphone::MediaEncryption::DTLS)) - list << buildEncryptionDescription(MediaEncryptionDtls, "DTLS"); + if (core->mediaEncryptionSupported(linphone::MediaEncryption::SRTP)) + list << buildEncryptionDescription(MediaEncryptionSrtp, "SRTP"); - if (core->mediaEncryptionSupported(linphone::MediaEncryption::SRTP)) - list << buildEncryptionDescription(MediaEncryptionSrtp, "SRTP"); + if (core->mediaEncryptionSupported(linphone::MediaEncryption::ZRTP)) + list << buildEncryptionDescription(MediaEncryptionZrtp, "ZRTP"); + + if (core->mediaEncryptionSupported(linphone::MediaEncryption::DTLS)) + list << buildEncryptionDescription(MediaEncryptionDtls, "DTLS"); - if (core->mediaEncryptionSupported(linphone::MediaEncryption::ZRTP)) - list << buildEncryptionDescription(MediaEncryptionZrtp, "ZRTP"); - - return list; + return list; } // ----------------------------------------------------------------------------- SettingsModel::MediaEncryption SettingsModel::getMediaEncryption () const { - return static_cast( - CoreManager::getInstance()->getCore()->getMediaEncryption() - ); + return static_cast( + CoreManager::getInstance()->getCore()->getMediaEncryption() + ); } void SettingsModel::setMediaEncryption (MediaEncryption encryption) { - if (encryption == getMediaEncryption()) - return; + if (encryption == getMediaEncryption()) + return; - if (encryption != SettingsModel::MediaEncryptionZrtp) - setLimeState(SettingsModel::LimeStateDisabled); + if (encryption != SettingsModel::MediaEncryptionZrtp) + setLimeState(SettingsModel::LimeStateDisabled); - CoreManager::getInstance()->getCore()->setMediaEncryption( - static_cast(encryption) - ); + CoreManager::getInstance()->getCore()->setMediaEncryption( + static_cast(encryption) + ); + if (mandatoryMediaEncryptionEnabled() && encryption == SettingsModel::MediaEncryptionNone) { + //Disable mandatory encryption if none is selected + enableMandatoryMediaEncryption(false); + } - emit mediaEncryptionChanged(encryption); + emit mediaEncryptionChanged(encryption); +} + +bool SettingsModel::mandatoryMediaEncryptionEnabled () const { + return CoreManager::getInstance()->getCore()->isMediaEncryptionMandatory(); +} + +void SettingsModel::enableMandatoryMediaEncryption(bool mandatory) { + if (mandatoryMediaEncryptionEnabled() == mandatory) { + return; + } + CoreManager::getInstance()->getCore()->setMediaEncryptionMandatory(mandatory); + if (mandatory && getMediaEncryption() == SettingsModel::MediaEncryptionNone) { + //Force to SRTP if mandatory but 'none' was selected + setMediaEncryption(SettingsModel::MediaEncryptionSrtp); + } else { + emit mediaEncryptionChanged(getMediaEncryption()); + } } // ----------------------------------------------------------------------------- SettingsModel::LimeState SettingsModel::getLimeState () const { - return static_cast( - CoreManager::getInstance()->getCore()->limeEnabled() - ); + return static_cast( + CoreManager::getInstance()->getCore()->limeEnabled() + ); } void SettingsModel::setLimeState (LimeState state) { - if (state == getLimeState()) - return; + if (state == getLimeState()) + return; - if (state != SettingsModel::LimeStateDisabled) - setMediaEncryption(SettingsModel::MediaEncryptionZrtp); + if (state != SettingsModel::LimeStateDisabled) + setMediaEncryption(SettingsModel::MediaEncryptionZrtp); - CoreManager::getInstance()->getCore()->enableLime( - static_cast(state) - ); + CoreManager::getInstance()->getCore()->enableLime( + static_cast(state) + ); - emit limeStateChanged(state); + emit limeStateChanged(state); } // ----------------------------------------------------------------------------- bool SettingsModel::getContactsEnabled () const { - return !!mConfig->getInt(UiSection, "contacts_enabled", 1); + return !!mConfig->getInt(UiSection, "contacts_enabled", 1); } void SettingsModel::setContactsEnabled (bool status) { - mConfig->setInt(UiSection, "contacts_enabled", status); - emit contactsEnabledChanged(status); + mConfig->setInt(UiSection, "contacts_enabled", status); + emit contactsEnabledChanged(status); } // ============================================================================= @@ -576,347 +737,347 @@ void SettingsModel::setContactsEnabled (bool status) { // ============================================================================= bool SettingsModel::getShowNetworkSettings () const { - return !!mConfig->getInt(UiSection, "show_network_settings", 1); + return !!mConfig->getInt(UiSection, "show_network_settings", 1); } void SettingsModel::setShowNetworkSettings (bool status) { - mConfig->setInt(UiSection, "show_network_settings", status); - emit showNetworkSettingsChanged(status); + mConfig->setInt(UiSection, "show_network_settings", status); + emit showNetworkSettingsChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getUseSipInfoForDtmfs () const { - return CoreManager::getInstance()->getCore()->getUseInfoForDtmf(); + return CoreManager::getInstance()->getCore()->getUseInfoForDtmf(); } void SettingsModel::setUseSipInfoForDtmfs (bool status) { - shared_ptr core = CoreManager::getInstance()->getCore(); + shared_ptr core = CoreManager::getInstance()->getCore(); - if (status) { - core->setUseRfc2833ForDtmf(false); - core->setUseInfoForDtmf(true); - } else { - core->setUseInfoForDtmf(false); - core->setUseRfc2833ForDtmf(true); - } + if (status) { + core->setUseRfc2833ForDtmf(false); + core->setUseInfoForDtmf(true); + } else { + core->setUseInfoForDtmf(false); + core->setUseRfc2833ForDtmf(true); + } - emit dtmfsProtocolChanged(); + emit dtmfsProtocolChanged(); } // ----------------------------------------------------------------------------- bool SettingsModel::getUseRfc2833ForDtmfs () const { - return CoreManager::getInstance()->getCore()->getUseRfc2833ForDtmf(); + return CoreManager::getInstance()->getCore()->getUseRfc2833ForDtmf(); } void SettingsModel::setUseRfc2833ForDtmfs (bool status) { - shared_ptr core = CoreManager::getInstance()->getCore(); + shared_ptr core = CoreManager::getInstance()->getCore(); - if (status) { - core->setUseInfoForDtmf(false); - core->setUseRfc2833ForDtmf(true); - } else { - core->setUseRfc2833ForDtmf(false); - core->setUseInfoForDtmf(true); - } + if (status) { + core->setUseInfoForDtmf(false); + core->setUseRfc2833ForDtmf(true); + } else { + core->setUseRfc2833ForDtmf(false); + core->setUseInfoForDtmf(true); + } - emit dtmfsProtocolChanged(); + emit dtmfsProtocolChanged(); } // ----------------------------------------------------------------------------- bool SettingsModel::getIpv6Enabled () const { - return CoreManager::getInstance()->getCore()->ipv6Enabled(); + return CoreManager::getInstance()->getCore()->ipv6Enabled(); } void SettingsModel::setIpv6Enabled (bool status) { - CoreManager::getInstance()->getCore()->enableIpv6(status); - emit ipv6EnabledChanged(status); + CoreManager::getInstance()->getCore()->enableIpv6(status); + emit ipv6EnabledChanged(status); } // ----------------------------------------------------------------------------- int SettingsModel::getDownloadBandwidth () const { - return CoreManager::getInstance()->getCore()->getDownloadBandwidth(); + return CoreManager::getInstance()->getCore()->getDownloadBandwidth(); } void SettingsModel::setDownloadBandwidth (int bandwidth) { - CoreManager::getInstance()->getCore()->setDownloadBandwidth(bandwidth); - emit downloadBandWidthChanged(getDownloadBandwidth()); + CoreManager::getInstance()->getCore()->setDownloadBandwidth(bandwidth); + emit downloadBandWidthChanged(getDownloadBandwidth()); } // ----------------------------------------------------------------------------- int SettingsModel::getUploadBandwidth () const { - return CoreManager::getInstance()->getCore()->getUploadBandwidth(); + return CoreManager::getInstance()->getCore()->getUploadBandwidth(); } void SettingsModel::setUploadBandwidth (int bandwidth) { - CoreManager::getInstance()->getCore()->setUploadBandwidth(bandwidth); - emit uploadBandWidthChanged(getUploadBandwidth()); + CoreManager::getInstance()->getCore()->setUploadBandwidth(bandwidth); + emit uploadBandWidthChanged(getUploadBandwidth()); } // ----------------------------------------------------------------------------- bool SettingsModel::getAdaptiveRateControlEnabled () const { - return CoreManager::getInstance()->getCore()->adaptiveRateControlEnabled(); + return CoreManager::getInstance()->getCore()->adaptiveRateControlEnabled(); } void SettingsModel::setAdaptiveRateControlEnabled (bool status) { - CoreManager::getInstance()->getCore()->enableAdaptiveRateControl(status); - emit adaptiveRateControlEnabledChanged(status); + CoreManager::getInstance()->getCore()->enableAdaptiveRateControl(status); + emit adaptiveRateControlEnabledChanged(status); } // ----------------------------------------------------------------------------- int SettingsModel::getTcpPort () const { - return CoreManager::getInstance()->getCore()->getTransports()->getTcpPort(); + return CoreManager::getInstance()->getCore()->getTransports()->getTcpPort(); } void SettingsModel::setTcpPort (int port) { - shared_ptr core = CoreManager::getInstance()->getCore(); - shared_ptr transports = core->getTransports(); + shared_ptr core = CoreManager::getInstance()->getCore(); + shared_ptr transports = core->getTransports(); - transports->setTcpPort(port); - core->setTransports(transports); + transports->setTcpPort(port); + core->setTransports(transports); - emit tcpPortChanged(port); + emit tcpPortChanged(port); } // ----------------------------------------------------------------------------- int SettingsModel::getUdpPort () const { - return CoreManager::getInstance()->getCore()->getTransports()->getUdpPort(); + return CoreManager::getInstance()->getCore()->getTransports()->getUdpPort(); } void SettingsModel::setUdpPort (int port) { - shared_ptr core = CoreManager::getInstance()->getCore(); - shared_ptr transports = core->getTransports(); + shared_ptr core = CoreManager::getInstance()->getCore(); + shared_ptr transports = core->getTransports(); - transports->setUdpPort(port); - core->setTransports(transports); + transports->setUdpPort(port); + core->setTransports(transports); - emit udpPortChanged(port); + emit udpPortChanged(port); } // ----------------------------------------------------------------------------- QList SettingsModel::getAudioPortRange () const { - shared_ptr range = CoreManager::getInstance()->getCore()->getAudioPortsRange(); - return QList() << range->getMin() << range->getMax(); + shared_ptr range = CoreManager::getInstance()->getCore()->getAudioPortsRange(); + return QList() << range->getMin() << range->getMax(); } void SettingsModel::setAudioPortRange (const QList &range) { - shared_ptr core = CoreManager::getInstance()->getCore(); - int a = range[0]; - int b = range[1]; + shared_ptr core = CoreManager::getInstance()->getCore(); + int a = range[0]; + int b = range[1]; - if (b == -1) - core->setAudioPort(a); - else - core->setAudioPortRange(a, b); + if (b == -1) + core->setAudioPort(a); + else + core->setAudioPortRange(a, b); - emit audioPortRangeChanged(a, b); + emit audioPortRangeChanged(a, b); } // ----------------------------------------------------------------------------- QList SettingsModel::getVideoPortRange () const { - shared_ptr range = CoreManager::getInstance()->getCore()->getVideoPortsRange(); - return QList() << range->getMin() << range->getMax(); + shared_ptr range = CoreManager::getInstance()->getCore()->getVideoPortsRange(); + return QList() << range->getMin() << range->getMax(); } void SettingsModel::setVideoPortRange (const QList &range) { - shared_ptr core = CoreManager::getInstance()->getCore(); - int a = range[0]; - int b = range[1]; + shared_ptr core = CoreManager::getInstance()->getCore(); + int a = range[0]; + int b = range[1]; - if (b == -1) - core->setVideoPort(a); - else - core->setVideoPortRange(a, b); + if (b == -1) + core->setVideoPort(a); + else + core->setVideoPortRange(a, b); - emit videoPortRangeChanged(a, b); + emit videoPortRangeChanged(a, b); } // ----------------------------------------------------------------------------- bool SettingsModel::getIceEnabled () const { - return CoreManager::getInstance()->getCore()->getNatPolicy()->iceEnabled(); + return CoreManager::getInstance()->getCore()->getNatPolicy()->iceEnabled(); } void SettingsModel::setIceEnabled (bool status) { - shared_ptr natPolicy = CoreManager::getInstance()->getCore()->getNatPolicy(); + shared_ptr natPolicy = CoreManager::getInstance()->getCore()->getNatPolicy(); - natPolicy->enableIce(status); - natPolicy->enableStun(status); + natPolicy->enableIce(status); + natPolicy->enableStun(status); - emit iceEnabledChanged(status); + emit iceEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getTurnEnabled () const { - return CoreManager::getInstance()->getCore()->getNatPolicy()->turnEnabled(); + return CoreManager::getInstance()->getCore()->getNatPolicy()->turnEnabled(); } void SettingsModel::setTurnEnabled (bool status) { - CoreManager::getInstance()->getCore()->getNatPolicy()->enableTurn(status); - emit turnEnabledChanged(status); + CoreManager::getInstance()->getCore()->getNatPolicy()->enableTurn(status); + emit turnEnabledChanged(status); } // ----------------------------------------------------------------------------- QString SettingsModel::getStunServer () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServer() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServer() + ); } void SettingsModel::setStunServer (const QString &stunServer) { - CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServer( - Utils::appStringToCoreString(stunServer) - ); + CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServer( + Utils::appStringToCoreString(stunServer) + ); } // ----------------------------------------------------------------------------- QString SettingsModel::getTurnUser () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServerUsername() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServerUsername() + ); } void SettingsModel::setTurnUser (const QString &user) { - CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServerUsername( - Utils::appStringToCoreString(user) - ); + CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServerUsername( + Utils::appStringToCoreString(user) + ); - emit turnUserChanged(user); + emit turnUserChanged(user); } // ----------------------------------------------------------------------------- QString SettingsModel::getTurnPassword () const { - shared_ptr core(CoreManager::getInstance()->getCore()); - shared_ptr natPolicy(core->getNatPolicy()); - shared_ptr authInfo(core->findAuthInfo( - "", - natPolicy->getStunServerUsername(), - natPolicy->getStunServer() - )); - return authInfo ? Utils::coreStringToAppString(authInfo->getPassword()) : QString(""); + shared_ptr core(CoreManager::getInstance()->getCore()); + shared_ptr natPolicy(core->getNatPolicy()); + shared_ptr authInfo(core->findAuthInfo( + "", + natPolicy->getStunServerUsername(), + natPolicy->getStunServer() + )); + return authInfo ? Utils::coreStringToAppString(authInfo->getPassword()) : QString(""); } void SettingsModel::setTurnPassword (const QString &password) { - shared_ptr core(CoreManager::getInstance()->getCore()); - shared_ptr natPolicy(core->getNatPolicy()); + shared_ptr core(CoreManager::getInstance()->getCore()); + shared_ptr natPolicy(core->getNatPolicy()); - const string &turnUser(natPolicy->getStunServerUsername()); - shared_ptr authInfo(core->findAuthInfo("", turnUser, natPolicy->getStunServer())); - if (authInfo) { - shared_ptr clonedAuthInfo(authInfo->clone()); - clonedAuthInfo->setPassword(Utils::appStringToCoreString(password)); + const string &turnUser(natPolicy->getStunServerUsername()); + shared_ptr authInfo(core->findAuthInfo("", turnUser, natPolicy->getStunServer())); + if (authInfo) { + shared_ptr clonedAuthInfo(authInfo->clone()); + clonedAuthInfo->setPassword(Utils::appStringToCoreString(password)); - core->addAuthInfo(clonedAuthInfo); - core->removeAuthInfo(authInfo); - } else - core->addAuthInfo(linphone::Factory::get()->createAuthInfo( - turnUser, - turnUser, - Utils::appStringToCoreString(password), - "", - "", - "" - )); + core->addAuthInfo(clonedAuthInfo); + core->removeAuthInfo(authInfo); + } else + core->addAuthInfo(linphone::Factory::get()->createAuthInfo( + turnUser, + turnUser, + Utils::appStringToCoreString(password), + "", + "", + "" + )); - emit turnPasswordChanged(password); + emit turnPasswordChanged(password); } // ----------------------------------------------------------------------------- int SettingsModel::getDscpSip () const { - return CoreManager::getInstance()->getCore()->getSipDscp(); + return CoreManager::getInstance()->getCore()->getSipDscp(); } void SettingsModel::setDscpSip (int dscp) { - CoreManager::getInstance()->getCore()->setSipDscp(dscp); - emit dscpSipChanged(dscp); + CoreManager::getInstance()->getCore()->setSipDscp(dscp); + emit dscpSipChanged(dscp); } int SettingsModel::getDscpAudio () const { - return CoreManager::getInstance()->getCore()->getAudioDscp(); + return CoreManager::getInstance()->getCore()->getAudioDscp(); } void SettingsModel::setDscpAudio (int dscp) { - CoreManager::getInstance()->getCore()->setAudioDscp(dscp); - emit dscpAudioChanged(dscp); + CoreManager::getInstance()->getCore()->setAudioDscp(dscp); + emit dscpAudioChanged(dscp); } int SettingsModel::getDscpVideo () const { - return CoreManager::getInstance()->getCore()->getVideoDscp(); + return CoreManager::getInstance()->getCore()->getVideoDscp(); } void SettingsModel::setDscpVideo (int dscp) { - CoreManager::getInstance()->getCore()->setVideoDscp(dscp); - emit dscpVideoChanged(dscp); + CoreManager::getInstance()->getCore()->setVideoDscp(dscp); + emit dscpVideoChanged(dscp); } // ----------------------------------------------------------------------------- bool SettingsModel::getRlsUriEnabled () const { - return !!mConfig->getInt(UiSection, "rls_uri_enabled", true); + return !!mConfig->getInt(UiSection, "rls_uri_enabled", true); } void SettingsModel::setRlsUriEnabled (bool status) { - mConfig->setInt(UiSection, "rls_uri_enabled", status); - mConfig->setString("sip", "rls_uri", status ? DefaultRlsUri : ""); - emit rlsUriEnabledChanged(status); + mConfig->setInt(UiSection, "rls_uri_enabled", status); + mConfig->setString("sip", "rls_uri", status ? DefaultRlsUri : ""); + emit rlsUriEnabledChanged(status); } static string getRlsUriDomain () { - static string domain; - if (!domain.empty()) - return domain; + static string domain; + if (!domain.empty()) + return domain; - shared_ptr linphoneAddress = CoreManager::getInstance()->getCore()->createAddress(DefaultRlsUri); - Q_CHECK_PTR(linphoneAddress); - domain = linphoneAddress->getDomain(); - return domain; + shared_ptr linphoneAddress = CoreManager::getInstance()->getCore()->createAddress(DefaultRlsUri); + Q_CHECK_PTR(linphoneAddress); + domain = linphoneAddress->getDomain(); + return domain; } void SettingsModel::configureRlsUri () { - // Ensure rls uri is empty. - if (!getRlsUriEnabled()) { - mConfig->setString("sip", "rls_uri", ""); - return; - } + // Ensure rls uri is empty. + if (!getRlsUriEnabled()) { + mConfig->setString("sip", "rls_uri", ""); + return; + } - // Set rls uri if necessary. - const string domain = getRlsUriDomain(); - for (const auto &proxyConfig : CoreManager::getInstance()->getCore()->getProxyConfigList()) - if (proxyConfig->getDomain() == domain) { - mConfig->setString("sip", "rls_uri", DefaultRlsUri); - return; - } + // Set rls uri if necessary. + const string domain = getRlsUriDomain(); + for (const auto &proxyConfig : CoreManager::getInstance()->getCore()->getProxyConfigList()) + if (proxyConfig->getDomain() == domain) { + mConfig->setString("sip", "rls_uri", DefaultRlsUri); + return; + } - mConfig->setString("sip", "rls_uri", ""); + mConfig->setString("sip", "rls_uri", ""); } void SettingsModel::configureRlsUri (const shared_ptr &proxyConfig) { - if (!getRlsUriEnabled()) { - mConfig->setString("sip", "rls_uri", ""); - return; - } + if (!getRlsUriEnabled()) { + mConfig->setString("sip", "rls_uri", ""); + return; + } - const string domain = getRlsUriDomain(); - if (proxyConfig->getDomain() == domain) { - mConfig->setString("sip", "rls_uri", DefaultRlsUri); - return; - } + const string domain = getRlsUriDomain(); + if (proxyConfig->getDomain() == domain) { + mConfig->setString("sip", "rls_uri", DefaultRlsUri); + return; + } - mConfig->setString("sip", "rls_uri", ""); + mConfig->setString("sip", "rls_uri", ""); } // ============================================================================= @@ -924,77 +1085,77 @@ void SettingsModel::configureRlsUri (const shared_ptrgetString(UiSection, "saved_screenshots_folder", Paths::getCapturesDirPath()) - ) - ) + QDir::separator(); + return QDir::cleanPath( + Utils::coreStringToAppString( + mConfig->getString(UiSection, "saved_screenshots_folder", Paths::getCapturesDirPath()) + ) + ) + QDir::separator(); } void SettingsModel::setSavedScreenshotsFolder (const QString &folder) { - QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); - mConfig->setString(UiSection, "saved_screenshots_folder", Utils::appStringToCoreString(cleanedFolder)); - emit savedScreenshotsFolderChanged(cleanedFolder); + QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); + mConfig->setString(UiSection, "saved_screenshots_folder", Utils::appStringToCoreString(cleanedFolder)); + emit savedScreenshotsFolderChanged(cleanedFolder); } // ----------------------------------------------------------------------------- static inline string getLegacySavedCallsFolder (const shared_ptr &config) { - return config->getString(SettingsModel::UiSection, "saved_videos_folder", Paths::getCapturesDirPath()); + return config->getString(SettingsModel::UiSection, "saved_videos_folder", Paths::getCapturesDirPath()); } QString SettingsModel::getSavedCallsFolder () const { - return QDir::cleanPath( - Utils::coreStringToAppString( - mConfig->getString(UiSection, "saved_calls_folder", getLegacySavedCallsFolder(mConfig)) - ) - ) + QDir::separator(); + return QDir::cleanPath( + Utils::coreStringToAppString( + mConfig->getString(UiSection, "saved_calls_folder", getLegacySavedCallsFolder(mConfig)) + ) + ) + QDir::separator(); } void SettingsModel::setSavedCallsFolder (const QString &folder) { - QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); - mConfig->setString(UiSection, "saved_calls_folder", Utils::appStringToCoreString(cleanedFolder)); - emit savedCallsFolderChanged(cleanedFolder); + QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); + mConfig->setString(UiSection, "saved_calls_folder", Utils::appStringToCoreString(cleanedFolder)); + emit savedCallsFolderChanged(cleanedFolder); } // ----------------------------------------------------------------------------- QString SettingsModel::getDownloadFolder () const { - return QDir::cleanPath( - Utils::coreStringToAppString( - mConfig->getString(UiSection, "download_folder", Paths::getDownloadDirPath()) - ) - ) + QDir::separator(); + return QDir::cleanPath( + Utils::coreStringToAppString( + mConfig->getString(UiSection, "download_folder", Paths::getDownloadDirPath()) + ) + ) + QDir::separator(); } void SettingsModel::setDownloadFolder (const QString &folder) { - QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); - mConfig->setString(UiSection, "download_folder", Utils::appStringToCoreString(cleanedFolder)); - emit downloadFolderChanged(cleanedFolder); + QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); + mConfig->setString(UiSection, "download_folder", Utils::appStringToCoreString(cleanedFolder)); + emit downloadFolderChanged(cleanedFolder); } // ----------------------------------------------------------------------------- QString SettingsModel::getRemoteProvisioning () const { - return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getProvisioningUri()); + return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getProvisioningUri()); } void SettingsModel::setRemoteProvisioning (const QString &remoteProvisioning) { - if (!CoreManager::getInstance()->getCore()->setProvisioningUri(Utils::appStringToCoreString(remoteProvisioning))) - emit remoteProvisioningChanged(remoteProvisioning); - else - emit remoteProvisioningNotChanged(remoteProvisioning); + if (!CoreManager::getInstance()->getCore()->setProvisioningUri(Utils::appStringToCoreString(remoteProvisioning))) + emit remoteProvisioningChanged(remoteProvisioning); + else + emit remoteProvisioningNotChanged(remoteProvisioning); } // ----------------------------------------------------------------------------- bool SettingsModel::getExitOnClose () const { - return !!mConfig->getInt(UiSection, "exit_on_close", 0); + return !!mConfig->getInt(UiSection, "exit_on_close", 0); } void SettingsModel::setExitOnClose (bool value) { - mConfig->setInt(UiSection, "exit_on_close", value); - emit exitOnCloseChanged(value); + mConfig->setInt(UiSection, "exit_on_close", value); + emit exitOnCloseChanged(value); } // ============================================================================= @@ -1002,85 +1163,97 @@ void SettingsModel::setExitOnClose (bool value) { // ============================================================================= QString SettingsModel::getLogsFolder () const { - return getLogsFolder(mConfig); + return getLogsFolder(mConfig); } void SettingsModel::setLogsFolder (const QString &folder) { - // Do not update path in linphone core. - // Just update the config file. - mConfig->setString(UiSection, "logs_folder", Utils::appStringToCoreString(folder)); + // Do not update path in linphone core. + // Just update the config file. + mConfig->setString(UiSection, "logs_folder", Utils::appStringToCoreString(folder)); - emit logsFolderChanged(folder); + emit logsFolderChanged(folder); } // ----------------------------------------------------------------------------- QString SettingsModel::getLogsUploadUrl () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getLogCollectionUploadServerUrl() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getLogCollectionUploadServerUrl() + ); } void SettingsModel::setLogsUploadUrl (const QString &url) { - CoreManager::getInstance()->getCore()->setLogCollectionUploadServerUrl( - Utils::appStringToCoreString(url) - ); + CoreManager::getInstance()->getCore()->setLogCollectionUploadServerUrl( + Utils::appStringToCoreString(url) + ); - emit logsUploadUrlChanged(getLogsUploadUrl()); + emit logsUploadUrlChanged(getLogsUploadUrl()); } // ----------------------------------------------------------------------------- bool SettingsModel::getLogsEnabled () const { - return getLogsEnabled(mConfig); + return getLogsEnabled(mConfig); } void SettingsModel::setLogsEnabled (bool status) { - mConfig->setInt(UiSection, "logs_enabled", status); - Logger::getInstance()->enable(status); - emit logsEnabledChanged(status); + mConfig->setInt(UiSection, "logs_enabled", status); + Logger::getInstance()->enable(status); + emit logsEnabledChanged(status); } // --------------------------------------------------------------------------- QString SettingsModel::getLogsEmail () const { - return Utils::coreStringToAppString( - mConfig->getString(UiSection, "logs_email", DefaultLogsEmail) - ); + return Utils::coreStringToAppString( + mConfig->getString(UiSection, "logs_email", DefaultLogsEmail) + ); } void SettingsModel::setLogsEmail (const QString &email) { - mConfig->setString(UiSection, "logs_email", Utils::appStringToCoreString(email)); - emit logsEmailChanged(email); + mConfig->setString(UiSection, "logs_email", Utils::appStringToCoreString(email)); + emit logsEmailChanged(email); } // --------------------------------------------------------------------------- QString SettingsModel::getLogsFolder (const shared_ptr &config) { - return Utils::coreStringToAppString(config - ? config->getString(UiSection, "logs_folder", Paths::getLogsDirPath()) - : Paths::getLogsDirPath()); + return Utils::coreStringToAppString(config + ? config->getString(UiSection, "logs_folder", Paths::getLogsDirPath()) + : Paths::getLogsDirPath()); } bool SettingsModel::getLogsEnabled (const shared_ptr &config) { - return config ? config->getInt(UiSection, "logs_enabled", false) : false; + return config ? config->getInt(UiSection, "logs_enabled", false) : false; } // --------------------------------------------------------------------------- bool SettingsModel::getDeveloperSettingsEnabled () const { - #ifdef DEBUG - return !!mConfig->getInt(UiSection, "developer_settings", 0); - #else - return false; - #endif // ifdef DEBUG +#ifdef DEBUG + return !!mConfig->getInt(UiSection, "developer_settings", 0); +#else + return false; +#endif // ifdef DEBUG } void SettingsModel::setDeveloperSettingsEnabled (bool status) { - #ifdef DEBUG - mConfig->setInt(UiSection, "developer_settings", status); - emit developerSettingsEnabledChanged(status); - #else - qWarning() << QStringLiteral("Unable to change developer settings mode in release version."); - #endif // ifdef DEBUG +#ifdef DEBUG + mConfig->setInt(UiSection, "developer_settings", status); + emit developerSettingsEnabledChanged(status); +#else + qWarning() << QStringLiteral("Unable to change developer settings mode in release version."); +#endif // ifdef DEBUG +} + +void SettingsModel::handleCallCreated(const shared_ptr &call) { + emit isInCallChanged(getIsInCall()); +} + +void SettingsModel::handleCallStateChanged(const shared_ptr &call, linphone::Call::State state) { + emit isInCallChanged(getIsInCall()); +} + +bool SettingsModel::getIsInCall() const { + return CoreManager::getInstance()->getCore()->getCallsNb() != 0; } diff --git a/src/components/settings/SettingsModel.hpp b/src/components/settings/SettingsModel.hpp index efee8835b..1c39482f9 100644 --- a/src/components/settings/SettingsModel.hpp +++ b/src/components/settings/SettingsModel.hpp @@ -17,534 +17,587 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Created on: February 2, 2017 - * Author: Ronan Abhamon + * Author: Ronan Abhamon */ #ifndef SETTINGS_MODEL_H_ #define SETTINGS_MODEL_H_ #include +#include #include +#include "components/core/CoreHandlers.hpp" + // ============================================================================= class SettingsModel : public QObject { - Q_OBJECT; + Q_OBJECT; - // =========================================================================== - // PROPERTIES. - // =========================================================================== + // =========================================================================== + // PROPERTIES. + // =========================================================================== - // Assistant. ---------------------------------------------------------------- + // Assistant. ---------------------------------------------------------------- - Q_PROPERTY(bool createAppSipAccountEnabled READ getCreateAppSipAccountEnabled WRITE setCreateAppSipAccountEnabled NOTIFY createAppSipAccountEnabledChanged); - Q_PROPERTY(bool fetchRemoteConfigurationEnabled READ getFetchRemoteConfigurationEnabled WRITE setFetchRemoteConfigurationEnabled NOTIFY fetchRemoteConfigurationEnabledChanged); - Q_PROPERTY(bool useAppSipAccountEnabled READ getUseAppSipAccountEnabled WRITE setUseAppSipAccountEnabled NOTIFY useAppSipAccountEnabledChanged); - Q_PROPERTY(bool useOtherSipAccountEnabled READ getUseOtherSipAccountEnabled WRITE setUseOtherSipAccountEnabled NOTIFY useOtherSipAccountEnabledChanged); + Q_PROPERTY(bool createAppSipAccountEnabled READ getCreateAppSipAccountEnabled WRITE setCreateAppSipAccountEnabled NOTIFY createAppSipAccountEnabledChanged); + Q_PROPERTY(bool fetchRemoteConfigurationEnabled READ getFetchRemoteConfigurationEnabled WRITE setFetchRemoteConfigurationEnabled NOTIFY fetchRemoteConfigurationEnabledChanged); + Q_PROPERTY(bool useAppSipAccountEnabled READ getUseAppSipAccountEnabled WRITE setUseAppSipAccountEnabled NOTIFY useAppSipAccountEnabledChanged); + Q_PROPERTY(bool useOtherSipAccountEnabled READ getUseOtherSipAccountEnabled WRITE setUseOtherSipAccountEnabled NOTIFY useOtherSipAccountEnabledChanged); - Q_PROPERTY(bool assistantSupportsPhoneNumbers READ getAssistantSupportsPhoneNumbers WRITE setAssistantSupportsPhoneNumbers NOTIFY assistantSupportsPhoneNumbersChanged); + Q_PROPERTY(bool assistantSupportsPhoneNumbers READ getAssistantSupportsPhoneNumbers WRITE setAssistantSupportsPhoneNumbers NOTIFY assistantSupportsPhoneNumbersChanged); - // Audio. -------------------------------------------------------------------- + // Audio. -------------------------------------------------------------------- - Q_PROPERTY(QStringList captureDevices READ getCaptureDevices CONSTANT); - Q_PROPERTY(QStringList playbackDevices READ getPlaybackDevices CONSTANT); + Q_PROPERTY(bool captureGraphRunning READ getCaptureGraphRunning NOTIFY captureGraphRunningChanged); - Q_PROPERTY(QString captureDevice READ getCaptureDevice WRITE setCaptureDevice NOTIFY captureDeviceChanged); - Q_PROPERTY(QString playbackDevice READ getPlaybackDevice WRITE setPlaybackDevice NOTIFY playbackDeviceChanged); - Q_PROPERTY(QString ringerDevice READ getRingerDevice WRITE setRingerDevice NOTIFY ringerDeviceChanged); + Q_PROPERTY(QStringList captureDevices READ getCaptureDevices NOTIFY captureDevicesChanged); + Q_PROPERTY(QStringList playbackDevices READ getPlaybackDevices NOTIFY playbackDevicesChanged); - Q_PROPERTY(QString ringPath READ getRingPath WRITE setRingPath NOTIFY ringPathChanged); + Q_PROPERTY(float playbackGain READ getPlaybackGain WRITE setPlaybackGain NOTIFY playbackGainChanged); + Q_PROPERTY(float captureGain READ getCaptureGain WRITE setCaptureGain NOTIFY captureGainChanged); - Q_PROPERTY(bool echoCancellationEnabled READ getEchoCancellationEnabled WRITE setEchoCancellationEnabled NOTIFY echoCancellationEnabledChanged); + Q_PROPERTY(QString captureDevice READ getCaptureDevice WRITE setCaptureDevice NOTIFY captureDeviceChanged); + Q_PROPERTY(QString playbackDevice READ getPlaybackDevice WRITE setPlaybackDevice NOTIFY playbackDeviceChanged); + Q_PROPERTY(QString ringerDevice READ getRingerDevice WRITE setRingerDevice NOTIFY ringerDeviceChanged); - Q_PROPERTY(bool showAudioCodecs READ getShowAudioCodecs WRITE setShowAudioCodecs NOTIFY showAudioCodecsChanged); + Q_PROPERTY(QString ringPath READ getRingPath WRITE setRingPath NOTIFY ringPathChanged); - // Video. -------------------------------------------------------------------- + Q_PROPERTY(bool echoCancellationEnabled READ getEchoCancellationEnabled WRITE setEchoCancellationEnabled NOTIFY echoCancellationEnabledChanged); - Q_PROPERTY(QStringList videoDevices READ getVideoDevices CONSTANT); + Q_PROPERTY(bool showAudioCodecs READ getShowAudioCodecs WRITE setShowAudioCodecs NOTIFY showAudioCodecsChanged); - Q_PROPERTY(QString videoDevice READ getVideoDevice WRITE setVideoDevice NOTIFY videoDeviceChanged); + // Video. -------------------------------------------------------------------- - Q_PROPERTY(QString videoPreset READ getVideoPreset WRITE setVideoPreset NOTIFY videoPresetChanged); - Q_PROPERTY(int videoFramerate READ getVideoFramerate WRITE setVideoFramerate NOTIFY videoFramerateChanged); + Q_PROPERTY(QStringList videoDevices READ getVideoDevices NOTIFY videoDevicesChanged); - Q_PROPERTY(QVariantList supportedVideoDefinitions READ getSupportedVideoDefinitions CONSTANT); + Q_PROPERTY(QString videoDevice READ getVideoDevice WRITE setVideoDevice NOTIFY videoDeviceChanged); - Q_PROPERTY(QVariantMap videoDefinition READ getVideoDefinition WRITE setVideoDefinition NOTIFY videoDefinitionChanged); + Q_PROPERTY(QString videoPreset READ getVideoPreset WRITE setVideoPreset NOTIFY videoPresetChanged); + Q_PROPERTY(int videoFramerate READ getVideoFramerate WRITE setVideoFramerate NOTIFY videoFramerateChanged); - Q_PROPERTY(bool videoSupported READ getVideoSupported CONSTANT); + Q_PROPERTY(QVariantList supportedVideoDefinitions READ getSupportedVideoDefinitions CONSTANT); - Q_PROPERTY(bool showVideoCodecs READ getShowVideoCodecs WRITE setShowVideoCodecs NOTIFY showVideoCodecsChanged); + Q_PROPERTY(QVariantMap videoDefinition READ getVideoDefinition WRITE setVideoDefinition NOTIFY videoDefinitionChanged); - // Chat & calls. ------------------------------------------------------------- + Q_PROPERTY(bool videoSupported READ getVideoSupported CONSTANT); - Q_PROPERTY(bool autoAnswerStatus READ getAutoAnswerStatus WRITE setAutoAnswerStatus NOTIFY autoAnswerStatusChanged); - Q_PROPERTY(bool autoAnswerVideoStatus READ getAutoAnswerVideoStatus WRITE setAutoAnswerVideoStatus NOTIFY autoAnswerVideoStatusChanged); - Q_PROPERTY(int autoAnswerDelay READ getAutoAnswerDelay WRITE setAutoAnswerDelay NOTIFY autoAnswerDelayChanged); + Q_PROPERTY(bool showVideoCodecs READ getShowVideoCodecs WRITE setShowVideoCodecs NOTIFY showVideoCodecsChanged); - Q_PROPERTY(bool showTelKeypadAutomatically READ getShowTelKeypadAutomatically WRITE setShowTelKeypadAutomatically NOTIFY showTelKeypadAutomaticallyChanged); + // Chat & calls. ------------------------------------------------------------- - Q_PROPERTY(bool keepCallsWindowInBackground READ getKeepCallsWindowInBackground WRITE setKeepCallsWindowInBackground NOTIFY keepCallsWindowInBackgroundChanged); + Q_PROPERTY(bool autoAnswerStatus READ getAutoAnswerStatus WRITE setAutoAnswerStatus NOTIFY autoAnswerStatusChanged); + Q_PROPERTY(bool autoAnswerVideoStatus READ getAutoAnswerVideoStatus WRITE setAutoAnswerVideoStatus NOTIFY autoAnswerVideoStatusChanged); + Q_PROPERTY(int autoAnswerDelay READ getAutoAnswerDelay WRITE setAutoAnswerDelay NOTIFY autoAnswerDelayChanged); - Q_PROPERTY(bool outgoingCallsEnabled READ getOutgoingCallsEnabled WRITE setOutgoingCallsEnabled NOTIFY outgoingCallsEnabledChanged); + Q_PROPERTY(bool showTelKeypadAutomatically READ getShowTelKeypadAutomatically WRITE setShowTelKeypadAutomatically NOTIFY showTelKeypadAutomaticallyChanged); - Q_PROPERTY(bool callRecorderEnabled READ getCallRecorderEnabled WRITE setCallRecorderEnabled NOTIFY callRecorderEnabledChanged); - Q_PROPERTY(bool automaticallyRecordCalls READ getAutomaticallyRecordCalls WRITE setAutomaticallyRecordCalls NOTIFY automaticallyRecordCallsChanged); + Q_PROPERTY(bool keepCallsWindowInBackground READ getKeepCallsWindowInBackground WRITE setKeepCallsWindowInBackground NOTIFY keepCallsWindowInBackgroundChanged); - Q_PROPERTY(bool callPauseEnabled READ getCallPauseEnabled WRITE setCallPauseEnabled NOTIFY callPauseEnabledChanged); - Q_PROPERTY(bool muteMicrophoneEnabled READ getMuteMicrophoneEnabled WRITE setMuteMicrophoneEnabled NOTIFY muteMicrophoneEnabledChanged); + Q_PROPERTY(bool outgoingCallsEnabled READ getOutgoingCallsEnabled WRITE setOutgoingCallsEnabled NOTIFY outgoingCallsEnabledChanged); - Q_PROPERTY(bool chatEnabled READ getChatEnabled WRITE setChatEnabled NOTIFY chatEnabledChanged); + Q_PROPERTY(bool callRecorderEnabled READ getCallRecorderEnabled WRITE setCallRecorderEnabled NOTIFY callRecorderEnabledChanged); + Q_PROPERTY(bool automaticallyRecordCalls READ getAutomaticallyRecordCalls WRITE setAutomaticallyRecordCalls NOTIFY automaticallyRecordCallsChanged); - Q_PROPERTY(bool conferenceEnabled READ getConferenceEnabled WRITE setConferenceEnabled NOTIFY conferenceEnabledChanged); + Q_PROPERTY(bool callPauseEnabled READ getCallPauseEnabled WRITE setCallPauseEnabled NOTIFY callPauseEnabledChanged); + Q_PROPERTY(bool muteMicrophoneEnabled READ getMuteMicrophoneEnabled WRITE setMuteMicrophoneEnabled NOTIFY muteMicrophoneEnabledChanged); - Q_PROPERTY(bool chatNotificationSoundEnabled READ getChatNotificationSoundEnabled WRITE setChatNotificationSoundEnabled NOTIFY chatNotificationSoundEnabledChanged); - Q_PROPERTY(QString chatNotificationSoundPath READ getChatNotificationSoundPath WRITE setChatNotificationSoundPath NOTIFY chatNotificationSoundPathChanged); + Q_PROPERTY(bool chatEnabled READ getChatEnabled WRITE setChatEnabled NOTIFY chatEnabledChanged); - Q_PROPERTY(QString fileTransferUrl READ getFileTransferUrl WRITE setFileTransferUrl NOTIFY fileTransferUrlChanged); + Q_PROPERTY(bool conferenceEnabled READ getConferenceEnabled WRITE setConferenceEnabled NOTIFY conferenceEnabledChanged); - Q_PROPERTY(bool limeIsSupported READ getLimeIsSupported CONSTANT); - Q_PROPERTY(QVariantList supportedMediaEncryptions READ getSupportedMediaEncryptions CONSTANT); + Q_PROPERTY(bool chatNotificationSoundEnabled READ getChatNotificationSoundEnabled WRITE setChatNotificationSoundEnabled NOTIFY chatNotificationSoundEnabledChanged); + Q_PROPERTY(QString chatNotificationSoundPath READ getChatNotificationSoundPath WRITE setChatNotificationSoundPath NOTIFY chatNotificationSoundPathChanged); - Q_PROPERTY(MediaEncryption mediaEncryption READ getMediaEncryption WRITE setMediaEncryption NOTIFY mediaEncryptionChanged); - Q_PROPERTY(LimeState limeState READ getLimeState WRITE setLimeState NOTIFY limeStateChanged); + Q_PROPERTY(QString fileTransferUrl READ getFileTransferUrl WRITE setFileTransferUrl NOTIFY fileTransferUrlChanged); - Q_PROPERTY(bool contactsEnabled READ getContactsEnabled WRITE setContactsEnabled NOTIFY contactsEnabledChanged); + Q_PROPERTY(bool limeIsSupported READ getLimeIsSupported CONSTANT); + Q_PROPERTY(QVariantList supportedMediaEncryptions READ getSupportedMediaEncryptions CONSTANT); - // Network. ------------------------------------------------------------------ + Q_PROPERTY(MediaEncryption mediaEncryption READ getMediaEncryption WRITE setMediaEncryption NOTIFY mediaEncryptionChanged); + Q_PROPERTY(bool mediaEncryptionMandatory READ mandatoryMediaEncryptionEnabled WRITE enableMandatoryMediaEncryption NOTIFY mediaEncryptionChanged); - Q_PROPERTY(bool showNetworkSettings READ getShowNetworkSettings WRITE setShowNetworkSettings NOTIFY showNetworkSettingsChanged); + Q_PROPERTY(LimeState limeState READ getLimeState WRITE setLimeState NOTIFY limeStateChanged); - Q_PROPERTY(bool useSipInfoForDtmfs READ getUseSipInfoForDtmfs WRITE setUseSipInfoForDtmfs NOTIFY dtmfsProtocolChanged); - Q_PROPERTY(bool useRfc2833ForDtmfs READ getUseRfc2833ForDtmfs WRITE setUseRfc2833ForDtmfs NOTIFY dtmfsProtocolChanged); + Q_PROPERTY(bool contactsEnabled READ getContactsEnabled WRITE setContactsEnabled NOTIFY contactsEnabledChanged); - Q_PROPERTY(bool ipv6Enabled READ getIpv6Enabled WRITE setIpv6Enabled NOTIFY ipv6EnabledChanged); + // Network. ------------------------------------------------------------------ - Q_PROPERTY(int downloadBandwidth READ getDownloadBandwidth WRITE setDownloadBandwidth NOTIFY downloadBandWidthChanged); - Q_PROPERTY(int uploadBandwidth READ getUploadBandwidth WRITE setUploadBandwidth NOTIFY uploadBandWidthChanged); + Q_PROPERTY(bool showNetworkSettings READ getShowNetworkSettings WRITE setShowNetworkSettings NOTIFY showNetworkSettingsChanged); - Q_PROPERTY( - bool adaptiveRateControlEnabled - READ getAdaptiveRateControlEnabled - WRITE setAdaptiveRateControlEnabled - NOTIFY adaptiveRateControlEnabledChanged - ); + Q_PROPERTY(bool useSipInfoForDtmfs READ getUseSipInfoForDtmfs WRITE setUseSipInfoForDtmfs NOTIFY dtmfsProtocolChanged); + Q_PROPERTY(bool useRfc2833ForDtmfs READ getUseRfc2833ForDtmfs WRITE setUseRfc2833ForDtmfs NOTIFY dtmfsProtocolChanged); - Q_PROPERTY(int tcpPort READ getTcpPort WRITE setTcpPort NOTIFY tcpPortChanged); - Q_PROPERTY(int udpPort READ getUdpPort WRITE setUdpPort NOTIFY udpPortChanged); + Q_PROPERTY(bool ipv6Enabled READ getIpv6Enabled WRITE setIpv6Enabled NOTIFY ipv6EnabledChanged); - Q_PROPERTY(QList audioPortRange READ getAudioPortRange WRITE setAudioPortRange NOTIFY audioPortRangeChanged); - Q_PROPERTY(QList videoPortRange READ getVideoPortRange WRITE setVideoPortRange NOTIFY videoPortRangeChanged); + Q_PROPERTY(int downloadBandwidth READ getDownloadBandwidth WRITE setDownloadBandwidth NOTIFY downloadBandWidthChanged); + Q_PROPERTY(int uploadBandwidth READ getUploadBandwidth WRITE setUploadBandwidth NOTIFY uploadBandWidthChanged); - Q_PROPERTY(bool iceEnabled READ getIceEnabled WRITE setIceEnabled NOTIFY iceEnabledChanged); - Q_PROPERTY(bool turnEnabled READ getTurnEnabled WRITE setTurnEnabled NOTIFY turnEnabledChanged); + Q_PROPERTY( + bool adaptiveRateControlEnabled + READ getAdaptiveRateControlEnabled + WRITE setAdaptiveRateControlEnabled + NOTIFY adaptiveRateControlEnabledChanged + ); - Q_PROPERTY(QString stunServer READ getStunServer WRITE setStunServer NOTIFY stunServerChanged); + Q_PROPERTY(int tcpPort READ getTcpPort WRITE setTcpPort NOTIFY tcpPortChanged); + Q_PROPERTY(int udpPort READ getUdpPort WRITE setUdpPort NOTIFY udpPortChanged); - Q_PROPERTY(QString turnUser READ getTurnUser WRITE setTurnUser NOTIFY turnUserChanged); - Q_PROPERTY(QString turnPassword READ getTurnPassword WRITE setTurnPassword NOTIFY turnPasswordChanged); + Q_PROPERTY(QList audioPortRange READ getAudioPortRange WRITE setAudioPortRange NOTIFY audioPortRangeChanged); + Q_PROPERTY(QList videoPortRange READ getVideoPortRange WRITE setVideoPortRange NOTIFY videoPortRangeChanged); - Q_PROPERTY(int dscpSip READ getDscpSip WRITE setDscpSip NOTIFY dscpSipChanged); - Q_PROPERTY(int dscpAudio READ getDscpAudio WRITE setDscpAudio NOTIFY dscpAudioChanged); - Q_PROPERTY(int dscpVideo READ getDscpVideo WRITE setDscpVideo NOTIFY dscpVideoChanged); + Q_PROPERTY(bool iceEnabled READ getIceEnabled WRITE setIceEnabled NOTIFY iceEnabledChanged); + Q_PROPERTY(bool turnEnabled READ getTurnEnabled WRITE setTurnEnabled NOTIFY turnEnabledChanged); - Q_PROPERTY(bool rlsUriEnabled READ getRlsUriEnabled WRITE setRlsUriEnabled NOTIFY rlsUriEnabledChanged); + Q_PROPERTY(QString stunServer READ getStunServer WRITE setStunServer NOTIFY stunServerChanged); - // UI. ----------------------------------------------------------------------- + Q_PROPERTY(QString turnUser READ getTurnUser WRITE setTurnUser NOTIFY turnUserChanged); + Q_PROPERTY(QString turnPassword READ getTurnPassword WRITE setTurnPassword NOTIFY turnPasswordChanged); - Q_PROPERTY(QString remoteProvisioning READ getRemoteProvisioning WRITE setRemoteProvisioning NOTIFY remoteProvisioningChanged); + Q_PROPERTY(int dscpSip READ getDscpSip WRITE setDscpSip NOTIFY dscpSipChanged); + Q_PROPERTY(int dscpAudio READ getDscpAudio WRITE setDscpAudio NOTIFY dscpAudioChanged); + Q_PROPERTY(int dscpVideo READ getDscpVideo WRITE setDscpVideo NOTIFY dscpVideoChanged); - Q_PROPERTY(QString savedScreenshotsFolder READ getSavedScreenshotsFolder WRITE setSavedScreenshotsFolder NOTIFY savedScreenshotsFolderChanged); - Q_PROPERTY(QString savedCallsFolder READ getSavedCallsFolder WRITE setSavedCallsFolder NOTIFY savedCallsFolderChanged); - Q_PROPERTY(QString downloadFolder READ getDownloadFolder WRITE setDownloadFolder NOTIFY downloadFolderChanged); + Q_PROPERTY(bool rlsUriEnabled READ getRlsUriEnabled WRITE setRlsUriEnabled NOTIFY rlsUriEnabledChanged); - Q_PROPERTY(bool exitOnClose READ getExitOnClose WRITE setExitOnClose NOTIFY exitOnCloseChanged); + // UI. ----------------------------------------------------------------------- - // Advanced. ----------------------------------------------------------------- + Q_PROPERTY(QString remoteProvisioning READ getRemoteProvisioning WRITE setRemoteProvisioning NOTIFY remoteProvisioningChanged); - Q_PROPERTY(QString logsFolder READ getLogsFolder WRITE setLogsFolder NOTIFY logsFolderChanged); - Q_PROPERTY(QString logsUploadUrl READ getLogsUploadUrl WRITE setLogsUploadUrl NOTIFY logsUploadUrlChanged); - Q_PROPERTY(bool logsEnabled READ getLogsEnabled WRITE setLogsEnabled NOTIFY logsEnabledChanged); - Q_PROPERTY(QString logsEmail READ getLogsEmail WRITE setLogsEmail NOTIFY logsEmailChanged); + Q_PROPERTY(QString savedScreenshotsFolder READ getSavedScreenshotsFolder WRITE setSavedScreenshotsFolder NOTIFY savedScreenshotsFolderChanged); + Q_PROPERTY(QString savedCallsFolder READ getSavedCallsFolder WRITE setSavedCallsFolder NOTIFY savedCallsFolderChanged); + Q_PROPERTY(QString downloadFolder READ getDownloadFolder WRITE setDownloadFolder NOTIFY downloadFolderChanged); - Q_PROPERTY(bool developerSettingsEnabled READ getDeveloperSettingsEnabled WRITE setDeveloperSettingsEnabled NOTIFY developerSettingsEnabledChanged); + Q_PROPERTY(bool exitOnClose READ getExitOnClose WRITE setExitOnClose NOTIFY exitOnCloseChanged); + + // Advanced. ----------------------------------------------------------------- + + Q_PROPERTY(QString logsFolder READ getLogsFolder WRITE setLogsFolder NOTIFY logsFolderChanged); + Q_PROPERTY(QString logsUploadUrl READ getLogsUploadUrl WRITE setLogsUploadUrl NOTIFY logsUploadUrlChanged); + Q_PROPERTY(bool logsEnabled READ getLogsEnabled WRITE setLogsEnabled NOTIFY logsEnabledChanged); + Q_PROPERTY(QString logsEmail READ getLogsEmail WRITE setLogsEmail NOTIFY logsEmailChanged); + + Q_PROPERTY(bool developerSettingsEnabled READ getDeveloperSettingsEnabled WRITE setDeveloperSettingsEnabled NOTIFY developerSettingsEnabledChanged); + + Q_PROPERTY(bool isInCall READ getIsInCall NOTIFY isInCallChanged); public: - enum MediaEncryption { - MediaEncryptionNone = int(linphone::MediaEncryption::None), - MediaEncryptionDtls = int(linphone::MediaEncryption::DTLS), - MediaEncryptionSrtp = int(linphone::MediaEncryption::SRTP), - MediaEncryptionZrtp = int(linphone::MediaEncryption::ZRTP) - }; - Q_ENUM(MediaEncryption); + enum MediaEncryption { + MediaEncryptionNone = int(linphone::MediaEncryption::None), + MediaEncryptionDtls = int(linphone::MediaEncryption::DTLS), + MediaEncryptionSrtp = int(linphone::MediaEncryption::SRTP), + MediaEncryptionZrtp = int(linphone::MediaEncryption::ZRTP) + }; + Q_ENUM(MediaEncryption); - enum LimeState { - LimeStateDisabled = int(linphone::LimeState::Disabled), - LimeStateMandatory = int(linphone::LimeState::Mandatory), - LimeStatePreferred = int(linphone::LimeState::Preferred) - }; - Q_ENUM(LimeState); + enum LimeState { + LimeStateDisabled = int(linphone::LimeState::Disabled), + LimeStateMandatory = int(linphone::LimeState::Mandatory), + LimeStatePreferred = int(linphone::LimeState::Preferred) + }; + Q_ENUM(LimeState); - SettingsModel (QObject *parent = Q_NULLPTR); + SettingsModel (QObject *parent = Q_NULLPTR); - // =========================================================================== - // METHODS. - // =========================================================================== + // =========================================================================== + // METHODS. + // =========================================================================== - // Assistant. ---------------------------------------------------------------- + Q_INVOKABLE void onSettingsTabChanged(int idx); + Q_INVOKABLE void settingsWindowClosing(void); - bool getCreateAppSipAccountEnabled () const; - void setCreateAppSipAccountEnabled (bool status); + // Assistant. ---------------------------------------------------------------- - bool getFetchRemoteConfigurationEnabled () const; - void setFetchRemoteConfigurationEnabled (bool status); + bool getCreateAppSipAccountEnabled () const; + void setCreateAppSipAccountEnabled (bool status); - bool getUseAppSipAccountEnabled () const; - void setUseAppSipAccountEnabled (bool status); + bool getFetchRemoteConfigurationEnabled () const; + void setFetchRemoteConfigurationEnabled (bool status); - bool getUseOtherSipAccountEnabled () const; - void setUseOtherSipAccountEnabled (bool status); + bool getUseAppSipAccountEnabled () const; + void setUseAppSipAccountEnabled (bool status); - bool getAssistantSupportsPhoneNumbers () const; - void setAssistantSupportsPhoneNumbers (bool status); + bool getUseOtherSipAccountEnabled () const; + void setUseOtherSipAccountEnabled (bool status); - // Audio. -------------------------------------------------------------------- + bool getAssistantSupportsPhoneNumbers () const; + void setAssistantSupportsPhoneNumbers (bool status); - QStringList getCaptureDevices () const; - QStringList getPlaybackDevices () const; + // Audio. -------------------------------------------------------------------- - QString getCaptureDevice () const; - void setCaptureDevice (const QString &device); + void createCaptureGraph(); + bool getCaptureGraphRunning(); + void accessAudioSettings(); + void closeAudioSettings(); - QString getPlaybackDevice () const; - void setPlaybackDevice (const QString &device); + Q_INVOKABLE float getMicVolume(); - QString getRingerDevice () const; - void setRingerDevice (const QString &device); + float getPlaybackGain() const; + void setPlaybackGain(float gain); - QString getRingPath () const; - void setRingPath (const QString &path); + float getCaptureGain() const; + void setCaptureGain(float gain); - bool getEchoCancellationEnabled () const; - void setEchoCancellationEnabled (bool status); + QStringList getCaptureDevices () const; + QStringList getPlaybackDevices () const; - bool getShowAudioCodecs () const; - void setShowAudioCodecs (bool status); + QString getCaptureDevice () const; + void setCaptureDevice (const QString &device); - // Video. -------------------------------------------------------------------- + QString getPlaybackDevice () const; + void setPlaybackDevice (const QString &device); - QStringList getVideoDevices () const; + QString getRingerDevice () const; + void setRingerDevice (const QString &device); - QString getVideoDevice () const; - void setVideoDevice (const QString &device); + QString getRingPath () const; + void setRingPath (const QString &path); - QString getVideoPreset () const; - void setVideoPreset (const QString &preset); + bool getEchoCancellationEnabled () const; + void setEchoCancellationEnabled (bool status); - int getVideoFramerate () const; - void setVideoFramerate (int framerate); + bool getShowAudioCodecs () const; + void setShowAudioCodecs (bool status); - QVariantList getSupportedVideoDefinitions () const; + // Video. -------------------------------------------------------------------- - QVariantMap getVideoDefinition () const; - void setVideoDefinition (const QVariantMap &definition); + //Called from qml when accessing audio settings panel + Q_INVOKABLE void accessVideoSettings(); - bool getVideoSupported () const; + QStringList getVideoDevices () const; - bool getShowVideoCodecs () const; - void setShowVideoCodecs (bool status); + QString getVideoDevice () const; + void setVideoDevice (const QString &device); - // Chat & calls. ------------------------------------------------------------- + QString getVideoPreset () const; + void setVideoPreset (const QString &preset); - bool getAutoAnswerStatus () const; - void setAutoAnswerStatus (bool status); + int getVideoFramerate () const; + void setVideoFramerate (int framerate); - bool getAutoAnswerVideoStatus () const; - void setAutoAnswerVideoStatus (bool status); + QVariantList getSupportedVideoDefinitions () const; - int getAutoAnswerDelay () const; - void setAutoAnswerDelay (int delay); + QVariantMap getVideoDefinition () const; + void setVideoDefinition (const QVariantMap &definition); - bool getShowTelKeypadAutomatically () const; - void setShowTelKeypadAutomatically (bool status); + bool getVideoSupported () const; - bool getKeepCallsWindowInBackground () const; - void setKeepCallsWindowInBackground (bool status); + bool getShowVideoCodecs () const; + void setShowVideoCodecs (bool status); - bool getOutgoingCallsEnabled () const; - void setOutgoingCallsEnabled (bool status); + // Chat & calls. ------------------------------------------------------------- - bool getCallRecorderEnabled () const; - void setCallRecorderEnabled (bool status); + bool getAutoAnswerStatus () const; + void setAutoAnswerStatus (bool status); - bool getAutomaticallyRecordCalls () const; - void setAutomaticallyRecordCalls (bool status); + bool getAutoAnswerVideoStatus () const; + void setAutoAnswerVideoStatus (bool status); - bool getCallPauseEnabled () const; - void setCallPauseEnabled (bool status); + int getAutoAnswerDelay () const; + void setAutoAnswerDelay (int delay); - bool getMuteMicrophoneEnabled () const; - void setMuteMicrophoneEnabled (bool status); + bool getShowTelKeypadAutomatically () const; + void setShowTelKeypadAutomatically (bool status); - bool getChatEnabled () const; - void setChatEnabled (bool status); + bool getKeepCallsWindowInBackground () const; + void setKeepCallsWindowInBackground (bool status); - bool getConferenceEnabled () const; - void setConferenceEnabled (bool status); + bool getOutgoingCallsEnabled () const; + void setOutgoingCallsEnabled (bool status); - bool getChatNotificationSoundEnabled () const; - void setChatNotificationSoundEnabled (bool status); + bool getCallRecorderEnabled () const; + void setCallRecorderEnabled (bool status); - QString getChatNotificationSoundPath () const; - void setChatNotificationSoundPath (const QString &path); + bool getAutomaticallyRecordCalls () const; + void setAutomaticallyRecordCalls (bool status); - QString getFileTransferUrl () const; - void setFileTransferUrl (const QString &url); + bool getCallPauseEnabled () const; + void setCallPauseEnabled (bool status); - bool getLimeIsSupported () const; - QVariantList getSupportedMediaEncryptions () const; + bool getMuteMicrophoneEnabled () const; + void setMuteMicrophoneEnabled (bool status); - MediaEncryption getMediaEncryption () const; - void setMediaEncryption (MediaEncryption encryption); + bool getChatEnabled () const; + void setChatEnabled (bool status); - LimeState getLimeState () const; - void setLimeState (LimeState state); + bool getConferenceEnabled () const; + void setConferenceEnabled (bool status); - bool getContactsEnabled () const; - void setContactsEnabled (bool status); + bool getChatNotificationSoundEnabled () const; + void setChatNotificationSoundEnabled (bool status); - // Network. ------------------------------------------------------------------ + QString getChatNotificationSoundPath () const; + void setChatNotificationSoundPath (const QString &path); - bool getShowNetworkSettings () const; - void setShowNetworkSettings (bool status); + QString getFileTransferUrl () const; + void setFileTransferUrl (const QString &url); - bool getUseSipInfoForDtmfs () const; - void setUseSipInfoForDtmfs (bool status); + bool getLimeIsSupported () const; + QVariantList getSupportedMediaEncryptions () const; - bool getUseRfc2833ForDtmfs () const; - void setUseRfc2833ForDtmfs (bool status); + MediaEncryption getMediaEncryption () const; + void setMediaEncryption (MediaEncryption encryption); - bool getIpv6Enabled () const; - void setIpv6Enabled (bool status); + bool mandatoryMediaEncryptionEnabled () const; + void enableMandatoryMediaEncryption(bool mandatory); - int getDownloadBandwidth () const; - void setDownloadBandwidth (int bandwidth); + LimeState getLimeState () const; + void setLimeState (LimeState state); - int getUploadBandwidth () const; - void setUploadBandwidth (int bandwidth); + bool getContactsEnabled () const; + void setContactsEnabled (bool status); - bool getAdaptiveRateControlEnabled () const; - void setAdaptiveRateControlEnabled (bool status); + // Network. ------------------------------------------------------------------ - int getTcpPort () const; - void setTcpPort (int port); + bool getShowNetworkSettings () const; + void setShowNetworkSettings (bool status); - int getUdpPort () const; - void setUdpPort (int port); + bool getUseSipInfoForDtmfs () const; + void setUseSipInfoForDtmfs (bool status); - QList getAudioPortRange () const; - void setAudioPortRange (const QList &range); + bool getUseRfc2833ForDtmfs () const; + void setUseRfc2833ForDtmfs (bool status); - QList getVideoPortRange () const; - void setVideoPortRange (const QList &range); + bool getIpv6Enabled () const; + void setIpv6Enabled (bool status); - bool getIceEnabled () const; - void setIceEnabled (bool status); + int getDownloadBandwidth () const; + void setDownloadBandwidth (int bandwidth); - bool getTurnEnabled () const; - void setTurnEnabled (bool status); + int getUploadBandwidth () const; + void setUploadBandwidth (int bandwidth); - QString getStunServer () const; - void setStunServer (const QString &stunServer); + bool getAdaptiveRateControlEnabled () const; + void setAdaptiveRateControlEnabled (bool status); - QString getTurnUser () const; - void setTurnUser (const QString &user); + int getTcpPort () const; + void setTcpPort (int port); - QString getTurnPassword () const; - void setTurnPassword (const QString &password); + int getUdpPort () const; + void setUdpPort (int port); - int getDscpSip () const; - void setDscpSip (int dscp); + QList getAudioPortRange () const; + void setAudioPortRange (const QList &range); - int getDscpAudio () const; - void setDscpAudio (int dscp); + QList getVideoPortRange () const; + void setVideoPortRange (const QList &range); - int getDscpVideo () const; - void setDscpVideo (int dscp); + bool getIceEnabled () const; + void setIceEnabled (bool status); - bool getRlsUriEnabled () const; - void setRlsUriEnabled (bool status); + bool getTurnEnabled () const; + void setTurnEnabled (bool status); - void configureRlsUri (); - void configureRlsUri (const std::shared_ptr &proxyConfig); + QString getStunServer () const; + void setStunServer (const QString &stunServer); - // UI. ----------------------------------------------------------------------- + QString getTurnUser () const; + void setTurnUser (const QString &user); - QString getSavedScreenshotsFolder () const; - void setSavedScreenshotsFolder (const QString &folder); + QString getTurnPassword () const; + void setTurnPassword (const QString &password); - QString getSavedCallsFolder () const; - void setSavedCallsFolder (const QString &folder); + int getDscpSip () const; + void setDscpSip (int dscp); - QString getDownloadFolder () const; - void setDownloadFolder (const QString &folder); + int getDscpAudio () const; + void setDscpAudio (int dscp); - QString getRemoteProvisioning () const; - void setRemoteProvisioning (const QString &remoteProvisioning); + int getDscpVideo () const; + void setDscpVideo (int dscp); - bool getExitOnClose () const; - void setExitOnClose (bool value); + bool getRlsUriEnabled () const; + void setRlsUriEnabled (bool status); - // --------------------------------------------------------------------------- + void configureRlsUri (); + void configureRlsUri (const std::shared_ptr &proxyConfig); - QString getLogsFolder () const; - void setLogsFolder (const QString &folder); + // UI. ----------------------------------------------------------------------- - QString getLogsUploadUrl () const; - void setLogsUploadUrl (const QString &url); + QString getSavedScreenshotsFolder () const; + void setSavedScreenshotsFolder (const QString &folder); - bool getLogsEnabled () const; - void setLogsEnabled (bool status); + QString getSavedCallsFolder () const; + void setSavedCallsFolder (const QString &folder); - QString getLogsEmail () const; - void setLogsEmail (const QString &email); + QString getDownloadFolder () const; + void setDownloadFolder (const QString &folder); - // --------------------------------------------------------------------------- + QString getRemoteProvisioning () const; + void setRemoteProvisioning (const QString &remoteProvisioning); - static QString getLogsFolder (const std::shared_ptr &config); - static bool getLogsEnabled (const std::shared_ptr &config); + bool getExitOnClose () const; + void setExitOnClose (bool value); - // --------------------------------------------------------------------------- + // --------------------------------------------------------------------------- - bool getDeveloperSettingsEnabled () const; - void setDeveloperSettingsEnabled (bool status); + QString getLogsFolder () const; + void setLogsFolder (const QString &folder); - static const std::string UiSection; + QString getLogsUploadUrl () const; + void setLogsUploadUrl (const QString &url); - // =========================================================================== - // SIGNALS. - // =========================================================================== + bool getLogsEnabled () const; + void setLogsEnabled (bool status); + + QString getLogsEmail () const; + void setLogsEmail (const QString &email); + + // --------------------------------------------------------------------------- + + static QString getLogsFolder (const std::shared_ptr &config); + static bool getLogsEnabled (const std::shared_ptr &config); + + // --------------------------------------------------------------------------- + + bool getDeveloperSettingsEnabled () const; + void setDeveloperSettingsEnabled (bool status); + + void handleCallCreated(const std::shared_ptr &call); + void handleCallStateChanged(const std::shared_ptr &call, linphone::Call::State state); + + bool getIsInCall() const; + + static const std::string UiSection; + + // =========================================================================== + // SIGNALS. + // =========================================================================== signals: - // Assistant. ---------------------------------------------------------------- + // Assistant. ---------------------------------------------------------------- - void createAppSipAccountEnabledChanged (bool status); - void fetchRemoteConfigurationEnabledChanged (bool status); - void useAppSipAccountEnabledChanged (bool status); - void useOtherSipAccountEnabledChanged (bool status); + void createAppSipAccountEnabledChanged (bool status); + void fetchRemoteConfigurationEnabledChanged (bool status); + void useAppSipAccountEnabledChanged (bool status); + void useOtherSipAccountEnabledChanged (bool status); - void assistantSupportsPhoneNumbersChanged (bool status); + void assistantSupportsPhoneNumbersChanged (bool status); - // Audio. -------------------------------------------------------------------- + // Audio. -------------------------------------------------------------------- - void captureDeviceChanged (const QString &device); - void playbackDeviceChanged (const QString &device); - void ringerDeviceChanged (const QString &device); + void captureGraphRunningChanged(bool running); - void ringPathChanged (const QString &path); + void playbackGainChanged(float gain); + void captureGainChanged(float gain); - void echoCancellationEnabledChanged (bool status); + void captureDevicesChanged (const QStringList &devices); + void playbackDevicesChanged (const QStringList &devices); - void showAudioCodecsChanged (bool status); + void captureDeviceChanged (const QString &device); + void playbackDeviceChanged (const QString &device); + void ringerDeviceChanged (const QString &device); - // Video. -------------------------------------------------------------------- + void ringPathChanged (const QString &path); - void videoDeviceChanged (const QString &device); + void echoCancellationEnabledChanged (bool status); - void videoPresetChanged (const QString &preset); - void videoFramerateChanged (int framerate); + void showAudioCodecsChanged (bool status); - void videoDefinitionChanged (const QVariantMap &definition); + // Video. -------------------------------------------------------------------- - void showVideoCodecsChanged (bool status); + void videoDevicesChanged (const QStringList &devices); + void videoDeviceChanged (const QString &device); - // Chat & calls. ------------------------------------------------------------- + void videoPresetChanged (const QString &preset); + void videoFramerateChanged (int framerate); - void autoAnswerStatusChanged (bool status); - void autoAnswerVideoStatusChanged (bool status); - void autoAnswerDelayChanged (int delay); + void videoDefinitionChanged (const QVariantMap &definition); - void showTelKeypadAutomaticallyChanged (bool status); + void showVideoCodecsChanged (bool status); - void keepCallsWindowInBackgroundChanged (bool status); + // Chat & calls. ------------------------------------------------------------- - void outgoingCallsEnabledChanged (bool status); + void autoAnswerStatusChanged (bool status); + void autoAnswerVideoStatusChanged (bool status); + void autoAnswerDelayChanged (int delay); - void callRecorderEnabledChanged (bool status); - void automaticallyRecordCallsChanged (bool status); + void showTelKeypadAutomaticallyChanged (bool status); - void callPauseEnabledChanged (bool status); - void muteMicrophoneEnabledChanged (bool status); + void keepCallsWindowInBackgroundChanged (bool status); - void chatEnabledChanged (bool status); + void outgoingCallsEnabledChanged (bool status); - void conferenceEnabledChanged (bool status); + void callRecorderEnabledChanged (bool status); + void automaticallyRecordCallsChanged (bool status); - void chatNotificationSoundEnabledChanged (bool status); - void chatNotificationSoundPathChanged (const QString &path); + void callPauseEnabledChanged (bool status); + void muteMicrophoneEnabledChanged (bool status); - void fileTransferUrlChanged (const QString &url); + void chatEnabledChanged (bool status); - void mediaEncryptionChanged (MediaEncryption encryption); - void limeStateChanged (LimeState state); + void conferenceEnabledChanged (bool status); - void contactsEnabledChanged (bool status); + void chatNotificationSoundEnabledChanged (bool status); + void chatNotificationSoundPathChanged (const QString &path); - // Network. ------------------------------------------------------------------ + void fileTransferUrlChanged (const QString &url); - void showNetworkSettingsChanged (bool status); + void mediaEncryptionChanged (MediaEncryption encryption); + void limeStateChanged (LimeState state); - void dtmfsProtocolChanged (); + void contactsEnabledChanged (bool status); - void ipv6EnabledChanged (bool status); + // Network. ------------------------------------------------------------------ - void downloadBandWidthChanged (int bandwidth); - void uploadBandWidthChanged (int bandwidth); + void showNetworkSettingsChanged (bool status); - bool adaptiveRateControlEnabledChanged (bool status); + void dtmfsProtocolChanged (); - void tcpPortChanged (int port); - void udpPortChanged (int port); + void ipv6EnabledChanged (bool status); - void audioPortRangeChanged (int a, int b); - void videoPortRangeChanged (int a, int b); + void downloadBandWidthChanged (int bandwidth); + void uploadBandWidthChanged (int bandwidth); - void iceEnabledChanged (bool status); - void turnEnabledChanged (bool status); + bool adaptiveRateControlEnabledChanged (bool status); - void stunServerChanged (const QString &server); + void tcpPortChanged (int port); + void udpPortChanged (int port); - void turnUserChanged (const QString &user); - void turnPasswordChanged (const QString &password); + void audioPortRangeChanged (int a, int b); + void videoPortRangeChanged (int a, int b); - void dscpSipChanged (int dscp); - void dscpAudioChanged (int dscp); - void dscpVideoChanged (int dscp); + void iceEnabledChanged (bool status); + void turnEnabledChanged (bool status); - void rlsUriEnabledChanged (bool status); + void stunServerChanged (const QString &server); - // UI. ----------------------------------------------------------------------- + void turnUserChanged (const QString &user); + void turnPasswordChanged (const QString &password); - void savedScreenshotsFolderChanged (const QString &folder); - void savedCallsFolderChanged (const QString &folder); - void downloadFolderChanged (const QString &folder); + void dscpSipChanged (int dscp); + void dscpAudioChanged (int dscp); + void dscpVideoChanged (int dscp); - void remoteProvisioningChanged (const QString &remoteProvisioning); - void remoteProvisioningNotChanged (const QString &remoteProvisioning); + void rlsUriEnabledChanged (bool status); - void exitOnCloseChanged (bool value); + // UI. ----------------------------------------------------------------------- - // Advanced. ----------------------------------------------------------------- + void savedScreenshotsFolderChanged (const QString &folder); + void savedCallsFolderChanged (const QString &folder); + void downloadFolderChanged (const QString &folder); - void logsFolderChanged (const QString &folder); - void logsUploadUrlChanged (const QString &url); - void logsEnabledChanged (bool status); - void logsEmailChanged (const QString &email); + void remoteProvisioningChanged (const QString &remoteProvisioning); + void remoteProvisioningNotChanged (const QString &remoteProvisioning); - bool developerSettingsEnabledChanged (bool status); + void exitOnCloseChanged (bool value); + + // Advanced. ----------------------------------------------------------------- + + void logsFolderChanged (const QString &folder); + void logsUploadUrlChanged (const QString &url); + void logsEnabledChanged (bool status); + void logsEmailChanged (const QString &email); + + bool developerSettingsEnabledChanged (bool status); + + bool isInCallChanged(bool); private: - std::shared_ptr mConfig; + int mCurrentSettingsTab = 0; + MediastreamerUtils::SimpleCaptureGraph *mSimpleCaptureGraph = nullptr; + + std::shared_ptr mConfig; }; Q_DECLARE_METATYPE(std::shared_ptr); diff --git a/src/components/sip-addresses/SipAddressesModel.cpp b/src/components/sip-addresses/SipAddressesModel.cpp index 353c99742..88f163f6c 100644 --- a/src/components/sip-addresses/SipAddressesModel.cpp +++ b/src/components/sip-addresses/SipAddressesModel.cpp @@ -451,6 +451,14 @@ void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, ].timestamp = callLog->getStatus() == linphone::Call::Status::Success ? QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000) : QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000); + + if (callLog->getStatus() == linphone::Call::Status::Missed) { + for (auto &observer : mObservers.values(QString::fromStdString((callLog->getRemoteAddress()->asStringUriOnly())))) { + if (observer->getLocalAddress() == QString::fromStdString(callLog->getLocalAddress()->asStringUriOnly())) { + observer->setUnreadMessageCount(1); + } + } + } } void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const shared_ptr &message) { @@ -561,18 +569,17 @@ void SipAddressesModel::initSipAddressesFromCalls () { const QString localAddress(Utils::coreStringToAppString(callLog->getLocalAddress()->asStringUriOnly())); switch (callLog->getStatus()) { - case linphone::Call::Status::Aborted: - case linphone::Call::Status::EarlyAborted: - return; // Ignore aborted calls. + case linphone::Call::Status::Aborted: + case linphone::Call::Status::EarlyAborted: + return; // Ignore aborted calls. + case linphone::Call::Status::AcceptedElsewhere: + case linphone::Call::Status::DeclinedElsewhere: + return; // Ignore accepted calls on other device. + case linphone::Call::Status::Success: + case linphone::Call::Status::Declined: - case linphone::Call::Status::AcceptedElsewhere: - case linphone::Call::Status::DeclinedElsewhere: - return; // Ignore accepted calls on other device. - - case linphone::Call::Status::Success: - case linphone::Call::Status::Missed: - case linphone::Call::Status::Declined: - break; + case linphone::Call::Status::Missed: + break; } ConferenceId conferenceId{ peerAddress, localAddress }; @@ -617,9 +624,10 @@ void SipAddressesModel::updateObservers (const QString &sipAddress, const Presen } void SipAddressesModel::updateObservers (const QString &peerAddress, const QString &localAddress, int messageCount) { - for (auto &observer : mObservers.values(peerAddress)) - if (observer->getLocalAddress() == localAddress) { - observer->setUnreadMessageCount(messageCount); - return; - } + for (auto &observer : mObservers.values(peerAddress)) { + if (observer->getLocalAddress() == localAddress) { + observer->setUnreadMessageCount(messageCount); + return; + } + } } diff --git a/src/components/sip-addresses/SipAddressesModel.hpp b/src/components/sip-addresses/SipAddressesModel.hpp index c0fd41aad..d304dbabf 100644 --- a/src/components/sip-addresses/SipAddressesModel.hpp +++ b/src/components/sip-addresses/SipAddressesModel.hpp @@ -114,6 +114,9 @@ private: void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr &call); void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr &message); + + //NMN TODO bind to missedCall event and implement void addOrUpdateSipAddress + template void addOrUpdateSipAddress (const QString &sipAddress, T data); diff --git a/src/components/sound-player/SoundPlayer.cpp b/src/components/sound-player/SoundPlayer.cpp index 7c02401a9..2c2d4762e 100644 --- a/src/components/sound-player/SoundPlayer.cpp +++ b/src/components/sound-player/SoundPlayer.cpp @@ -143,7 +143,7 @@ void SoundPlayer::buildInternalPlayer () { mInternalPlayer = coreManager->getCore()->createLocalPlayer( Utils::appStringToCoreString(settingsModel->getRingerDevice()), "", nullptr ); - mInternalPlayer->setListener(mHandlers); + mInternalPlayer->addListener(mHandlers); QObject::connect(settingsModel, &SettingsModel::ringerDeviceChanged, this, [this] { rebuildInternalPlayer(); diff --git a/src/utils/LinphoneUtils.hpp b/src/utils/LinphoneUtils.hpp index b6c5fbb33..c360167c8 100644 --- a/src/utils/LinphoneUtils.hpp +++ b/src/utils/LinphoneUtils.hpp @@ -30,17 +30,6 @@ class QString; namespace LinphoneUtils { - inline float computeVu (float volume) { - constexpr float VuMin = -20.f; - constexpr float VuMax = 4.f; - - if (volume < VuMin) - return 0.f; - if (volume > VuMax) - return 1.f; - - return (volume - VuMin) / (VuMax - VuMin); - } linphone::TransportType stringToTransportType (const QString &transport); diff --git a/src/utils/MediastreamerUtils.cpp b/src/utils/MediastreamerUtils.cpp new file mode 100644 index 000000000..a0742f476 --- /dev/null +++ b/src/utils/MediastreamerUtils.cpp @@ -0,0 +1,141 @@ +/* + * MediastreamerUtils.cpp + * Copyright (C) 2017-2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Created on: Nov 6, 2019 + * Author: Nicolas Michon + */ + +#include +#include "mediastreamer2/msvolume.h" +#include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/msticker.h" +#include "components/core/CoreManager.hpp" +#include "MediastreamerUtils.hpp" + +using namespace MediastreamerUtils; + +SimpleCaptureGraph::SimpleCaptureGraph(const std::string &capture, const std::string &playback) + : captureCardId(capture), playbackCardId(playback) +{ + LinphoneCore *ccore = CoreManager::getInstance()->getCore()->cPtr(); + msFactory = linphone_core_get_ms_factory(ccore); + + playbackCard = ms_snd_card_manager_get_card(ms_factory_get_snd_card_manager(msFactory), playbackCardId.c_str()); + captureCard = ms_snd_card_manager_get_card(ms_factory_get_snd_card_manager(msFactory), captureCardId.c_str()); + + init(); +} + +SimpleCaptureGraph::~SimpleCaptureGraph() +{ + destroy(); +} + +void SimpleCaptureGraph::init() { + if (!audioCapture) { + audioCapture = ms_snd_card_create_reader(captureCard); + } + if (!audioSink) { + audioSink = ms_snd_card_create_writer(playbackCard); + } + if (!captureVolumeFilter) { + captureVolumeFilter = ms_factory_create_filter(msFactory, MS_VOLUME_ID); + } + if (!playbackVolumeFilter) { + playbackVolumeFilter = ms_factory_create_filter(msFactory, MS_VOLUME_ID); + } + + ms_filter_link(audioCapture, 0, captureVolumeFilter, 0); + ms_filter_link(captureVolumeFilter, 0, playbackVolumeFilter, 0); + ms_filter_link(playbackVolumeFilter, 0, audioSink, 0); + + //Mute playback + float muteGain = 0.0f; + ms_filter_call_method(playbackVolumeFilter, static_cast(MS_VOLUME_SET_GAIN), &muteGain); + + ticker = ms_ticker_new(); + running = false; +} + +void SimpleCaptureGraph::start() { + if (!running) { + ms_ticker_attach(ticker, audioCapture); + running = true; + } +} + +void SimpleCaptureGraph::stop() { + if (running) { + ms_ticker_detach(ticker, audioCapture); + running = false; + } +} + +void SimpleCaptureGraph::destroy() { + if (running) { + stop(); + } + ms_ticker_destroy(ticker); + ms_filter_unlink(audioCapture, 0, captureVolumeFilter, 0); + ms_filter_unlink(captureVolumeFilter, 0, playbackVolumeFilter, 0); + ms_filter_unlink(playbackVolumeFilter, 0, audioSink, 0); + + ms_free(audioCapture); + ms_free(captureVolumeFilter); + ms_free(audioSink); + ms_free(playbackVolumeFilter); +} + +float SimpleCaptureGraph::getCaptureGain() { + float gain = 0.0f; + + if (isRunning() && audioCapture) { + ms_filter_call_method(audioCapture, MS_AUDIO_CAPTURE_GET_VOLUME_GAIN, &gain); + } + return gain; +} + +void SimpleCaptureGraph::setCaptureGain(float gain) { + if (isRunning() && audioCapture) { + ms_filter_call_method(audioCapture, MS_AUDIO_CAPTURE_SET_VOLUME_GAIN, &gain); + } +} + +float SimpleCaptureGraph::getPlaybackGain() { + float gain = 0.0f; + if (isRunning() && audioSink) { + ms_filter_call_method(audioSink, MS_AUDIO_PLAYBACK_GET_VOLUME_GAIN, &gain); + } + return gain; +} + +void SimpleCaptureGraph::setPlaybackGain(float gain) { + if (isRunning() && audioSink) { + ms_filter_call_method(audioSink, MS_AUDIO_PLAYBACK_SET_VOLUME_GAIN, &gain); + } +} + +float SimpleCaptureGraph::getCaptureVolume() { + float vol = 0; + + if (captureVolumeFilter) { + ms_filter_call_method(captureVolumeFilter, MS_VOLUME_GET, &vol); + vol = MediastreamerUtils::dbToLinear(vol); + } + return vol; +} diff --git a/src/utils/MediastreamerUtils.hpp b/src/utils/MediastreamerUtils.hpp new file mode 100644 index 000000000..35ed99bcf --- /dev/null +++ b/src/utils/MediastreamerUtils.hpp @@ -0,0 +1,102 @@ +/* + * MediastreamerUtils.hpp + * Copyright (C) 2017-2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Created on: Nov 6, 2019 + * Author: Nicolas Michon + */ + +#ifndef MEDIASTREAMER_UTILS_H_ +#define MEDIASTREAMER_UTILS_H_ + +#include + +#include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/msvolume.h" +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msticker.h" +#include + +// ============================================================================= + +namespace MediastreamerUtils { + + inline float computeVu (float volume) { + constexpr float VuMin = -20.f; + constexpr float VuMax = 4.f; + + if (volume < VuMin) + return 0.f; + if (volume > VuMax) + return 1.f; + + return (volume - VuMin) / (VuMax - VuMin); + } + + inline float dbToLinear(float volume) { + return static_cast(pow(10, volume / 10)); + } + + inline float linearToDb(float volume) { + if (volume == 0.0f) { + return MS_VOLUME_DB_LOWEST; + } + return static_cast(10 * log10(volume)); + } + + //Simple mediastreamer audio capture graph + //Used to get current microphone volume in audio settings + class SimpleCaptureGraph { + public: + SimpleCaptureGraph(const std::string &captureCardId, const std::string &playbackCardId); + ~SimpleCaptureGraph(); + + void start(); + void stop(); + + float getCaptureVolume(); + + float getCaptureGain(); + float getPlaybackGain(); + void setCaptureGain(float volume); + void setPlaybackGain(float volume); + + bool isRunning() const { + return running; + } + protected: + void init(); + void destroy(); + + bool running = false; + + std::string captureCardId; + std::string playbackCardId; + + MSFilter *audioSink = nullptr; + MSFilter *audioCapture = nullptr; + MSFilter *captureVolumeFilter = nullptr; + MSFilter *playbackVolumeFilter = nullptr; + MSTicker *ticker = nullptr; + MSSndCard *playbackCard = nullptr; + MSSndCard *captureCard = nullptr; + MSFactory *msFactory = nullptr; + }; + +} + +#endif // ifndef MEDIASTREAMER_UTILS_H_ diff --git a/src/utils/Utils.cpp b/src/utils/Utils.cpp index db9ff3270..fb2097a82 100644 --- a/src/utils/Utils.cpp +++ b/src/utils/Utils.cpp @@ -69,3 +69,54 @@ QString Utils::getSafeFilePath (const QString &filePath, bool *soFarSoGood) { return QString(""); } +// Data to retrieve WIN32 process +#ifdef _WIN32 +#include +struct EnumData { + DWORD dwProcessId; + HWND hWnd; +}; +// Application-defined callback for EnumWindows +BOOL CALLBACK EnumProc(HWND hWnd, LPARAM lParam) { +// Retrieve storage location for communication data + EnumData& ed = *(EnumData*)lParam; + DWORD dwProcessId = 0x0; +// Query process ID for hWnd + GetWindowThreadProcessId(hWnd, &dwProcessId); +// Apply filter - if you want to implement additional restrictions, +// this is the place to do so. + if (ed.dwProcessId == dwProcessId) { + // Found a window matching the process ID + ed.hWnd = hWnd; + // Report success + SetLastError(ERROR_SUCCESS); + // Stop enumeration + return FALSE; + } +// Continue enumeration + return TRUE; +} +// Main entry +HWND FindWindowFromProcessId(DWORD dwProcessId) { + EnumData ed = { dwProcessId }; + if (!EnumWindows(EnumProc, (LPARAM)&ed) && + (GetLastError() == ERROR_SUCCESS)) { + return ed.hWnd; + } + return NULL; +} + +// Helper method for convenience +HWND FindWindowFromProcess(HANDLE hProcess) { + return FindWindowFromProcessId(GetProcessId(hProcess)); +} +#endif + +bool Utils::processExists(const quint64& p_processId) +{ +#ifdef _WIN32 + return FindWindowFromProcessId(p_processId) != NULL; +#else + return true; +#endif +} \ No newline at end of file diff --git a/src/utils/Utils.hpp b/src/utils/Utils.hpp index a77e1b6d1..ebdd6108e 100644 --- a/src/utils/Utils.hpp +++ b/src/utils/Utils.hpp @@ -56,6 +56,9 @@ namespace Utils { // Otherwise returns a safe path with a unique number before the extension. QString getSafeFilePath (const QString &filePath, bool *soFarSoGood = nullptr); + // Test if the process exists + bool processExists(const quint64& p_processId); + // Connect once to a member function. template static inline QMetaObject::Connection connectOnce ( diff --git a/ui/modules/Common/Form/ActionButton.qml b/ui/modules/Common/Form/ActionButton.qml index ca621e24d..1d03184de 100644 --- a/ui/modules/Common/Form/ActionButton.qml +++ b/ui/modules/Common/Form/ActionButton.qml @@ -17,6 +17,7 @@ Item { property bool useStates: true property int iconSize // Optional. readonly property alias hovered: button.hovered + property alias text: button.text // If `useStates` = true, the used icons are: // `icon`_pressed, `icon`_hovered and `icon`_normal. @@ -51,7 +52,7 @@ Item { // --------------------------------------------------------------------------- height: iconSize || parent.iconSize || parent.height - width: iconSize || parent.iconSize || parent.height + width: iconSize || parent.iconSize || parent.width Button { id: button diff --git a/ui/modules/Common/Form/ActionSwitch.qml b/ui/modules/Common/Form/ActionSwitch.qml index 541953bef..88d86f23e 100644 --- a/ui/modules/Common/Form/ActionSwitch.qml +++ b/ui/modules/Common/Form/ActionSwitch.qml @@ -5,6 +5,7 @@ import QtQuick 2.7 Item { property alias updating: actionButton.updating property alias useStates: actionButton.useStates + property alias text: actionButton.text property bool enabled: true property int iconSize // Optionnal. property string icon @@ -16,7 +17,7 @@ Item { // --------------------------------------------------------------------------- height: iconSize || parent.iconSize || parent.height - width: iconSize || parent.iconSize || parent.height + width: iconSize || parent.iconSize || parent.width ActionButton { id: actionButton diff --git a/ui/modules/Common/Tooltip/Tooltip.qml b/ui/modules/Common/Tooltip/Tooltip.qml index 7c9967d5d..1ebcd43ed 100644 --- a/ui/modules/Common/Tooltip/Tooltip.qml +++ b/ui/modules/Common/Tooltip/Tooltip.qml @@ -1,5 +1,5 @@ -import QtQuick 2.7 -import QtQuick.Controls 2.2 +import QtQuick 2.7 as Core +import QtQuick.Controls 2.2 as Core import Common 1.0 import Common.Styles 1.0 @@ -7,7 +7,7 @@ import Utils 1.0 // ============================================================================= -ToolTip { +Core.ToolTip { id: tooltip property var _edge: 'left' @@ -78,7 +78,7 @@ ToolTip { // --------------------------------------------------------------------------- - background: Item { + background: Core.Item { id: container layer { @@ -86,7 +86,7 @@ ToolTip { effect: PopupShadow {} } - Rectangle { + Core.Rectangle { anchors { fill: parent margins: TooltipStyle.margins @@ -97,10 +97,10 @@ ToolTip { // Do not use `Icon` component to access to `implicitHeight` // and `implicitWidth`. - Image { + Core.Image { id: icon - fillMode: Image.PreserveAspectFit + fillMode: Core.Image.PreserveAspectFit height: TooltipStyle.arrowSize source: _edge ? Utils.resolveImageUri('tooltip_arrow_' + _edge) @@ -111,11 +111,11 @@ ToolTip { width: TooltipStyle.arrowSize z: Constants.zMax - onStatusChanged: status === Image.Ready && _setArrowPosition() + onStatusChanged: status === Core.Image.Ready && _setArrowPosition() } } - contentItem: Text { + contentItem: Core.Text { id: text color: TooltipStyle.color diff --git a/ui/modules/Common/qmldir b/ui/modules/Common/qmldir index bb3ae4d55..5f8e5a071 100644 --- a/ui/modules/Common/qmldir +++ b/ui/modules/Common/qmldir @@ -81,6 +81,8 @@ PopupShadow 1.0 Popup/PopupShadow.qml TooltipArea 1.0 Tooltip/TooltipArea.qml +ToolTip 1.0 Tooltip/Tooltip.qml + ScrollableListView 1.0 View/ScrollableListView.qml ApplicationWindow 1.0 Window/ApplicationWindow.qml diff --git a/ui/views/App/Calls/CallsWindow.qml b/ui/views/App/Calls/CallsWindow.qml index 6282ec2c0..5d9951928 100644 --- a/ui/views/App/Calls/CallsWindow.qml +++ b/ui/views/App/Calls/CallsWindow.qml @@ -17,7 +17,7 @@ Window { // --------------------------------------------------------------------------- - // `{}` is a workaround to avoid `TypeError: Cannot read property...`. + // `{}` is a workaround to avoid `TypeError: Cannot read property...` when calls list is empty readonly property var call: calls.selectedCall || ({ callError: '', isOutgoing: true, diff --git a/ui/views/App/Calls/Dialogs/MultimediaParameters.qml b/ui/views/App/Calls/Dialogs/MultimediaParameters.qml index 5effa2331..3118616d1 100644 --- a/ui/views/App/Calls/Dialogs/MultimediaParameters.qml +++ b/ui/views/App/Calls/Dialogs/MultimediaParameters.qml @@ -1,4 +1,5 @@ import QtQuick 2.7 +import QtQuick.Controls 2.7 import QtQuick.Layouts 1.3 import Common 1.0 @@ -67,10 +68,17 @@ DialogPlus { } Slider { + id: playbackSlider width: parent.width Component.onCompleted: value = call.speakerVolumeGain onPositionChanged: call.speakerVolumeGain = position + + ToolTip { + parent: playbackSlider.handle + visible: playbackSlider.pressed + text: (playbackSlider.value * 100).toFixed(0) + " %" + } } } } @@ -103,10 +111,17 @@ DialogPlus { } Slider { + id: captureSlider width: parent.width Component.onCompleted: value = call.microVolumeGain onPositionChanged: call.microVolumeGain = position + + ToolTip { + parent: captureSlider.handle + visible: captureSlider.pressed + text: "+ " + (captureSlider.value * 100).toFixed(0) + " %" + } } } } diff --git a/ui/views/App/Main/ContactEdit.qml b/ui/views/App/Main/ContactEdit.qml index d63ca9f53..0e870f8c9 100644 --- a/ui/views/App/Main/ContactEdit.qml +++ b/ui/views/App/Main/ContactEdit.qml @@ -129,6 +129,10 @@ ColumnLayout { icon: 'history' onClicked: sipAddressesMenu.open() + + TooltipArea { + text: qsTr('tooltipShowConversation') + } } } diff --git a/ui/views/App/Main/Conversation.js b/ui/views/App/Main/Conversation.js index 28fc8beef..978a27d3f 100644 --- a/ui/views/App/Main/Conversation.js +++ b/ui/views/App/Main/Conversation.js @@ -28,6 +28,10 @@ function getEditIcon () { return conversation._sipAddressObserver.contact ? 'contact_edit' : 'contact_add' } +function getEditTooltipText() { + return conversation._sipAddressObserver.contact ? qsTr('tooltipContactEdit') : qsTr('tooltipContactAdd') +} + function getUsername () { return LinphoneUtils.getContactUsername(conversation._sipAddressObserver) } diff --git a/ui/views/App/Main/Conversation.qml b/ui/views/App/Main/Conversation.qml index 22180797a..0d36b8fcf 100644 --- a/ui/views/App/Main/Conversation.qml +++ b/ui/views/App/Main/Conversation.qml @@ -100,6 +100,9 @@ ColumnLayout { onClicked: window.setView('ContactEdit', { sipAddress: conversation.peerAddress }) + TooltipArea { + text: Logic.getEditTooltipText() + } } ActionButton { @@ -107,6 +110,10 @@ ColumnLayout { iconSize: ConversationStyle.bar.actions.edit.iconSize onClicked: Logic.removeAllEntries() + + TooltipArea { + text: qsTr('cleanHistory') + } } } } diff --git a/ui/views/App/Main/Dialogs/ManageAccounts.qml b/ui/views/App/Main/Dialogs/ManageAccounts.qml index 790a1cfae..2a3f78411 100644 --- a/ui/views/App/Main/Dialogs/ManageAccounts.qml +++ b/ui/views/App/Main/Dialogs/ManageAccounts.qml @@ -81,6 +81,13 @@ DialogPlus { itemIcon: Logic.getItemIcon(flattenedModel) width: parent.width + ActionButton { + icon: 'options' + iconSize: 30 + anchors.fill: parent + //TODO handle click and jump to proxy config settings + } + onClicked: { container.currentIndex = index AccountSettingsModel.setDefaultProxyConfig(flattenedModel.proxyConfig) diff --git a/ui/views/App/Main/MainWindow.qml b/ui/views/App/Main/MainWindow.qml index 35af3699e..9661c6a0f 100644 --- a/ui/views/App/Main/MainWindow.qml +++ b/ui/views/App/Main/MainWindow.qml @@ -180,6 +180,10 @@ ApplicationWindow { visible: SettingsModel.conferenceEnabled onClicked: Logic.openConferenceManager() + + TooltipArea { + text: qsTr('newConferenceButton') + } } ActionButton { diff --git a/ui/views/App/Settings/SettingsAudio.qml b/ui/views/App/Settings/SettingsAudio.qml index b59634377..d160ad7cc 100644 --- a/ui/views/App/Settings/SettingsAudio.qml +++ b/ui/views/App/Settings/SettingsAudio.qml @@ -1,4 +1,6 @@ -import QtQuick 2.7 +import QtQuick 2.7 as Core +import QtQuick.Controls 2.7 as Core +import QtQuick.Layouts 1.10 as Core import Common 1.0 import Linphone 1.0 @@ -9,7 +11,7 @@ import App.Styles 1.0 // ============================================================================= TabContainer { - Column { + Core.Column { spacing: SettingsWindowStyle.forms.spacing width: parent.width @@ -21,6 +23,28 @@ TabContainer { title: qsTr('audioTitle') width: parent.width + //Warning if in call + FormLine { + visible: SettingsModel.isInCall + + FormGroup { + Core.RowLayout { + spacing: SettingsAudioStyle.warningMessage.iconSize + Icon { + icon: 'warning' + iconSize: SettingsAudioStyle.warningMessage.iconSize + anchors { + rightMargin: SettingsAudioStyle.warningMessage.iconSize + leftMargin: SettingsAudioStyle.warningMessage.iconSize + } + } + Core.Text { + text: qsTr('audioSettingsInCallWarning') + } + } + } + } + FormLine { FormGroup { label: qsTr('playbackDeviceLabel') @@ -36,6 +60,28 @@ TabContainer { } } + FormLine { + FormGroup { + label: qsTr('playbackGainLabel') + enabled: !SettingsModel.isInCall + + Slider { + id: playbackSlider + width: parent.width + enabled: !SettingsModel.isInCall + + Core.Component.onCompleted: value = SettingsModel.playbackGain + onPositionChanged: SettingsModel.playbackGain = position + + Core.ToolTip { + parent: playbackSlider.handle + visible: playbackSlider.pressed + text: (playbackSlider.value * 100).toFixed(0) + " %" + } + } + } + } + FormLine { FormGroup { label: qsTr('captureDeviceLabel') @@ -51,11 +97,83 @@ TabContainer { } } + FormLine { + FormGroup { + label: qsTr('captureGainLabel') + + Slider { + id: captureSlider + width: parent.width + enabled: !SettingsModel.isInCall + + Core.Component.onCompleted: value = SettingsModel.captureGain + onPositionChanged: SettingsModel.captureGain = position + + Core.ToolTip { + parent: captureSlider.handle + visible: captureSlider.pressed + text: (captureSlider.value * 100).toFixed(0) + " %" + } + } + } + } + + FormLine { + FormGroup { + id: audioTestRow + label: qsTr('audioTestLabel') + visible: !SettingsModel.isInCall + + Core.Slider { + id: audioTestSlider + + enabled: false + width: parent.width + anchors { + leftMargin: SettingsAudioStyle.ringPlayer.leftMargin + } + + background: Core.Rectangle { + x: audioTestSlider.leftPadding + y: audioTestSlider.topPadding + audioTestSlider.availableHeight / 2 - height / 2 + implicitWidth: 200 + implicitHeight: 8 + width: audioTestSlider.availableWidth + height: implicitHeight + radius: 2 + color: "#bdbebf" + + Core.Rectangle { + width: audioTestSlider.visualPosition * parent.width + height: parent.height + color: audioTestSlider.value > 0.8 ? "#ff0000" : "#21be2b" + radius: 2 + } + } + + //Empty slider handle + handle: Core.Text { + text: '' + visible: false + } + + Core.Timer { + interval: 50 + repeat: true + running: SettingsModel.captureGraphRunning + + onTriggered: parent.value = SettingsModel.getMicVolume() + } + } + } + } + FormLine { FormGroup { label: qsTr('ringerDeviceLabel') ComboBox { + enabled: !SettingsModel.isInCall currentIndex: Utils.findIndex(model, function (device) { return device === SettingsModel.ringerDevice }) @@ -108,7 +226,7 @@ TabContainer { } } - Loader { + Core.Loader { id: ringPlayer active: window.visible diff --git a/ui/views/App/Settings/SettingsCallsChat.qml b/ui/views/App/Settings/SettingsCallsChat.qml index 8305930f9..cfdc70550 100644 --- a/ui/views/App/Settings/SettingsCallsChat.qml +++ b/ui/views/App/Settings/SettingsCallsChat.qml @@ -55,6 +55,17 @@ TabContainer { } } } + FormGroup { + label: qsTr('encryptionMandatoryLabel') + + Switch { + id: encryptionMandatory + + checked: SettingsModel.mediaEncryptionMandatory + + onClicked: SettingsModel.mediaEncryptionMandatory = !checked + } + } } FormLine { diff --git a/ui/views/App/Settings/SettingsWindow.qml b/ui/views/App/Settings/SettingsWindow.qml index d3261a266..374f3a81a 100644 --- a/ui/views/App/Settings/SettingsWindow.qml +++ b/ui/views/App/Settings/SettingsWindow.qml @@ -19,6 +19,8 @@ ApplicationWindow { title: qsTr('settingsTitle') + onClosing: SettingsModel.settingsWindowClosing() + // --------------------------------------------------------------------------- Shortcut { @@ -48,16 +50,21 @@ ApplicationWindow { TabBar { id: tabBar + onCurrentIndexChanged: SettingsModel.onSettingsTabChanged(currentIndex) + TabButton { iconName: 'settings_sip_accounts' text: qsTr('sipAccountsTab') width: implicitWidth - } + //onClicked: SettingsModel.settingsButtonClicked("sip") + } TabButton { iconName: 'settings_audio' text: qsTr('audioTab') width: implicitWidth + //onClicked: SettingsModel.accessAudioSettings() + //onClicked: SettingsModel.settingsButtonClicked("audio") } TabButton { @@ -65,12 +72,15 @@ ApplicationWindow { iconName: 'settings_video' text: qsTr('videoTab') width: implicitWidth + //onClicked: SettingsModel.accessVideoSettings() + //onClicked: SettingsModel.settingsButtonClicked("video") } TabButton { iconName: 'settings_call' text: qsTr('callsAndChatTab') width: implicitWidth + //onClicked: SettingsModel.settingsButtonClicked("call") } TabButton { @@ -78,18 +88,21 @@ ApplicationWindow { iconName: 'settings_network' text: qsTr('networkTab') width: implicitWidth + //onClicked: SettingsModel.settingsButtonClicked("network") } TabButton { iconName: 'settings_advanced' text: qsTr('uiTab') width: implicitWidth + //onClicked: SettingsModel.settingsButtonClicked("ui") } TabButton { iconName: 'settings_advanced' text: qsTr('uiAdvanced') width: implicitWidth + //onClicked: SettingsModel.settingsButtonClicked("advanced") } } diff --git a/ui/views/App/Styles/Settings/SettingsAudioStyle.qml b/ui/views/App/Styles/Settings/SettingsAudioStyle.qml index 00b85aa34..a7145c284 100644 --- a/ui/views/App/Styles/Settings/SettingsAudioStyle.qml +++ b/ui/views/App/Styles/Settings/SettingsAudioStyle.qml @@ -7,4 +7,7 @@ QtObject { property QtObject ringPlayer: QtObject { property int leftMargin: 10 } + property QtObject warningMessage: QtObject { + property int iconSize: 20 + } }