From ca7278d51fabdd52d6d976637a9a2fd6fd19d69a Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Fri, 16 Feb 2024 14:43:03 +0100 Subject: [PATCH] Feature: Screen Sharing Avoid to use SCShareableContent API because of crash on release. --- .gitlab-ci-files/job-macosx-desktop.yml | 10 +- CHANGELOG.md | 1 + CMakeLists.txt | 4 +- cmake/TasksMacos.cmake | 2 +- linphone-app/CMakeLists.txt | 17 +- .../linphone_package/CMakeLists.txt | 2 +- linphone-app/src/app/App.cpp | 8 + .../src/app/providers/ScreenProvider.cpp | 43 + .../src/app/providers/ScreenProvider.hpp | 37 + .../singleapplication_p.cpp | 4 +- .../src/components/call/CallListener.cpp | 2 +- .../src/components/call/CallModel.cpp | 56 +- .../src/components/call/CallModel.hpp | 16 +- linphone-app/src/components/camera/Camera.cpp | 8 +- .../conference/ConferenceListener.cpp | 8 +- .../conference/ConferenceListener.hpp | 7 +- .../components/conference/ConferenceModel.cpp | 66 +- .../components/conference/ConferenceModel.hpp | 13 + .../src/components/contact/ContactModel.cpp | 1 - .../history/CallHistoryProxyModel.cpp | 2 +- .../other/desktop-tools/DesktopToolsLinux.cpp | 104 +- .../other/desktop-tools/DesktopToolsLinux.hpp | 38 +- .../other/desktop-tools/DesktopToolsMacOs.hpp | 28 +- .../desktop-tools/DesktopToolsMacOsNative.mm | 71 +- .../desktop-tools/DesktopToolsWindows.cpp | 70 +- .../desktop-tools/DesktopToolsWindows.hpp | 34 +- .../ParticipantDeviceListModel.cpp | 48 +- .../ParticipantDeviceListModel.hpp | 2 + .../participant/ParticipantDeviceListener.cpp | 6 +- .../participant/ParticipantDeviceListener.hpp | 2 + .../participant/ParticipantDeviceModel.cpp | 69 +- .../participant/ParticipantDeviceModel.hpp | 10 +- .../ParticipantDeviceProxyModel.cpp | 2 + .../src/components/screen/ScreenListModel.cpp | 44 + .../src/components/screen/ScreenListModel.hpp | 39 + .../components/screen/ScreenProxyModel.cpp | 30 + .../components/screen/ScreenProxyModel.hpp | 39 + .../src/components/settings/SettingsModel.cpp | 1225 ++++++++------- .../src/components/settings/SettingsModel.hpp | 1333 +++++++++-------- .../VideoSourceDescriptorModel.cpp | 69 + .../VideoSourceDescriptorModel.hpp | 57 + linphone-app/src/utils/LinphoneEnums.cpp | 9 + linphone-app/src/utils/LinphoneEnums.hpp | 12 + linphone-app/src/utils/Utils.cpp | 6 + linphone-app/src/utils/Utils.hpp | 2 + .../Form/Buttons/AbstractTextButton.qml | 10 +- .../ui/modules/Common/Form/RadioButton.qml | 19 +- .../ui/modules/Common/Image/RoundedImage.qml | 5 +- .../ui/modules/Linphone/Camera/CameraItem.qml | 6 +- .../ui/modules/Linphone/Camera/CameraView.qml | 1 + .../ui/modules/Linphone/Menus/IncallMenu.qml | 153 +- .../Linphone/Sticker/CameraSticker.qml | 1 + .../ui/modules/Linphone/Sticker/Sticker.qml | 1 + .../Linphone/Styles/Menus/IncallMenuStyle.qml | 2 + linphone-app/ui/views/App/Calls/Incall.qml | 44 +- .../views/App/Calls/IncallActiveSpeaker.qml | 18 +- .../ui/views/App/Calls/IncallFullscreen.qml | 32 +- .../Settings/Dialogs/SettingsVideoPreview.qml | 6 +- .../ui/views/App/Settings/SettingsVideo.qml | 14 + .../ui/views/App/Styles/Calls/IncallStyle.qml | 3 + linphone-sdk | 2 +- 61 files changed, 2560 insertions(+), 1413 deletions(-) create mode 100644 linphone-app/src/app/providers/ScreenProvider.cpp create mode 100644 linphone-app/src/app/providers/ScreenProvider.hpp create mode 100644 linphone-app/src/components/screen/ScreenListModel.cpp create mode 100644 linphone-app/src/components/screen/ScreenListModel.hpp create mode 100644 linphone-app/src/components/screen/ScreenProxyModel.cpp create mode 100644 linphone-app/src/components/screen/ScreenProxyModel.hpp create mode 100644 linphone-app/src/components/videoSource/VideoSourceDescriptorModel.cpp create mode 100644 linphone-app/src/components/videoSource/VideoSourceDescriptorModel.hpp diff --git a/.gitlab-ci-files/job-macosx-desktop.yml b/.gitlab-ci-files/job-macosx-desktop.yml index dc5e743fc..0580e7304 100644 --- a/.gitlab-ci-files/job-macosx-desktop.yml +++ b/.gitlab-ci-files/job-macosx-desktop.yml @@ -18,7 +18,7 @@ echo $DEFAULT_MACOS_CMAKE_OPTIONS echo $CMAKE_OPTIONS echo $ADDITIONAL_BUILD_OPTIONS - cmake .. -G "$CMAKE_GENERATOR" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_BUILD_TYPE=$CI_BUILD_TYPE $DEFAULT_MACOS_CMAKE_OPTIONS -DLINPHONE_BUILDER_SIGNING_IDENTITY="$MACOS_SIGNING_IDENTITY" $XCODE_OPTIONS $CMAKE_OPTIONS $SCHEDULE_CMAKE_OPTIONS $RELEASE_FILE + cmake .. -G "$CMAKE_GENERATOR" -DCMAKE_OSX_DEPLOYMENT_TARGET=12.3 -DCMAKE_BUILD_TYPE=$CI_BUILD_TYPE $DEFAULT_MACOS_CMAKE_OPTIONS -DLINPHONE_BUILDER_SIGNING_IDENTITY="$MACOS_SIGNING_IDENTITY" $XCODE_OPTIONS $CMAKE_OPTIONS $SCHEDULE_CMAKE_OPTIONS $RELEASE_FILE cmake --build . --target install --config $CI_BUILD_TYPE $LBC_NODEBUG_OPTIONS -- $ADDITIONAL_BUILD_OPTIONS ccache -s @@ -46,7 +46,7 @@ job-macosx-ninja: - schedules variables: CMAKE_GENERATOR: Ninja - CMAKE_OPTIONS: -DENABLE_PQCRYPTO=OFF + CMAKE_OPTIONS: -DENABLE_PQCRYPTO=ON extends: .job-macosx-desktop ################################################# @@ -60,7 +60,7 @@ job-macosx-makefile: - $DEPLOY_PLUGINS variables: CMAKE_GENERATOR: Unix Makefiles - CMAKE_OPTIONS: -DENABLE_PQCRYPTO=OFF + CMAKE_OPTIONS: -DENABLE_PQCRYPTO=ON ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS extends: .job-macosx-desktop @@ -69,7 +69,7 @@ job-macosx-ninja-novideo: - !reference [.rules-merge-request-manual, rules] - if: $NIGHTLY_MASTER variables: - CMAKE_OPTIONS: -DENABLE_VIDEO=OFF -DENABLE_PQCRYPTO=OFF + CMAKE_OPTIONS: -DENABLE_VIDEO=OFF -DENABLE_PQCRYPTO=ON CMAKE_GENERATOR: Ninja extends: .job-macosx-desktop @@ -99,7 +99,7 @@ job-macosx-makefile-package: - $PACKAGE_MACOSX - $DEPLOY_MACOSX variables: - CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=ON -DENABLE_GPL_THIRD_PARTIES=ON -DENABLE_G729=ON + CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=ON -DENABLE_GPL_THIRD_PARTIES=ON -DENABLE_G729=ON -DENABLE_PQCRYPTO=ON RELEASE_FILE: -DLINPHONE_SDK_MAKE_RELEASE_FILE_URL=$MAKE_RELEASE_FILE_URL/$MACOSX_PLATFORM/$APP_FOLDER extends: job-macosx-makefile script: diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c73782ca..d3d6d0411 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - '[ui] logs_max_size' : option to set the max size of one log file. +- Screen Sharing ## 5.2.1 - 2024-02-01 diff --git a/CMakeLists.txt b/CMakeLists.txt index d6a4ccdc7..56376ad2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,8 @@ if( APPLE ) set(CMAKE_INSTALL_DATAROOTDIR "${APPLICATION_NAME}.app/Contents/Resources/share") if( NOT CMAKE_OSX_DEPLOYMENT_TARGET) - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15")#Qt: 'path' is unavailable: introduced in macOS 10.15 + #set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15")#Qt: 'path' is unavailable: introduced in macOS 10.15 + set(CMAKE_OSX_DEPLOYMENT_TARGET "12.3")#ScreenSharing: 'SCStreamConfiguration' has been introduced in macOS 12.3 endif() set(LINPHONESDK_MACOS_ARCHS ${LINPHONEAPP_MACOS_ARCHS}) set(CMAKE_OSX_ARCHITECTURES ${LINPHONESDK_MACOS_ARCHS} CACHE STRING "") @@ -151,6 +152,7 @@ add_option(OPTION_LIST ENABLE_QT_KEYCHAIN "Build QtKeychain to manage VFS from S add_option(OPTION_LIST ENABLE_QRCODE "Enable QRCode support" OFF)#Experimental add_option(OPTION_LIST ENABLE_RELATIVE_PREFIX "Set Internal packages relative to the binary" ON) add_option(OPTION_LIST ENABLE_SANITIZER "Enable sanitizer." OFF) +add_option(OPTION_LIST ENABLE_SCREENSHARING "Enable screen sharing." ON) add_option(OPTION_LIST ENABLE_STRICT "Build with strict compilator flags e.g. -Wall -Werror" OFF) add_option(OPTION_LIST ENABLE_TESTS "Build with testing binaries of SDK" OFF) add_option(OPTION_LIST ENABLE_TESTS_COMPONENTS "Build libbctoolbox-tester" OFF) diff --git a/cmake/TasksMacos.cmake b/cmake/TasksMacos.cmake index b41d8f663..d188f2fa3 100644 --- a/cmake/TasksMacos.cmake +++ b/cmake/TasksMacos.cmake @@ -45,7 +45,7 @@ set(_MACOS_INSTALL_DIR "${APPLICATION_OUTPUT_DIR}/${_MACOS_INSTALL_RELATIVE_DIR} #linphone_sdk_get_inherited_cmake_args(_CMAKE_CONFIGURE_ARGS _CMAKE_BUILD_ARGS) #linphone_sdk_get_enable_cmake_args(_MACOS_CMAKE_ARGS) -set(_MACOS_CMAKE_ARGS ${CMAKE_OSX_DEPLOYMENT_TARGET}) +set(_MACOS_CMAKE_ARGS "-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") set(_MACOS_TARGETS) foreach(_MACOS_ARCH IN LISTS _MACOS_ARCHS) diff --git a/linphone-app/CMakeLists.txt b/linphone-app/CMakeLists.txt index d3e0e7b69..1934f5e2e 100644 --- a/linphone-app/CMakeLists.txt +++ b/linphone-app/CMakeLists.txt @@ -259,6 +259,7 @@ set(SOURCES src/app/providers/ExternalImageProvider.cpp src/app/providers/QRCodeProvider.cpp src/app/providers/ThumbnailProvider.cpp + src/app/providers/ScreenProvider.cpp src/app/proxyModel/ProxyListModel.cpp src/app/proxyModel/SortFilterProxyModel.cpp #src/app/proxyModel/ProxyMapModel.cpp @@ -359,6 +360,8 @@ set(SOURCES src/components/recorder/RecorderModel.cpp src/components/recorder/RecordingListModel.cpp src/components/recorder/RecordingProxyModel.cpp + src/components/screen/ScreenListModel.cpp + src/components/screen/ScreenProxyModel.cpp src/components/search/SearchListener.cpp src/components/search/SearchResultModel.cpp src/components/search/SearchSipAddressesModel.cpp @@ -380,6 +383,7 @@ set(SOURCES src/components/tunnel/TunnelConfigListModel.cpp src/components/tunnel/TunnelConfigProxyModel.cpp src/components/url-handlers/UrlHandlers.cpp + src/components/videoSource/VideoSourceDescriptorModel.cpp src/utils/Constants.cpp src/utils/LinphoneEnums.cpp src/utils/MediastreamerUtils.cpp @@ -404,6 +408,7 @@ set(HEADERS src/app/providers/ExternalImageProvider.hpp src/app/providers/QRCodeProvider.hpp src/app/providers/ThumbnailProvider.hpp + src/app/providers/ScreenProvider.hpp src/app/proxyModel/ProxyAbstractListModel.hpp src/app/proxyModel/ProxyAbstractMapModel.hpp src/app/proxyModel/ProxyAbstractObject.hpp @@ -510,6 +515,8 @@ set(HEADERS src/components/recorder/RecorderModel.hpp src/components/recorder/RecordingListModel.hpp src/components/recorder/RecordingProxyModel.hpp + src/components/screen/ScreenListModel.hpp + src/components/screen/ScreenProxyModel.hpp src/components/search/SearchListener.hpp src/components/search/SearchResultModel.hpp src/components/search/SearchSipAddressesModel.hpp @@ -531,6 +538,7 @@ set(HEADERS src/components/tunnel/TunnelConfigListModel.hpp src/components/tunnel/TunnelConfigProxyModel.hpp src/components/url-handlers/UrlHandlers.hpp + src/components/videoSource/VideoSourceDescriptorModel.hpp src/utils/Constants.hpp src/utils/LinphoneEnums.hpp src/utils/MediastreamerUtils.hpp @@ -820,7 +828,7 @@ foreach(T ${APP_TARGETS}) endforeach() if (APPLE) - target_link_libraries(${TARGET_NAME} "-framework Cocoa" "-framework IOKit" "-framework AVFoundation") + target_link_libraries(${TARGET_NAME} "-framework Cocoa" "-framework IOKit" "-framework AVFoundation" "-framework ScreenCaptureKit") endif() target_link_libraries(${TARGET_NAME} ${APP_PLUGIN}) @@ -830,6 +838,13 @@ if(WIN32 AND ENABLE_LDAP) target_link_libraries(${TARGET_NAME} wsock32 ws2_32 ${OPENLDAP_LIBRARIES}) endif() +if(NOT WIN32) + find_package(X11) +endif() +if(X11_FOUND) + target_link_libraries(${TARGET_NAME} X11::X11) +endif() + add_dependencies(${APP_LIBRARY} update_translations ${APP_PLUGIN}) # ------------------------------------------------------------------------------ # CPack settings & RPM. diff --git a/linphone-app/cmake_builder/linphone_package/CMakeLists.txt b/linphone-app/cmake_builder/linphone_package/CMakeLists.txt index b4d65909c..6495b7673 100644 --- a/linphone-app/cmake_builder/linphone_package/CMakeLists.txt +++ b/linphone-app/cmake_builder/linphone_package/CMakeLists.txt @@ -432,7 +432,7 @@ if(${ENABLE_APP_PACKAGING}) message(FATAL_ERROR "Could not find the macdeployqt program. Make sure it is in the PATH.") endif() endif() - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cleanCpack.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cleanCpack.cmake" @ONLY) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cleanCPack.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cleanCPack.cmake" @ONLY) set(CPACK_PRE_BUILD_SCRIPTS "${CMAKE_CURRENT_BINARY_DIR}/cleanCPack.cmake") diff --git a/linphone-app/src/app/App.cpp b/linphone-app/src/app/App.cpp index 569e1c0fe..cb7ff8ae8 100644 --- a/linphone-app/src/app/App.cpp +++ b/linphone-app/src/app/App.cpp @@ -48,6 +48,7 @@ #include "providers/ExternalImageProvider.hpp" #include "providers/QRCodeProvider.hpp" #include "providers/ThumbnailProvider.hpp" +#include "providers/ScreenProvider.hpp" #include "translator/DefaultTranslator.hpp" #include "utils/Utils.hpp" #include "utils/Constants.hpp" @@ -57,6 +58,7 @@ #include "components/other/date/DateModel.hpp" #include "components/other/spell-checker/SpellChecker.hpp" +#include "components/screen/ScreenProxyModel.hpp" #include "components/settings/EmojisSettingsModel.hpp" #include "components/timeline/TimelineModel.hpp" #include "components/timeline/TimelineListModel.hpp" @@ -66,6 +68,8 @@ #include "components/participant/ParticipantListModel.hpp" #include "components/participant/ParticipantProxyModel.hpp" +#include "components/videoSource/VideoSourceDescriptorModel.hpp" + // ============================================================================= using namespace std; @@ -268,6 +272,7 @@ App::App (int &argc, char *argv[]) : SingleApplication(argc, argv, true, Mode::U _putenv(("TZ="+QTimeZone::systemTimeZoneId().toStdString()).c_str()); _tzset(); #else + QString t = QTimeZone::systemTimeZoneId(); setenv("TZ", QTimeZone::systemTimeZoneId().toStdString().c_str(), 1); tzset(); #endif @@ -489,6 +494,7 @@ void App::initContentApp () { mEngine->addImageProvider(ExternalImageProvider::ProviderId, new ExternalImageProvider()); mEngine->addImageProvider(QRCodeProvider::ProviderId, new QRCodeProvider()); mEngine->addImageProvider(ThumbnailProvider::ProviderId, new ThumbnailProvider()); + mEngine->addImageProvider(ScreenProvider::ProviderId, new ScreenProvider()); mEngine->rootContext()->setContextProperty("applicationName", APPLICATION_NAME); mEngine->rootContext()->setContextProperty("executableName", EXECUTABLE_NAME); @@ -778,6 +784,7 @@ void App::registerTypes () { registerType("SearchSipAddressesProxyModel"); registerType("TemporaryFile"); registerType("TimeZoneProxyModel"); + registerType("VideoSourceDescriptorModel"); registerType("CallHistoryProxyModel"); registerType("ColorProxyModel"); @@ -788,6 +795,7 @@ void App::registerTypes () { registerType("ParticipantDeviceProxyModel"); registerType("SoundPlayer"); registerType("TelephoneNumbersModel"); + registerType("ScreenProxyModel"); registerType("SpellChecker"); registerSingletonType("AudioCodecsModel"); diff --git a/linphone-app/src/app/providers/ScreenProvider.cpp b/linphone-app/src/app/providers/ScreenProvider.cpp new file mode 100644 index 000000000..77ce58763 --- /dev/null +++ b/linphone-app/src/app/providers/ScreenProvider.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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, see . + */ + +#include "ScreenProvider.hpp" +#include +#include + +// ============================================================================= + +const QString ScreenProvider::ProviderId = "screen"; + +ScreenProvider::ScreenProvider () : QQuickImageProvider( + QQmlImageProviderBase::Image, + QQmlImageProviderBase::ForceAsynchronousImageLoading +) {} + +QImage ScreenProvider::requestImage (const QString &id, QSize *size, const QSize &) { + int index = id.toInt(); + auto screens = QGuiApplication::screens(); + if(index >= 0 && index < screens.size()){ + auto image = screens[index]->grabWindow(0); + *size = image.size(); + return image.toImage(); + }else + return QImage(); +} diff --git a/linphone-app/src/app/providers/ScreenProvider.hpp b/linphone-app/src/app/providers/ScreenProvider.hpp new file mode 100644 index 000000000..47b58b3c1 --- /dev/null +++ b/linphone-app/src/app/providers/ScreenProvider.hpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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, see . + */ + +#ifndef SCREEN_PROVIDER_H_ +#define SCREEN_PROVIDER_H_ + +#include + +// ============================================================================= + +class ScreenProvider : public QQuickImageProvider { +public: + ScreenProvider (); + + QImage requestImage (const QString &id, QSize *size, const QSize &requestedSize) override; + + static const QString ProviderId; +}; + +#endif diff --git a/linphone-app/src/app/single-application/singleapplication_p.cpp b/linphone-app/src/app/single-application/singleapplication_p.cpp index 4b83c7714..0f40eaf7c 100644 --- a/linphone-app/src/app/single-application/singleapplication_p.cpp +++ b/linphone-app/src/app/single-application/singleapplication_p.cpp @@ -315,8 +315,8 @@ bool SingleApplicationPrivate::writeConfirmedFrame( int msecs, const QByteArray { socket->write( msg ); socket->flush(); - - bool result = socket->waitForReadyRead( msecs < 0 ? -1 : msecs ); // await ack byte + + bool result = socket->waitForReadyRead( msecs < 0 ? -1 : msecs ); // await ack byte if (result) { socket->read( 1 ); return true; diff --git a/linphone-app/src/components/call/CallListener.cpp b/linphone-app/src/components/call/CallListener.cpp index 067eae0a8..4f1684286 100644 --- a/linphone-app/src/components/call/CallListener.cpp +++ b/linphone-app/src/components/call/CallListener.cpp @@ -37,4 +37,4 @@ CallListener::CallListener(QObject* parent) : QObject(parent){ void CallListener::onRemoteRecording(const std::shared_ptr & call, bool recording){ qDebug() << "onRemoteRecording: " << recording; emit remoteRecording(call, recording); -} \ No newline at end of file +} diff --git a/linphone-app/src/components/call/CallModel.cpp b/linphone-app/src/components/call/CallModel.cpp index cfc488e87..3fd931544 100644 --- a/linphone-app/src/components/call/CallModel.cpp +++ b/linphone-app/src/components/call/CallModel.cpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop @@ -40,6 +40,7 @@ #include "components/settings/AccountSettingsModel.hpp" #include "components/settings/SettingsModel.hpp" #include "components/timeline/TimelineListModel.hpp" +#include "components/videoSource/VideoSourceDescriptorModel.hpp" #include "utils/MediastreamerUtils.hpp" #include "utils/Utils.hpp" @@ -65,6 +66,7 @@ CallModel::CallModel (shared_ptr call){ connect(this, &CallModel::isPQZrtpChanged, this, &CallModel::securityUpdated); connect(this, &CallModel::securityUpdated, this, &CallModel::onSecurityUpdated); + mCall = call; if(mCall) mCall->setData("call-model", *this); @@ -120,12 +122,14 @@ CallModel::CallModel (shared_ptr call){ if(mCall->getConference()) { mConferenceModel = ConferenceModel::create(mCall->getConference()); connect(mConferenceModel.get(), &ConferenceModel::participantAdminStatusChanged, this, &CallModel::onParticipantAdminStatusChanged); + connect(mConferenceModel.get(), &ConferenceModel::localScreenSharingChanged, this, &CallModel::onLocalScreenSharingChanged); } auto conferenceInfo = CoreManager::getInstance()->getCore()->findConferenceInformationFromUri(getConferenceAddress()); if( conferenceInfo ){ mConferenceInfoModel = ConferenceInfoModel::create(conferenceInfo); } mMagicSearch->getContactsListAsync(mRemoteAddress->getUsername(),mRemoteAddress->getDomain(), (int)linphone::MagicSearch::Source::LdapServers | (int)linphone::MagicSearch::Source::Friends, linphone::MagicSearch::Aggregation::Friend); + } } @@ -248,6 +252,7 @@ QSharedPointer CallModel::getConferenceSharedModel(){ if(mCall->getState() != linphone::Call::State::End && mCall->getConference() && !mConferenceModel){ mConferenceModel = ConferenceModel::create(mCall->getConference()); connect(mConferenceModel.get(), &ConferenceModel::participantAdminStatusChanged, this, &CallModel::onParticipantAdminStatusChanged); + connect(mConferenceModel.get(), &ConferenceModel::localScreenSharingChanged, this, &CallModel::onLocalScreenSharingChanged); emit conferenceModelChanged(); } return mConferenceModel; @@ -570,7 +575,6 @@ void CallModel::handleCallStateChanged (const shared_ptr &call, case linphone::Call::State::PushIncomingReceived: break; } - emit statusChanged(getStatus()); } @@ -1031,6 +1035,12 @@ void CallModel::onSecurityUpdated(){ model->updateSecurityLevel(); } +void CallModel::onLocalScreenSharingChanged(bool enabled) { + qDebug() << "onLocalScreenSharingChanged" << enabled; + if(!enabled) + setVideoSource(nullptr); +} + void CallModel::setRemoteDisplayName(const std::string& name){ mRemoteAddress->setDisplayName(name); if(mCall) { @@ -1081,6 +1091,9 @@ void CallModel::changeConferenceVideoLayout(LinphoneEnums::ConferenceLayout layo shared_ptr params = coreManager->getCore()->createCallParams(mCall); params->setConferenceVideoLayout(LinphoneEnums::toLinphone(layout)); params->enableVideo(layout != LinphoneEnums::ConferenceLayoutAudioOnly); + if (!params->videoEnabled() && params->screenSharingEnabled()) { + params->enableScreenSharing(false); // Deactivate screensharing if going to audio only. + } mCall->update(params); } @@ -1105,6 +1118,45 @@ void CallModel::updateConferenceVideoLayout(){ } } +void CallModel::setVideoSource(std::shared_ptr videoDesc){ + //auto videoSource = mCall->getVideoSource(); + //if(!videoDesc) { + // auto oldDesc = linphone::Factory::get()->createVideoSourceDescriptor(); + // oldDesc->setCameraId(CoreManager::getInstance()->getCore()->getVideoDevice()); + // mCall->setVideoSource(oldDesc); + // mCall->setVideoSource(videoDesc); + //}else + mCall->setVideoSource(videoDesc); + + emit videoDescriptorChanged(); +} + +LinphoneEnums::VideoSourceScreenSharingType CallModel::getVideoSourceType() const{ + auto videoSource = mCall->getVideoSource(); + return LinphoneEnums::fromLinphone(videoSource ? videoSource->getScreenSharingType() : linphone::VideoSourceScreenSharingType::Display); +} +int CallModel::getScreenSharingIndex() const{ + auto videoSource = mCall->getVideoSource(); + if(videoSource && videoSource->getScreenSharingType() == linphone::VideoSourceScreenSharingType::Display) { + void * t = videoSource->getScreenSharing(); + return *(int*)(&t); + }else + return -1; +} + +VideoSourceDescriptorModel *CallModel::getVideoSourceDescriptorModel() const { + auto videoSource = mCall->getVideoSource(); + return new VideoSourceDescriptorModel(videoSource ? videoSource->clone() : nullptr); +} + +void CallModel::setVideoSourceDescriptorModel(VideoSourceDescriptorModel *model) { + if(model) + setVideoSource(model->mDesc); + else { + setVideoSource(nullptr); + } +} + // ----------------------------------------------------------------------------- CallModel::CallEncryption CallModel::getEncryption () const { diff --git a/linphone-app/src/components/call/CallModel.hpp b/linphone-app/src/components/call/CallModel.hpp index c8b8dea6b..f35b8cfa0 100644 --- a/linphone-app/src/components/call/CallModel.hpp +++ b/linphone-app/src/components/call/CallModel.hpp @@ -34,6 +34,7 @@ class ConferenceInfoModel; class ConferenceModel; class ContactModel; class ChatRoomModel; +class VideoSourceDescriptorModel; class CallModel : public QObject { Q_OBJECT @@ -97,7 +98,9 @@ class CallModel : public QObject { Q_PROPERTY(LinphoneEnums::ConferenceLayout conferenceVideoLayout READ getConferenceVideoLayout WRITE changeConferenceVideoLayout NOTIFY conferenceVideoLayoutChanged) - + Q_PROPERTY(LinphoneEnums::VideoSourceScreenSharingType screenSharingType READ getVideoSourceType NOTIFY videoDescriptorChanged) + Q_PROPERTY(bool screenSharingIndex READ getScreenSharingIndex NOTIFY videoDescriptorChanged) + Q_PROPERTY(VideoSourceDescriptorModel *videoSourceDescriptorModel READ getVideoSourceDescriptorModel WRITE setVideoSourceDescriptorModel NOTIFY videoDescriptorChanged) public: enum CallStatus { @@ -194,6 +197,13 @@ public: void changeConferenceVideoLayout(LinphoneEnums::ConferenceLayout layout); // Make a call request void updateConferenceVideoLayout(); // Called from call state changed ater the new layout has been set. + void setVideoSource(std::shared_ptr videoDesc); + LinphoneEnums::VideoSourceScreenSharingType getVideoSourceType() const; + int getScreenSharingIndex() const; + Q_INVOKABLE VideoSourceDescriptorModel *getVideoSourceDescriptorModel() const; + Q_INVOKABLE void setVideoSourceDescriptorModel(VideoSourceDescriptorModel *model = nullptr); + + static constexpr int DtmfSoundDelay = 200; std::shared_ptr mCall; @@ -210,6 +220,7 @@ public slots: void onChatRoomInitialized(int state); void onParticipantAdminStatusChanged(const std::shared_ptr & participant); void onSecurityUpdated(); + void onLocalScreenSharingChanged(bool enabled); signals: void meAdminChanged(); @@ -241,8 +252,7 @@ signals: void transferAddressChanged (const QString &transferAddress); void conferenceVideoLayoutChanged(); - - + void videoDescriptorChanged(); public: void handleCallEncryptionChanged (const std::shared_ptr &call); void handleCallStateChanged (const std::shared_ptr &call, linphone::Call::State state); diff --git a/linphone-app/src/components/camera/Camera.cpp b/linphone-app/src/components/camera/Camera.cpp index 0d7c2b4d4..c5cd2860a 100644 --- a/linphone-app/src/components/camera/Camera.cpp +++ b/linphone-app/src/components/camera/Camera.cpp @@ -140,6 +140,7 @@ void Camera::updateWindowIdLocation(){ if(mIsPreview) setWindowIdLocation( WindowIdLocation::CorePreview); else{ + if(mCallModel){ auto call = mCallModel->getCall(); if(call){ @@ -180,6 +181,7 @@ void Camera::removeLinphonePlayer(){ QQuickFramebufferObject::Renderer *Camera::createRenderer () const { QQuickFramebufferObject::Renderer * renderer = NULL; + resetWindowId(); if(mWindowIdLocation == CorePreview){ qInfo() << "[Camera] (" << mQmlName << ") Setting Camera to Preview"; renderer=(QQuickFramebufferObject::Renderer *)CoreManager::getInstance()->getCore()->createNativePreviewWindowId(); @@ -334,8 +336,10 @@ void Camera::isNotReady(){ void Camera::activatePreview(){ mPreviewCounterMutex.lock(); - if (++mPreviewCounter == 1) + if (++mPreviewCounter == 1) { CoreManager::getInstance()->getCore()->enableVideoPreview(true); + CoreManager::getInstance()->getSettingsModel()->setCaptureWindowId(); + } mPreviewCounterMutex.unlock(); } @@ -355,4 +359,4 @@ void Camera::onCallStateChanged(){ disconnect(mCallModel, &CallModel::statusChanged, this, &Camera::onCallStateChanged); mCallModel = nullptr; } -} \ No newline at end of file +} diff --git a/linphone-app/src/components/conference/ConferenceListener.cpp b/linphone-app/src/components/conference/ConferenceListener.cpp index cb18d2e10..0254c02b4 100644 --- a/linphone-app/src/components/conference/ConferenceListener.cpp +++ b/linphone-app/src/components/conference/ConferenceListener.cpp @@ -46,7 +46,7 @@ void ConferenceListener::onActiveSpeakerParticipantDevice(const std::shared_ptr< emit activeSpeakerParticipantDevice(participantDevice); } -void ConferenceListener::onParticipantAdded(const std::shared_ptr & conference, const std::shared_ptr & participant){ +void ConferenceListener::onParticipantAdded(const std::shared_ptr & conference, const std::shared_ptr & participant){ qDebug() << "onParticipantAdded: " << participant->getAddress()->asString().c_str(); emit participantAdded(participant); } @@ -54,7 +54,7 @@ void ConferenceListener::onParticipantRemoved(const std::shared_ptr & conference, const std::shared_ptr & participantDevice){ +void ConferenceListener::onParticipantDeviceAdded(const std::shared_ptr & conference, const std::shared_ptr & participantDevice){ qDebug() << "onParticipantDeviceAdded"; qDebug() << "Me devices : " << conference->getMe()->getDevices().size(); if( conference->getMe()->getDevices().size() > 1) @@ -87,6 +87,10 @@ void ConferenceListener::onParticipantDeviceIsSpeakingChanged(const std::shared_ //qDebug() << "onParticipantDeviceIsSpeakingChanged: " << participantDevice->getAddress()->asString().c_str() << ". Speaking:" << isSpeaking; emit participantDeviceIsSpeakingChanged(participantDevice, isSpeaking); } +void ConferenceListener::onParticipantDeviceScreenSharingChanged(const std::shared_ptr & conference, const std::shared_ptr & device, bool enabled) { + qDebug() << "onParticipantDeviceScreenSharingChanged: " << device->getAddress()->asString().c_str() << ". Enabled:" << enabled; + emit participantDeviceScreenSharingChanged(device,enabled); +} void ConferenceListener::onStateChanged(const std::shared_ptr & conference, linphone::Conference::State newState){ qDebug() << "onStateChanged:" << (int)newState; emit conferenceStateChanged(newState); diff --git a/linphone-app/src/components/conference/ConferenceListener.hpp b/linphone-app/src/components/conference/ConferenceListener.hpp index 6f234a816..fe1d15250 100644 --- a/linphone-app/src/components/conference/ConferenceListener.hpp +++ b/linphone-app/src/components/conference/ConferenceListener.hpp @@ -36,15 +36,16 @@ public: // LINPHONE LISTENERS virtual void onActiveSpeakerParticipantDevice(const std::shared_ptr & conference, const std::shared_ptr & participantDevice) override; - virtual void onParticipantAdded(const std::shared_ptr & conference, const std::shared_ptr & participant) override; + virtual void onParticipantAdded(const std::shared_ptr & conference, const std::shared_ptr & participant) override; virtual void onParticipantRemoved(const std::shared_ptr & conference, const std::shared_ptr & participant) override; virtual void onParticipantAdminStatusChanged(const std::shared_ptr & conference, const std::shared_ptr & participant) override; - virtual void onParticipantDeviceAdded(const std::shared_ptr & conference, const std::shared_ptr & participantDevice) override; + virtual void onParticipantDeviceAdded(const std::shared_ptr & conference, const std::shared_ptr & participantDevice) override; virtual void onParticipantDeviceRemoved(const std::shared_ptr & conference, const std::shared_ptr & participantDevice) override; virtual void onParticipantDeviceStateChanged(const std::shared_ptr & conference, const std::shared_ptr & device, linphone::ParticipantDevice::State state) override; virtual void onParticipantDeviceMediaCapabilityChanged(const std::shared_ptr & conference, const std::shared_ptr & device) override; virtual void onParticipantDeviceMediaAvailabilityChanged(const std::shared_ptr & conference, const std::shared_ptr & device) override; virtual void onParticipantDeviceIsSpeakingChanged(const std::shared_ptr & conference, const std::shared_ptr & participantDevice, bool isSpeaking) override; + virtual void onParticipantDeviceScreenSharingChanged(const std::shared_ptr & conference, const std::shared_ptr & device, bool enabled) override; virtual void onStateChanged(const std::shared_ptr & conference, linphone::Conference::State newState) override; virtual void onSubjectChanged(const std::shared_ptr & conference, const std::string & subject) override; virtual void onAudioDeviceChanged(const std::shared_ptr & conference, const std::shared_ptr & audioDevice) override; @@ -61,7 +62,9 @@ signals: void participantDeviceMediaCapabilityChanged(const std::shared_ptr & participantDevice); void participantDeviceMediaAvailabilityChanged(const std::shared_ptr & participantDevice); void participantDeviceIsSpeakingChanged(const std::shared_ptr & participantDevice, bool isSpeaking); + void participantDeviceScreenSharingChanged( const std::shared_ptr & device, bool enabled); void conferenceStateChanged(linphone::Conference::State newState); + void subjectChanged(const std::string & subject); }; diff --git a/linphone-app/src/components/conference/ConferenceModel.cpp b/linphone-app/src/components/conference/ConferenceModel.cpp index e32580e33..3a7a89c81 100644 --- a/linphone-app/src/components/conference/ConferenceModel.cpp +++ b/linphone-app/src/components/conference/ConferenceModel.cpp @@ -28,6 +28,8 @@ #include "app/App.hpp" #include "components/participant/ParticipantListModel.hpp" +#include "components/core/CoreManager.hpp" +#include "components/settings/SettingsModel.hpp" #include "utils/Utils.hpp" @@ -42,6 +44,7 @@ void ConferenceModel::connectTo(ConferenceListener * listener){ connect(listener, &ConferenceListener::participantDeviceMediaCapabilityChanged, this, &ConferenceModel::onParticipantDeviceMediaCapabilityChanged); connect(listener, &ConferenceListener::participantDeviceMediaAvailabilityChanged, this, &ConferenceModel::onParticipantDeviceMediaAvailabilityChanged); connect(listener, &ConferenceListener::participantDeviceIsSpeakingChanged, this, &ConferenceModel::onParticipantDeviceIsSpeakingChanged); + connect(listener, &ConferenceListener::participantDeviceScreenSharingChanged, this, &ConferenceModel::onParticipantDeviceScreenSharingChanged); connect(listener, &ConferenceListener::conferenceStateChanged, this, &ConferenceModel::onConferenceStateChanged); connect(listener, &ConferenceListener::subjectChanged, this, &ConferenceModel::onSubjectChanged); } @@ -61,7 +64,9 @@ ConferenceModel::ConferenceModel (std::shared_ptr conferen mConference->addListener(mConferenceListener); connect(this, &ConferenceModel::participantDeviceAdded, this, &ConferenceModel::participantDeviceCountChanged); connect(this, &ConferenceModel::participantDeviceRemoved, this, &ConferenceModel::participantDeviceCountChanged); + connect(this, &ConferenceModel::isScreenSharingEnabledChanged, this, &ConferenceModel::onIsScreenSharingEnabledChanged); connect(mParticipantListModel.get(), &ParticipantListModel::participantsChanged, this, &ConferenceModel::participantDeviceCountChanged); + connect(this, &ConferenceModel::participantDeviceCountChanged, this, &ConferenceModel::updateLayout); onConferenceStateChanged(mConference->getState());// Is it already Created like for local conference? } @@ -87,6 +92,42 @@ bool ConferenceModel::updateLocalParticipant(){ return changed; } +void ConferenceModel::updateLayout(){ + if(getParticipantDeviceCount() > CoreManager::getInstance()->getSettingsModel()->getConferenceMaxThumbnails()+1) { + auto call = mConference->getCall(); + std::shared_ptr params = CoreManager::getInstance()->getCore()->createCallParams(call); + if( params->getConferenceVideoLayout() == linphone::Conference::Layout::Grid && params->videoEnabled()) { + params->setConferenceVideoLayout(linphone::Conference::Layout::ActiveSpeaker); + call->update(params); + } + } +} + +void ConferenceModel::toggleScreenSharing() { + auto device = mConference->getScreenSharingParticipantDevice(); + + if(!device || Utils::isLocal(mConference, device)) { + bool enable = !device; + auto params = CoreManager::getInstance()->getCore()->createCallParams(mConference->getCall()); + params->enableScreenSharing(enable); + if(enable) { + params->setConferenceVideoLayout(linphone::Conference::Layout::ActiveSpeaker); + params->enableVideo(true); + } + if(params->isValid()) + mConference->getCall()->update(params); + } +} + +bool ConferenceModel::isLocalScreenSharingEnabled() const{ + auto device = mConference->getScreenSharingParticipantDevice(); + return device && Utils::isLocal(mConference, device); +} + +bool ConferenceModel::isScreenSharingEnabled() const{ + return mConference && mConference->getScreenSharingParticipant(); +} + std::shared_ptr ConferenceModel::getConference()const{ return mConference; } @@ -157,11 +198,14 @@ void ConferenceModel::onParticipantAdminStatusChanged(const std::shared_ptr & participantDevice){ qDebug() << "Me devices : " << mConference->getMe()->getDevices().size(); + updateLayout(); updateLocalParticipant(); emit participantDeviceAdded(participantDevice); } void ConferenceModel::onParticipantDeviceRemoved(const std::shared_ptr & participantDevice){ qDebug() << "Me devices : " << mConference->getMe()->getDevices().size(); + if( participantDevice->screenSharingEnabled()) + emit isScreenSharingEnabledChanged(); emit participantDeviceRemoved(participantDevice); } @@ -182,10 +226,21 @@ void ConferenceModel::onParticipantDeviceMediaAvailabilityChanged(const std::sha void ConferenceModel::onParticipantDeviceIsSpeakingChanged(const std::shared_ptr & participantDevice, bool isSpeaking){ emit participantDeviceIsSpeakingChanged(participantDevice, isSpeaking); } +void ConferenceModel::onParticipantDeviceScreenSharingChanged(const std::shared_ptr & device, bool enabled){ + emit participantDeviceScreenSharingChanged(device, enabled); + if(Utils::isLocal(mConference, device)){ + emit localScreenSharingChanged(enabled); + } + emit isScreenSharingEnabledChanged(); +} + + void ConferenceModel::onConferenceStateChanged(linphone::Conference::State newState){ if(newState == linphone::Conference::State::Created){ setIsReady(true); emit participantDeviceCountChanged(); + if(mConference->getScreenSharingParticipant()) + emit isScreenSharingEnabledChanged(); } updateLocalParticipant(); emit conferenceStateChanged(newState); @@ -193,6 +248,13 @@ void ConferenceModel::onConferenceStateChanged(linphone::Conference::State newSt void ConferenceModel::onSubjectChanged(const std::string& string){ emit subjectChanged(); } - - + +void ConferenceModel::onIsScreenSharingEnabledChanged(){ + auto call = mConference->getCall(); + std::shared_ptr params = CoreManager::getInstance()->getCore()->createCallParams(call); + if(params->getConferenceVideoLayout() == linphone::Conference::Layout::Grid && params->videoEnabled()) { + params->setConferenceVideoLayout(linphone::Conference::Layout::ActiveSpeaker); + } + call->update(params); +} //----------------------------------------------------------------------------------------------------------------------- diff --git a/linphone-app/src/components/conference/ConferenceModel.hpp b/linphone-app/src/components/conference/ConferenceModel.hpp index 2147aa586..a9e6be8df 100644 --- a/linphone-app/src/components/conference/ConferenceModel.hpp +++ b/linphone-app/src/components/conference/ConferenceModel.hpp @@ -32,6 +32,7 @@ class ConferenceListener; class ParticipantListModel; +class VideoSourceDescriptorModel; class ConferenceModel : public QObject{ Q_OBJECT @@ -43,12 +44,18 @@ public: Q_PROPERTY(ParticipantModel* localParticipant READ getLocalParticipant NOTIFY localParticipantChanged) Q_PROPERTY(bool isReady MEMBER mIsReady WRITE setIsReady NOTIFY isReadyChanged) Q_PROPERTY(int participantDeviceCount READ getParticipantDeviceCount NOTIFY participantDeviceCountChanged) + Q_PROPERTY(bool isLocalScreenSharingEnabled READ isLocalScreenSharingEnabled NOTIFY localScreenSharingChanged) + Q_PROPERTY(bool isScreenSharingEnabled READ isScreenSharingEnabled NOTIFY isScreenSharingEnabledChanged) static QSharedPointer create(std::shared_ptr chatRoom, QObject *parent = Q_NULLPTR); ConferenceModel(std::shared_ptr content, QObject *parent = Q_NULLPTR); virtual ~ConferenceModel(); bool updateLocalParticipant(); // true if changed + void updateLayout(); + Q_INVOKABLE void toggleScreenSharing(); + bool isLocalScreenSharingEnabled() const; + bool isScreenSharingEnabled() const; std::shared_ptr getConference()const; @@ -71,9 +78,12 @@ public: virtual void onParticipantDeviceMediaCapabilityChanged(const std::shared_ptr & device); virtual void onParticipantDeviceMediaAvailabilityChanged(const std::shared_ptr & device); virtual void onParticipantDeviceIsSpeakingChanged(const std::shared_ptr & device, bool isSpeaking); + virtual void onParticipantDeviceScreenSharingChanged(const std::shared_ptr & device, bool enabled); virtual void onParticipantDeviceStateChanged(const std::shared_ptr & conference, const std::shared_ptr & device, linphone::ParticipantDevice::State state); virtual void onConferenceStateChanged(linphone::Conference::State newState); virtual void onSubjectChanged(const std::string& subject); + + void onIsScreenSharingEnabledChanged(); //--------------------------------------------------------------------------- signals: @@ -87,11 +97,14 @@ signals: void participantDeviceMediaCapabilityChanged(const std::shared_ptr & participantDevice); void participantDeviceMediaAvailabilityChanged(const std::shared_ptr & participantDevice); void participantDeviceIsSpeakingChanged(const std::shared_ptr & device, bool isSpeaking); + void participantDeviceScreenSharingChanged( const std::shared_ptr & device, bool enabled); void participantDeviceStateChanged(const std::shared_ptr & device, linphone::ParticipantDevice::State state); void conferenceStateChanged(linphone::Conference::State newState); void subjectChanged(); void isReadyChanged(); void participantDeviceCountChanged(); + void localScreenSharingChanged(bool enabled); + void isScreenSharingEnabledChanged(); private: void connectTo(ConferenceListener * listener); diff --git a/linphone-app/src/components/contact/ContactModel.cpp b/linphone-app/src/components/contact/ContactModel.cpp index e961626a4..0ca797cf2 100644 --- a/linphone-app/src/components/contact/ContactModel.cpp +++ b/linphone-app/src/components/contact/ContactModel.cpp @@ -42,7 +42,6 @@ ContactModel::ContactModel (VcardModel *vcardModel, QObject * parent) : QObject( Q_CHECK_PTR(vcardModel); Q_CHECK_PTR(vcardModel->mVcard); Q_ASSERT(!vcardModel->mIsReadOnly); - mLinphoneFriend = CoreManager::getInstance()->getCore()->createFriendFromVcard(vcardModel->mVcard); mLinphoneFriend->setData("contact-model", *this); if(mLinphoneFriend) diff --git a/linphone-app/src/components/history/CallHistoryProxyModel.cpp b/linphone-app/src/components/history/CallHistoryProxyModel.cpp index 6376a60d4..193266d4c 100644 --- a/linphone-app/src/components/history/CallHistoryProxyModel.cpp +++ b/linphone-app/src/components/history/CallHistoryProxyModel.cpp @@ -115,4 +115,4 @@ void CallHistoryProxyModel::handleIsActiveChanged (QWindow *window) { if (window->isActive() && getParentWindow(this) == window) { CoreManager::getInstance()->resetMissedCallsCount(); } -} \ No newline at end of file +} diff --git a/linphone-app/src/components/other/desktop-tools/DesktopToolsLinux.cpp b/linphone-app/src/components/other/desktop-tools/DesktopToolsLinux.cpp index 98fb0799e..ada2658af 100644 --- a/linphone-app/src/components/other/desktop-tools/DesktopToolsLinux.cpp +++ b/linphone-app/src/components/other/desktop-tools/DesktopToolsLinux.cpp @@ -20,23 +20,103 @@ #include "DesktopToolsLinux.hpp" +#include "components/core/CoreManager.hpp" +#include "components/settings/SettingsModel.hpp" +#include "components/videoSource/VideoSourceDescriptorModel.hpp" + +#include +#include +#include +#include +#include +// #include + +#include + // ============================================================================= -DesktopTools::~DesktopTools () { - setScreenSaverStatus(true); +DesktopTools::~DesktopTools() { + setScreenSaverStatus(true); } -bool DesktopTools::getScreenSaverStatus () const { - return mScreenSaverStatus; +bool DesktopTools::getScreenSaverStatus() const { + return mScreenSaverStatus; } -void DesktopTools::setScreenSaverStatus (bool status) { - screenSaverDBus.setScreenSaverStatus(status); - screenSaverXdg.setScreenSaverStatus(status); +void DesktopTools::setScreenSaverStatus(bool status) { + screenSaverDBus.setScreenSaverStatus(status); + screenSaverXdg.setScreenSaverStatus(status); - bool newStatus = screenSaverDBus.getScreenSaverStatus() || screenSaverXdg.getScreenSaverStatus(); - if (newStatus != mScreenSaverStatus) { - mScreenSaverStatus = newStatus; - emit screenSaverStatusChanged(mScreenSaverStatus); - } + bool newStatus = screenSaverDBus.getScreenSaverStatus() || screenSaverXdg.getScreenSaverStatus(); + if (newStatus != mScreenSaverStatus) { + mScreenSaverStatus = newStatus; + emit screenSaverStatusChanged(mScreenSaverStatus); + } +} +class T : public QThread { +public: + Display *mDisplay; + Window mWindow; + VideoSourceDescriptorModel *mVideoSourceDescriptorModel = nullptr; + DesktopTools *mParent; + T() { + } + virtual void run() { + bool endLoop = false; + unsigned char data[3]; + const char *pDevice = "/dev/input/event6"; + int fd = open(pDevice, O_RDONLY), bytes; + XEvent event; + endLoop = (fd == -1); + int left, middle, right; + XEvent report; + XButtonEvent *xb = (XButtonEvent *)&report; + + auto cursor = XCreateFontCursor(mDisplay, XC_crosshair); + auto i = XGrabPointer(mDisplay, mWindow, False, ButtonReleaseMask | ButtonPressMask | Button1MotionMask, + GrabModeSync, GrabModeAsync, mWindow, cursor, CurrentTime); + + endLoop = (i != GrabSuccess); + if (endLoop) qCritical() << "Cannot open mouse events"; + while (!endLoop) { + XAllowEvents(mDisplay, SyncPointer, CurrentTime); + XWindowEvent(mDisplay, mWindow, ButtonPressMask | ButtonReleaseMask, &report); + if (report.type == ButtonPress) { + printf("Press @ (%d, %d)\n", xb->x_root, xb->y_root); + XQueryPointer(mDisplay, mWindow, &event.xbutton.root, &event.xbutton.subwindow, &event.xbutton.x_root, + &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state); + auto id = event.xbutton.subwindow; + QMetaObject::invokeMethod(CoreManager::getInstance(), [id, this]() mutable { + mVideoSourceDescriptorModel->setScreenSharingWindow(reinterpret_cast(id)); + }); + endLoop = true; + } + } + XFlush(mDisplay); + XUngrabServer(mDisplay); + XCloseDisplay(mDisplay); + deleteLater(); + } +}; +void DesktopTools::getWindowIdFromMouse(VideoSourceDescriptorModel *model) { + const char *displayStr = getenv("DISPLAY"); + if (displayStr == NULL) displayStr = ":0"; + Display *display = XOpenDisplay(displayStr); // QX11Info::display(); + if (display == NULL) { + qCritical() << "Can't open X display!"; + return; + } + emit windowIdSelectionStarted(); + T *t = new T(); + connect(t, &QThread::finished, this, &DesktopTools::windowIdSelectionEnded); + t->mVideoSourceDescriptorModel = model; + t->mDisplay = display; + auto screen = DefaultScreen(display); // QX11Info::appScreen(); + t->mWindow = RootWindow(display, screen); // QX11Info::appRootWindow(m_x11_screen); + t->mParent = this; + t->start(); +} + +uintptr_t DesktopTools::getDisplayIndex(void* screenSharing){ + return *(uintptr_t*)(&screenSharing); } diff --git a/linphone-app/src/components/other/desktop-tools/DesktopToolsLinux.hpp b/linphone-app/src/components/other/desktop-tools/DesktopToolsLinux.hpp index d3cf5f96b..fee309cc1 100644 --- a/linphone-app/src/components/other/desktop-tools/DesktopToolsLinux.hpp +++ b/linphone-app/src/components/other/desktop-tools/DesktopToolsLinux.hpp @@ -25,30 +25,44 @@ #include "components/other/desktop-tools/screen-saver/ScreenSaverXdg.hpp" // ============================================================================= +class VideoSourceDescriptorModel; class DesktopTools : public QObject { - Q_OBJECT; + Q_OBJECT - Q_PROPERTY(bool screenSaverStatus READ getScreenSaverStatus WRITE setScreenSaverStatus NOTIFY screenSaverStatusChanged); + Q_PROPERTY( + bool screenSaverStatus READ getScreenSaverStatus WRITE setScreenSaverStatus NOTIFY screenSaverStatusChanged) public: - DesktopTools (QObject *parent = Q_NULLPTR) : QObject(parent) {} - ~DesktopTools (); + DesktopTools(QObject *parent = Q_NULLPTR) : QObject(parent) { + } + ~DesktopTools(); - bool getScreenSaverStatus () const; - void setScreenSaverStatus (bool status); + bool getScreenSaverStatus() const; + void setScreenSaverStatus(bool status); - static void init(){} - static void applicationStateChanged(Qt::ApplicationState){}; + static void init() { + } + static void applicationStateChanged(Qt::ApplicationState){}; + + Q_INVOKABLE void getWindowIdFromMouse(VideoSourceDescriptorModel *model); + static void *getDisplay(uintptr_t screenIndex){return reinterpret_cast(screenIndex);} + static uintptr_t getDisplayIndex(void* screenSharing); signals: - void screenSaverStatusChanged (bool status); + void screenSaverStatusChanged(bool status); + void windowIdSelectionStarted(); + void windowIdSelectionEnded(); private: - bool mScreenSaverStatus = true; + bool mScreenSaverStatus = true; - ScreenSaverDBus screenSaverDBus; - ScreenSaverXdg screenSaverXdg; + ScreenSaverDBus screenSaverDBus; + ScreenSaverXdg screenSaverXdg; + + // X11 headers cannot be used in hpp. moc don't' compile. + void *mDisplay = nullptr; // Display + unsigned int mWindow = 0; // Window }; #endif // DESKTOP_TOOLS_LINUX_H_ diff --git a/linphone-app/src/components/other/desktop-tools/DesktopToolsMacOs.hpp b/linphone-app/src/components/other/desktop-tools/DesktopToolsMacOs.hpp index a9c7c442f..fc0b698cd 100644 --- a/linphone-app/src/components/other/desktop-tools/DesktopToolsMacOs.hpp +++ b/linphone-app/src/components/other/desktop-tools/DesktopToolsMacOs.hpp @@ -23,28 +23,34 @@ #include // ============================================================================= +class VideoSourceDescriptorModel; class DesktopTools : public QObject { - Q_OBJECT; + Q_OBJECT; - Q_PROPERTY(bool screenSaverStatus READ getScreenSaverStatus WRITE setScreenSaverStatus NOTIFY screenSaverStatusChanged); + Q_PROPERTY( + bool screenSaverStatus READ getScreenSaverStatus WRITE setScreenSaverStatus NOTIFY screenSaverStatusChanged); public: - DesktopTools (QObject *parent = Q_NULLPTR); - ~DesktopTools (); + DesktopTools(QObject *parent = Q_NULLPTR); + ~DesktopTools(); - bool getScreenSaverStatus () const; - void setScreenSaverStatus (bool status); - - static void init(); // Do first initialization - static void applicationStateChanged(Qt::ApplicationState currentState); + bool getScreenSaverStatus() const; + void setScreenSaverStatus(bool status); + static void init(); // Do first initialization + static void applicationStateChanged(Qt::ApplicationState currentState); + static void *getDisplay(int screenIndex); + static int getDisplayIndex(void *screenSharing); + Q_INVOKABLE void getWindowIdFromMouse(VideoSourceDescriptorModel *model); signals: - void screenSaverStatusChanged (bool status); + void screenSaverStatusChanged(bool status); + void windowIdSelectionStarted(); + void windowIdSelectionEnded(); private: - bool mScreenSaverStatus = true; + bool mScreenSaverStatus = true; }; #endif // DESKTOP_TOOLS_MAC_OS_H_ diff --git a/linphone-app/src/components/other/desktop-tools/DesktopToolsMacOsNative.mm b/linphone-app/src/components/other/desktop-tools/DesktopToolsMacOsNative.mm index da4a4dbff..70e65fb3a 100644 --- a/linphone-app/src/components/other/desktop-tools/DesktopToolsMacOsNative.mm +++ b/linphone-app/src/components/other/desktop-tools/DesktopToolsMacOsNative.mm @@ -1,12 +1,71 @@ #include "DesktopToolsMacOs.hpp" #import +#import +#include +#include +#include "components/videoSource/VideoSourceDescriptorModel.hpp" void DesktopTools::init(){ // Request permissions - if( @available(macOS 10.14, *) ) { - if([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] == AVAuthorizationStatusNotDetermined) - [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL) {}]; - if([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio] == AVAuthorizationStatusNotDetermined) - [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL) {}]; - } + if([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] != AVAuthorizationStatusAuthorized) { + qDebug() << "Requesting Video permission"; + [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL) {}]; + } + if([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio] != AVAuthorizationStatusAuthorized){ + qDebug() << "Requesting Audio permission"; + [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL) {}]; + } +} + + +void *DesktopTools::getDisplay(int screenIndex){ + CGDirectDisplayID displays[screenIndex+1]; + CGDisplayCount displayCount; + CGGetOnlineDisplayList(screenIndex+1, displays, &displayCount); + CGDirectDisplayID display = 0; + if(displayCount > screenIndex) + display = displays[screenIndex]; + return reinterpret_cast(display); +} + +int DesktopTools::getDisplayIndex(void* screenSharing){ + CGDirectDisplayID displayId = *(CGDirectDisplayID*)&screenSharing; + int maxDisplayCount = 10; + CGDisplayCount displayCount; + do { + CGDirectDisplayID displays[maxDisplayCount]; + CGGetOnlineDisplayList(maxDisplayCount, displays, &displayCount); + for(int i = 0 ; i < displayCount ; ++i) + if( displays[i] == displayId) { + return i; + } + maxDisplayCount *= 2; + }while(displayCount == maxDisplayCount/2); + return 0; +} + +void DesktopTools::getWindowIdFromMouse(VideoSourceDescriptorModel *model) { + __block id globalMonitorId; + __block id localMonitorId; + __block DesktopTools * tools = this; + emit windowIdSelectionStarted(); + globalMonitorId = [NSEvent addGlobalMonitorForEventsMatchingMask:NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown + handler:^(NSEvent *event){ + CGWindowID windowID = (CGWindowID)[event windowNumber]; + if(event.type == NSEventTypeLeftMouseDown) + model->setScreenSharingWindow(reinterpret_cast(windowID)); + [NSEvent removeMonitor:globalMonitorId]; + [NSEvent removeMonitor:localMonitorId]; + emit tools->windowIdSelectionEnded(); + }]; + localMonitorId = [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown + handler:^NSEvent *(NSEvent *event){ + CGWindowID windowID = (CGWindowID)[event windowNumber]; + if(event.type == NSEventTypeLeftMouseDown) + model->setScreenSharingWindow(reinterpret_cast(windowID)); + [NSEvent removeMonitor:globalMonitorId]; + [NSEvent removeMonitor:localMonitorId]; + emit tools->windowIdSelectionEnded(); + return nil; + }]; } diff --git a/linphone-app/src/components/other/desktop-tools/DesktopToolsWindows.cpp b/linphone-app/src/components/other/desktop-tools/DesktopToolsWindows.cpp index cbabd3def..bfec21f9e 100644 --- a/linphone-app/src/components/other/desktop-tools/DesktopToolsWindows.cpp +++ b/linphone-app/src/components/other/desktop-tools/DesktopToolsWindows.cpp @@ -18,32 +18,64 @@ * along with this program. If not, see . */ - - #include "DesktopToolsWindows.hpp" +#include "components/core/CoreManager.hpp" +#include "components/settings/SettingsModel.hpp" +#include "components/videoSource/VideoSourceDescriptorModel.hpp" + +#include #include // ============================================================================= -DesktopTools::DesktopTools (QObject *parent) : QObject(parent) {} - -DesktopTools::~DesktopTools () { - setScreenSaverStatus(true); +DesktopTools::DesktopTools(QObject *parent) : QObject(parent) { } -bool DesktopTools::getScreenSaverStatus () const { - return mScreenSaverStatus; +DesktopTools::~DesktopTools() { + setScreenSaverStatus(true); } -void DesktopTools::setScreenSaverStatus (bool status) { - if (status == mScreenSaverStatus) - return; - - if (status) - SetThreadExecutionState(ES_CONTINUOUS); - else - SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED); - - mScreenSaverStatus = status; - emit screenSaverStatusChanged(status); +bool DesktopTools::getScreenSaverStatus() const { + return mScreenSaverStatus; +} + +void DesktopTools::setScreenSaverStatus(bool status) { + if (status == mScreenSaverStatus) return; + + if (status) SetThreadExecutionState(ES_CONTINUOUS); + else SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED); + + mScreenSaverStatus = status; + emit screenSaverStatusChanged(status); +} + +HHOOK hMouseHook; +DesktopTools *gTools = nullptr; +LRESULT CALLBACK mouseProc(int nCode, WPARAM wParam, LPARAM lParam) { + MOUSEHOOKSTRUCT *pMouseStruct = (MOUSEHOOKSTRUCT *)lParam; + if (pMouseStruct != NULL) { + if (wParam == WM_LBUTTONDOWN) { + printf("clicked"); + auto id = WindowFromPoint(pMouseStruct->pt); + UnhookWindowsHookEx(hMouseHook); + QMetaObject::invokeMethod(CoreManager::getInstance(), [id]() { + gTools->mVideoSourceDescriptorModel->setScreenSharingWindow(reinterpret_cast(id)); + }); + emit gTools->windowIdSelectionEnded(); + } + qDebug() << "Mouse position X = " << pMouseStruct->pt.x << " Mouse Position Y = " << pMouseStruct->pt.y; + } + return CallNextHookEx(hMouseHook, nCode, wParam, lParam); +} + +void DesktopTools::getWindowIdFromMouse(VideoSourceDescriptorModel *model) { + gTools = this; + gTools->mVideoSourceDescriptorModel = model; + emit windowIdSelectionStarted(); + HINSTANCE hInstance = GetModuleHandle(NULL); + hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, mouseProc, hInstance, NULL); +} + +uintptr_t DesktopTools::getDisplayIndex(void* screenSharing) { + return *(uintptr_t*)(&screenSharing); } diff --git a/linphone-app/src/components/other/desktop-tools/DesktopToolsWindows.hpp b/linphone-app/src/components/other/desktop-tools/DesktopToolsWindows.hpp index a0f24852e..92c8352d4 100644 --- a/linphone-app/src/components/other/desktop-tools/DesktopToolsWindows.hpp +++ b/linphone-app/src/components/other/desktop-tools/DesktopToolsWindows.hpp @@ -22,29 +22,43 @@ #define DESKTOP_TOOLS_WINDOWS_H_ #include +#include +class VideoSourceDescriptorModel; // ============================================================================= class DesktopTools : public QObject { - Q_OBJECT; + Q_OBJECT - Q_PROPERTY(bool screenSaverStatus READ getScreenSaverStatus WRITE setScreenSaverStatus NOTIFY screenSaverStatusChanged); + Q_PROPERTY( + bool screenSaverStatus READ getScreenSaverStatus WRITE setScreenSaverStatus NOTIFY screenSaverStatusChanged) public: - DesktopTools (QObject *parent = Q_NULLPTR); - ~DesktopTools (); + DesktopTools(QObject *parent = Q_NULLPTR); + ~DesktopTools(); - bool getScreenSaverStatus () const; - void setScreenSaverStatus (bool status); + bool getScreenSaverStatus() const; + void setScreenSaverStatus(bool status); - static void init(){} - static void applicationStateChanged(Qt::ApplicationState){}; + static void init() { + } + static void applicationStateChanged(Qt::ApplicationState){}; + + Q_INVOKABLE void getWindowIdFromMouse(VideoSourceDescriptorModel *model); + static void *getDisplay(uintptr_t screenIndex) { + return reinterpret_cast(screenIndex); + } + static uintptr_t getDisplayIndex(void *screenSharing); + HWND mWindowId = 0; // Window + VideoSourceDescriptorModel *mVideoSourceDescriptorModel = nullptr; signals: - void screenSaverStatusChanged (bool status); + void screenSaverStatusChanged(bool status); + void windowIdSelectionStarted(); + void windowIdSelectionEnded(); private: - bool mScreenSaverStatus = true; + bool mScreenSaverStatus = true; }; #endif // DESKTOP_TOOLS_WINDOWS_H_ diff --git a/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp b/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp index cbd1d9537..71796239f 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp +++ b/linphone-app/src/components/participant/ParticipantDeviceListModel.cpp @@ -70,7 +70,13 @@ void ParticipantDeviceListModel::initConferenceModel(){ connect(conferenceModel.get(), &ConferenceModel::participantDeviceMediaCapabilityChanged, this, &ParticipantDeviceListModel::onParticipantDeviceMediaCapabilityChanged); connect(conferenceModel.get(), &ConferenceModel::participantDeviceMediaAvailabilityChanged, this, &ParticipantDeviceListModel::onParticipantDeviceMediaAvailabilityChanged); connect(conferenceModel.get(), &ConferenceModel::participantDeviceIsSpeakingChanged, this, &ParticipantDeviceListModel::onParticipantDeviceIsSpeakingChanged); - mActiveSpeaker = get(conferenceModel->getConference()->getActiveSpeakerParticipantDevice()); + connect(conferenceModel.get(), &ConferenceModel::participantDeviceScreenSharingChanged, this, &ParticipantDeviceListModel::onParticipantDeviceScreenSharingChanged); + + // TODO activeSpeaker + //auto activeSpeaker = conferenceModel->getConference()->getScreenSharingParticipantDevice(); + //if(!activeSpeaker) + auto activeSpeaker = conferenceModel->getConference()->getActiveSpeakerParticipantDevice(); + mActiveSpeaker = get(activeSpeaker); mInitialized = true; } } @@ -102,6 +108,13 @@ void ParticipantDeviceListModel::updateDevices(const std::list activeSpeaker) { + if( mActiveSpeaker != activeSpeaker) { + mActiveSpeaker = activeSpeaker; + emit activeSpeakerChanged(); + } +} + bool ParticipantDeviceListModel::add(std::shared_ptr deviceToAdd){ auto deviceToAddAddr = deviceToAdd->getAddress(); int row = 0; @@ -135,8 +148,14 @@ bool ParticipantDeviceListModel::add(std::shared_ptr()->getDevice()))){ - mActiveSpeaker = mList.back().objectCast(); + }else{ + // Todo ActiveSpeaker + //if(deviceToAdd->screenSharingEnabled()) + // mActiveSpeaker = deviceModel; + //else + mActiveSpeaker = get(mCallModel->getConferenceSharedModel()->getConference()->getActiveSpeakerParticipantDevice()); + if(!mActiveSpeaker && (mList.size() == 1 || (mList.size() == 2 && isMe(mList.front().objectCast()->getDevice())))) + mActiveSpeaker = mList.back().objectCast(); emit activeSpeakerChanged(); } return true; @@ -239,6 +258,8 @@ void ParticipantDeviceListModel::onParticipantDeviceAdded(const std::shared_ptr< qDebug() << "Adding new device : " << mList.count(); auto conferenceModel = mCallModel->getConferenceSharedModel(); std::list> devices; + + for(int i = 0 ; i < 2 ; ++i){ if( i == 0) devices = conferenceModel->getConference()->getParticipantDeviceList();// Active devices. @@ -296,11 +317,12 @@ void ParticipantDeviceListModel::onParticipantDeviceMediaAvailabilityChanged(con onParticipantDeviceAdded(participantDevice); } void ParticipantDeviceListModel::onActiveSpeakerParticipantDevice(const std::shared_ptr& participantDevice){ - auto device = get(participantDevice); - if( device){ - mActiveSpeaker = device; - emit activeSpeakerChanged(); - } +// TODO activeSpeaker + //auto activeSpeaker = get(mCallModel->getConferenceSharedModel()->getConference()->getScreenSharingParticipantDevice()); + //if(!activeSpeaker) + auto activeSpeaker = get(participantDevice); + qDebug() << "onActiveSpeakerParticipantDevice " << participantDevice.get() << " == " << get(participantDevice) << " : " << (participantDevice ? participantDevice->getAddress()->asStringUriOnly().c_str() : ""); + setActiveSpeaker(activeSpeaker); } void ParticipantDeviceListModel::onParticipantDeviceIsSpeakingChanged(const std::shared_ptr & participantDevice, bool isSpeaking){ @@ -308,6 +330,16 @@ void ParticipantDeviceListModel::onParticipantDeviceIsSpeakingChanged(const std: if( device) emit participantSpeaking(device.get()); } +void ParticipantDeviceListModel::onParticipantDeviceScreenSharingChanged(const std::shared_ptr & participantDevice){ +// TODO activeSpeaker + //auto activeSpeaker = mCallModel->getConferenceSharedModel()->getConference()->getScreenSharingParticipantDevice(); + //if(!activeSpeaker) + auto activeSpeaker = mCallModel->getConferenceSharedModel()->getConference()->getActiveSpeakerParticipantDevice(); + qDebug() << "onParticipantDeviceScreenSharingChanged " << participantDevice.get() << " == " << get(participantDevice) << " ; " + << activeSpeaker.get() << " == " << get(activeSpeaker) << " : " << (activeSpeaker ? activeSpeaker->getAddress()->asStringUriOnly().c_str() : "") + << ", ScreenShared:" << participantDevice->screenSharingEnabled(); + setActiveSpeaker(get(activeSpeaker)); +} void ParticipantDeviceListModel::onParticipantDeviceSpeaking(){ diff --git a/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp b/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp index 9f0790122..be910e1ac 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp +++ b/linphone-app/src/components/participant/ParticipantDeviceListModel.hpp @@ -42,6 +42,7 @@ public: void initConferenceModel(); void updateDevices(std::shared_ptr participant); void updateDevices(const std::list>& devices, const bool& isMe); + void setActiveSpeaker(QSharedPointer activeSpeaker); bool add(std::shared_ptr deviceToAdd); bool remove(std::shared_ptr deviceToAdd); @@ -65,6 +66,7 @@ public slots: void onParticipantDeviceMediaAvailabilityChanged(const std::shared_ptr & participantDevice); void onParticipantDeviceIsSpeakingChanged(const std::shared_ptr & device, bool isSpeaking); void onParticipantDeviceSpeaking(); + void onParticipantDeviceScreenSharingChanged(const std::shared_ptr & participantDevice); signals: void activeSpeakerChanged(); diff --git a/linphone-app/src/components/participant/ParticipantDeviceListener.cpp b/linphone-app/src/components/participant/ParticipantDeviceListener.cpp index 95d700c7a..0bb84aa58 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceListener.cpp +++ b/linphone-app/src/components/participant/ParticipantDeviceListener.cpp @@ -38,6 +38,10 @@ void ParticipantDeviceListener::onIsMuted(const std::shared_ptr & participantDevice, bool isScreenSharing) { + emit isScreenSharingChanged(participantDevice, isScreenSharing); +} + void ParticipantDeviceListener::onStateChanged(const std::shared_ptr & participantDevice, linphone::ParticipantDevice::State state){ qDebug() << "onStateChanged: " << participantDevice->getAddress()->asString().c_str() << " " << (int)state; emit stateChanged(participantDevice, state); @@ -51,4 +55,4 @@ void ParticipantDeviceListener::onStreamCapabilityChanged(const std::shared_ptr< void ParticipantDeviceListener::onStreamAvailabilityChanged(const std::shared_ptr & participantDevice, bool available, linphone::StreamType streamType) { qDebug() << "onStreamAvailabilityChanged: " << participantDevice->getAddress()->asString().c_str() << " " << available<< " / " << (int)streamType; emit streamAvailabilityChanged(participantDevice, available, streamType); -} \ No newline at end of file +} diff --git a/linphone-app/src/components/participant/ParticipantDeviceListener.hpp b/linphone-app/src/components/participant/ParticipantDeviceListener.hpp index 89524a2b1..9f82ecc46 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceListener.hpp +++ b/linphone-app/src/components/participant/ParticipantDeviceListener.hpp @@ -38,12 +38,14 @@ public: virtual void onIsSpeakingChanged(const std::shared_ptr & participantDevice, bool isSpeaking) override; virtual void onIsMuted(const std::shared_ptr & participantDevice, bool isMuted) override; + virtual void onScreenSharingChanged(const std::shared_ptr & participantDevice, bool isScreenSharing) override; virtual void onStateChanged(const std::shared_ptr & participantDevice, linphone::ParticipantDevice::State state) override; virtual void onStreamCapabilityChanged(const std::shared_ptr & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType) override; virtual void onStreamAvailabilityChanged(const std::shared_ptr & participantDevice, bool available, linphone::StreamType streamType) override; signals: void isSpeakingChanged(const std::shared_ptr & participantDevice, bool isSpeaking); void isMuted(const std::shared_ptr & participantDevice, bool isMuted); + void isScreenSharingChanged(const std::shared_ptr & participantDevice, bool isScreenSharing); void stateChanged(const std::shared_ptr & participantDevice, linphone::ParticipantDevice::State state); void streamCapabilityChanged(const std::shared_ptr & participantDevice, linphone::MediaDirection direction, linphone::StreamType streamType); void streamAvailabilityChanged(const std::shared_ptr & participantDevice, bool available, linphone::StreamType streamType); diff --git a/linphone-app/src/components/participant/ParticipantDeviceModel.cpp b/linphone-app/src/components/participant/ParticipantDeviceModel.cpp index 11ebb72a4..1effea4cf 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceModel.cpp +++ b/linphone-app/src/components/participant/ParticipantDeviceModel.cpp @@ -29,6 +29,7 @@ void ParticipantDeviceModel::connectTo(ParticipantDeviceListener * listener){ connect(listener, &ParticipantDeviceListener::isSpeakingChanged, this, &ParticipantDeviceModel::onIsSpeakingChanged); connect(listener, &ParticipantDeviceListener::isMuted, this, &ParticipantDeviceModel::onIsMuted); + connect(listener, &ParticipantDeviceListener::isScreenSharingChanged, this, &ParticipantDeviceModel::onScreenSharingChanged); connect(listener, &ParticipantDeviceListener::stateChanged, this, &ParticipantDeviceModel::onStateChanged); connect(listener, &ParticipantDeviceListener::streamCapabilityChanged, this, &ParticipantDeviceModel::onStreamCapabilityChanged); connect(listener, &ParticipantDeviceListener::streamAvailabilityChanged, this, &ParticipantDeviceModel::onStreamAvailabilityChanged); @@ -108,6 +109,10 @@ bool ParticipantDeviceModel::getIsMuted() const{ return mParticipantDevice ? mParticipantDevice->getIsMuted() : false; } +bool ParticipantDeviceModel::getIsScreenSharingEnabled() const { + return mParticipantDevice ? mParticipantDevice->screenSharingEnabled() : false; +} + LinphoneEnums::ParticipantDeviceState ParticipantDeviceModel::getState() const{ return LinphoneEnums::fromLinphone(mState); } @@ -120,6 +125,10 @@ bool ParticipantDeviceModel::isVideoEnabled() const{ return mIsVideoEnabled; } +bool ParticipantDeviceModel::isThumbnailVideoEnabled() const{ + return mIsThumbnailVideoEnabled; +} + void ParticipantDeviceModel::setPaused(bool paused){ if(mIsPaused != paused){ mIsPaused = paused; @@ -149,16 +158,51 @@ void ParticipantDeviceModel::setState(LinphoneEnums::ParticipantDeviceState stat } } -void ParticipantDeviceModel::updateVideoEnabled(){ - bool enabled = (mParticipantDevice && mParticipantDevice->isInConference() && mParticipantDevice->getStreamAvailability(linphone::StreamType::Video) && - ( mParticipantDevice->getStreamCapability(linphone::StreamType::Video) == linphone::MediaDirection::SendRecv - || mParticipantDevice->getStreamCapability(linphone::StreamType::Video) == linphone::MediaDirection::SendOnly - ) - || (isMe() && isLocal())) && !mIsPaused; - if( mIsVideoEnabled != enabled && mCall && mCall->getCall()->getState() == linphone::Call::State::StreamsRunning) { - qDebug() << "VideoEnabled: " << enabled << ", old=" << mIsVideoEnabled << (mParticipantDevice ? mParticipantDevice->getAddress()->asString().c_str() : "") << ", me=" << isMe() << ", isLocal=" << isLocal() << ", CallState=" << (mCall ? (int)mCall->getCall()->getState() : -1); - mIsVideoEnabled = enabled; - emit videoEnabledChanged(); +void ParticipantDeviceModel::updateVideoEnabled() { + if (mCall && mCall->getCall()->getState() == linphone::Call::State::StreamsRunning) { + bool enabled = (mParticipantDevice && mParticipantDevice->isInConference() + && mParticipantDevice->getStreamAvailability(linphone::StreamType::Video) + || (isMe() && isLocal())) + && !mIsPaused; + if (mIsVideoEnabled != enabled) { + qDebug() << "VideoEnabled: " << enabled << ", old=" << mIsVideoEnabled + << (mParticipantDevice ? mParticipantDevice->getAddress()->asString().c_str() + : "") + << ", me=" << isMe() << ", isLocal=" << isLocal() << ", inConf=" + << (mParticipantDevice ? mParticipantDevice->isInConference() : false) + << ", CallState=" << (mCall ? (int) mCall->getCall()->getState() : -1) + << ", StreamAvailability:" + << (mParticipantDevice + ? mParticipantDevice->getStreamAvailability(linphone::StreamType::Video) + : false) + << ", StreamDir=" + << (mParticipantDevice ? (int) mParticipantDevice->getStreamCapability( + linphone::StreamType::Video) + : -1); + mIsVideoEnabled = enabled; + emit videoEnabledChanged(); + } + enabled = (mParticipantDevice && mParticipantDevice->isInConference() + && mParticipantDevice->getThumbnailStreamAvailability() + || (isMe() && isLocal())) + && !mIsPaused; + if (mIsThumbnailVideoEnabled != enabled) { + qDebug() << "ThumbnailVideoEnabled: " << enabled << ", old=" << mIsThumbnailVideoEnabled + << (mParticipantDevice ? mParticipantDevice->getAddress()->asString().c_str() + : "") + << ", me=" << isMe() << ", isLocal=" << isLocal() << ", inConf=" + << (mParticipantDevice ? mParticipantDevice->isInConference() : false) + << ", CallState=" << (mCall ? (int) mCall->getCall()->getState() : -1) + << ", StreamAvailability:" + << (mParticipantDevice ? mParticipantDevice->getThumbnailStreamAvailability() + : false) + << ", StreamDir=" + << (mParticipantDevice + ? (int) mParticipantDevice->getThumbnailStreamCapability() + : -1); + mIsThumbnailVideoEnabled = enabled; + emit thumbnailVideoEnabledChanged(); + } } } @@ -189,6 +233,9 @@ void ParticipantDeviceModel::onCallStatusChanged(){ } //-------------------------------------------------------------------- +void ParticipantDeviceModel::onScreenSharingChanged(const std::shared_ptr & participantDevice, bool isScreenSharing) { + emit isScreenSharingEnabledChanged(); +} void ParticipantDeviceModel::onIsSpeakingChanged(const std::shared_ptr & participantDevice, bool isSpeaking) { setIsSpeaking(isSpeaking); } @@ -216,4 +263,4 @@ void ParticipantDeviceModel::onStreamCapabilityChanged(const std::shared_ptr & participantDevice, bool available, linphone::StreamType streamType) { updateVideoEnabled(); -} \ No newline at end of file +} diff --git a/linphone-app/src/components/participant/ParticipantDeviceModel.hpp b/linphone-app/src/components/participant/ParticipantDeviceModel.hpp index 389d12284..39f345f53 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceModel.hpp +++ b/linphone-app/src/components/participant/ParticipantDeviceModel.hpp @@ -50,11 +50,13 @@ public: Q_PROPERTY(int securityLevel READ getSecurityLevel NOTIFY securityLevelChanged) Q_PROPERTY(time_t timeOfJoining READ getTimeOfJoining CONSTANT) Q_PROPERTY(bool videoEnabled READ isVideoEnabled NOTIFY videoEnabledChanged) + Q_PROPERTY(bool thumbnailVideoEnabled READ isThumbnailVideoEnabled NOTIFY thumbnailVideoEnabledChanged) Q_PROPERTY(bool isMe READ isMe CONSTANT) Q_PROPERTY(bool isLocal READ isLocal WRITE setIsLocal NOTIFY isLocalChanged)// Can change on call update. Not really used but it just in case as Object can be initialized with empty call/device. Q_PROPERTY(bool isPaused READ getPaused WRITE setPaused NOTIFY isPausedChanged) Q_PROPERTY(bool isSpeaking READ getIsSpeaking WRITE setIsSpeaking NOTIFY isSpeakingChanged) Q_PROPERTY(bool isMuted READ getIsMuted NOTIFY isMutedChanged) + Q_PROPERTY(bool isScreenSharingEnabled READ getIsScreenSharingEnabled NOTIFY isScreenSharingEnabledChanged) Q_PROPERTY(LinphoneEnums::ParticipantDeviceState state READ getState WRITE setState NOTIFY stateChanged) QString getName() const; @@ -63,11 +65,13 @@ public: int getSecurityLevel() const; time_t getTimeOfJoining() const; bool isVideoEnabled() const; + bool isThumbnailVideoEnabled() const; bool isMe() const; bool isLocal()const; bool getPaused() const; bool getIsSpeaking() const; bool getIsMuted() const; + bool getIsScreenSharingEnabled() const; LinphoneEnums::ParticipantDeviceState getState() const; std::shared_ptr getDevice(); @@ -77,6 +81,7 @@ public: void setIsLocal(bool local); void setState(LinphoneEnums::ParticipantDeviceState state); + virtual void onScreenSharingChanged(const std::shared_ptr & participantDevice, bool isScreenSharing); virtual void onIsSpeakingChanged(const std::shared_ptr & participantDevice, bool isSpeaking); virtual void onIsMuted(const std::shared_ptr & participantDevice, bool isMuted); virtual void onStateChanged(const std::shared_ptr & participantDevice, linphone::ParticipantDevice::State state); @@ -93,9 +98,11 @@ public slots: signals: void securityLevelChanged(); void videoEnabledChanged(); + void thumbnailVideoEnabledChanged(); void isPausedChanged(); void isSpeakingChanged(); void isMutedChanged(); + void isScreenSharingEnabledChanged(); void isLocalChanged(); void stateChanged(); @@ -103,7 +110,8 @@ private: bool mIsMe = false; bool mIsLocal = false; - bool mIsVideoEnabled; + bool mIsVideoEnabled = false; + bool mIsThumbnailVideoEnabled = false; bool mIsPaused = false; bool mIsSpeaking = false; linphone::ParticipantDevice::State mState; diff --git a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp index b56fa6148..c074fb48b 100644 --- a/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp +++ b/linphone-app/src/components/participant/ParticipantDeviceProxyModel.cpp @@ -100,6 +100,7 @@ void ParticipantDeviceProxyModel::setCallModel(CallModel * callModel){ sort(0); emit countChanged(); emit meChanged(); + emit activeSpeakerChanged(); } void ParticipantDeviceProxyModel::setParticipant(ParticipantModel * participant){ @@ -112,6 +113,7 @@ void ParticipantDeviceProxyModel::setParticipant(ParticipantModel * participant) sort(0); emit countChanged(); emit meChanged(); + emit activeSpeakerChanged(); } void ParticipantDeviceProxyModel::setShowMe(const bool& show){ diff --git a/linphone-app/src/components/screen/ScreenListModel.cpp b/linphone-app/src/components/screen/ScreenListModel.cpp new file mode 100644 index 000000000..2b382e0b4 --- /dev/null +++ b/linphone-app/src/components/screen/ScreenListModel.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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, see . + */ + +#include "ScreenListModel.hpp" +#include +#include +#include + +ScreenListModel::ScreenListModel(QObject *parent) : ProxyAbstractListModel(parent) { + mList = QGuiApplication::screens(); +} + +ScreenListModel::~ScreenListModel() { +} + +QVariant ScreenListModel::data(const QModelIndex &index, int role) const { + int row = index.row(); + if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant(); + if (role == Qt::DisplayRole) { + auto screen = mList[row]; + QVariantMap data; + data["name"] = screen->name(); + data["screenshot"] = QVariant::fromValue(screen->grabWindow(0)); + return data; + } + return QVariant(); +} diff --git a/linphone-app/src/components/screen/ScreenListModel.hpp b/linphone-app/src/components/screen/ScreenListModel.hpp new file mode 100644 index 000000000..4a9b3c4cf --- /dev/null +++ b/linphone-app/src/components/screen/ScreenListModel.hpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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, see . + */ + +#ifndef SCREEN_LIST_MODEL_H_ +#define SCREEN_LIST_MODEL_H_ + +#include "app/proxyModel/ProxyListModel.hpp" + +#include + +class ScreenListModel : public ProxyAbstractListModel { + + Q_OBJECT + +public: + ScreenListModel(QObject *parent = Q_NULLPTR); + virtual ~ScreenListModel(); + + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; +}; + +#endif diff --git a/linphone-app/src/components/screen/ScreenProxyModel.cpp b/linphone-app/src/components/screen/ScreenProxyModel.cpp new file mode 100644 index 000000000..31e5e8df5 --- /dev/null +++ b/linphone-app/src/components/screen/ScreenProxyModel.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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, see . + */ + +#include + +#include "ScreenListModel.hpp" +#include "ScreenProxyModel.hpp" +// ============================================================================= + +ScreenProxyModel::ScreenProxyModel(QObject *parent) : SortFilterProxyModel(parent) { + setSourceModel(new ScreenListModel(this)); + sort(0); +} diff --git a/linphone-app/src/components/screen/ScreenProxyModel.hpp b/linphone-app/src/components/screen/ScreenProxyModel.hpp new file mode 100644 index 000000000..509bd904a --- /dev/null +++ b/linphone-app/src/components/screen/ScreenProxyModel.hpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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, see . + */ + +#ifndef SCREEN_PROXY_MODEL_H_ +#define SCREEN_PROXY_MODEL_H_ + +#include "app/proxyModel/SortFilterProxyModel.hpp" + +// ============================================================================= + +class QWindow; + +class ScreenProxyModel : public SortFilterProxyModel { + class ScreenModelFilter; + + Q_OBJECT + +public: + ScreenProxyModel(QObject *parent = Q_NULLPTR); +}; + +#endif diff --git a/linphone-app/src/components/settings/SettingsModel.cpp b/linphone-app/src/components/settings/SettingsModel.cpp index 9608d55da..36a31dd15 100644 --- a/linphone-app/src/components/settings/SettingsModel.cpp +++ b/linphone-app/src/components/settings/SettingsModel.cpp @@ -19,12 +19,12 @@ */ #include -#include -#include #include - -#include +#include +#include +#include #include +#include #include "config.h" @@ -32,16 +32,15 @@ #include "app/logger/Logger.hpp" #include "app/paths/Paths.hpp" +#include "AccountSettingsModel.hpp" +#include "SettingsModel.hpp" #include "components/assistant/AssistantModel.hpp" #include "components/core/CoreManager.hpp" #include "components/tunnel/TunnelModel.hpp" #include "include/LinphoneApp/PluginNetworkHelper.hpp" -#include "utils/Utils.hpp" #include "utils/Constants.hpp" #include "utils/MediastreamerUtils.hpp" -#include "AccountSettingsModel.hpp" -#include "SettingsModel.hpp" - +#include "utils/Utils.hpp" // ============================================================================= @@ -50,33 +49,41 @@ using namespace std; const string SettingsModel::UiSection("ui"); const string SettingsModel::ContactsSection("contacts_import"); -SettingsModel::SettingsModel (QObject *parent) : QObject(parent) { +SettingsModel::SettingsModel(QObject *parent) : QObject(parent) { CoreManager *coreManager = CoreManager::getInstance(); mConfig = coreManager->getCore()->getConfig(); - - connect(this, &SettingsModel::dontAskAgainInfoEncryptionChanged, this, &SettingsModel::haveDontAskAgainChoicesChanged); + + connect(this, &SettingsModel::dontAskAgainInfoEncryptionChanged, this, + &SettingsModel::haveDontAskAgainChoicesChanged); connect(this, &SettingsModel::haveAtLeastOneVideoCodecChanged, this, &SettingsModel::videoAvailableChanged); - QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::callCreated, - this, &SettingsModel::handleCallCreated); - QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::callStateChanged, - this, &SettingsModel::handleCallStateChanged); - QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::ecCalibrationResult, - this, &SettingsModel::handleEcCalibrationResult); - -// Readonly state that can change from default account - connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::defaultAccountChanged, this, &SettingsModel::groupChatEnabledChanged); - connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::defaultAccountChanged, this, &SettingsModel::videoConferenceEnabledChanged); - connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::defaultAccountChanged, this, &SettingsModel::secureChatEnabledChanged); - connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::defaultAccountChanged, this, &SettingsModel::onDefaultAccountChanged); - - connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::accountSettingsUpdated, this, &SettingsModel::groupChatEnabledChanged); - connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::accountSettingsUpdated, this, &SettingsModel::videoConferenceEnabledChanged); - connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::accountSettingsUpdated, this, &SettingsModel::secureChatEnabledChanged); + QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::callCreated, this, + &SettingsModel::handleCallCreated); + QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::callStateChanged, this, + &SettingsModel::handleCallStateChanged); + QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::ecCalibrationResult, this, + &SettingsModel::handleEcCalibrationResult); + + // Readonly state that can change from default account + connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::defaultAccountChanged, this, + &SettingsModel::groupChatEnabledChanged); + connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::defaultAccountChanged, this, + &SettingsModel::videoConferenceEnabledChanged); + connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::defaultAccountChanged, this, + &SettingsModel::secureChatEnabledChanged); + connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::defaultAccountChanged, this, + &SettingsModel::onDefaultAccountChanged); + + connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::accountSettingsUpdated, this, + &SettingsModel::groupChatEnabledChanged); + connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::accountSettingsUpdated, this, + &SettingsModel::videoConferenceEnabledChanged); + connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::accountSettingsUpdated, this, + &SettingsModel::secureChatEnabledChanged); #ifdef ENABLE_QT_KEYCHAIN - connect(&mVfsUtils, &VfsUtils::keyRead, this, [&](const QString& key, const QString& value){ - if(key == mVfsUtils.getApplicationVfsEncryptionKey()){ - if(!getVfsEncrypted()){ + connect(&mVfsUtils, &VfsUtils::keyRead, this, [&](const QString &key, const QString &value) { + if (key == mVfsUtils.getApplicationVfsEncryptionKey()) { + if (!getVfsEncrypted()) { QSettings settings; settings.beginGroup("keychain"); settings.setValue("enabled", true); @@ -84,9 +91,9 @@ SettingsModel::SettingsModel (QObject *parent) : QObject(parent) { } } }); - connect(&mVfsUtils, &VfsUtils::keyWritten, this, [&](const QString& key){ - if(key == mVfsUtils.getApplicationVfsEncryptionKey()){ - if(!getVfsEncrypted()){ + connect(&mVfsUtils, &VfsUtils::keyWritten, this, [&](const QString &key) { + if (key == mVfsUtils.getApplicationVfsEncryptionKey()) { + if (!getVfsEncrypted()) { QSettings settings; settings.beginGroup("keychain"); settings.setValue("enabled", true); @@ -94,24 +101,22 @@ SettingsModel::SettingsModel (QObject *parent) : QObject(parent) { } } }); - connect(&mVfsUtils, &VfsUtils::keyDeleted, this, [&](const QString& key){ - if(key == mVfsUtils.getApplicationVfsEncryptionKey()){ + connect(&mVfsUtils, &VfsUtils::keyDeleted, this, [&](const QString &key) { + if (key == mVfsUtils.getApplicationVfsEncryptionKey()) { QSettings settings; settings.beginGroup("keychain"); settings.setValue("enabled", false); emit vfsEncryptedChanged(); - if(mVfsUtils.needToDeleteUserData()) - Utils::deleteAllUserData(); - else{ + if (mVfsUtils.needToDeleteUserData()) Utils::deleteAllUserData(); + else { qInfo() << "Exiting App from VFS settings"; App::getInstance()->quit(); } } }); - - - connect(&mVfsUtils, &VfsUtils::error, this, [&](){ - + + connect(&mVfsUtils, &VfsUtils::error, this, [&]() { + }); #endif updateRlsUri(); @@ -119,9 +124,8 @@ SettingsModel::SettingsModel (QObject *parent) : QObject(parent) { factory->setDownloadDir(Utils::appStringToCoreString(getDownloadFolder())); } -SettingsModel::~SettingsModel() -{ - if(mSimpleCaptureGraph ) { +SettingsModel::~SettingsModel() { + if (mSimpleCaptureGraph) { delete mSimpleCaptureGraph; mSimpleCaptureGraph = nullptr; } @@ -131,7 +135,7 @@ void SettingsModel::settingsWindowClosing(void) { onSettingsTabChanged(-1); } -void SettingsModel::reloadDevices(){ +void SettingsModel::reloadDevices() { CoreManager::getInstance()->getCore()->reloadSoundDevices(); emit captureDevicesChanged(getCaptureDevices()); emit playbackDevicesChanged(getPlaybackDevices()); @@ -142,46 +146,46 @@ void SettingsModel::reloadDevices(){ emit videoDevicesChanged(getVideoDevices()); } -//Provides tabbar per-tab setup/teardown mechanism for specific settings views +// Provides tabbar per-tab setup/teardown mechanism 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; + 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 - accessAdvancedSettings(); - break; - default: - break; + 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 + accessAdvancedSettings(); + break; + default: + break; } } @@ -189,60 +193,59 @@ void SettingsModel::onSettingsTabChanged(int idx) { // Assistant. // ============================================================================= -bool SettingsModel::getUseAppSipAccountEnabled () const { +bool SettingsModel::getUseAppSipAccountEnabled() const { return !!mConfig->getInt(UiSection, "use_app_sip_account_enabled", 1); } -void SettingsModel::setUseAppSipAccountEnabled (bool status) { +void SettingsModel::setUseAppSipAccountEnabled(bool status) { mConfig->setInt(UiSection, "use_app_sip_account_enabled", status); emit useAppSipAccountEnabledChanged(status); } -bool SettingsModel::getUseOtherSipAccountEnabled () const { +bool SettingsModel::getUseOtherSipAccountEnabled() const { return !!mConfig->getInt(UiSection, "use_other_sip_account_enabled", 1); } -void SettingsModel::setUseOtherSipAccountEnabled (bool status) { +void SettingsModel::setUseOtherSipAccountEnabled(bool status) { mConfig->setInt(UiSection, "use_other_sip_account_enabled", status); emit useOtherSipAccountEnabledChanged(status); } -bool SettingsModel::getCreateAppSipAccountEnabled () const { +bool SettingsModel::getCreateAppSipAccountEnabled() const { return !!mConfig->getInt(UiSection, "create_app_sip_account_enabled", 1); } -void SettingsModel::setCreateAppSipAccountEnabled (bool status) { +void SettingsModel::setCreateAppSipAccountEnabled(bool status) { mConfig->setInt(UiSection, "create_app_sip_account_enabled", status); emit createAppSipAccountEnabledChanged(status); } -bool SettingsModel::getFetchRemoteConfigurationEnabled () const { +bool SettingsModel::getFetchRemoteConfigurationEnabled() const { return !!mConfig->getInt(UiSection, "fetch_remote_configuration_enabled", 1); } -void SettingsModel::setFetchRemoteConfigurationEnabled (bool status) { +void SettingsModel::setFetchRemoteConfigurationEnabled(bool status) { mConfig->setInt(UiSection, "fetch_remote_configuration_enabled", status); emit fetchRemoteConfigurationEnabledChanged(status); } -bool SettingsModel::getAutoApplyProvisioningConfigUriHandlerEnabled () const { +bool SettingsModel::getAutoApplyProvisioningConfigUriHandlerEnabled() const { return !!mConfig->getInt(UiSection, "auto_apply_provisioning_config_uri_handler", 0); } -void SettingsModel::setAutoApplyProvisioningConfigUriHandlerEnabled (bool status) { +void SettingsModel::setAutoApplyProvisioningConfigUriHandlerEnabled(bool status) { mConfig->setInt(UiSection, "auto_apply_provisioning_config_uri_handler", status); emit autoApplyProvisioningConfigUriHandlerEnabledChanged(); } - // --------------------------------------------------------------------------- -bool SettingsModel::getAssistantSupportsPhoneNumbers () const { - return !!mConfig->getInt(UiSection, getEntryFullName(UiSection, "assistant_supports_phone_numbers") , 1); +bool SettingsModel::getAssistantSupportsPhoneNumbers() const { + return !!mConfig->getInt(UiSection, getEntryFullName(UiSection, "assistant_supports_phone_numbers"), 1); } -void SettingsModel::setAssistantSupportsPhoneNumbers (bool status) { - if(!isReadOnly(UiSection, "assistant_supports_phone_numbers")) { +void SettingsModel::setAssistantSupportsPhoneNumbers(bool status) { + if (!isReadOnly(UiSection, "assistant_supports_phone_numbers")) { mConfig->setInt(UiSection, "assistant_supports_phone_numbers", status); emit assistantSupportsPhoneNumbersChanged(status); } @@ -259,7 +262,7 @@ void SettingsModel::setAssistantDefaultTransport(int transport) { } } -bool SettingsModel::useWebview() const{ +bool SettingsModel::useWebview() const { #ifdef ENABLE_APP_WEBVIEW return true; #else @@ -267,45 +270,52 @@ bool SettingsModel::useWebview() const{ #endif } -QString SettingsModel::getAssistantRegistrationUrl () const { - return Utils::coreStringToAppString(mConfig->getString(UiSection, "assistant_registration_url", Constants::DefaultAssistantRegistrationUrl)); +QString SettingsModel::getAssistantRegistrationUrl() const { + return Utils::coreStringToAppString( + mConfig->getString(UiSection, "assistant_registration_url", Constants::DefaultAssistantRegistrationUrl)); } -void SettingsModel::setAssistantRegistrationUrl (QString url) { +void SettingsModel::setAssistantRegistrationUrl(QString url) { mConfig->setString(UiSection, "assistant_registration_url", Utils::appStringToCoreString(url)); emit assistantRegistrationUrlChanged(url); } -QString SettingsModel::getAssistantLoginUrl () const { - return Utils::coreStringToAppString(mConfig->getString(UiSection, "assistant_login_url", Constants::DefaultAssistantLoginUrl)); +QString SettingsModel::getAssistantLoginUrl() const { + return Utils::coreStringToAppString( + mConfig->getString(UiSection, "assistant_login_url", Constants::DefaultAssistantLoginUrl)); } -void SettingsModel::setAssistantLoginUrl (QString url) { +void SettingsModel::setAssistantLoginUrl(QString url) { mConfig->setString(UiSection, "assistant_login_url", Utils::appStringToCoreString(url)); emit assistantLoginUrlChanged(url); } -QString SettingsModel::getAssistantLogoutUrl () const { - return Utils::coreStringToAppString(mConfig->getString(UiSection, "assistant_logout_url", Constants::DefaultAssistantLogoutUrl)); +QString SettingsModel::getAssistantLogoutUrl() const { + return Utils::coreStringToAppString( + mConfig->getString(UiSection, "assistant_logout_url", Constants::DefaultAssistantLogoutUrl)); } -void SettingsModel::setAssistantLogoutUrl (QString url) { +void SettingsModel::setAssistantLogoutUrl(QString url) { mConfig->setString(UiSection, "assistant_logout_url", Utils::appStringToCoreString(url)); emit assistantLogoutUrlChanged(url); } -bool SettingsModel::isCguAccepted () const{ +bool SettingsModel::isCguAccepted() const { #ifdef APPLICATION_VENDOR QString applicationVendor = APPLICATION_VENDOR; #else QString applicationVendor; #endif - return !!mConfig->getInt(UiSection, "read_and_agree_terms_and_privacy", ( applicationVendor != "" && Constants::CguUrl != QString("") && Constants::PrivatePolicyUrl != QString("") ? 0 : 1)); + return !!mConfig->getInt( + UiSection, "read_and_agree_terms_and_privacy", + (applicationVendor != "" && Constants::CguUrl != QString("") && Constants::PrivatePolicyUrl != QString("") + ? 0 + : 1)); } -void SettingsModel::acceptCgu(const bool accept){ +void SettingsModel::acceptCgu(const bool accept) { bool oldAccept = isCguAccepted(); - if( oldAccept != accept){ + if (oldAccept != accept) { mConfig->setInt(UiSection, "read_and_agree_terms_and_privacy", accept); emit cguAcceptedChanged(accept); } @@ -315,15 +325,16 @@ void SettingsModel::acceptCgu(const bool accept){ // SIP Accounts. // ============================================================================= -QString SettingsModel::getDeviceName(const std::shared_ptr& config){ - return Utils::coreStringToAppString(config->getString(UiSection, "device_name", Utils::appStringToCoreString(QSysInfo::machineHostName()))); +QString SettingsModel::getDeviceName(const std::shared_ptr &config) { + return Utils::coreStringToAppString( + config->getString(UiSection, "device_name", Utils::appStringToCoreString(QSysInfo::machineHostName()))); } -QString SettingsModel::getDeviceName() const{ +QString SettingsModel::getDeviceName() const { return getDeviceName(mConfig); } -void SettingsModel::setDeviceName(const QString& deviceName){ +void SettingsModel::setDeviceName(const QString &deviceName) { mConfig->setString(UiSection, "device_name", Utils::appStringToCoreString(deviceName)); emit deviceNameChanged(); CoreManager::getInstance()->updateUserAgent(); @@ -338,26 +349,20 @@ void SettingsModel::resetCaptureGraph() { createCaptureGraph(); } void SettingsModel::createCaptureGraph() { - mSimpleCaptureGraph = - new MediastreamerUtils::SimpleCaptureGraph(Utils::appStringToCoreString(getCaptureDevice()), Utils::appStringToCoreString(getPlaybackDevice())); + mSimpleCaptureGraph = new MediastreamerUtils::SimpleCaptureGraph(Utils::appStringToCoreString(getCaptureDevice()), + Utils::appStringToCoreString(getPlaybackDevice())); mSimpleCaptureGraph->start(); emit captureGraphRunningChanged(getCaptureGraphRunning()); } void SettingsModel::startCaptureGraph() { - if (!getIsInCall()) { - if (!mSimpleCaptureGraph) { - qDebug() << "Starting capture graph [" << mCaptureGraphListenerCount << "]"; - createCaptureGraph(); - } + if(!getIsInCall()) { + if (!mSimpleCaptureGraph) createCaptureGraph(); ++mCaptureGraphListenerCount; } } void SettingsModel::stopCaptureGraph() { if (mCaptureGraphListenerCount > 0) { - if (--mCaptureGraphListenerCount == 0) { - qDebug() << "Stopping capture graph [" << mCaptureGraphListenerCount << "]"; - deleteCaptureGraph(); - } + if (--mCaptureGraphListenerCount == 0) deleteCaptureGraph(); } } void SettingsModel::stopCaptureGraphs() { @@ -375,8 +380,8 @@ void SettingsModel::deleteCaptureGraph() { mSimpleCaptureGraph = nullptr; } } -//Force a call on the 'detect' method of all audio filters, updating new or removed devices -void SettingsModel::accessAudioSettings() { +// 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()); @@ -388,7 +393,6 @@ void SettingsModel::accessAudioSettings() { // Media cards must not be used twice (capture card + call) else we will get latencies issues and bad echo calibrations in call. if (!getIsInCall()) { - qDebug() << "Starting capture graph from accessing audio panel"; startCaptureGraph(); } } @@ -422,8 +426,7 @@ void SettingsModel::setPlaybackGain(float gain) { if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { mSimpleCaptureGraph->setPlaybackGain(gain); } - if((int)(oldGain*1000) != (int)(gain*1000)) - emit playbackGainChanged(gain); + if ((int)(oldGain * 1000) != (int)(gain * 1000)) emit playbackGainChanged(gain); } float SettingsModel::getCaptureGain() const { @@ -437,22 +440,20 @@ void SettingsModel::setCaptureGain(float gain) { if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { mSimpleCaptureGraph->setCaptureGain(gain); } - if((int)(oldGain *1000) != (int)(gain *1000)) - emit captureGainChanged(gain); + if ((int)(oldGain * 1000) != (int)(gain * 1000)) emit captureGainChanged(gain); } -QStringList SettingsModel::getCaptureDevices () const { +QStringList SettingsModel::getCaptureDevices() const { shared_ptr core = CoreManager::getInstance()->getCore(); QStringList list; for (const auto &device : core->getSoundDevicesList()) { - if (core->soundDeviceCanCapture(device)) - list << Utils::coreStringToAppString(device); + if (core->soundDeviceCanCapture(device)) list << Utils::coreStringToAppString(device); } return list; } -QStringList SettingsModel::getPlaybackDevices () const { +QStringList SettingsModel::getPlaybackDevices() const { shared_ptr core = CoreManager::getInstance()->getCore(); QStringList list; @@ -467,120 +468,113 @@ QStringList SettingsModel::getPlaybackDevices () const { // ----------------------------------------------------------------------------- -QString SettingsModel::getCaptureDevice () const { +QString SettingsModel::getCaptureDevice() const { auto audioDevice = CoreManager::getInstance()->getCore()->getInputAudioDevice(); - return Utils::coreStringToAppString(audioDevice? audioDevice->getId() : CoreManager::getInstance()->getCore()->getCaptureDevice()); + return Utils::coreStringToAppString(audioDevice ? audioDevice->getId() + : CoreManager::getInstance()->getCore()->getCaptureDevice()); } -void SettingsModel::setCaptureDevice (const QString &device) { +void SettingsModel::setCaptureDevice(const QString &device) { std::string devId = Utils::appStringToCoreString(device); auto list = CoreManager::getInstance()->getCore()->getExtendedAudioDevices(); - auto audioDevice = find_if(list.cbegin(), list.cend(), [&] ( const std::shared_ptr & audioItem) { - return audioItem->getId() == devId; - }); - if(audioDevice != list.cend()){ + auto audioDevice = + find_if(list.cbegin(), list.cend(), + [&](const std::shared_ptr &audioItem) { return audioItem->getId() == devId; }); + if (audioDevice != list.cend()) { CoreManager::getInstance()->getCore()->setCaptureDevice(devId); CoreManager::getInstance()->getCore()->setInputAudioDevice(*audioDevice); emit captureDeviceChanged(device); resetCaptureGraph(); - }else - qWarning() << "Cannot set Capture device. The ID cannot be matched with an existant device : " << device; + } else qWarning() << "Cannot set Capture device. The ID cannot be matched with an existant device : " << device; } // ----------------------------------------------------------------------------- -QString SettingsModel::getPlaybackDevice () const { +QString SettingsModel::getPlaybackDevice() const { auto audioDevice = CoreManager::getInstance()->getCore()->getOutputAudioDevice(); - return Utils::coreStringToAppString(audioDevice? audioDevice->getId() : CoreManager::getInstance()->getCore()->getPlaybackDevice()); + return Utils::coreStringToAppString(audioDevice ? audioDevice->getId() + : CoreManager::getInstance()->getCore()->getPlaybackDevice()); } -void SettingsModel::setPlaybackDevice (const QString &device) { +void SettingsModel::setPlaybackDevice(const QString &device) { std::string devId = Utils::appStringToCoreString(device); auto list = CoreManager::getInstance()->getCore()->getExtendedAudioDevices(); - auto audioDevice = find_if(list.cbegin(), list.cend(), [&] ( const std::shared_ptr & audioItem) { - return audioItem->getId() == devId; - }); - if(audioDevice != list.cend()){ + auto audioDevice = + find_if(list.cbegin(), list.cend(), + [&](const std::shared_ptr &audioItem) { return audioItem->getId() == devId; }); + if (audioDevice != list.cend()) { CoreManager::getInstance()->getCore()->setPlaybackDevice(devId); CoreManager::getInstance()->getCore()->setOutputAudioDevice(*audioDevice); emit playbackDeviceChanged(device); resetCaptureGraph(); - }else - qWarning() << "Cannot set Playback device. The ID cannot be matched with an existant device : " << device; + } else qWarning() << "Cannot set Playback device. The ID cannot be matched with an existant device : " << device; } // ----------------------------------------------------------------------------- -QString SettingsModel::getRingerDevice () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getRingerDevice() - ); +QString SettingsModel::getRingerDevice() const { + return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getRingerDevice()); } -void SettingsModel::setRingerDevice (const QString &device) { - CoreManager::getInstance()->getCore()->setRingerDevice( - Utils::appStringToCoreString(device) - ); +void SettingsModel::setRingerDevice(const QString &device) { + CoreManager::getInstance()->getCore()->setRingerDevice(Utils::appStringToCoreString(device)); emit ringerDeviceChanged(device); } // ----------------------------------------------------------------------------- -QString SettingsModel::getRingPath () const { +QString SettingsModel::getRingPath() const { return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getRing()); } -void SettingsModel::setRingPath (const QString &path) { +void SettingsModel::setRingPath(const QString &path) { QString cleanedPath = QDir::cleanPath(path); - CoreManager::getInstance()->getCore()->setRing( - Utils::appStringToCoreString(cleanedPath) - ); + CoreManager::getInstance()->getCore()->setRing(Utils::appStringToCoreString(cleanedPath)); emit ringPathChanged(cleanedPath); } // ----------------------------------------------------------------------------- -bool SettingsModel::getEchoCancellationEnabled () const { +bool SettingsModel::getEchoCancellationEnabled() const { return CoreManager::getInstance()->getCore()->echoCancellationEnabled(); } -void SettingsModel::setEchoCancellationEnabled (bool status) { +void SettingsModel::setEchoCancellationEnabled(bool status) { CoreManager::getInstance()->getCore()->enableEchoCancellation(status); emit echoCancellationEnabledChanged(status); } -void SettingsModel::startEchoCancellerCalibration(){ +void SettingsModel::startEchoCancellerCalibration() { CoreManager::getInstance()->getCore()->startEchoCancellerCalibration(); - } // ----------------------------------------------------------------------------- -bool SettingsModel::getShowAudioCodecs () const { +bool SettingsModel::getShowAudioCodecs() const { return !!mConfig->getInt(UiSection, "show_audio_codecs", 1); } -void SettingsModel::setShowAudioCodecs (bool status) { +void SettingsModel::setShowAudioCodecs(bool 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 +// Force a call on the 'detect' method of all video filters, updating new or removed devices void SettingsModel::accessVideoSettings() { - //if(!getIsInCall())// TODO : This is a workaround to a crash when reloading video devices while in call. Spotted on Macos. - CoreManager::getInstance()->getCore()->reloadVideoDevices(); + // if(!getIsInCall())// TODO : This is a workaround to a crash when reloading video devices while in call. Spotted + // on Macos. + CoreManager::getInstance()->getCore()->reloadVideoDevices(); emit videoDevicesChanged(getVideoDevices()); } -QStringList SettingsModel::getVideoDevices () const { +QStringList SettingsModel::getVideoDevices() const { QStringList list; for (const auto &device : CoreManager::getInstance()->getCore()->getVideoDevicesList()) @@ -591,48 +585,66 @@ QStringList SettingsModel::getVideoDevices () const { // ----------------------------------------------------------------------------- -QString SettingsModel::getVideoDevice () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getVideoDevice() - ); +QString SettingsModel::getVideoDevice() const { + return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getVideoDevice()); } -void SettingsModel::setVideoDevice (const QString &device) { - CoreManager::getInstance()->getCore()->setVideoDevice( - Utils::appStringToCoreString(device) - ); +void SettingsModel::setVideoDevice(const QString &device) { + CoreManager::getInstance()->getCore()->setVideoDevice(Utils::appStringToCoreString(device)); emit videoDeviceChanged(device); } -// ----------------------------------------------------------------------------- - -QString SettingsModel::getVideoPreset () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getVideoPreset() - ); +void SettingsModel::saveCaptureWindowId(void *windowId) { + mCaptureWindowId = windowId; + //CoreManager::getInstance()->getCore()->setVideoCaptureWindowId(mCaptureWindowId); + emit captureScreenIndexChanged(-1); + qDebug() << -1; } -void SettingsModel::setVideoPreset (const QString &preset) { - CoreManager::getInstance()->getCore()->setVideoPreset( - Utils::appStringToCoreString(preset) - ); +void SettingsModel::saveCaptureScreenIndex(int index) { + mCaptureWindowId = reinterpret_cast(-index); + //CoreManager::getInstance()->getCore()->setVideoCaptureWindowId(mCaptureWindowId); + emit captureScreenIndexChanged(index); + qDebug() << index; +} + +int SettingsModel::getCaptureScreenIndex() { +/* + int64_t id = (int64_t)CoreManager::getInstance()->getCore()->getVideoCaptureWindowId(); + if(id <= 0){ + return -id; + }else*/ + return -1; +} + +void SettingsModel::setCaptureWindowId() { + //CoreManager::getInstance()->getCore()->setVideoCaptureWindowId(mCaptureWindowId); +} +// ----------------------------------------------------------------------------- + +QString SettingsModel::getVideoPreset() const { + return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getVideoPreset()); +} + +void SettingsModel::setVideoPreset(const QString &preset) { + CoreManager::getInstance()->getCore()->setVideoPreset(Utils::appStringToCoreString(preset)); emit videoPresetChanged(preset); } // ----------------------------------------------------------------------------- -int SettingsModel::getVideoFramerate () const { +int SettingsModel::getVideoFramerate() const { return int(CoreManager::getInstance()->getCore()->getPreferredFramerate()); } -void SettingsModel::setVideoFramerate (int framerate) { +void SettingsModel::setVideoFramerate(int framerate) { CoreManager::getInstance()->getCore()->setPreferredFramerate(float(framerate)); emit videoFramerateChanged(framerate); } // ----------------------------------------------------------------------------- -static inline QVariantMap createMapFromVideoDefinition (const shared_ptr &definition) { +static inline QVariantMap createMapFromVideoDefinition(const shared_ptr &definition) { QVariantMap map; if (!definition) { @@ -650,22 +662,21 @@ static inline QVariantMap createMapFromVideoDefinition (const shared_ptrgetSupportedVideoDefinitions()) list << createMapFromVideoDefinition(definition); return list; } -QVariantMap SettingsModel::getVideoDefinition () const { +QVariantMap SettingsModel::getVideoDefinition() const { return createMapFromVideoDefinition(CoreManager::getInstance()->getCore()->getPreferredVideoDefinition()); } -QVariantMap SettingsModel::getCurrentPreviewVideoDefinition () const { - if(CoreManager::getInstance()->getCore()->videoPreviewEnabled()){ +QVariantMap SettingsModel::getCurrentPreviewVideoDefinition() const { + if (CoreManager::getInstance()->getCore()->videoPreviewEnabled()) { auto definition = CoreManager::getInstance()->getCore()->getCurrentPreviewVideoDefinition(); - if(definition) - return createMapFromVideoDefinition(definition); + if (definition) return createMapFromVideoDefinition(definition); } QVariantMap map; map["width"] = 0; @@ -673,365 +684,388 @@ QVariantMap SettingsModel::getCurrentPreviewVideoDefinition () const { return map; } -void SettingsModel::setVideoDefinition (const QVariantMap &definition) { +void SettingsModel::setVideoDefinition(const QVariantMap &definition) { CoreManager::getInstance()->getCore()->setPreferredVideoDefinition( - definition.value("__definition").value>()->clone() - ); + definition.value("__definition").value>()->clone()); emit videoDefinitionChanged(definition); } bool SettingsModel::getVideoEnabled() const { - return CoreManager::getInstance()->getCore()->videoSupported() - && !mConfig->getInt("app", "disable_video_feature", !mConfig->getInt(UiSection, "video_enabled", 1)); + return CoreManager::getInstance()->getCore()->videoSupported() && + !mConfig->getInt("app", "disable_video_feature", !mConfig->getInt(UiSection, "video_enabled", 1)); } -void SettingsModel::setVideoEnabled(const bool& enable){ - if( CoreManager::getInstance()->getCore()->videoSupported()){ +void SettingsModel::setVideoEnabled(const bool &enable) { + if (CoreManager::getInstance()->getCore()->videoSupported()) { mConfig->setInt("app", "disable_video_feature", !enable); emit videoEnabledChanged(); } } -void SettingsModel::setHighMosaicQuality(){ +void SettingsModel::setHighMosaicQuality() { mConfig->setString("video", "max_mosaic_size", ""); } -void SettingsModel::setLimitedMosaicQuality(){ +void SettingsModel::setLimitedMosaicQuality() { mConfig->setString("video", "max_mosaic_size", "vga"); } // ----------------------------------------------------------------------------- -bool SettingsModel::getShowVideoCodecs () const { +bool SettingsModel::getShowVideoCodecs() const { return !!mConfig->getInt(UiSection, "show_video_codecs", 1); } -void SettingsModel::setShowVideoCodecs (bool status) { +void SettingsModel::setShowVideoCodecs(bool status) { mConfig->setInt(UiSection, "show_video_codecs", status); emit showVideoCodecsChanged(status); } -bool SettingsModel::getVideoAvailable() const{ +bool SettingsModel::getVideoAvailable() const { return getVideoEnabled() && haveAtLeastOneVideoCodec(); } -bool SettingsModel::haveAtLeastOneVideoCodec() const{ +bool SettingsModel::haveAtLeastOneVideoCodec() const { auto codecs = CoreManager::getInstance()->getCore()->getVideoPayloadTypes(); - for (auto &codec : codecs){ - if(codec->enabled() && codec->isUsable()) - return true; + for (auto &codec : codecs) { + if (codec->enabled() && codec->isUsable()) return true; } return false; } // ============================================================================= -void SettingsModel::updateCameraMode(){ - auto mode = mConfig->getString("video", "main_display_mode", "OccupyAllSpace"); +void SettingsModel::updateCameraMode() { + auto mode = mConfig->getString("video", "main_display_mode", "OccupyAllSpace"); mConfig->setString("video", "main_display_mode", mode); mConfig->setString("video", "other_display_mode", mode); } -SettingsModel::CameraMode SettingsModel::cameraModefromString(const std::string& mode){ - if( mode == "Hybrid") - return CameraMode::CameraMode_Hybrid; - else if( mode == "BlackBars") - return CameraMode::CameraMode_BlackBars; - else - return CameraMode::CameraMode_OccupyAllSpace; +SettingsModel::CameraMode SettingsModel::cameraModefromString(const std::string &mode) { + if (mode == "Hybrid") return CameraMode::CameraMode_Hybrid; + else if (mode == "BlackBars") return CameraMode::CameraMode_BlackBars; + else return CameraMode::CameraMode_OccupyAllSpace; } -std::string SettingsModel::toString(const CameraMode& mode){ + +std::string SettingsModel::toString(const CameraMode &mode) { std::string modeStr; - switch(mode){ - case CameraMode::CameraMode_Hybrid : modeStr = "Hybrid";break; - case CameraMode::CameraMode_BlackBars: modeStr = "BlackBars";break; - default: modeStr = "OccupyAllSpace"; + switch (mode) { + case CameraMode::CameraMode_Hybrid: + modeStr = "Hybrid"; + break; + case CameraMode::CameraMode_BlackBars: + modeStr = "BlackBars"; + break; + default: + modeStr = "OccupyAllSpace"; } return modeStr; } -SettingsModel::CameraMode SettingsModel::getCameraMode() const{ + +SettingsModel::CameraMode SettingsModel::getCameraMode() const { return cameraModefromString(mConfig->getString("video", "main_display_mode", "OccupyAllSpace")); } -void SettingsModel::setCameraMode(CameraMode mode){ +void SettingsModel::setCameraMode(CameraMode mode) { std::string modeToSet; - switch(mode){ - case CameraMode::CameraMode_Hybrid : modeToSet = "Hybrid";break; - case CameraMode::CameraMode_BlackBars: modeToSet = "BlackBars";break; - default: modeToSet = "OccupyAllSpace"; + switch (mode) { + case CameraMode::CameraMode_Hybrid: + modeToSet = "Hybrid"; + break; + case CameraMode::CameraMode_BlackBars: + modeToSet = "BlackBars"; + break; + default: + modeToSet = "OccupyAllSpace"; } mConfig->setString("video", "main_display_mode", modeToSet); mConfig->setString("video", "other_display_mode", modeToSet); emit cameraModeChanged(); } -SettingsModel::CameraMode SettingsModel::getGridCameraMode() const{ +SettingsModel::CameraMode SettingsModel::getGridCameraMode() const { return cameraModefromString(mConfig->getString(UiSection, "main_grid_display_mode", "OccupyAllSpace")); } -void SettingsModel::setGridCameraMode(CameraMode mode){ +void SettingsModel::setGridCameraMode(CameraMode mode) { auto modeStd = toString(mode); mConfig->setString(UiSection, "main_grid_display_mode", modeStd); emit gridCameraModeChanged(); } -SettingsModel::CameraMode SettingsModel::getActiveSpeakerCameraMode() const{ +SettingsModel::CameraMode SettingsModel::getActiveSpeakerCameraMode() const { return cameraModefromString(mConfig->getString(UiSection, "main_active_speaker_display_mode", "Hybrid")); } -void SettingsModel::setActiveSpeakerCameraMode(CameraMode mode){ +void SettingsModel::setActiveSpeakerCameraMode(CameraMode mode) { auto modeStd = toString(mode); mConfig->setString(UiSection, "main_active_speaker_display_mode", modeStd); emit activeSpeakerCameraModeChanged(); } -SettingsModel::CameraMode SettingsModel::getCallCameraMode() const{ +SettingsModel::CameraMode SettingsModel::getCallCameraMode() const { return cameraModefromString(mConfig->getString(UiSection, "main_call_display_mode", "Hybrid")); } -void SettingsModel::setCallCameraMode(CameraMode mode){ +void SettingsModel::setCallCameraMode(CameraMode mode) { auto modeStd = toString(mode); mConfig->setString(UiSection, "main_call_display_mode", modeStd); emit callCameraModeChanged(); } -LinphoneEnums::ConferenceLayout SettingsModel::getVideoConferenceLayout() const{ - return (LinphoneEnums::ConferenceLayout) mConfig->getInt(UiSection, "video_conference_layout", (int)LinphoneEnums::ConferenceLayoutActiveSpeaker); +LinphoneEnums::ConferenceLayout SettingsModel::getVideoConferenceLayout() const { + return (LinphoneEnums::ConferenceLayout)mConfig->getInt(UiSection, "video_conference_layout", + (int)LinphoneEnums::ConferenceLayoutActiveSpeaker); } -void SettingsModel::setVideoConferenceLayout(LinphoneEnums::ConferenceLayout layout){ +void SettingsModel::setVideoConferenceLayout(LinphoneEnums::ConferenceLayout layout) { mConfig->setInt(UiSection, "video_conference_layout", (int)layout); emit videoConferenceLayoutChanged(); } +int SettingsModel::getConferenceMaxThumbnails() const { + return CoreManager::getInstance()->getCore()->getConferenceMaxThumbnails(); +} + +void SettingsModel::setConferenceMaxThumbnails(int limit) { + if( getConferenceMaxThumbnails() != limit) { + CoreManager::getInstance()->getCore()->setConferenceMaxThumbnails(limit); + emit conferenceMaxThumbnailsChanged(); + } +} + // ============================================================================= // Chat & calls. // ============================================================================= -bool SettingsModel::getAutoAnswerStatus () const { +bool SettingsModel::getAutoAnswerStatus() const { return !!mConfig->getInt(UiSection, "auto_answer", 0); } -void SettingsModel::setAutoAnswerStatus (bool status) { +void SettingsModel::setAutoAnswerStatus(bool status) { mConfig->setInt(UiSection, "auto_answer", status); emit autoAnswerStatusChanged(status); } // ----------------------------------------------------------------------------- -bool SettingsModel::getAutoAnswerVideoStatus () const { +bool SettingsModel::getAutoAnswerVideoStatus() const { return !!mConfig->getInt(UiSection, "auto_answer_with_video", 0); } -void SettingsModel::setAutoAnswerVideoStatus (bool status) { +void SettingsModel::setAutoAnswerVideoStatus(bool status) { mConfig->setInt(UiSection, "auto_answer_with_video", status); emit autoAnswerVideoStatusChanged(status); } // ----------------------------------------------------------------------------- -int SettingsModel::getAutoAnswerDelay () const { +int SettingsModel::getAutoAnswerDelay() const { return mConfig->getInt(UiSection, "auto_answer_delay", 0); } -void SettingsModel::setAutoAnswerDelay (int delay) { +void SettingsModel::setAutoAnswerDelay(int delay) { mConfig->setInt(UiSection, "auto_answer_delay", delay); emit autoAnswerDelayChanged(delay); } // ----------------------------------------------------------------------------- -bool SettingsModel::getShowTelKeypadAutomatically () const { +bool SettingsModel::getShowTelKeypadAutomatically() const { return !!mConfig->getInt(UiSection, "show_tel_keypad_automatically", 0); } -void SettingsModel::setShowTelKeypadAutomatically (bool status) { +void SettingsModel::setShowTelKeypadAutomatically(bool status) { mConfig->setInt(UiSection, "show_tel_keypad_automatically", status); emit showTelKeypadAutomaticallyChanged(status); } // ----------------------------------------------------------------------------- -bool SettingsModel::getKeepCallsWindowInBackground () const { +bool SettingsModel::getKeepCallsWindowInBackground() const { return !!mConfig->getInt(UiSection, "keep_calls_window_in_background", 0); } -void SettingsModel::setKeepCallsWindowInBackground (bool status) { +void SettingsModel::setKeepCallsWindowInBackground(bool status) { mConfig->setInt(UiSection, "keep_calls_window_in_background", status); emit keepCallsWindowInBackgroundChanged(status); } // ----------------------------------------------------------------------------- -bool SettingsModel::getOutgoingCallsEnabled () const { +bool SettingsModel::getOutgoingCallsEnabled() const { return !!mConfig->getInt(UiSection, "outgoing_calls_enabled", 1); } -void SettingsModel::setOutgoingCallsEnabled (bool status) { +void SettingsModel::setOutgoingCallsEnabled(bool status) { mConfig->setInt(UiSection, "outgoing_calls_enabled", status); emit outgoingCallsEnabledChanged(status); } // ----------------------------------------------------------------------------- -bool SettingsModel::getCallRecorderEnabled () const { +bool SettingsModel::getCallRecorderEnabled() const { return !!mConfig->getInt(UiSection, "call_recorder_enabled", 1); } -void SettingsModel::setCallRecorderEnabled (bool status) { +void SettingsModel::setCallRecorderEnabled(bool status) { mConfig->setInt(UiSection, "call_recorder_enabled", status); emit callRecorderEnabledChanged(status); } // ----------------------------------------------------------------------------- -bool SettingsModel::getAutomaticallyRecordCalls () const { +bool SettingsModel::getAutomaticallyRecordCalls() const { return !!mConfig->getInt(UiSection, "automatically_record_calls", 0); } -void SettingsModel::setAutomaticallyRecordCalls (bool status) { +void SettingsModel::setAutomaticallyRecordCalls(bool status) { mConfig->setInt(UiSection, "automatically_record_calls", status); emit automaticallyRecordCallsChanged(status); } -int SettingsModel::getAutoDownloadMaxSize() const{ +int SettingsModel::getAutoDownloadMaxSize() const { return CoreManager::getInstance()->getCore()->getMaxSizeForAutoDownloadIncomingFiles(); } -void SettingsModel::setAutoDownloadMaxSize(int maxSize){ - if(maxSize != getAutoDownloadMaxSize()){ +void SettingsModel::setAutoDownloadMaxSize(int maxSize) { + if (maxSize != getAutoDownloadMaxSize()) { CoreManager::getInstance()->getCore()->setMaxSizeForAutoDownloadIncomingFiles(maxSize); emit autoDownloadMaxSizeChanged(maxSize); } } - + // ----------------------------------------------------------------------------- -bool SettingsModel::getCallPauseEnabled () const { +bool SettingsModel::getCallPauseEnabled() const { return !!mConfig->getInt(UiSection, "call_pause_enabled", 1); } -void SettingsModel::setCallPauseEnabled (bool status) { +void SettingsModel::setCallPauseEnabled(bool status) { mConfig->setInt(UiSection, "call_pause_enabled", status); emit callPauseEnabledChanged(status); } -bool SettingsModel::getMuteMicrophoneEnabled () const { +bool SettingsModel::getMuteMicrophoneEnabled() const { return !!mConfig->getInt(UiSection, "mute_microphone_enabled", 1); } -void SettingsModel::setMuteMicrophoneEnabled (bool status) { +void SettingsModel::setMuteMicrophoneEnabled(bool status) { mConfig->setInt(UiSection, "mute_microphone_enabled", status); emit muteMicrophoneEnabledChanged(status); } // ----------------------------------------------------------------------------- - -bool SettingsModel::getStandardChatEnabled () const { - return getChatEnabled() && !!mConfig->getInt(UiSection, getEntryFullName(UiSection,"standard_chat_enabled"), 1); +bool SettingsModel::getStandardChatEnabled() const { + return getChatEnabled() && !!mConfig->getInt(UiSection, getEntryFullName(UiSection, "standard_chat_enabled"), 1); } -void SettingsModel::setStandardChatEnabled (bool status) { - if(!isReadOnly(UiSection, "standard_chat_enabled")) - mConfig->setInt(UiSection, "standard_chat_enabled", status); - emit standardChatEnabledChanged(getStandardChatEnabled ()); +void SettingsModel::setStandardChatEnabled(bool status) { + if (!isReadOnly(UiSection, "standard_chat_enabled")) mConfig->setInt(UiSection, "standard_chat_enabled", status); + emit standardChatEnabledChanged(getStandardChatEnabled()); } -bool SettingsModel::getSecureChatEnabled () const { - return getChatEnabled() && !!mConfig->getInt(UiSection, getEntryFullName(UiSection, "secure_chat_enabled"), 1) - && getLimeIsSupported() - && CoreManager::getInstance()->getCore()->getDefaultAccount() && !CoreManager::getInstance()->getCore()->getDefaultAccount()->getParams()->getLimeServerUrl().empty() - //&& !CoreManager::getInstance()->getCore()->getLimeX3DhServerUrl().empty() - && getGroupChatEnabled(); +bool SettingsModel::getSecureChatEnabled() const { + return getChatEnabled() && !!mConfig->getInt(UiSection, getEntryFullName(UiSection, "secure_chat_enabled"), 1) && + getLimeIsSupported() && CoreManager::getInstance()->getCore()->getDefaultAccount() && + !CoreManager::getInstance()->getCore()->getDefaultAccount()->getParams()->getLimeServerUrl().empty() + //&& !CoreManager::getInstance()->getCore()->getLimeX3DhServerUrl().empty() + && getGroupChatEnabled(); ; } -void SettingsModel::setSecureChatEnabled (bool status) { - if(!isReadOnly(UiSection, "secure_chat_enabled")) - mConfig->setInt(UiSection, "secure_chat_enabled", status); +void SettingsModel::setSecureChatEnabled(bool status) { + if (!isReadOnly(UiSection, "secure_chat_enabled")) mConfig->setInt(UiSection, "secure_chat_enabled", status); emit secureChatEnabledChanged(); } -bool SettingsModel::getChatEnabled () const { - return !mConfig->getInt("app", getEntryFullName("app","disable_chat_feature"), 0); +bool SettingsModel::getChatEnabled() const { + return !mConfig->getInt("app", getEntryFullName("app", "disable_chat_feature"), 0); } -bool SettingsModel::getGroupChatEnabled() const{ - return CoreManager::getInstance()->getCore()->getDefaultAccount() && !CoreManager::getInstance()->getCore()->getDefaultAccount()->getParams()->getConferenceFactoryUri().empty(); +bool SettingsModel::getGroupChatEnabled() const { + return CoreManager::getInstance()->getCore()->getDefaultAccount() && + !CoreManager::getInstance()->getCore()->getDefaultAccount()->getParams()->getConferenceFactoryUri().empty(); } // ----------------------------------------------------------------------------- -bool SettingsModel::getHideEmptyChatRooms() const{ +bool SettingsModel::getHideEmptyChatRooms() const { int defaultValue = 0; - if(!mConfig->hasEntry("misc", "hide_empty_chat_rooms"))// This step should be removed when this option comes from API and not directly from config file + if (!mConfig->hasEntry("misc", "hide_empty_chat_rooms")) // This step should be removed when this option comes from + // API and not directly from config file mConfig->setInt("misc", "hide_empty_chat_rooms", defaultValue); return !!mConfig->getInt("misc", "hide_empty_chat_rooms", defaultValue); } -void SettingsModel::setHideEmptyChatRooms(const bool& status){ +void SettingsModel::setHideEmptyChatRooms(const bool &status) { mConfig->setInt("misc", "hide_empty_chat_rooms", status); emit hideEmptyChatRoomsChanged(status); } // ----------------------------------------------------------------------------- -bool SettingsModel::getWaitRegistrationForCall() const{ +bool SettingsModel::getWaitRegistrationForCall() const { return !!mConfig->getInt(UiSection, "call_wait_registration", 0); } -void SettingsModel::setWaitRegistrationForCall(const bool& status){ +void SettingsModel::setWaitRegistrationForCall(const bool &status) { mConfig->setInt(UiSection, "call_wait_registration", status); emit waitRegistrationForCallChanged(status); } -bool SettingsModel::getIncallScreenshotEnabled() const{ +bool SettingsModel::getIncallScreenshotEnabled() const { return !!mConfig->getInt(UiSection, "show_take_screenshot_button_in_call", 0); } -void SettingsModel::setIncallScreenshotEnabled(const bool& status){ +void SettingsModel::setIncallScreenshotEnabled(const bool &status) { mConfig->setInt(UiSection, "show_take_screenshot_button_in_call", status); emit incallScreenshotEnabledChanged(status); } // ----------------------------------------------------------------------------- -bool SettingsModel::getConferenceEnabled () const { +bool SettingsModel::getConferenceEnabled() const { return !!mConfig->getInt(UiSection, "conference_enabled", 1); } -void SettingsModel::setConferenceEnabled (bool status) { +void SettingsModel::setConferenceEnabled(bool status) { mConfig->setInt(UiSection, "conference_enabled", status); emit conferenceEnabledChanged(status); } -bool SettingsModel::getVideoConferenceEnabled() const{ - return CoreManager::getInstance()->getCore()->getDefaultAccount() && !!CoreManager::getInstance()->getCore()->getDefaultAccount()->getParams()->getAudioVideoConferenceFactoryAddress(); +bool SettingsModel::getVideoConferenceEnabled() const { + return CoreManager::getInstance()->getCore()->getDefaultAccount() && + !!CoreManager::getInstance() + ->getCore() + ->getDefaultAccount() + ->getParams() + ->getAudioVideoConferenceFactoryAddress(); } // ----------------------------------------------------------------------------- -bool SettingsModel::getChatNotificationsEnabled () const { +bool SettingsModel::getChatNotificationsEnabled() const { return !!mConfig->getInt(UiSection, "chat_notifications_enabled", 1); } -void SettingsModel::setChatNotificationsEnabled (bool status) { +void SettingsModel::setChatNotificationsEnabled(bool status) { mConfig->setInt(UiSection, "chat_notifications_enabled", status); emit chatNotificationsEnabledChanged(status); } // ----------------------------------------------------------------------------- -bool SettingsModel::getChatNotificationSoundEnabled () const { +bool SettingsModel::getChatNotificationSoundEnabled() const { return !!mConfig->getInt(UiSection, "chat_sound_notification_enabled", 1); } -void SettingsModel::setChatNotificationSoundEnabled (bool status) { +void SettingsModel::setChatNotificationSoundEnabled(bool status) { mConfig->setInt(UiSection, "chat_sound_notification_enabled", status); emit chatNotificationSoundEnabledChanged(status); } // ----------------------------------------------------------------------------- -QString SettingsModel::getChatNotificationSoundPath () const { +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)); } -void SettingsModel::setChatNotificationSoundPath (const QString &path) { +void SettingsModel::setChatNotificationSoundPath(const QString &path) { QString cleanedPath = QDir::cleanPath(path); mConfig->setString(UiSection, "chat_sound_notification_file", Utils::appStringToCoreString(cleanedPath)); emit chatNotificationSoundPathChanged(cleanedPath); @@ -1039,48 +1073,43 @@ void SettingsModel::setChatNotificationSoundPath (const QString &path) { // ----------------------------------------------------------------------------- -QString SettingsModel::getFileTransferUrl () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getFileTransferServer() - ); +QString SettingsModel::getFileTransferUrl() const { + return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getFileTransferServer()); } -void SettingsModel::setFileTransferUrl (const QString &url) { - CoreManager::getInstance()->getCore()->setFileTransferServer( - Utils::appStringToCoreString(url) - ); +void SettingsModel::setFileTransferUrl(const QString &url) { + CoreManager::getInstance()->getCore()->setFileTransferServer(Utils::appStringToCoreString(url)); emit fileTransferUrlChanged(url); } // ----------------------------------------------------------------------------- -bool SettingsModel::getLimeIsSupported () const { - return CoreManager::getInstance()->getCore()->limeX3DhAvailable(); +bool SettingsModel::getLimeIsSupported() const { + return CoreManager::getInstance()->getCore()->limeX3DhAvailable(); } // ----------------------------------------------------------------------------- -static inline QVariant buildEncryptionDescription (SettingsModel::MediaEncryption encryption, const char *description) { +static inline QVariant buildEncryptionDescription(SettingsModel::MediaEncryption encryption, const char *description) { QVariantMap m; m["key"] = description; m["value"] = encryption; return m; } -QVariantList SettingsModel::getSupportedMediaEncryptions () const { +QVariantList SettingsModel::getSupportedMediaEncryptions() const { shared_ptr core = CoreManager::getInstance()->getCore(); QVariantList list; if (core->mediaEncryptionSupported(linphone::MediaEncryption::SRTP)) list << buildEncryptionDescription(MediaEncryptionSrtp, "SRTP"); - if (core->mediaEncryptionSupported(linphone::MediaEncryption::ZRTP)){ - if( core->getPostQuantumAvailable()) + if (core->mediaEncryptionSupported(linphone::MediaEncryption::ZRTP)) { + if (core->getPostQuantumAvailable()) list << buildEncryptionDescription(MediaEncryptionZrtp, "Post Quantum ZRTP"); - else - list << buildEncryptionDescription(MediaEncryptionZrtp, "ZRTP"); + else list << buildEncryptionDescription(MediaEncryptionZrtp, "ZRTP"); } - + if (core->mediaEncryptionSupported(linphone::MediaEncryption::DTLS)) list << buildEncryptionDescription(MediaEncryptionDtls, "DTLS"); @@ -1089,28 +1118,23 @@ QVariantList SettingsModel::getSupportedMediaEncryptions () const { // ----------------------------------------------------------------------------- -SettingsModel::MediaEncryption SettingsModel::getMediaEncryption () const { - return static_cast( - CoreManager::getInstance()->getCore()->getMediaEncryption() - ); +SettingsModel::MediaEncryption SettingsModel::getMediaEncryption() const { + return static_cast(CoreManager::getInstance()->getCore()->getMediaEncryption()); } -void SettingsModel::setMediaEncryption (MediaEncryption encryption) { - if (encryption == getMediaEncryption()) - return; +void SettingsModel::setMediaEncryption(MediaEncryption encryption) { + if (encryption == getMediaEncryption()) return; - 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 + // Disable mandatory encryption if none is selected enableMandatoryMediaEncryption(false); } emit mediaEncryptionChanged(encryption); } -bool SettingsModel::mandatoryMediaEncryptionEnabled () const { +bool SettingsModel::mandatoryMediaEncryptionEnabled() const { return CoreManager::getInstance()->getCore()->isMediaEncryptionMandatory(); } @@ -1120,23 +1144,23 @@ void SettingsModel::enableMandatoryMediaEncryption(bool mandatory) { } CoreManager::getInstance()->getCore()->setMediaEncryptionMandatory(mandatory); if (mandatory && getMediaEncryption() == SettingsModel::MediaEncryptionNone) { - //Force to SRTP if mandatory but 'none' was selected + // Force to SRTP if mandatory but 'none' was selected setMediaEncryption(SettingsModel::MediaEncryptionSrtp); } else { emit mediaEncryptionChanged(getMediaEncryption()); } } -bool SettingsModel::getPostQuantumAvailable() const{ +bool SettingsModel::getPostQuantumAvailable() const { return CoreManager::getInstance()->getCore() && CoreManager::getInstance()->getCore()->getPostQuantumAvailable(); } -bool SettingsModel::getDontAskAgainInfoEncryption() const{ +bool SettingsModel::getDontAskAgainInfoEncryption() const { return mConfig->getBool(UiSection, "dont_ask_again_info_encryption", false); } -void SettingsModel::setDontAskAgainInfoEncryption(bool show){ - if(show != getDontAskAgainInfoEncryption()) { +void SettingsModel::setDontAskAgainInfoEncryption(bool show) { + if (show != getDontAskAgainInfoEncryption()) { mConfig->setBool(UiSection, "dont_ask_again_info_encryption", show); emit dontAskAgainInfoEncryptionChanged(); } @@ -1148,41 +1172,39 @@ bool SettingsModel::getHaveDontAskAgainChoices() const { // ----------------------------------------------------------------------------- -bool SettingsModel::getLimeState () const { - return CoreManager::getInstance()->getCore()->limeX3DhEnabled(); +bool SettingsModel::getLimeState() const { + return CoreManager::getInstance()->getCore()->limeX3DhEnabled(); } -void SettingsModel::setLimeState (const bool& state) { - if (state == getLimeState()) - return; +void SettingsModel::setLimeState(const bool &state) { + if (state == getLimeState()) return; - CoreManager::getInstance()->getCore()->enableLimeX3Dh(state); + CoreManager::getInstance()->getCore()->enableLimeX3Dh(state); emit limeStateChanged(state); } // ----------------------------------------------------------------------------- -bool SettingsModel::getContactsEnabled () const { +bool SettingsModel::getContactsEnabled() const { return !!mConfig->getInt(UiSection, getEntryFullName(UiSection, "contacts_enabled"), 1); } -void SettingsModel::setContactsEnabled (bool status) { - if(!isReadOnly(UiSection, "contacts_enabled")) - mConfig->setInt(UiSection, "contacts_enabled", status); - emit contactsEnabledChanged(getContactsEnabled ()); +void SettingsModel::setContactsEnabled(bool status) { + if (!isReadOnly(UiSection, "contacts_enabled")) mConfig->setInt(UiSection, "contacts_enabled", status); + emit contactsEnabledChanged(getContactsEnabled()); } int SettingsModel::getIncomingCallTimeout() const { return CoreManager::getInstance()->getCore()->getIncTimeout(); } -int SettingsModel::getCreateEphemeralChatRooms() const{ +int SettingsModel::getCreateEphemeralChatRooms() const { return mConfig->getInt(UiSection, "create_ephemeral_chat_rooms", 0); } void SettingsModel::setCreateEphemeralChatRooms(int seconds) { - if(!isReadOnly(UiSection, "create_ephemeral_chat_rooms")) + if (!isReadOnly(UiSection, "create_ephemeral_chat_rooms")) mConfig->setInt(UiSection, "create_ephemeral_chat_rooms", seconds); emit createEphemeralsChatRoomsChanged(); } @@ -1191,22 +1213,22 @@ void SettingsModel::setCreateEphemeralChatRooms(int seconds) { // Network. // ============================================================================= -bool SettingsModel::getShowNetworkSettings () const { +bool SettingsModel::getShowNetworkSettings() const { return !!mConfig->getInt(UiSection, "show_network_settings", 1); } -void SettingsModel::setShowNetworkSettings (bool status) { +void SettingsModel::setShowNetworkSettings(bool status) { mConfig->setInt(UiSection, "show_network_settings", status); emit showNetworkSettingsChanged(status); } // ----------------------------------------------------------------------------- -bool SettingsModel::getUseSipInfoForDtmfs () const { +bool SettingsModel::getUseSipInfoForDtmfs() const { return CoreManager::getInstance()->getCore()->getUseInfoForDtmf(); } -void SettingsModel::setUseSipInfoForDtmfs (bool status) { +void SettingsModel::setUseSipInfoForDtmfs(bool status) { shared_ptr core = CoreManager::getInstance()->getCore(); if (status) { @@ -1222,11 +1244,11 @@ void SettingsModel::setUseSipInfoForDtmfs (bool status) { // ----------------------------------------------------------------------------- -bool SettingsModel::getUseRfc2833ForDtmfs () const { +bool SettingsModel::getUseRfc2833ForDtmfs() const { return CoreManager::getInstance()->getCore()->getUseRfc2833ForDtmf(); } -void SettingsModel::setUseRfc2833ForDtmfs (bool status) { +void SettingsModel::setUseRfc2833ForDtmfs(bool status) { shared_ptr core = CoreManager::getInstance()->getCore(); if (status) { @@ -1242,55 +1264,55 @@ void SettingsModel::setUseRfc2833ForDtmfs (bool status) { // ----------------------------------------------------------------------------- -bool SettingsModel::getIpv6Enabled () const { +bool SettingsModel::getIpv6Enabled() const { return CoreManager::getInstance()->getCore()->ipv6Enabled(); } -void SettingsModel::setIpv6Enabled (bool status) { +void SettingsModel::setIpv6Enabled(bool status) { CoreManager::getInstance()->getCore()->enableIpv6(status); emit ipv6EnabledChanged(status); } // ----------------------------------------------------------------------------- -int SettingsModel::getDownloadBandwidth () const { +int SettingsModel::getDownloadBandwidth() const { return CoreManager::getInstance()->getCore()->getDownloadBandwidth(); } -void SettingsModel::setDownloadBandwidth (int bandwidth) { +void SettingsModel::setDownloadBandwidth(int bandwidth) { CoreManager::getInstance()->getCore()->setDownloadBandwidth(bandwidth); emit downloadBandWidthChanged(getDownloadBandwidth()); } // ----------------------------------------------------------------------------- -int SettingsModel::getUploadBandwidth () const { +int SettingsModel::getUploadBandwidth() const { return CoreManager::getInstance()->getCore()->getUploadBandwidth(); } -void SettingsModel::setUploadBandwidth (int bandwidth) { +void SettingsModel::setUploadBandwidth(int bandwidth) { CoreManager::getInstance()->getCore()->setUploadBandwidth(bandwidth); emit uploadBandWidthChanged(getUploadBandwidth()); } // ----------------------------------------------------------------------------- -bool SettingsModel::getAdaptiveRateControlEnabled () const { +bool SettingsModel::getAdaptiveRateControlEnabled() const { return CoreManager::getInstance()->getCore()->adaptiveRateControlEnabled(); } -void SettingsModel::setAdaptiveRateControlEnabled (bool status) { +void SettingsModel::setAdaptiveRateControlEnabled(bool status) { CoreManager::getInstance()->getCore()->enableAdaptiveRateControl(status); emit adaptiveRateControlEnabledChanged(status); } // ----------------------------------------------------------------------------- -int SettingsModel::getTcpPort () const { +int SettingsModel::getTcpPort() const { return CoreManager::getInstance()->getCore()->getTransports()->getTcpPort(); } -void SettingsModel::setTcpPort (int port) { +void SettingsModel::setTcpPort(int port) { shared_ptr core = CoreManager::getInstance()->getCore(); shared_ptr transports = core->getTransports(); @@ -1302,11 +1324,11 @@ void SettingsModel::setTcpPort (int port) { // ----------------------------------------------------------------------------- -int SettingsModel::getUdpPort () const { +int SettingsModel::getUdpPort() const { return CoreManager::getInstance()->getCore()->getTransports()->getUdpPort(); } -void SettingsModel::setUdpPort (int port) { +void SettingsModel::setUdpPort(int port) { shared_ptr core = CoreManager::getInstance()->getCore(); shared_ptr transports = core->getTransports(); @@ -1318,51 +1340,47 @@ void SettingsModel::setUdpPort (int port) { // ----------------------------------------------------------------------------- -QList SettingsModel::getAudioPortRange () const { +QList SettingsModel::getAudioPortRange() const { shared_ptr range = CoreManager::getInstance()->getCore()->getAudioPortsRange(); return QList() << range->getMin() << range->getMax(); } -void SettingsModel::setAudioPortRange (const QList &range) { +void SettingsModel::setAudioPortRange(const QList &range) { 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); } // ----------------------------------------------------------------------------- -QList SettingsModel::getVideoPortRange () const { +QList SettingsModel::getVideoPortRange() const { shared_ptr range = CoreManager::getInstance()->getCore()->getVideoPortsRange(); return QList() << range->getMin() << range->getMax(); } -void SettingsModel::setVideoPortRange (const QList &range) { +void SettingsModel::setVideoPortRange(const QList &range) { 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); } // ----------------------------------------------------------------------------- -bool SettingsModel::getIceEnabled () const { +bool SettingsModel::getIceEnabled() const { return CoreManager::getInstance()->getCore()->getNatPolicy()->iceEnabled(); } -void SettingsModel::setIceEnabled (bool status) { +void SettingsModel::setIceEnabled(bool status) { shared_ptr natPolicy = CoreManager::getInstance()->getCore()->getNatPolicy(); natPolicy->enableIce(status); @@ -1373,59 +1391,48 @@ void SettingsModel::setIceEnabled (bool status) { // ----------------------------------------------------------------------------- -bool SettingsModel::getTurnEnabled () const { +bool SettingsModel::getTurnEnabled() const { return CoreManager::getInstance()->getCore()->getNatPolicy()->turnEnabled(); } -void SettingsModel::setTurnEnabled (bool status) { +void SettingsModel::setTurnEnabled(bool status) { CoreManager::getInstance()->getCore()->getNatPolicy()->enableTurn(status); emit turnEnabledChanged(status); } // ----------------------------------------------------------------------------- -QString SettingsModel::getStunServer () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServer() - ); +QString SettingsModel::getStunServer() const { + return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServer()); } -void SettingsModel::setStunServer (const QString &stunServer) { - CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServer( - Utils::appStringToCoreString(stunServer) - ); +void SettingsModel::setStunServer(const QString &stunServer) { + CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServer(Utils::appStringToCoreString(stunServer)); } // ----------------------------------------------------------------------------- -QString SettingsModel::getTurnUser () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServerUsername() - ); +QString SettingsModel::getTurnUser() const { + return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServerUsername()); } -void SettingsModel::setTurnUser (const QString &user) { - CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServerUsername( - Utils::appStringToCoreString(user) - ); +void SettingsModel::setTurnUser(const QString &user) { + CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServerUsername(Utils::appStringToCoreString(user)); emit turnUserChanged(user); } // ----------------------------------------------------------------------------- -QString SettingsModel::getTurnPassword () const { +QString SettingsModel::getTurnPassword() const { shared_ptr core(CoreManager::getInstance()->getCore()); shared_ptr natPolicy(core->getNatPolicy()); - shared_ptr authInfo(core->findAuthInfo( - "", - natPolicy->getStunServerUsername(), - natPolicy->getStunServer() - )); + shared_ptr authInfo( + core->findAuthInfo("", natPolicy->getStunServerUsername(), natPolicy->getStunServer())); return authInfo ? Utils::coreStringToAppString(authInfo->getPassword()) : QString(""); } -void SettingsModel::setTurnPassword (const QString &password) { +void SettingsModel::setTurnPassword(const QString &password) { shared_ptr core(CoreManager::getInstance()->getCore()); shared_ptr natPolicy(core->getNatPolicy()); @@ -1438,65 +1445,59 @@ void SettingsModel::setTurnPassword (const QString &password) { core->addAuthInfo(clonedAuthInfo); core->removeAuthInfo(authInfo); } else - core->addAuthInfo(linphone::Factory::get()->createAuthInfo( - turnUser, - turnUser, - Utils::appStringToCoreString(password), - "", - "", - "" - )); + core->addAuthInfo(linphone::Factory::get()->createAuthInfo(turnUser, turnUser, + Utils::appStringToCoreString(password), "", "", "")); emit turnPasswordChanged(password); } // ----------------------------------------------------------------------------- -int SettingsModel::getDscpSip () const { +int SettingsModel::getDscpSip() const { return CoreManager::getInstance()->getCore()->getSipDscp(); } -void SettingsModel::setDscpSip (int dscp) { +void SettingsModel::setDscpSip(int dscp) { CoreManager::getInstance()->getCore()->setSipDscp(dscp); emit dscpSipChanged(dscp); } -int SettingsModel::getDscpAudio () const { +int SettingsModel::getDscpAudio() const { return CoreManager::getInstance()->getCore()->getAudioDscp(); } -void SettingsModel::setDscpAudio (int dscp) { +void SettingsModel::setDscpAudio(int dscp) { CoreManager::getInstance()->getCore()->setAudioDscp(dscp); emit dscpAudioChanged(dscp); } -int SettingsModel::getDscpVideo () const { +int SettingsModel::getDscpVideo() const { return CoreManager::getInstance()->getCore()->getVideoDscp(); } -void SettingsModel::setDscpVideo (int dscp) { +void SettingsModel::setDscpVideo(int dscp) { CoreManager::getInstance()->getCore()->setVideoDscp(dscp); emit dscpVideoChanged(dscp); } // ----------------------------------------------------------------------------- -bool SettingsModel::getRlsUriEnabled () const { +bool SettingsModel::getRlsUriEnabled() const { return !!mConfig->getInt(UiSection, "rls_uri_enabled", true); } -void SettingsModel::setRlsUriEnabled (bool status) { - if(getRlsUriEnabled () != status){ +void SettingsModel::setRlsUriEnabled(bool status) { + if (getRlsUriEnabled() != status) { mConfig->setInt(UiSection, "rls_uri_enabled", status); emit rlsUriEnabledChanged(status); } } -QString SettingsModel::getRlsUri() const{ +QString SettingsModel::getRlsUri() const { return Utils::coreStringToAppString(mConfig->getString("sip", "rls_uri", "")); } -void SettingsModel::setRlsUri (const QString& rlsUri){ +void SettingsModel::setRlsUri(const QString &rlsUri) { bool status = !rlsUri.isEmpty(); mConfig->setInt(UiSection, "rls_uri_enabled", status); mConfig->setString("sip", "rls_uri", Utils::appStringToCoreString(rlsUri)); @@ -1504,19 +1505,20 @@ void SettingsModel::setRlsUri (const QString& rlsUri){ emit rlsUriEnabledChanged(status); } -void SettingsModel::updateRlsUri(){ - if( getRlsUriEnabled() && getRlsUri().isEmpty()){// if enabled, uri should not be empty : set default. This allow to take account of old configuration. +void SettingsModel::updateRlsUri() { + if (getRlsUriEnabled() && getRlsUri().isEmpty()) { // if enabled, uri should not be empty : set default. This allow + // to take account of old configuration. setRlsUri(Constants::DefaultRlsUri); } } //------------------------------------------------------------------------------ -bool SettingsModel::tunnelAvailable() const{ +bool SettingsModel::tunnelAvailable() const { return CoreManager::getInstance()->getCore()->tunnelAvailable(); } -TunnelModel* SettingsModel::getTunnel() const{ +TunnelModel *SettingsModel::getTunnel() const { return new TunnelModel(CoreManager::getInstance()->getCore()->getTunnel()); } @@ -1524,19 +1526,20 @@ TunnelModel* SettingsModel::getTunnel() const{ // UI. // ============================================================================= -QFont SettingsModel::getTextMessageFont() const{ - QString family = Utils::coreStringToAppString(mConfig->getString(UiSection, "text_message_font", Utils::appStringToCoreString(App::getInstance()->font().family()))); +QFont SettingsModel::getTextMessageFont() const { + QString family = Utils::coreStringToAppString(mConfig->getString( + UiSection, "text_message_font", Utils::appStringToCoreString(App::getInstance()->font().family()))); int pointSize = getTextMessageFontSize(); - return QFont(family,pointSize); + return QFont(family, pointSize); } -void SettingsModel::setTextMessageFont(const QFont& font){ +void SettingsModel::setTextMessageFont(const QFont &font) { QString family; int pointSize; - if(font == QFont()){ + if (font == QFont()) { family = Constants::DefaultFont; pointSize = Constants::DefaultFontPointSize; - }else{ + } else { family = font.family(); pointSize = font.pointSize(); } @@ -1545,28 +1548,29 @@ void SettingsModel::setTextMessageFont(const QFont& font){ emit textMessageFontChanged(font); } -int SettingsModel::getTextMessageFontSize() const{ +int SettingsModel::getTextMessageFontSize() const { return mConfig->getInt(UiSection, "text_message_font_size", Constants::DefaultFontPointSize); } -void SettingsModel::setTextMessageFontSize(const int& size){ +void SettingsModel::setTextMessageFontSize(const int &size) { mConfig->setInt(UiSection, "text_message_font_size", size); emit textMessageFontSizeChanged(size); } -QFont SettingsModel::getEmojiFont() const{ - QString family = Utils::coreStringToAppString(mConfig->getString(UiSection, "emoji_font", Utils::appStringToCoreString(QFont(Constants::DefaultEmojiFont).family()))); +QFont SettingsModel::getEmojiFont() const { + QString family = Utils::coreStringToAppString(mConfig->getString( + UiSection, "emoji_font", Utils::appStringToCoreString(QFont(Constants::DefaultEmojiFont).family()))); int pointSize = getEmojiFontSize(); - return QFont(family,pointSize); + return QFont(family, pointSize); } -void SettingsModel::setEmojiFont(const QFont& font){ +void SettingsModel::setEmojiFont(const QFont &font) { QString family; int pointSize; - if(font == QFont()){ + if (font == QFont()) { family = Constants::DefaultEmojiFont; pointSize = Constants::DefaultEmojiFontPointSize; - }else{ + } else { family = font.family(); pointSize = font.pointSize(); } @@ -1575,66 +1579,64 @@ void SettingsModel::setEmojiFont(const QFont& font){ emit emojiFontChanged(font); } -int SettingsModel::getEmojiFontSize() const{ +int SettingsModel::getEmojiFontSize() const { return mConfig->getInt(UiSection, "emoji_font_size", Constants::DefaultEmojiFontPointSize); } -void SettingsModel::setEmojiFontSize(const int& size){ +void SettingsModel::setEmojiFontSize(const int &size) { mConfig->setInt(UiSection, "emoji_font_size", size); emit emojiFontSizeChanged(size); } - -QString SettingsModel::getSavedScreenshotsFolder () const { + +QString SettingsModel::getSavedScreenshotsFolder() const { auto path = mConfig->getString(UiSection, "saved_screenshots_folder", ""); - if(path == "") - path = Paths::getCapturesDirPath(); + if (path == "") path = Paths::getCapturesDirPath(); return QDir::cleanPath(Utils::coreStringToAppString(path)) + QDir::separator(); } -void SettingsModel::setSavedScreenshotsFolder (const QString &folder) { +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 SettingsModel::getSpellCheckerOverrideLocale() const{ +QString SettingsModel::getSpellCheckerOverrideLocale() const { return Utils::coreStringToAppString(mConfig->getString(UiSection, "spell_checker_override_locale", "")); } -void SettingsModel::setSpellCheckerOverrideLocale (const QString &locale) { +void SettingsModel::setSpellCheckerOverrideLocale(const QString &locale) { CoreManager::getInstance()->getCore()->getConfig()->setString( - SettingsModel::UiSection, "spell_checker_override_locale", Utils::appStringToCoreString(locale) - ); - + SettingsModel::UiSection, "spell_checker_override_locale", Utils::appStringToCoreString(locale)); + emit spellCheckerOverrideLocaleChanged(); } -bool SettingsModel::getSpellCheckerEnabled() const{ +bool SettingsModel::getSpellCheckerEnabled() const { return mConfig->getBool(UiSection, "spell_checker_enabled", false); } -void SettingsModel::setSpellCheckerEnabled(bool enable){ +void SettingsModel::setSpellCheckerEnabled(bool enable) { mConfig->setBool(UiSection, "spell_checker_enabled", enable); emit spellCheckerEnabledChanged(); } // ----------------------------------------------------------------------------- -static inline string getLegacySavedCallsFolder (const shared_ptr &config) { +static inline string getLegacySavedCallsFolder(const shared_ptr &config) { auto path = config->getString(SettingsModel::UiSection, "saved_videos_folder", ""); - if(path == "")// Avoid to call default function if exist because calling Path:: will create a folder to be writable. + if (path == + "") // Avoid to call default function if exist because calling Path:: will create a folder to be writable. path = Paths::getCapturesDirPath(); return path; } -QString SettingsModel::getSavedCallsFolder () const { - auto path = mConfig->getString(UiSection, "saved_calls_folder", "");// Avoid to call default function if exist. - if(path == "") - path = getLegacySavedCallsFolder(mConfig); +QString SettingsModel::getSavedCallsFolder() const { + auto path = mConfig->getString(UiSection, "saved_calls_folder", ""); // Avoid to call default function if exist. + if (path == "") path = getLegacySavedCallsFolder(mConfig); return QDir::cleanPath(Utils::coreStringToAppString(path)) + QDir::separator(); } -void SettingsModel::setSavedCallsFolder (const QString &folder) { +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); @@ -1642,14 +1644,15 @@ void SettingsModel::setSavedCallsFolder (const QString &folder) { // ----------------------------------------------------------------------------- -QString SettingsModel::getDownloadFolder () const { - auto path = mConfig->getString(UiSection, "download_folder", "");// Avoid to call default function if exist because calling Path:: will create a folder to be writable. - if(path == "" ) - path = Paths::getDownloadDirPath(); +QString SettingsModel::getDownloadFolder() const { + auto path = mConfig->getString( + UiSection, "download_folder", + ""); // Avoid to call default function if exist because calling Path:: will create a folder to be writable. + if (path == "") path = Paths::getDownloadDirPath(); return QDir::cleanPath(Utils::coreStringToAppString(path)) + QDir::separator(); } -void SettingsModel::setDownloadFolder (const QString &folder) { +void SettingsModel::setDownloadFolder(const QString &folder) { QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); auto lFolder = Utils::appStringToCoreString(cleanedFolder); mConfig->setString(UiSection, "download_folder", lFolder); @@ -1660,141 +1663,143 @@ void SettingsModel::setDownloadFolder (const QString &folder) { // ----------------------------------------------------------------------------- -QString SettingsModel::getRemoteProvisioningRootUrl() const{ - return Utils::coreStringToAppString(mConfig->getString(UiSection, "remote_provisioning_root", Constants::RemoteProvisioningURL)); +QString SettingsModel::getRemoteProvisioningRootUrl() const { + return Utils::coreStringToAppString( + mConfig->getString(UiSection, "remote_provisioning_root", Constants::RemoteProvisioningURL)); } -QString SettingsModel::getRemoteProvisioning () const { +QString SettingsModel::getRemoteProvisioning() const { return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getProvisioningUri()); } -void SettingsModel::setRemoteProvisioning (const QString &remoteProvisioning) { +void SettingsModel::setRemoteProvisioning(const QString &remoteProvisioning) { QString urlRemoteProvisioning = remoteProvisioning; - if( QUrl(urlRemoteProvisioning).isRelative()) { - urlRemoteProvisioning = getRemoteProvisioningRootUrl() +"/"+ remoteProvisioning; + if (QUrl(urlRemoteProvisioning).isRelative()) { + urlRemoteProvisioning = getRemoteProvisioningRootUrl() + "/" + remoteProvisioning; } if (!CoreManager::getInstance()->getCore()->setProvisioningUri(Utils::appStringToCoreString(urlRemoteProvisioning))) emit remoteProvisioningChanged(urlRemoteProvisioning); - else - emit remoteProvisioningNotChanged(urlRemoteProvisioning); + else emit remoteProvisioningNotChanged(urlRemoteProvisioning); } -bool SettingsModel::isQRCodeAvailable() const{ +bool SettingsModel::isQRCodeAvailable() const { return linphone::Factory::get()->isQrcodeAvailable() && !!mConfig->getInt(UiSection, "use_qrcode", 1); } -QString SettingsModel::getFlexiAPIUrl() const{ +QString SettingsModel::getFlexiAPIUrl() const { return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getAccountCreatorUrl()); } -void SettingsModel::setFlexiAPIUrl (const QString &url){ +void SettingsModel::setFlexiAPIUrl(const QString &url) { CoreManager::getInstance()->getCore()->setAccountCreatorUrl(Utils::appStringToCoreString(url)); emit flexiAPIUrlChanged(url); } // ----------------------------------------------------------------------------- -bool SettingsModel::getExitOnClose () const { +bool SettingsModel::getExitOnClose() const { return !!mConfig->getInt(UiSection, "exit_on_close", 0); } -void SettingsModel::setExitOnClose (bool value) { +void SettingsModel::setExitOnClose(bool value) { mConfig->setInt(UiSection, "exit_on_close", value); emit exitOnCloseChanged(value); } -bool SettingsModel::isCheckForUpdateAvailable(){ +bool SettingsModel::isCheckForUpdateAvailable() { #ifdef ENABLE_UPDATE_CHECK return true; #else return false; #endif } -bool SettingsModel::isCheckForUpdateEnabled() const{ +bool SettingsModel::isCheckForUpdateEnabled() const { return !!mConfig->getInt(UiSection, "check_for_update_enabled", isCheckForUpdateAvailable()); } -void SettingsModel::setCheckForUpdateEnabled(bool enable){ +void SettingsModel::setCheckForUpdateEnabled(bool enable) { mConfig->setInt(UiSection, "check_for_update_enabled", enable); emit checkForUpdateEnabledChanged(); } -QString SettingsModel::getVersionCheckUrl(){ +QString SettingsModel::getVersionCheckUrl() { auto url = mConfig->getString("misc", "version_check_url_root", ""); - if( url == "" ){ + if (url == "") { url = Constants::VersionCheckReleaseUrl; - if( url != "") - mConfig->setString("misc", "version_check_url_root", url); + if (url != "") mConfig->setString("misc", "version_check_url_root", url); } return Utils::coreStringToAppString(url); } -void SettingsModel::setVersionCheckUrl(const QString& url){ - if( url != getVersionCheckUrl()){ - // Do not trim the url before because we want to update GUI from potential auto fix. +void SettingsModel::setVersionCheckUrl(const QString &url) { + if (url != getVersionCheckUrl()) { + // Do not trim the url before because we want to update GUI from potential auto fix. mConfig->setString("misc", "version_check_url_root", Utils::appStringToCoreString(url.trimmed())); - if( url == Constants::VersionCheckReleaseUrl) - setVersionCheckType(VersionCheckType_Release); - else if( url == Constants::VersionCheckNightlyUrl) - setVersionCheckType(VersionCheckType_Nightly); - else - setVersionCheckType(VersionCheckType_Custom); + if (url == Constants::VersionCheckReleaseUrl) setVersionCheckType(VersionCheckType_Release); + else if (url == Constants::VersionCheckNightlyUrl) setVersionCheckType(VersionCheckType_Nightly); + else setVersionCheckType(VersionCheckType_Custom); emit versionCheckUrlChanged(); } } -QString SettingsModel::getLastRunningVersionOfApp(){ +QString SettingsModel::getLastRunningVersionOfApp() { auto version = mConfig->getString("app_version", "last_running", "unknown"); return Utils::coreStringToAppString(version); } -void SettingsModel::setLastRunningVersionOfApp(const QString& version){ +void SettingsModel::setLastRunningVersionOfApp(const QString &version) { mConfig->setString("app_version", "last_running", Utils::appStringToCoreString(version)); } -SettingsModel::VersionCheckType SettingsModel::getVersionCheckType() const{ - return (SettingsModel::VersionCheckType) mConfig->getInt(UiSection, "version_check_type", (int)VersionCheckType_Release); +SettingsModel::VersionCheckType SettingsModel::getVersionCheckType() const { + return (SettingsModel::VersionCheckType)mConfig->getInt(UiSection, "version_check_type", + (int)VersionCheckType_Release); } -void SettingsModel::setVersionCheckType(const VersionCheckType& type){ - if( type != getVersionCheckType()){ +void SettingsModel::setVersionCheckType(const VersionCheckType &type) { + if (type != getVersionCheckType()) { mConfig->setInt(UiSection, "version_check_type", (int)type); - switch(type){ - case VersionCheckType_Release : setVersionCheckUrl(Constants::VersionCheckReleaseUrl); break; - case VersionCheckType_Nightly : setVersionCheckUrl(Constants::VersionCheckNightlyUrl);break; - case VersionCheckType_Custom : break;// Do not override URL + switch (type) { + case VersionCheckType_Release: + setVersionCheckUrl(Constants::VersionCheckReleaseUrl); + break; + case VersionCheckType_Nightly: + setVersionCheckUrl(Constants::VersionCheckNightlyUrl); + break; + case VersionCheckType_Custom: + break; // Do not override URL } emit versionCheckTypeChanged(); } } -bool SettingsModel::haveVersionNightlyUrl()const{ +bool SettingsModel::haveVersionNightlyUrl() const { return QString(Constants::VersionCheckNightlyUrl) != ""; } // ----------------------------------------------------------------------------- -bool SettingsModel::getShowLocalSipAccount()const{ +bool SettingsModel::getShowLocalSipAccount() const { return !!mConfig->getInt(UiSection, "show_local_sip_account", 1); } -bool SettingsModel::getShowStartChatButton ()const{ +bool SettingsModel::getShowStartChatButton() const { return !!mConfig->getInt(UiSection, "show_start_chat_button", 1); } -bool SettingsModel::getShowStartVideoCallButton ()const{ +bool SettingsModel::getShowStartVideoCallButton() const { return !!mConfig->getInt(UiSection, "show_start_video_button", 1); } int SettingsModel::getShowDefaultPage() const { - return mConfig->getInt(UiSection, "show_default_page", -1); + return mConfig->getInt(UiSection, "show_default_page", -1); } int SettingsModel::getShowForcedAssistantPage() const { - return mConfig->getInt(UiSection, "show_forced_assistant_page", -1); + return mConfig->getInt(UiSection, "show_forced_assistant_page", -1); } bool SettingsModel::getShowHomePage() const { - return !!mConfig->getInt(UiSection, "show_home_page", true); + return !!mConfig->getInt(UiSection, "show_home_page", true); } bool SettingsModel::getShowHomeInviteButton() const { @@ -1809,30 +1814,31 @@ bool SettingsModel::getMessageCounterRedirectEnabled() const { return !!mConfig->getInt(UiSection, "message_counter_redirect_enabled", false); } -bool SettingsModel::isMipmapEnabled() const{ +bool SettingsModel::isMipmapEnabled() const { return !!mConfig->getInt(UiSection, "mipmap_enabled", 0); } -void SettingsModel::setMipmapEnabled(const bool& enabled){ +void SettingsModel::setMipmapEnabled(const bool &enabled) { mConfig->setInt(UiSection, "mipmap_enabled", enabled); emit mipmapEnabledChanged(); } -bool SettingsModel::useMinimalTimelineFilter() const{ +bool SettingsModel::useMinimalTimelineFilter() const { return !!mConfig->getInt(UiSection, "use_minimal_timeline_filter", 1); } -void SettingsModel::setUseMinimalTimelineFilter(const bool& useMinimal) { +void SettingsModel::setUseMinimalTimelineFilter(const bool &useMinimal) { mConfig->setInt(UiSection, "use_minimal_timeline_filter", useMinimal); emit useMinimalTimelineFilterChanged(); } -Utils::SipDisplayMode SettingsModel::getSipDisplayMode() const{ - return static_cast(mConfig->getInt(UiSection, getEntryFullName(UiSection, "sip_display_mode"), (int)Utils::SipDisplayMode::SIP_DISPLAY_ALL)); +Utils::SipDisplayMode SettingsModel::getSipDisplayMode() const { + return static_cast(mConfig->getInt( + UiSection, getEntryFullName(UiSection, "sip_display_mode"), (int)Utils::SipDisplayMode::SIP_DISPLAY_ALL)); } -void SettingsModel::setSipDisplayMode(Utils::SipDisplayMode mode){ - if(!isReadOnly(UiSection, "sip_display_mode")) { +void SettingsModel::setSipDisplayMode(Utils::SipDisplayMode mode) { + if (!isReadOnly(UiSection, "sip_display_mode")) { mConfig->setInt(UiSection, "sip_display_mode", (int)mode); emit sipDisplayModeChanged(); } @@ -1843,13 +1849,13 @@ int SettingsModel::getMagicSearchMaxResults() const { } void SettingsModel::setMagicSearchMaxResults(int maxResults) { - if(getMagicSearchMaxResults() != maxResults){ + if (getMagicSearchMaxResults() != maxResults) { mConfig->setInt(UiSection, "magic_search_max_results", maxResults); emit magicSearchMaxResultsChanged(); } } -void SettingsModel::resetDontAskAgainChoices(){ +void SettingsModel::resetDontAskAgainChoices() { setDontAskAgainInfoEncryption(false); } @@ -1863,65 +1869,62 @@ void SettingsModel::accessAdvancedSettings() { //------------------------------------------------------------------------------ -QString SettingsModel::getLogText()const{ +QString SettingsModel::getLogText() const { return Logger::getInstance()->getLogText(); } -QString SettingsModel::getLogsFolder () const { +QString SettingsModel::getLogsFolder() const { return getLogsFolder(mConfig); } -void SettingsModel::setLogsFolder (const QString &folder) { -// Copy all logs files in the new folder path to keep trace of old logs +void SettingsModel::setLogsFolder(const QString &folder) { + // Copy all logs files in the new folder path to keep trace of old logs std::string logPath = Utils::appStringToCoreString(folder); QDir oldDirectory(Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getLogCollectionPath())); - QFileInfoList logsFiles = oldDirectory.entryInfoList(QStringList("*.log"));// Get all log files - for(int i = 0 ; i < logsFiles.size() ; ++i){ + QFileInfoList logsFiles = oldDirectory.entryInfoList(QStringList("*.log")); // Get all log files + for (int i = 0; i < logsFiles.size(); ++i) { int count = 0; QString fileName = logsFiles[i].fileName(); - while( QFile::exists(folder+QDir::separator()+fileName))// assure unicity of backup files - fileName = logsFiles[i].baseName()+"_"+QString::number(++count)+"."+logsFiles[i].completeSuffix(); - if(QFile::copy(logsFiles[i].filePath(), folder+QDir::separator()+fileName)) + while (QFile::exists(folder + QDir::separator() + fileName)) // assure unicity of backup files + fileName = logsFiles[i].baseName() + "_" + QString::number(++count) + "." + logsFiles[i].completeSuffix(); + if (QFile::copy(logsFiles[i].filePath(), folder + QDir::separator() + fileName)) QFile::remove(logsFiles[i].filePath()); } - mConfig->setString(UiSection, "logs_folder", logPath); // Update configuration file - CoreManager::getInstance()->getCore()->setLogCollectionPath(logPath); // Update Core to the new path. Liblinphone should update it. + mConfig->setString(UiSection, "logs_folder", logPath); // Update configuration file + CoreManager::getInstance()->getCore()->setLogCollectionPath( + logPath); // Update Core to the new path. Liblinphone should update it. emit logsFolderChanged(folder); } // ----------------------------------------------------------------------------- -QString SettingsModel::getLogsUploadUrl () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getLogCollectionUploadServerUrl() - ); +QString SettingsModel::getLogsUploadUrl() const { + return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getLogCollectionUploadServerUrl()); } -void SettingsModel::setLogsUploadUrl (const QString &url) { - CoreManager::getInstance()->getCore()->setLogCollectionUploadServerUrl( - Utils::appStringToCoreString(url) - ); +void SettingsModel::setLogsUploadUrl(const QString &url) { + CoreManager::getInstance()->getCore()->setLogCollectionUploadServerUrl(Utils::appStringToCoreString(url)); emit logsUploadUrlChanged(getLogsUploadUrl()); } // ----------------------------------------------------------------------------- -bool SettingsModel::getLogsEnabled () const { +bool SettingsModel::getLogsEnabled() const { return getLogsEnabled(mConfig); } -void SettingsModel::setLogsEnabled (bool status) { +void SettingsModel::setLogsEnabled(bool status) { mConfig->setInt(UiSection, "logs_enabled", status); Logger::getInstance()->enable(status); emit logsEnabledChanged(status); } -bool SettingsModel::getFullLogsEnabled () const { +bool SettingsModel::getFullLogsEnabled() const { return getFullLogsEnabled(mConfig); } -void SettingsModel::setFullLogsEnabled (bool status) { +void SettingsModel::setFullLogsEnabled(bool status) { mConfig->setInt(UiSection, "full_logs_enabled", status); Logger::getInstance()->enableFullLogs(status); emit fullLogsEnabledChanged(); @@ -1929,110 +1932,96 @@ void SettingsModel::setFullLogsEnabled (bool status) { // --------------------------------------------------------------------------- -QString SettingsModel::getLogsEmail () const { - return Utils::coreStringToAppString( - mConfig->getString(UiSection, "logs_email", Constants::DefaultLogsEmail) - ); +QString SettingsModel::getLogsEmail() const { + return Utils::coreStringToAppString(mConfig->getString(UiSection, "logs_email", Constants::DefaultLogsEmail)); } -void SettingsModel::setLogsEmail (const QString &email) { +void SettingsModel::setLogsEmail(const QString &email) { mConfig->setString(UiSection, "logs_email", Utils::appStringToCoreString(email)); emit logsEmailChanged(email); } -bool SettingsModel::isLdapAvailable(){ +bool SettingsModel::isLdapAvailable() { return CoreManager::getInstance()->getCore()->ldapAvailable(); } -bool SettingsModel::isOAuth2Available(){ +bool SettingsModel::isOAuth2Available() { return AssistantModel::isOAuth2Available(); } -QString SettingsModel::getOAuth2AuthorizationUrl()const{ +QString SettingsModel::getOAuth2AuthorizationUrl() const { return Utils::coreStringToAppString( - mConfig->getString(UiSection, "oauth2_authorization_url", Constants::OAuth2AuthorizationUrl) - ); + mConfig->getString(UiSection, "oauth2_authorization_url", Constants::OAuth2AuthorizationUrl)); } -QString SettingsModel::getOAuth2AccessTokenUrl()const{ +QString SettingsModel::getOAuth2AccessTokenUrl() const { return Utils::coreStringToAppString( - mConfig->getString(UiSection, "oauth2_access_token_url", Constants::OAuth2AccessTokenUrl) - ); + mConfig->getString(UiSection, "oauth2_access_token_url", Constants::OAuth2AccessTokenUrl)); } -QString SettingsModel::getOAuth2RedirectUri()const{ +QString SettingsModel::getOAuth2RedirectUri() const { return Utils::coreStringToAppString( - mConfig->getString(UiSection, "oauth2_redirect_uri", Constants::OAuth2RedirectUri) - ); + mConfig->getString(UiSection, "oauth2_redirect_uri", Constants::OAuth2RedirectUri)); } -QString SettingsModel::getOAuth2Identifier()const{ +QString SettingsModel::getOAuth2Identifier() const { return Utils::coreStringToAppString( - mConfig->getString(UiSection, "oauth2_identifier", Constants::OAuth2Identifier) - ); + mConfig->getString(UiSection, "oauth2_identifier", Constants::OAuth2Identifier)); } -QString SettingsModel::getOAuth2Password()const{ - return Utils::coreStringToAppString( - mConfig->getString(UiSection, "oauth2_password", Constants::OAuth2Password) - ); +QString SettingsModel::getOAuth2Password() const { + return Utils::coreStringToAppString(mConfig->getString(UiSection, "oauth2_password", Constants::OAuth2Password)); } -QString SettingsModel::getOAuth2Scope()const{ - return Utils::coreStringToAppString( - mConfig->getString(UiSection, "oauth2_scope", Constants::OAuth2Scope) - ); +QString SettingsModel::getOAuth2Scope() const { + return Utils::coreStringToAppString(mConfig->getString(UiSection, "oauth2_scope", Constants::OAuth2Scope)); } -QString SettingsModel::getOAuth2RemoteProvisioningBasicAuth()const{ +QString SettingsModel::getOAuth2RemoteProvisioningBasicAuth() const { return Utils::coreStringToAppString( - mConfig->getString(UiSection, "oauth2_remote_provisioning_basic_auth", Constants::RemoteProvisioningBasicAuth) - ); + mConfig->getString(UiSection, "oauth2_remote_provisioning_basic_auth", Constants::RemoteProvisioningBasicAuth)); } -QString SettingsModel::getOAuth2RemoteProvisioningHeader()const{ - return Utils::coreStringToAppString( - mConfig->getString(UiSection, "oauth2_remote_provisioning_header", Constants::DefaultOAuth2RemoteProvisioningHeader) - ); +QString SettingsModel::getOAuth2RemoteProvisioningHeader() const { + return Utils::coreStringToAppString(mConfig->getString(UiSection, "oauth2_remote_provisioning_header", + Constants::DefaultOAuth2RemoteProvisioningHeader)); } // --------------------------------------------------------------------------- -QString SettingsModel::getLogsFolder (const shared_ptr &config) { - return Utils::coreStringToAppString(config - ? config->getString(UiSection, "logs_folder", Paths::getLogsDirPath()) - : Paths::getLogsDirPath()); +QString SettingsModel::getLogsFolder(const shared_ptr &config) { + return Utils::coreStringToAppString(config ? config->getString(UiSection, "logs_folder", Paths::getLogsDirPath()) + : Paths::getLogsDirPath()); } -size_t SettingsModel::getMaxLogsCollectionSize (const shared_ptr &config) { - return config - ? config->getInt(UiSection, "logs_max_size", Constants::MaxLogsCollectionSize) - : Constants::MaxLogsCollectionSize; +size_t SettingsModel::getMaxLogsCollectionSize(const shared_ptr &config) { + return config ? config->getInt(UiSection, "logs_max_size", Constants::MaxLogsCollectionSize) + : Constants::MaxLogsCollectionSize; } -bool SettingsModel::getLogsEnabled (const shared_ptr &config) { +bool SettingsModel::getLogsEnabled(const shared_ptr &config) { return config ? config->getInt(UiSection, "logs_enabled", false) : true; } -bool SettingsModel::getFullLogsEnabled (const shared_ptr &config) { +bool SettingsModel::getFullLogsEnabled(const shared_ptr &config) { return config ? config->getInt(UiSection, "full_logs_enabled", false) : false; } // --------------------------------------------------------------------------- -bool SettingsModel::getVfsEncrypted (){ +bool SettingsModel::getVfsEncrypted() { QSettings settings; settings.beginGroup("keychain"); return settings.value("enabled", false).toBool(); } -void SettingsModel::setVfsEncrypted (bool encrypted, const bool deleteUserData){ +void SettingsModel::setVfsEncrypted(bool encrypted, const bool deleteUserData) { #ifdef ENABLE_QT_KEYCHAIN - if(getVfsEncrypted() != encrypted){ - if(encrypted) { + if (getVfsEncrypted() != encrypted) { + if (encrypted) { mVfsUtils.newEncryptionKeyAsync(); shared_ptr factory = linphone::Factory::get(); factory->setDownloadDir(Utils::appStringToCoreString(getDownloadFolder())); - }else{// Remove key, stop core, delete data and initiate reboot + } else { // Remove key, stop core, delete data and initiate reboot mVfsUtils.needToDeleteUserData(deleteUserData); mVfsUtils.deleteKey(mVfsUtils.getApplicationVfsEncryptionKey()); } @@ -2049,7 +2038,7 @@ bool SettingsModel::isDeveloperSettingsAvailable() const { return false; #endif } -bool SettingsModel::getDeveloperSettingsEnabled () const { +bool SettingsModel::getDeveloperSettingsEnabled() const { #ifdef DEBUG return !!mConfig->getInt(UiSection, "developer_settings", 0); #else @@ -2057,45 +2046,43 @@ bool SettingsModel::getDeveloperSettingsEnabled () const { #endif // ifdef DEBUG } -void SettingsModel::setDeveloperSettingsEnabled (bool status) { +void SettingsModel::setDeveloperSettingsEnabled(bool status) { #ifdef DEBUG mConfig->setInt(UiSection, "developer_settings", status); emit developerSettingsEnabledChanged(status); #else - Q_UNUSED(status) + Q_UNUSED(status) qWarning() << QStringLiteral("Unable to change developer settings mode in release version."); #endif // ifdef DEBUG } void SettingsModel::handleCallCreated(const shared_ptr &) { bool isInCall = getIsInCall(); - if (isInCall) stopCaptureGraphs(); // Ensure to stop all graphs - else if (mCurrentSettingsTab == 1) startCaptureGraph(); + if(isInCall) stopCaptureGraphs(); // Ensure to stop all graphs emit isInCallChanged(isInCall); } void SettingsModel::handleCallStateChanged(const shared_ptr &, linphone::Call::State) { bool isInCall = getIsInCall(); - if (isInCall) stopCaptureGraphs(); // Ensure to stop all graphs - else if (mCurrentSettingsTab == 1) startCaptureGraph(); + if(isInCall) stopCaptureGraphs(); // Ensure to stop all graphs emit isInCallChanged(isInCall); } - -void SettingsModel::handleEcCalibrationResult(linphone::EcCalibratorStatus status, int delayMs){ +void SettingsModel::handleEcCalibrationResult(linphone::EcCalibratorStatus status, int delayMs) { emit echoCancellationStatus((int)status, delayMs); } bool SettingsModel::getIsInCall() const { return CoreManager::getInstance()->getCore()->getCallsNb() != 0; } -bool SettingsModel::isReadOnly(const std::string& section, const std::string& name) const { - return mConfig->hasEntry(section, name+"/readonly"); +bool SettingsModel::isReadOnly(const std::string §ion, const std::string &name) const { + return mConfig->hasEntry(section, name + "/readonly"); } -std::string SettingsModel::getEntryFullName(const std::string& section, const std::string& name) const { - return isReadOnly(section, name)?name+"/readonly" : name; +std::string SettingsModel::getEntryFullName(const std::string §ion, const std::string &name) const { + return isReadOnly(section, name) ? name + "/readonly" : name; } -void SettingsModel::onDefaultAccountChanged(){ - mConfig->setInt("misc", "hide_chat_rooms_from_removed_proxies", CoreManager::getInstance()->getCore()->getDefaultAccount() != nullptr); +void SettingsModel::onDefaultAccountChanged() { + mConfig->setInt("misc", "hide_chat_rooms_from_removed_proxies", + CoreManager::getInstance()->getCore()->getDefaultAccount() != nullptr); } diff --git a/linphone-app/src/components/settings/SettingsModel.hpp b/linphone-app/src/components/settings/SettingsModel.hpp index 115378273..74373f6f8 100644 --- a/linphone-app/src/components/settings/SettingsModel.hpp +++ b/linphone-app/src/components/settings/SettingsModel.hpp @@ -21,14 +21,14 @@ #ifndef SETTINGS_MODEL_H_ #define SETTINGS_MODEL_H_ -#include -#include +#include #include #include -#include +#include +#include -#include "components/core/CoreHandlers.hpp" #include "components/contacts/ContactsImporterModel.hpp" +#include "components/core/CoreHandlers.hpp" #include "utils/LinphoneEnums.hpp" #include "utils/Utils.hpp" @@ -41,217 +41,264 @@ class TunnelModel; class SettingsModel : public QObject { Q_OBJECT - + // =========================================================================== // PROPERTIES. // =========================================================================== - + // 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 autoApplyProvisioningConfigUriHandlerEnabled READ getAutoApplyProvisioningConfigUriHandlerEnabled WRITE setAutoApplyProvisioningConfigUriHandlerEnabled NOTIFY autoApplyProvisioningConfigUriHandlerEnabledChanged) - - Q_PROPERTY(bool assistantSupportsPhoneNumbers READ getAssistantSupportsPhoneNumbers WRITE setAssistantSupportsPhoneNumbers NOTIFY assistantSupportsPhoneNumbersChanged) - Q_PROPERTY(int assistantDefaultTransport READ getAssistantDefaultTransport WRITE setAssistantDefaultTransport NOTIFY assistantDefaultTransportChanged) - -// Webviews config - Q_PROPERTY(QString assistantRegistrationUrl READ getAssistantRegistrationUrl WRITE setAssistantRegistrationUrl NOTIFY assistantRegistrationUrlChanged) - Q_PROPERTY(QString assistantLoginUrl READ getAssistantLoginUrl WRITE setAssistantLoginUrl NOTIFY assistantLoginUrlChanged) - Q_PROPERTY(QString assistantLogoutUrl READ getAssistantLogoutUrl WRITE setAssistantLogoutUrl NOTIFY assistantLogoutUrlChanged) -//---- + 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 autoApplyProvisioningConfigUriHandlerEnabled READ getAutoApplyProvisioningConfigUriHandlerEnabled WRITE + setAutoApplyProvisioningConfigUriHandlerEnabled NOTIFY autoApplyProvisioningConfigUriHandlerEnabledChanged) + + Q_PROPERTY(bool assistantSupportsPhoneNumbers READ getAssistantSupportsPhoneNumbers WRITE + setAssistantSupportsPhoneNumbers NOTIFY assistantSupportsPhoneNumbersChanged) + Q_PROPERTY(int assistantDefaultTransport READ getAssistantDefaultTransport WRITE setAssistantDefaultTransport NOTIFY + assistantDefaultTransportChanged) + // Webviews config + Q_PROPERTY(QString assistantRegistrationUrl READ getAssistantRegistrationUrl WRITE setAssistantRegistrationUrl + NOTIFY assistantRegistrationUrlChanged) + Q_PROPERTY( + QString assistantLoginUrl READ getAssistantLoginUrl WRITE setAssistantLoginUrl NOTIFY assistantLoginUrlChanged) + Q_PROPERTY(QString assistantLogoutUrl READ getAssistantLogoutUrl WRITE setAssistantLogoutUrl NOTIFY + assistantLogoutUrlChanged) + //---- Q_PROPERTY(bool cguAccepted READ isCguAccepted WRITE acceptCgu NOTIFY cguAcceptedChanged) - + // SIP Accounts. ------------------------------------------------------------- - + Q_PROPERTY(QString deviceName READ getDeviceName WRITE setDeviceName NOTIFY deviceNameChanged) // Audio. -------------------------------------------------------------------- - + Q_PROPERTY(bool captureGraphRunning READ getCaptureGraphRunning NOTIFY captureGraphRunningChanged) - + Q_PROPERTY(QStringList captureDevices READ getCaptureDevices NOTIFY captureDevicesChanged) Q_PROPERTY(QStringList playbackDevices READ getPlaybackDevices NOTIFY playbackDevicesChanged) - + Q_PROPERTY(float playbackGain READ getPlaybackGain WRITE setPlaybackGain NOTIFY playbackGainChanged) Q_PROPERTY(float captureGain READ getCaptureGain WRITE setCaptureGain NOTIFY captureGainChanged) - + 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(QString ringPath READ getRingPath WRITE setRingPath NOTIFY ringPathChanged) - - Q_PROPERTY(bool echoCancellationEnabled READ getEchoCancellationEnabled WRITE setEchoCancellationEnabled NOTIFY echoCancellationEnabledChanged) - + + Q_PROPERTY(bool echoCancellationEnabled READ getEchoCancellationEnabled WRITE setEchoCancellationEnabled NOTIFY + echoCancellationEnabledChanged) + Q_PROPERTY(bool showAudioCodecs READ getShowAudioCodecs WRITE setShowAudioCodecs NOTIFY showAudioCodecsChanged) - + // Video. -------------------------------------------------------------------- - + Q_PROPERTY(QStringList videoDevices READ getVideoDevices NOTIFY videoDevicesChanged) - + Q_PROPERTY(QString videoDevice READ getVideoDevice WRITE setVideoDevice NOTIFY videoDeviceChanged) - + Q_PROPERTY( + int captureScreenIndex READ getCaptureScreenIndex WRITE saveCaptureScreenIndex NOTIFY captureScreenIndexChanged) + Q_PROPERTY(QString videoPreset READ getVideoPreset WRITE setVideoPreset NOTIFY videoPresetChanged) Q_PROPERTY(int videoFramerate READ getVideoFramerate WRITE setVideoFramerate NOTIFY videoFramerateChanged) - + Q_PROPERTY(QVariantList supportedVideoDefinitions READ getSupportedVideoDefinitions CONSTANT) - - Q_PROPERTY(QVariantMap videoDefinition READ getVideoDefinition WRITE setVideoDefinition NOTIFY videoDefinitionChanged) - + + Q_PROPERTY( + QVariantMap videoDefinition READ getVideoDefinition WRITE setVideoDefinition NOTIFY videoDefinitionChanged) + Q_PROPERTY(bool videoEnabled READ getVideoEnabled WRITE setVideoEnabled NOTIFY videoEnabledChanged) Q_PROPERTY(bool videoAvailable READ getVideoAvailable NOTIFY videoAvailableChanged) - + Q_PROPERTY(bool showVideoCodecs READ getShowVideoCodecs WRITE setShowVideoCodecs NOTIFY showVideoCodecsChanged) - + Q_PROPERTY(CameraMode gridCameraMode READ getGridCameraMode WRITE setGridCameraMode NOTIFY gridCameraModeChanged) - Q_PROPERTY(CameraMode activeSpeakerCameraMode READ getActiveSpeakerCameraMode WRITE setActiveSpeakerCameraMode NOTIFY activeSpeakerCameraModeChanged) + Q_PROPERTY(CameraMode activeSpeakerCameraMode READ getActiveSpeakerCameraMode WRITE setActiveSpeakerCameraMode + NOTIFY activeSpeakerCameraModeChanged) Q_PROPERTY(CameraMode callCameraMode READ getCallCameraMode WRITE setCallCameraMode NOTIFY callCameraModeChanged) - Q_PROPERTY(LinphoneEnums::ConferenceLayout videoConferenceLayout READ getVideoConferenceLayout WRITE setVideoConferenceLayout NOTIFY videoConferenceLayoutChanged) - - + Q_PROPERTY(LinphoneEnums::ConferenceLayout videoConferenceLayout READ getVideoConferenceLayout WRITE + setVideoConferenceLayout NOTIFY videoConferenceLayoutChanged) + Q_PROPERTY(int conferenceMaxThumbnails READ getConferenceMaxThumbnails WRITE setConferenceMaxThumbnails NOTIFY + conferenceMaxThumbnailsChanged) + // Chat & calls. ------------------------------------------------------------- - + Q_PROPERTY(bool autoAnswerStatus READ getAutoAnswerStatus WRITE setAutoAnswerStatus NOTIFY autoAnswerStatusChanged) - Q_PROPERTY(bool autoAnswerVideoStatus READ getAutoAnswerVideoStatus WRITE setAutoAnswerVideoStatus NOTIFY autoAnswerVideoStatusChanged) + Q_PROPERTY(bool autoAnswerVideoStatus READ getAutoAnswerVideoStatus WRITE setAutoAnswerVideoStatus NOTIFY + autoAnswerVideoStatusChanged) Q_PROPERTY(int autoAnswerDelay READ getAutoAnswerDelay WRITE setAutoAnswerDelay NOTIFY autoAnswerDelayChanged) - - Q_PROPERTY(bool showTelKeypadAutomatically READ getShowTelKeypadAutomatically WRITE setShowTelKeypadAutomatically NOTIFY showTelKeypadAutomaticallyChanged) - - Q_PROPERTY(bool keepCallsWindowInBackground READ getKeepCallsWindowInBackground WRITE setKeepCallsWindowInBackground NOTIFY keepCallsWindowInBackgroundChanged) - - Q_PROPERTY(bool outgoingCallsEnabled READ getOutgoingCallsEnabled WRITE setOutgoingCallsEnabled NOTIFY outgoingCallsEnabledChanged) - - Q_PROPERTY(bool callRecorderEnabled READ getCallRecorderEnabled WRITE setCallRecorderEnabled NOTIFY callRecorderEnabledChanged) - Q_PROPERTY(bool automaticallyRecordCalls READ getAutomaticallyRecordCalls WRITE setAutomaticallyRecordCalls NOTIFY automaticallyRecordCallsChanged) - Q_PROPERTY(int autoDownloadMaxSize READ getAutoDownloadMaxSize WRITE setAutoDownloadMaxSize NOTIFY autoDownloadMaxSizeChanged) - + + Q_PROPERTY(bool showTelKeypadAutomatically READ getShowTelKeypadAutomatically WRITE setShowTelKeypadAutomatically + NOTIFY showTelKeypadAutomaticallyChanged) + + Q_PROPERTY(bool keepCallsWindowInBackground READ getKeepCallsWindowInBackground WRITE setKeepCallsWindowInBackground + NOTIFY keepCallsWindowInBackgroundChanged) + + Q_PROPERTY(bool outgoingCallsEnabled READ getOutgoingCallsEnabled WRITE setOutgoingCallsEnabled NOTIFY + outgoingCallsEnabledChanged) + + Q_PROPERTY(bool callRecorderEnabled READ getCallRecorderEnabled WRITE setCallRecorderEnabled NOTIFY + callRecorderEnabledChanged) + Q_PROPERTY(bool automaticallyRecordCalls READ getAutomaticallyRecordCalls WRITE setAutomaticallyRecordCalls NOTIFY + automaticallyRecordCallsChanged) + Q_PROPERTY(int autoDownloadMaxSize READ getAutoDownloadMaxSize WRITE setAutoDownloadMaxSize NOTIFY + autoDownloadMaxSizeChanged) + Q_PROPERTY(bool callPauseEnabled READ getCallPauseEnabled WRITE setCallPauseEnabled NOTIFY callPauseEnabledChanged) - Q_PROPERTY(bool muteMicrophoneEnabled READ getMuteMicrophoneEnabled WRITE setMuteMicrophoneEnabled NOTIFY muteMicrophoneEnabledChanged) - - Q_PROPERTY(bool standardChatEnabled READ getStandardChatEnabled WRITE setStandardChatEnabled NOTIFY standardChatEnabledChanged) - Q_PROPERTY(bool secureChatEnabled READ getSecureChatEnabled WRITE setSecureChatEnabled NOTIFY secureChatEnabledChanged) + Q_PROPERTY(bool muteMicrophoneEnabled READ getMuteMicrophoneEnabled WRITE setMuteMicrophoneEnabled NOTIFY + muteMicrophoneEnabledChanged) + + Q_PROPERTY(bool standardChatEnabled READ getStandardChatEnabled WRITE setStandardChatEnabled NOTIFY + standardChatEnabledChanged) + Q_PROPERTY( + bool secureChatEnabled READ getSecureChatEnabled WRITE setSecureChatEnabled NOTIFY secureChatEnabledChanged) Q_PROPERTY(bool groupChatEnabled READ getGroupChatEnabled NOTIFY groupChatEnabledChanged) - Q_PROPERTY(bool hideEmptyChatRooms READ getHideEmptyChatRooms WRITE setHideEmptyChatRooms NOTIFY hideEmptyChatRoomsChanged) - - - Q_PROPERTY(bool waitRegistrationForCall READ getWaitRegistrationForCall WRITE setWaitRegistrationForCall NOTIFY waitRegistrationForCallChanged)// Allow call only if the current proxy has been registered - Q_PROPERTY(bool incallScreenshotEnabled READ getIncallScreenshotEnabled WRITE setIncallScreenshotEnabled NOTIFY incallScreenshotEnabledChanged) - - Q_PROPERTY(bool conferenceEnabled READ getConferenceEnabled WRITE setConferenceEnabled NOTIFY conferenceEnabledChanged) + Q_PROPERTY( + bool hideEmptyChatRooms READ getHideEmptyChatRooms WRITE setHideEmptyChatRooms NOTIFY hideEmptyChatRoomsChanged) + + Q_PROPERTY(bool waitRegistrationForCall READ getWaitRegistrationForCall WRITE setWaitRegistrationForCall NOTIFY + waitRegistrationForCallChanged) // Allow call only if the current proxy has been registered + Q_PROPERTY(bool incallScreenshotEnabled READ getIncallScreenshotEnabled WRITE setIncallScreenshotEnabled NOTIFY + incallScreenshotEnabledChanged) + + Q_PROPERTY( + bool conferenceEnabled READ getConferenceEnabled WRITE setConferenceEnabled NOTIFY conferenceEnabledChanged) Q_PROPERTY(bool videoConferenceEnabled READ getVideoConferenceEnabled NOTIFY videoConferenceEnabledChanged) - - Q_PROPERTY(bool chatNotificationsEnabled READ getChatNotificationsEnabled WRITE setChatNotificationsEnabled NOTIFY chatNotificationsEnabledChanged) - Q_PROPERTY(bool chatNotificationSoundEnabled READ getChatNotificationSoundEnabled WRITE setChatNotificationSoundEnabled NOTIFY chatNotificationSoundEnabledChanged) - Q_PROPERTY(QString chatNotificationSoundPath READ getChatNotificationSoundPath WRITE setChatNotificationSoundPath NOTIFY chatNotificationSoundPathChanged) - + + Q_PROPERTY(bool chatNotificationsEnabled READ getChatNotificationsEnabled WRITE setChatNotificationsEnabled NOTIFY + chatNotificationsEnabledChanged) + Q_PROPERTY(bool chatNotificationSoundEnabled READ getChatNotificationSoundEnabled WRITE + setChatNotificationSoundEnabled NOTIFY chatNotificationSoundEnabledChanged) + Q_PROPERTY(QString chatNotificationSoundPath READ getChatNotificationSoundPath WRITE setChatNotificationSoundPath + NOTIFY chatNotificationSoundPathChanged) + Q_PROPERTY(QString fileTransferUrl READ getFileTransferUrl WRITE setFileTransferUrl NOTIFY fileTransferUrlChanged) - + Q_PROPERTY(bool limeIsSupported READ getLimeIsSupported CONSTANT) Q_PROPERTY(QVariantList supportedMediaEncryptions READ getSupportedMediaEncryptions CONSTANT) - - Q_PROPERTY(MediaEncryption mediaEncryption READ getMediaEncryption WRITE setMediaEncryption NOTIFY mediaEncryptionChanged) - Q_PROPERTY(bool mediaEncryptionMandatory READ mandatoryMediaEncryptionEnabled WRITE enableMandatoryMediaEncryption NOTIFY mediaEncryptionChanged) - Q_PROPERTY(bool isPostQuantumAvailable READ getPostQuantumAvailable CONSTANT) - - Q_PROPERTY(bool limeState READ getLimeState WRITE setLimeState NOTIFY limeStateChanged) - - Q_PROPERTY(bool contactsEnabled READ getContactsEnabled WRITE setContactsEnabled NOTIFY contactsEnabledChanged) - - // Network. ------------------------------------------------------------------ - - Q_PROPERTY(bool showNetworkSettings READ getShowNetworkSettings WRITE setShowNetworkSettings NOTIFY showNetworkSettingsChanged) - - Q_PROPERTY(bool useSipInfoForDtmfs READ getUseSipInfoForDtmfs WRITE setUseSipInfoForDtmfs NOTIFY dtmfsProtocolChanged) - Q_PROPERTY(bool useRfc2833ForDtmfs READ getUseRfc2833ForDtmfs WRITE setUseRfc2833ForDtmfs NOTIFY dtmfsProtocolChanged) - - Q_PROPERTY(bool ipv6Enabled READ getIpv6Enabled WRITE setIpv6Enabled NOTIFY ipv6EnabledChanged) - - Q_PROPERTY(int downloadBandwidth READ getDownloadBandwidth WRITE setDownloadBandwidth NOTIFY downloadBandWidthChanged) - Q_PROPERTY(int uploadBandwidth READ getUploadBandwidth WRITE setUploadBandwidth NOTIFY uploadBandWidthChanged) - + Q_PROPERTY( - bool adaptiveRateControlEnabled - READ getAdaptiveRateControlEnabled - WRITE setAdaptiveRateControlEnabled - NOTIFY adaptiveRateControlEnabledChanged - ) - + MediaEncryption mediaEncryption READ getMediaEncryption WRITE setMediaEncryption NOTIFY mediaEncryptionChanged) + Q_PROPERTY(bool mediaEncryptionMandatory READ mandatoryMediaEncryptionEnabled WRITE enableMandatoryMediaEncryption + NOTIFY mediaEncryptionChanged) + Q_PROPERTY(bool isPostQuantumAvailable READ getPostQuantumAvailable CONSTANT) + + Q_PROPERTY(bool limeState READ getLimeState WRITE setLimeState NOTIFY limeStateChanged) + + Q_PROPERTY(bool contactsEnabled READ getContactsEnabled WRITE setContactsEnabled NOTIFY contactsEnabledChanged) + + // Network. ------------------------------------------------------------------ + + Q_PROPERTY(bool showNetworkSettings READ getShowNetworkSettings WRITE setShowNetworkSettings NOTIFY + showNetworkSettingsChanged) + + Q_PROPERTY( + bool useSipInfoForDtmfs READ getUseSipInfoForDtmfs WRITE setUseSipInfoForDtmfs NOTIFY dtmfsProtocolChanged) + Q_PROPERTY( + bool useRfc2833ForDtmfs READ getUseRfc2833ForDtmfs WRITE setUseRfc2833ForDtmfs NOTIFY dtmfsProtocolChanged) + + Q_PROPERTY(bool ipv6Enabled READ getIpv6Enabled WRITE setIpv6Enabled NOTIFY ipv6EnabledChanged) + + Q_PROPERTY( + int downloadBandwidth READ getDownloadBandwidth WRITE setDownloadBandwidth NOTIFY downloadBandWidthChanged) + Q_PROPERTY(int uploadBandwidth READ getUploadBandwidth WRITE setUploadBandwidth NOTIFY uploadBandWidthChanged) + + Q_PROPERTY(bool adaptiveRateControlEnabled READ getAdaptiveRateControlEnabled WRITE setAdaptiveRateControlEnabled + NOTIFY adaptiveRateControlEnabledChanged) + Q_PROPERTY(int tcpPort READ getTcpPort WRITE setTcpPort NOTIFY tcpPortChanged) Q_PROPERTY(int udpPort READ getUdpPort WRITE setUdpPort NOTIFY udpPortChanged) - + Q_PROPERTY(QList audioPortRange READ getAudioPortRange WRITE setAudioPortRange NOTIFY audioPortRangeChanged) Q_PROPERTY(QList videoPortRange READ getVideoPortRange WRITE setVideoPortRange NOTIFY videoPortRangeChanged) - + Q_PROPERTY(bool iceEnabled READ getIceEnabled WRITE setIceEnabled NOTIFY iceEnabledChanged) Q_PROPERTY(bool turnEnabled READ getTurnEnabled WRITE setTurnEnabled NOTIFY turnEnabledChanged) - + Q_PROPERTY(QString stunServer READ getStunServer WRITE setStunServer NOTIFY stunServerChanged) - + Q_PROPERTY(QString turnUser READ getTurnUser WRITE setTurnUser NOTIFY turnUserChanged) Q_PROPERTY(QString turnPassword READ getTurnPassword WRITE setTurnPassword NOTIFY turnPasswordChanged) - + 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 rlsUriEnabled READ getRlsUriEnabled WRITE setRlsUriEnabled NOTIFY rlsUriEnabledChanged) Q_PROPERTY(QString rlsUri READ getRlsUri WRITE setRlsUri NOTIFY rlsUriChanged) - + // UI. ----------------------------------------------------------------------- - - Q_PROPERTY(QString spellCheckerOverrideLocale READ getSpellCheckerOverrideLocale WRITE setSpellCheckerOverrideLocale NOTIFY spellCheckerOverrideLocaleChanged) - Q_PROPERTY(bool spellCheckerEnabled READ getSpellCheckerEnabled WRITE setSpellCheckerEnabled NOTIFY spellCheckerEnabledChanged) - + + Q_PROPERTY(QString spellCheckerOverrideLocale READ getSpellCheckerOverrideLocale WRITE setSpellCheckerOverrideLocale + NOTIFY spellCheckerOverrideLocaleChanged) + Q_PROPERTY(bool spellCheckerEnabled READ getSpellCheckerEnabled WRITE setSpellCheckerEnabled NOTIFY + spellCheckerEnabledChanged) + Q_PROPERTY(QFont textMessageFont READ getTextMessageFont WRITE setTextMessageFont NOTIFY textMessageFontChanged) - Q_PROPERTY(int textMessageFontSize READ getTextMessageFontSize WRITE setTextMessageFontSize NOTIFY textMessageFontSizeChanged) + Q_PROPERTY(int textMessageFontSize READ getTextMessageFontSize WRITE setTextMessageFontSize NOTIFY + textMessageFontSizeChanged) Q_PROPERTY(QFont emojiFont READ getEmojiFont WRITE setEmojiFont NOTIFY emojiFontChanged) Q_PROPERTY(int emojiFontSize READ getEmojiFontSize WRITE setEmojiFontSize NOTIFY emojiFontSizeChanged) - - Q_PROPERTY(QString remoteProvisioning READ getRemoteProvisioning WRITE setRemoteProvisioning NOTIFY remoteProvisioningChanged) + + Q_PROPERTY(QString remoteProvisioning READ getRemoteProvisioning WRITE setRemoteProvisioning NOTIFY + remoteProvisioningChanged) Q_PROPERTY(QString flexiAPIUrl READ getFlexiAPIUrl WRITE setFlexiAPIUrl NOTIFY flexiAPIUrlChanged) - - Q_PROPERTY(QString savedScreenshotsFolder READ getSavedScreenshotsFolder WRITE setSavedScreenshotsFolder NOTIFY savedScreenshotsFolderChanged) - Q_PROPERTY(QString savedCallsFolder READ getSavedCallsFolder WRITE setSavedCallsFolder NOTIFY savedCallsFolderChanged) + + 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 exitOnClose READ getExitOnClose WRITE setExitOnClose NOTIFY exitOnCloseChanged) - Q_PROPERTY(bool checkForUpdateEnabled READ isCheckForUpdateEnabled WRITE setCheckForUpdateEnabled NOTIFY checkForUpdateEnabledChanged) + Q_PROPERTY(bool checkForUpdateEnabled READ isCheckForUpdateEnabled WRITE setCheckForUpdateEnabled NOTIFY + checkForUpdateEnabledChanged) Q_PROPERTY(QString versionCheckUrl READ getVersionCheckUrl WRITE setVersionCheckUrl NOTIFY versionCheckUrlChanged) - Q_PROPERTY(VersionCheckType versionCheckType READ getVersionCheckType WRITE setVersionCheckType NOTIFY versionCheckTypeChanged) - + Q_PROPERTY(VersionCheckType versionCheckType READ getVersionCheckType WRITE setVersionCheckType NOTIFY + versionCheckTypeChanged) + Q_PROPERTY(bool showLocalSipAccount READ getShowLocalSipAccount CONSTANT) Q_PROPERTY(bool showStartChatButton READ getShowStartChatButton CONSTANT) Q_PROPERTY(bool showStartVideoCallButton READ getShowStartVideoCallButton CONSTANT) Q_PROPERTY(bool showHomeInviteButton READ getShowHomeInviteButton CONSTANT) Q_PROPERTY(QString defaultOtherSipAccountDomain READ getDefaultOtherSipAccountDomain CONSTANT) Q_PROPERTY(bool messageCounterRedirectEnabled READ getMessageCounterRedirectEnabled CONSTANT) - + Q_PROPERTY(bool mipmapEnabled READ isMipmapEnabled WRITE setMipmapEnabled NOTIFY mipmapEnabledChanged) - Q_PROPERTY(bool useMinimalTimelineFilter READ useMinimalTimelineFilter WRITE setUseMinimalTimelineFilter NOTIFY useMinimalTimelineFilterChanged) - Q_PROPERTY(Utils::SipDisplayMode sipDisplayMode READ getSipDisplayMode WRITE setSipDisplayMode NOTIFY sipDisplayModeChanged) - Q_PROPERTY(int magicSearchMaxResults READ getMagicSearchMaxResults WRITE setMagicSearchMaxResults NOTIFY magicSearchMaxResultsChanged) - - Q_PROPERTY(bool dontAskAgainInfoEncryption READ getDontAskAgainInfoEncryption WRITE setDontAskAgainInfoEncryption NOTIFY dontAskAgainInfoEncryptionChanged) + Q_PROPERTY(bool useMinimalTimelineFilter READ useMinimalTimelineFilter WRITE setUseMinimalTimelineFilter NOTIFY + useMinimalTimelineFilterChanged) + Q_PROPERTY(Utils::SipDisplayMode sipDisplayMode READ getSipDisplayMode WRITE setSipDisplayMode NOTIFY + sipDisplayModeChanged) + Q_PROPERTY(int magicSearchMaxResults READ getMagicSearchMaxResults WRITE setMagicSearchMaxResults NOTIFY + magicSearchMaxResultsChanged) + + Q_PROPERTY(bool dontAskAgainInfoEncryption READ getDontAskAgainInfoEncryption WRITE setDontAskAgainInfoEncryption + NOTIFY dontAskAgainInfoEncryptionChanged) Q_PROPERTY(bool haveDontAskAgainChoices READ getHaveDontAskAgainChoices NOTIFY haveDontAskAgainChoicesChanged) - - + // 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(bool fullLogsEnabled READ getFullLogsEnabled WRITE setFullLogsEnabled NOTIFY fullLogsEnabledChanged) Q_PROPERTY(QString logsEmail READ getLogsEmail WRITE setLogsEmail NOTIFY logsEmailChanged) - + Q_PROPERTY(bool isVfsEncrypted READ getVfsEncrypted NOTIFY vfsEncryptedChanged) - - Q_PROPERTY(bool developerSettingsEnabled READ getDeveloperSettingsEnabled WRITE setDeveloperSettingsEnabled NOTIFY developerSettingsEnabledChanged) - + + 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), @@ -260,82 +307,74 @@ public: MediaEncryptionZrtp = int(linphone::MediaEncryption::ZRTP) }; Q_ENUM(MediaEncryption) - - enum VersionCheckType { - VersionCheckType_Release, - VersionCheckType_Nightly, - VersionCheckType_Custom - }; + + enum VersionCheckType { VersionCheckType_Release, VersionCheckType_Nightly, VersionCheckType_Custom }; Q_ENUM(VersionCheckType); - - enum CameraMode{ - CameraMode_Hybrid = 0, - CameraMode_OccupyAllSpace = 1, - CameraMode_BlackBars = 2 - }; + + enum CameraMode { CameraMode_Hybrid = 0, CameraMode_OccupyAllSpace = 1, CameraMode_BlackBars = 2 }; Q_ENUM(CameraMode); - static SettingsModel::CameraMode cameraModefromString(const std::string& mode); - static std::string toString(const CameraMode& mode); - - - SettingsModel (QObject *parent = Q_NULLPTR); - virtual ~SettingsModel (); - + static SettingsModel::CameraMode cameraModefromString(const std::string &mode); + static std::string toString(const CameraMode &mode); + + SettingsModel(QObject *parent = Q_NULLPTR); + virtual ~SettingsModel(); + // =========================================================================== // METHODS. // =========================================================================== - + Q_INVOKABLE void onSettingsTabChanged(int idx); Q_INVOKABLE void settingsWindowClosing(void); Q_INVOKABLE void reloadDevices(); - + // Assistant. ---------------------------------------------------------------- - - bool getCreateAppSipAccountEnabled () const; - void setCreateAppSipAccountEnabled (bool status); - - bool getFetchRemoteConfigurationEnabled () const; - void setFetchRemoteConfigurationEnabled (bool status); - - bool getAutoApplyProvisioningConfigUriHandlerEnabled () const; - void setAutoApplyProvisioningConfigUriHandlerEnabled (bool status); - - bool getUseAppSipAccountEnabled () const; - void setUseAppSipAccountEnabled (bool status); - - bool getUseOtherSipAccountEnabled () const; - void setUseOtherSipAccountEnabled (bool status); - - bool getAssistantSupportsPhoneNumbers () const; - void setAssistantSupportsPhoneNumbers (bool status); - + + bool getCreateAppSipAccountEnabled() const; + void setCreateAppSipAccountEnabled(bool status); + + bool getFetchRemoteConfigurationEnabled() const; + void setFetchRemoteConfigurationEnabled(bool status); + + bool getAutoApplyProvisioningConfigUriHandlerEnabled() const; + void setAutoApplyProvisioningConfigUriHandlerEnabled(bool status); + + bool getUseAppSipAccountEnabled() const; + void setUseAppSipAccountEnabled(bool status); + + bool getUseOtherSipAccountEnabled() const; + void setUseOtherSipAccountEnabled(bool status); + + bool getAssistantSupportsPhoneNumbers() const; + void setAssistantSupportsPhoneNumbers(bool status); + int getAssistantDefaultTransport() const; - void setAssistantDefaultTransport(int transport);// 0:UDP, 1:TCP, 2:TLS - + void setAssistantDefaultTransport(int transport); // 0:UDP, 1:TCP, 2:TLS + Q_INVOKABLE bool useWebview() const; - QString getAssistantRegistrationUrl () const; - void setAssistantRegistrationUrl (QString url); + QString getAssistantRegistrationUrl() const; + void setAssistantRegistrationUrl(QString url); - QString getAssistantLoginUrl () const; - void setAssistantLoginUrl (QString url); - - QString getAssistantLogoutUrl () const; - void setAssistantLogoutUrl (QString url); - - bool isCguAccepted () const; + QString getAssistantLoginUrl() const; + void setAssistantLoginUrl(QString url); + + QString getAssistantLogoutUrl() const; + void setAssistantLogoutUrl(QString url); + + bool isCguAccepted() const; void acceptCgu(const bool accept); - + // SIP Accounts. ------------------------------------------------------------- - - static QString getDeviceName(const std::shared_ptr& config); + + static QString getDeviceName(const std::shared_ptr &config); QString getDeviceName() const; - void setDeviceName(const QString& deviceName); + void setDeviceName(const QString &deviceName); // Audio. -------------------------------------------------------------------- Q_INVOKABLE void startCaptureGraph(); - Q_INVOKABLE void stopCaptureGraph();; + Q_INVOKABLE void stopCaptureGraph(); + ; Q_INVOKABLE void stopCaptureGraphs(); Q_INVOKABLE void resetCaptureGraph(); void createCaptureGraph(); @@ -343,71 +382,76 @@ public: bool getCaptureGraphRunning(); void accessAudioSettings(); void closeAudioSettings(); - + Q_INVOKABLE float getMicVolume(); - + float getPlaybackGain() const; void setPlaybackGain(float gain); - + float getCaptureGain() const; void setCaptureGain(float gain); - - QStringList getCaptureDevices () const; - QStringList getPlaybackDevices () const; - - QString getCaptureDevice () const; - void setCaptureDevice (const QString &device); - - QString getPlaybackDevice () const; - void setPlaybackDevice (const QString &device); - - QString getRingerDevice () const; - void setRingerDevice (const QString &device); - - QString getRingPath () const; - void setRingPath (const QString &path); - - bool getEchoCancellationEnabled () const; - void setEchoCancellationEnabled (bool status); - + + QStringList getCaptureDevices() const; + QStringList getPlaybackDevices() const; + + QString getCaptureDevice() const; + void setCaptureDevice(const QString &device); + + QString getPlaybackDevice() const; + void setPlaybackDevice(const QString &device); + + QString getRingerDevice() const; + void setRingerDevice(const QString &device); + + QString getRingPath() const; + void setRingPath(const QString &path); + + bool getEchoCancellationEnabled() const; + void setEchoCancellationEnabled(bool status); + Q_INVOKABLE void startEchoCancellerCalibration(); - - bool getShowAudioCodecs () const; - void setShowAudioCodecs (bool status); - + + bool getShowAudioCodecs() const; + void setShowAudioCodecs(bool status); + // Video. -------------------------------------------------------------------- - - //Called from qml when accessing audio settings panel + + // Called from qml when accessing audio settings panel Q_INVOKABLE void accessVideoSettings(); - - QStringList getVideoDevices () const; - - QString getVideoDevice () const; - void setVideoDevice (const QString &device); - - QString getVideoPreset () const; - void setVideoPreset (const QString &preset); - - int getVideoFramerate () const; - void setVideoFramerate (int framerate); - - QVariantList getSupportedVideoDefinitions () const; - + + QStringList getVideoDevices() const; + + QString getVideoDevice() const; + void setVideoDevice(const QString &device); + + Q_INVOKABLE void saveCaptureWindowId(void *windowId); + Q_INVOKABLE void saveCaptureScreenIndex(int index); + Q_INVOKABLE int getCaptureScreenIndex(); + void setCaptureWindowId(); + + QString getVideoPreset() const; + void setVideoPreset(const QString &preset); + + int getVideoFramerate() const; + void setVideoFramerate(int framerate); + + QVariantList getSupportedVideoDefinitions() const; + Q_INVOKABLE void setHighMosaicQuality(); Q_INVOKABLE void setLimitedMosaicQuality(); - - QVariantMap getVideoDefinition () const; - Q_INVOKABLE QVariantMap getCurrentPreviewVideoDefinition () const; - void setVideoDefinition (const QVariantMap &definition); - - bool getVideoEnabled() const; // Enabled from settings - void setVideoEnabled(const bool& enable); + + QVariantMap getVideoDefinition() const; + Q_INVOKABLE QVariantMap getCurrentPreviewVideoDefinition() const; + void setVideoDefinition(const QVariantMap &definition); + + bool getVideoEnabled() const; // Enabled from settings + void setVideoEnabled(const bool &enable); bool getVideoAvailable() const; // Enabled and have enough codecs. bool haveAtLeastOneVideoCodec() const; - - bool getShowVideoCodecs () const; - void setShowVideoCodecs (bool status); - + + bool getShowVideoCodecs() const; + void setShowVideoCodecs(bool status); + void updateCameraMode(); CameraMode getCameraMode() const; Q_INVOKABLE void setCameraMode(CameraMode mode); @@ -418,512 +462,513 @@ public: void setActiveSpeakerCameraMode(CameraMode mode); CameraMode getCallCameraMode() const; void setCallCameraMode(CameraMode mode); - + LinphoneEnums::ConferenceLayout getVideoConferenceLayout() const; void setVideoConferenceLayout(LinphoneEnums::ConferenceLayout layout); - - + + int getConferenceMaxThumbnails() const; + void setConferenceMaxThumbnails(int limit); + // Chat & calls. ------------------------------------------------------------- - - bool getAutoAnswerStatus () const; - void setAutoAnswerStatus (bool status); - - bool getAutoAnswerVideoStatus () const; - void setAutoAnswerVideoStatus (bool status); - - int getAutoAnswerDelay () const; - void setAutoAnswerDelay (int delay); - - bool getShowTelKeypadAutomatically () const; - void setShowTelKeypadAutomatically (bool status); - - bool getKeepCallsWindowInBackground () const; - void setKeepCallsWindowInBackground (bool status); - - bool getOutgoingCallsEnabled () const; - void setOutgoingCallsEnabled (bool status); - - bool getCallRecorderEnabled () const; - void setCallRecorderEnabled (bool status); - - bool getAutomaticallyRecordCalls () const; - void setAutomaticallyRecordCalls (bool status); - + + bool getAutoAnswerStatus() const; + void setAutoAnswerStatus(bool status); + + bool getAutoAnswerVideoStatus() const; + void setAutoAnswerVideoStatus(bool status); + + int getAutoAnswerDelay() const; + void setAutoAnswerDelay(int delay); + + bool getShowTelKeypadAutomatically() const; + void setShowTelKeypadAutomatically(bool status); + + bool getKeepCallsWindowInBackground() const; + void setKeepCallsWindowInBackground(bool status); + + bool getOutgoingCallsEnabled() const; + void setOutgoingCallsEnabled(bool status); + + bool getCallRecorderEnabled() const; + void setCallRecorderEnabled(bool status); + + bool getAutomaticallyRecordCalls() const; + void setAutomaticallyRecordCalls(bool status); + int getAutoDownloadMaxSize() const; void setAutoDownloadMaxSize(int maxSize); - - bool getCallPauseEnabled () const; - void setCallPauseEnabled (bool status); - - bool getMuteMicrophoneEnabled () const; - void setMuteMicrophoneEnabled (bool status); - - bool getStandardChatEnabled () const; - void setStandardChatEnabled (bool status); - - bool getSecureChatEnabled () const; - void setSecureChatEnabled (bool status); - + + bool getCallPauseEnabled() const; + void setCallPauseEnabled(bool status); + + bool getMuteMicrophoneEnabled() const; + void setMuteMicrophoneEnabled(bool status); + + bool getStandardChatEnabled() const; + void setStandardChatEnabled(bool status); + + bool getSecureChatEnabled() const; + void setSecureChatEnabled(bool status); + bool getHideEmptyChatRooms() const; - void setHideEmptyChatRooms(const bool& data); - + void setHideEmptyChatRooms(const bool &data); + bool getWaitRegistrationForCall() const; - void setWaitRegistrationForCall(const bool& status); - + void setWaitRegistrationForCall(const bool &status); + bool getIncallScreenshotEnabled() const; - void setIncallScreenshotEnabled(const bool& status); - - bool getChatEnabled()const; - bool getGroupChatEnabled()const; - - bool getConferenceEnabled () const; - void setConferenceEnabled (bool status); - bool getVideoConferenceEnabled()const; - - bool getChatNotificationsEnabled () const; - void setChatNotificationsEnabled (bool status); - - bool getChatNotificationSoundEnabled () const; - void setChatNotificationSoundEnabled (bool status); - - QString getChatNotificationSoundPath () const; - void setChatNotificationSoundPath (const QString &path); - - QString getFileTransferUrl () const; - void setFileTransferUrl (const QString &url); - - bool getLimeIsSupported () const; - QVariantList getSupportedMediaEncryptions () const; - - MediaEncryption getMediaEncryption () const; - void setMediaEncryption (MediaEncryption encryption); - - bool mandatoryMediaEncryptionEnabled () const; + void setIncallScreenshotEnabled(const bool &status); + + bool getChatEnabled() const; + bool getGroupChatEnabled() const; + + bool getConferenceEnabled() const; + void setConferenceEnabled(bool status); + bool getVideoConferenceEnabled() const; + + bool getChatNotificationsEnabled() const; + void setChatNotificationsEnabled(bool status); + + bool getChatNotificationSoundEnabled() const; + void setChatNotificationSoundEnabled(bool status); + + QString getChatNotificationSoundPath() const; + void setChatNotificationSoundPath(const QString &path); + + QString getFileTransferUrl() const; + void setFileTransferUrl(const QString &url); + + bool getLimeIsSupported() const; + QVariantList getSupportedMediaEncryptions() const; + + MediaEncryption getMediaEncryption() const; + void setMediaEncryption(MediaEncryption encryption); + + bool mandatoryMediaEncryptionEnabled() const; void enableMandatoryMediaEncryption(bool mandatory); - + bool getPostQuantumAvailable() const; - + bool getDontAskAgainInfoEncryption() const; void setDontAskAgainInfoEncryption(bool show); - - bool getLimeState () const; - void setLimeState (const bool& state); - - bool getContactsEnabled () const; - void setContactsEnabled (bool status); - + + bool getLimeState() const; + void setLimeState(const bool &state); + + bool getContactsEnabled() const; + void setContactsEnabled(bool status); + int getIncomingCallTimeout() const; - + int getCreateEphemeralChatRooms() const; - void setCreateEphemeralChatRooms(int seconds);// <=0 deactivate - + void setCreateEphemeralChatRooms(int seconds); // <=0 deactivate + // Network. ------------------------------------------------------------------ - - bool getShowNetworkSettings () const; - void setShowNetworkSettings (bool status); - - bool getUseSipInfoForDtmfs () const; - void setUseSipInfoForDtmfs (bool status); - - bool getUseRfc2833ForDtmfs () const; - void setUseRfc2833ForDtmfs (bool status); - - bool getIpv6Enabled () const; - void setIpv6Enabled (bool status); - - int getDownloadBandwidth () const; - void setDownloadBandwidth (int bandwidth); - - int getUploadBandwidth () const; - void setUploadBandwidth (int bandwidth); - - bool getAdaptiveRateControlEnabled () const; - void setAdaptiveRateControlEnabled (bool status); - - int getTcpPort () const; - void setTcpPort (int port); - - int getUdpPort () const; - void setUdpPort (int port); - - QList getAudioPortRange () const; - void setAudioPortRange (const QList &range); - - QList getVideoPortRange () const; - void setVideoPortRange (const QList &range); - - bool getIceEnabled () const; - void setIceEnabled (bool status); - - bool getTurnEnabled () const; - void setTurnEnabled (bool status); - - QString getStunServer () const; - void setStunServer (const QString &stunServer); - - QString getTurnUser () const; - void setTurnUser (const QString &user); - - QString getTurnPassword () const; - void setTurnPassword (const QString &password); - - int getDscpSip () const; - void setDscpSip (int dscp); - - int getDscpAudio () const; - void setDscpAudio (int dscp); - - int getDscpVideo () const; - void setDscpVideo (int dscp); - - bool getRlsUriEnabled () const; - void setRlsUriEnabled (bool status); - + + bool getShowNetworkSettings() const; + void setShowNetworkSettings(bool status); + + bool getUseSipInfoForDtmfs() const; + void setUseSipInfoForDtmfs(bool status); + + bool getUseRfc2833ForDtmfs() const; + void setUseRfc2833ForDtmfs(bool status); + + bool getIpv6Enabled() const; + void setIpv6Enabled(bool status); + + int getDownloadBandwidth() const; + void setDownloadBandwidth(int bandwidth); + + int getUploadBandwidth() const; + void setUploadBandwidth(int bandwidth); + + bool getAdaptiveRateControlEnabled() const; + void setAdaptiveRateControlEnabled(bool status); + + int getTcpPort() const; + void setTcpPort(int port); + + int getUdpPort() const; + void setUdpPort(int port); + + QList getAudioPortRange() const; + void setAudioPortRange(const QList &range); + + QList getVideoPortRange() const; + void setVideoPortRange(const QList &range); + + bool getIceEnabled() const; + void setIceEnabled(bool status); + + bool getTurnEnabled() const; + void setTurnEnabled(bool status); + + QString getStunServer() const; + void setStunServer(const QString &stunServer); + + QString getTurnUser() const; + void setTurnUser(const QString &user); + + QString getTurnPassword() const; + void setTurnPassword(const QString &password); + + int getDscpSip() const; + void setDscpSip(int dscp); + + int getDscpAudio() const; + void setDscpAudio(int dscp); + + int getDscpVideo() const; + void setDscpVideo(int dscp); + + bool getRlsUriEnabled() const; + void setRlsUriEnabled(bool status); + QString getRlsUri() const; - void setRlsUri (const QString& rlsUri); + void setRlsUri(const QString &rlsUri); void updateRlsUri(); - + Q_INVOKABLE bool tunnelAvailable() const; - Q_INVOKABLE TunnelModel * getTunnel() const; - + Q_INVOKABLE TunnelModel *getTunnel() const; + // UI. ----------------------------------------------------------------------- - + QFont getTextMessageFont() const; - void setTextMessageFont(const QFont& font); - + void setTextMessageFont(const QFont &font); + int getTextMessageFontSize() const; - void setTextMessageFontSize(const int& size); - + void setTextMessageFontSize(const int &size); + QFont getEmojiFont() const; - void setEmojiFont(const QFont& font); - + void setEmojiFont(const QFont &font); + int getEmojiFontSize() const; - void setEmojiFontSize(const int& size); - + void setEmojiFontSize(const int &size); + QString getSpellCheckerOverrideLocale() const; - void setSpellCheckerOverrideLocale (const QString &locale); + void setSpellCheckerOverrideLocale(const QString &locale); bool getSpellCheckerEnabled() const; void setSpellCheckerEnabled(bool enable); - - QString getSavedScreenshotsFolder () const; - void setSavedScreenshotsFolder (const QString &folder); - - QString getSavedCallsFolder () const; - void setSavedCallsFolder (const QString &folder); - - QString getDownloadFolder () const; - void setDownloadFolder (const QString &folder); - + + QString getSavedScreenshotsFolder() const; + void setSavedScreenshotsFolder(const QString &folder); + + QString getSavedCallsFolder() const; + void setSavedCallsFolder(const QString &folder); + + QString getDownloadFolder() const; + void setDownloadFolder(const QString &folder); + QString getRemoteProvisioningRootUrl() const; - Q_INVOKABLE QString getRemoteProvisioning () const; - void setRemoteProvisioning (const QString &remoteProvisioning); - + Q_INVOKABLE QString getRemoteProvisioning() const; + void setRemoteProvisioning(const QString &remoteProvisioning); + Q_INVOKABLE bool isQRCodeAvailable() const; QString getFlexiAPIUrl() const; - void setFlexiAPIUrl (const QString &url); - - bool getExitOnClose () const; - void setExitOnClose (bool value); - + void setFlexiAPIUrl(const QString &url); + + bool getExitOnClose() const; + void setExitOnClose(bool value); + Q_INVOKABLE static bool isCheckForUpdateAvailable(); bool isCheckForUpdateEnabled() const; void setCheckForUpdateEnabled(bool enable); - + QString getVersionCheckUrl(); - void setVersionCheckUrl(const QString& url); - + void setVersionCheckUrl(const QString &url); + QString getLastRunningVersionOfApp(); - void setLastRunningVersionOfApp (const QString& version); - + void setLastRunningVersionOfApp(const QString &version); + VersionCheckType getVersionCheckType() const; - void setVersionCheckType(const VersionCheckType& type); - Q_INVOKABLE bool haveVersionNightlyUrl()const; - - - Q_INVOKABLE bool getShowLocalSipAccount () const; - Q_INVOKABLE bool getShowStartChatButton () const; - Q_INVOKABLE bool getShowStartVideoCallButton () const; - Q_INVOKABLE int getShowDefaultPage() const; // -1 : default + void setVersionCheckType(const VersionCheckType &type); + Q_INVOKABLE bool haveVersionNightlyUrl() const; + + Q_INVOKABLE bool getShowLocalSipAccount() const; + Q_INVOKABLE bool getShowStartChatButton() const; + Q_INVOKABLE bool getShowStartVideoCallButton() const; + Q_INVOKABLE int getShowDefaultPage() const; // -1 : default Q_INVOKABLE int getShowForcedAssistantPage() const; // -1 : no force Q_INVOKABLE bool getShowHomePage() const; Q_INVOKABLE bool getShowHomeInviteButton() const; Q_INVOKABLE QString getDefaultOtherSipAccountDomain() const; Q_INVOKABLE bool getMessageCounterRedirectEnabled() const; - - + bool isMipmapEnabled() const; - void setMipmapEnabled(const bool& enabled); - + void setMipmapEnabled(const bool &enabled); + bool useMinimalTimelineFilter() const; - void setUseMinimalTimelineFilter(const bool& useMinimal); - + void setUseMinimalTimelineFilter(const bool &useMinimal); + Utils::SipDisplayMode getSipDisplayMode() const; void setSipDisplayMode(Utils::SipDisplayMode mode); - + int getMagicSearchMaxResults() const; void setMagicSearchMaxResults(int maxResults); - -// Show all "don't ask again" checkboxes and popups. + + // Show all "don't ask again" checkboxes and popups. bool getHaveDontAskAgainChoices() const; Q_INVOKABLE void resetDontAskAgainChoices(); - + // Advanced. --------------------------------------------------------------------------- - - + void accessAdvancedSettings(); - - Q_INVOKABLE QString getLogText()const; - - QString getLogsFolder () const; - void setLogsFolder (const QString &folder); - - QString getLogsUploadUrl () const; - void setLogsUploadUrl (const QString &url); - - bool getLogsEnabled () const; - void setLogsEnabled (bool status); - - bool getFullLogsEnabled () const; - void setFullLogsEnabled (bool status); - - QString getLogsEmail () const; - void setLogsEmail (const QString &email); - - static bool getVfsEncrypted (); - Q_INVOKABLE void setVfsEncrypted (bool encrypted, const bool deleteUserData); - + + Q_INVOKABLE QString getLogText() const; + + QString getLogsFolder() const; + void setLogsFolder(const QString &folder); + + QString getLogsUploadUrl() const; + void setLogsUploadUrl(const QString &url); + + bool getLogsEnabled() const; + void setLogsEnabled(bool status); + + bool getFullLogsEnabled() const; + void setFullLogsEnabled(bool status); + + QString getLogsEmail() const; + void setLogsEmail(const QString &email); + + static bool getVfsEncrypted(); + Q_INVOKABLE void setVfsEncrypted(bool encrypted, const bool deleteUserData); + Q_INVOKABLE bool isLdapAvailable(); - -// OAuth 2 + + // OAuth 2 Q_INVOKABLE bool isOAuth2Available(); - QString getOAuth2AuthorizationUrl()const; - QString getOAuth2AccessTokenUrl()const; - QString getOAuth2RedirectUri()const; - QString getOAuth2Identifier()const; - QString getOAuth2Password()const; - QString getOAuth2Scope()const; - QString getOAuth2RemoteProvisioningBasicAuth()const; - QString getOAuth2RemoteProvisioningHeader()const; - + QString getOAuth2AuthorizationUrl() const; + QString getOAuth2AccessTokenUrl() const; + QString getOAuth2RedirectUri() const; + QString getOAuth2Identifier() const; + QString getOAuth2Password() const; + QString getOAuth2Scope() const; + QString getOAuth2RemoteProvisioningBasicAuth() const; + QString getOAuth2RemoteProvisioningHeader() const; + // --------------------------------------------------------------------------- - - static QString getLogsFolder (const std::shared_ptr &config); - static size_t getMaxLogsCollectionSize (const std::shared_ptr &config); - static bool getLogsEnabled (const std::shared_ptr &config); - static bool getFullLogsEnabled (const std::shared_ptr &config); - + + static QString getLogsFolder(const std::shared_ptr &config); + static size_t getMaxLogsCollectionSize(const std::shared_ptr &config); + static bool getLogsEnabled(const std::shared_ptr &config); + static bool getFullLogsEnabled(const std::shared_ptr &config); + // --------------------------------------------------------------------------- Q_INVOKABLE bool isDeveloperSettingsAvailable() const; - bool getDeveloperSettingsEnabled () const; - void setDeveloperSettingsEnabled (bool status); - + 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); void handleEcCalibrationResult(linphone::EcCalibratorStatus status, int delayMs); - + bool getIsInCall() const; - - bool isReadOnly(const std::string& section, const std::string& name) const; - std::string getEntryFullName(const std::string& section, const std::string& name) const; // Return the full name of the entry : 'name/readonly' or 'name' - + + bool isReadOnly(const std::string §ion, const std::string &name) const; + std::string + getEntryFullName(const std::string §ion, + const std::string &name) const; // Return the full name of the entry : 'name/readonly' or 'name' + void onDefaultAccountChanged(); - + static const std::string UiSection; static const std::string ContactsSection; - + // =========================================================================== // SIGNALS. // =========================================================================== - + signals: // 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 autoApplyProvisioningConfigUriHandlerEnabledChanged(); - - void assistantSupportsPhoneNumbersChanged (bool status); - void assistantDefaultTransportChanged (int transport); - void assistantRegistrationUrlChanged (QString url); - void assistantLoginUrlChanged (QString url); - void assistantLogoutUrlChanged (QString url); - + void assistantSupportsPhoneNumbersChanged(bool status); + void assistantDefaultTransportChanged(int transport); + void assistantRegistrationUrlChanged(QString url); + void assistantLoginUrlChanged(QString url); + void assistantLogoutUrlChanged(QString url); + void cguAcceptedChanged(bool accepted); - + // SIP Accounts. ------------------------------------------------------------- - + void deviceNameChanged(); // Audio. -------------------------------------------------------------------- - + void captureGraphRunningChanged(bool running); - + void playbackGainChanged(float gain); void captureGainChanged(float gain); - - void captureDevicesChanged (const QStringList &devices); - void playbackDevicesChanged (const QStringList &devices); - - void captureDeviceChanged (const QString &device); - void playbackDeviceChanged (const QString &device); - void ringerDeviceChanged (const QString &device); - - void ringPathChanged (const QString &path); - - void echoCancellationEnabledChanged (bool status); + + void captureDevicesChanged(const QStringList &devices); + void playbackDevicesChanged(const QStringList &devices); + + void captureDeviceChanged(const QString &device); + void playbackDeviceChanged(const QString &device); + void ringerDeviceChanged(const QString &device); + + void ringPathChanged(const QString &path); + + void echoCancellationEnabledChanged(bool status); void echoCancellationStatus(int status, int msDelay); - - void showAudioCodecsChanged (bool status); - + + void showAudioCodecsChanged(bool status); + // Video. -------------------------------------------------------------------- void videoEnabledChanged(); void videoAvailableChanged(); - void videoDevicesChanged (const QStringList &devices); - void videoDeviceChanged (const QString &device); - - void videoPresetChanged (const QString &preset); - void videoFramerateChanged (int framerate); - - void videoDefinitionChanged (const QVariantMap &definition); - - void showVideoCodecsChanged (bool status); - + void videoDevicesChanged(const QStringList &devices); + void videoDeviceChanged(const QString &device); + void captureScreenIndexChanged(int index); + + void videoPresetChanged(const QString &preset); + void videoFramerateChanged(int framerate); + + void videoDefinitionChanged(const QVariantMap &definition); + + void showVideoCodecsChanged(bool status); + void cameraModeChanged(); void gridCameraModeChanged(); void activeSpeakerCameraModeChanged(); void callCameraModeChanged(); void videoConferenceLayoutChanged(); - + void conferenceMaxThumbnailsChanged(); + void haveAtLeastOneVideoCodecChanged(); - + // Chat & calls. ------------------------------------------------------------- - - void autoAnswerStatusChanged (bool status); - void autoAnswerVideoStatusChanged (bool status); - void autoAnswerDelayChanged (int delay); - - void showTelKeypadAutomaticallyChanged (bool status); - - void keepCallsWindowInBackgroundChanged (bool status); - - void outgoingCallsEnabledChanged (bool status); - - void callRecorderEnabledChanged (bool status); - void automaticallyRecordCallsChanged (bool status); - void autoDownloadMaxSizeChanged (int maxSize); - - void callPauseEnabledChanged (bool status); - void muteMicrophoneEnabledChanged (bool status); - - void standardChatEnabledChanged (bool status); - void secureChatEnabledChanged (); + + void autoAnswerStatusChanged(bool status); + void autoAnswerVideoStatusChanged(bool status); + void autoAnswerDelayChanged(int delay); + + void showTelKeypadAutomaticallyChanged(bool status); + + void keepCallsWindowInBackgroundChanged(bool status); + + void outgoingCallsEnabledChanged(bool status); + + void callRecorderEnabledChanged(bool status); + void automaticallyRecordCallsChanged(bool status); + void autoDownloadMaxSizeChanged(int maxSize); + + void callPauseEnabledChanged(bool status); + void muteMicrophoneEnabledChanged(bool status); + + void standardChatEnabledChanged(bool status); + void secureChatEnabledChanged(); void groupChatEnabledChanged(); - void hideEmptyChatRoomsChanged (bool status); - void waitRegistrationForCallChanged (bool status); + void hideEmptyChatRoomsChanged(bool status); + void waitRegistrationForCallChanged(bool status); void incallScreenshotEnabledChanged(bool status); - - void conferenceEnabledChanged (bool status); - void videoConferenceEnabledChanged (); - - void chatNotificationsEnabledChanged (bool status); - void chatNotificationSoundEnabledChanged (bool status); - void chatNotificationSoundPathChanged (const QString &path); - - void fileTransferUrlChanged (const QString &url); - - void mediaEncryptionChanged (MediaEncryption encryption); - void limeStateChanged (bool state); - - void contactsEnabledChanged (bool status); - + + void conferenceEnabledChanged(bool status); + void videoConferenceEnabledChanged(); + + void chatNotificationsEnabledChanged(bool status); + void chatNotificationSoundEnabledChanged(bool status); + void chatNotificationSoundPathChanged(const QString &path); + + void fileTransferUrlChanged(const QString &url); + + void mediaEncryptionChanged(MediaEncryption encryption); + void limeStateChanged(bool state); + + void contactsEnabledChanged(bool status); + void createEphemeralsChatRoomsChanged(); - + // Network. ------------------------------------------------------------------ - - void showNetworkSettingsChanged (bool status); - - void dtmfsProtocolChanged (); - - void ipv6EnabledChanged (bool status); - - void downloadBandWidthChanged (int bandwidth); - void uploadBandWidthChanged (int bandwidth); - - bool adaptiveRateControlEnabledChanged (bool status); - - void tcpPortChanged (int port); - void udpPortChanged (int port); - - void audioPortRangeChanged (int a, int b); - void videoPortRangeChanged (int a, int b); - - void iceEnabledChanged (bool status); - void turnEnabledChanged (bool status); - - void stunServerChanged (const QString &server); - - void turnUserChanged (const QString &user); - void turnPasswordChanged (const QString &password); - - void dscpSipChanged (int dscp); - void dscpAudioChanged (int dscp); - void dscpVideoChanged (int dscp); - - void rlsUriEnabledChanged (bool status); - void rlsUriChanged (); - + + void showNetworkSettingsChanged(bool status); + + void dtmfsProtocolChanged(); + + void ipv6EnabledChanged(bool status); + + void downloadBandWidthChanged(int bandwidth); + void uploadBandWidthChanged(int bandwidth); + + bool adaptiveRateControlEnabledChanged(bool status); + + void tcpPortChanged(int port); + void udpPortChanged(int port); + + void audioPortRangeChanged(int a, int b); + void videoPortRangeChanged(int a, int b); + + void iceEnabledChanged(bool status); + void turnEnabledChanged(bool status); + + void stunServerChanged(const QString &server); + + void turnUserChanged(const QString &user); + void turnPasswordChanged(const QString &password); + + void dscpSipChanged(int dscp); + void dscpAudioChanged(int dscp); + void dscpVideoChanged(int dscp); + + void rlsUriEnabledChanged(bool status); + void rlsUriChanged(); + // UI. ----------------------------------------------------------------------- - + void spellCheckerOverrideLocaleChanged(); void spellCheckerEnabledChanged(); - - void textMessageFontChanged(const QFont& font); - void textMessageFontSizeChanged(const int& size); - - void emojiFontChanged(const QFont& font); - void emojiFontSizeChanged(const int& size); - - void savedScreenshotsFolderChanged (const QString &folder); - void savedCallsFolderChanged (const QString &folder); - void downloadFolderChanged (const QString &folder); - - void remoteProvisioningChanged (const QString &remoteProvisioning); - void remoteProvisioningNotChanged (const QString &remoteProvisioning); - void flexiAPIUrlChanged (const QString &url); - - void exitOnCloseChanged (bool value); + + void textMessageFontChanged(const QFont &font); + void textMessageFontSizeChanged(const int &size); + + void emojiFontChanged(const QFont &font); + void emojiFontSizeChanged(const int &size); + + void savedScreenshotsFolderChanged(const QString &folder); + void savedCallsFolderChanged(const QString &folder); + void downloadFolderChanged(const QString &folder); + + void remoteProvisioningChanged(const QString &remoteProvisioning); + void remoteProvisioningNotChanged(const QString &remoteProvisioning); + void flexiAPIUrlChanged(const QString &url); + + void exitOnCloseChanged(bool value); void mipmapEnabledChanged(); void useMinimalTimelineFilterChanged(); - + void sipDisplayModeChanged(); - + void checkForUpdateEnabledChanged(); void versionCheckUrlChanged(); void versionCheckTypeChanged(); - + void magicSearchMaxResultsChanged(); - + void dontAskAgainInfoEncryptionChanged(); void haveDontAskAgainChoicesChanged(); - + // Advanced. ----------------------------------------------------------------- - - void logsFolderChanged (const QString &folder); - void logsUploadUrlChanged (const QString &url); - void logsEnabledChanged (bool status); - void fullLogsEnabledChanged (); - void logsEmailChanged (const QString &email); + + void logsFolderChanged(const QString &folder); + void logsUploadUrlChanged(const QString &url); + void logsEnabledChanged(bool status); + void fullLogsEnabledChanged(); + void logsEmailChanged(const QString &email); void vfsEncryptedChanged(); - + void contactImporterChanged(); - - bool developerSettingsEnabledChanged (bool status); - + + bool developerSettingsEnabledChanged(bool status); + bool isInCallChanged(bool); - + private: int mCurrentSettingsTab = 0; MediastreamerUtils::SimpleCaptureGraph *mSimpleCaptureGraph = nullptr; @@ -931,7 +976,7 @@ private: #ifdef ENABLE_QT_KEYCHAIN VfsUtils mVfsUtils; #endif - + void *mCaptureWindowId = NULL; std::shared_ptr mConfig; }; diff --git a/linphone-app/src/components/videoSource/VideoSourceDescriptorModel.cpp b/linphone-app/src/components/videoSource/VideoSourceDescriptorModel.cpp new file mode 100644 index 000000000..f312483fe --- /dev/null +++ b/linphone-app/src/components/videoSource/VideoSourceDescriptorModel.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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, see . + */ + +#include "VideoSourceDescriptorModel.hpp" +#include "components/other/desktop-tools/DesktopTools.hpp" +// ============================================================================= +VideoSourceDescriptorModel::VideoSourceDescriptorModel() { + +} +VideoSourceDescriptorModel::VideoSourceDescriptorModel(std::shared_ptr desc) { + mDesc = desc; + if(mDesc && mDesc->getScreenSharingType() == linphone::VideoSourceScreenSharingType::Display) + mScreenIndex = DesktopTools::getDisplayIndex(mDesc->getScreenSharing()); +} + +void VideoSourceDescriptorModel::setScreenSharingDisplay(int index) { + if(!mDesc) mDesc = linphone::Factory::get()->createVideoSourceDescriptor(); + mScreenIndex = index; + mDesc->setScreenSharing(linphone::VideoSourceScreenSharingType::Display, DesktopTools::getDisplay(index)); + emit videoDescriptorChanged(); +} + +void VideoSourceDescriptorModel::setScreenSharingWindow(void *window){ // Get data from DesktopTools. + if(!mDesc) mDesc = linphone::Factory::get()->createVideoSourceDescriptor(); + else if(getVideoSourceType() == LinphoneEnums::VideoSourceScreenSharingTypeWindow && window == getScreenSharing()) + return; + mDesc->setScreenSharing(linphone::VideoSourceScreenSharingType::Window, window); + emit videoDescriptorChanged(); +} + +void * VideoSourceDescriptorModel::getScreenSharing() const{ + if(!mDesc) + return nullptr; + else + return mDesc->getScreenSharing(); +} + +bool VideoSourceDescriptorModel::isScreenSharing() const{ + return mDesc && mDesc->getType() == linphone::VideoSourceType::ScreenSharing; +} + +LinphoneEnums::VideoSourceScreenSharingType VideoSourceDescriptorModel::getVideoSourceType() const{ + return mDesc ? LinphoneEnums::fromLinphone(mDesc->getScreenSharingType()) : LinphoneEnums::VideoSourceScreenSharingType::VideoSourceScreenSharingTypeDisplay; +} + +int VideoSourceDescriptorModel::getScreenSharingIndex() const{ + if(mDesc && mDesc->getScreenSharingType() == linphone::VideoSourceScreenSharingType::Display) { + return mScreenIndex; + }else + return -1; +} + diff --git a/linphone-app/src/components/videoSource/VideoSourceDescriptorModel.hpp b/linphone-app/src/components/videoSource/VideoSourceDescriptorModel.hpp new file mode 100644 index 000000000..276f969f9 --- /dev/null +++ b/linphone-app/src/components/videoSource/VideoSourceDescriptorModel.hpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that 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, see . + */ + +#ifndef VIDEO_SOURCE_DESCRIPTOR_MODEL_H_ +#define VIDEO_SOURCE_DESCRIPTOR_MODEL_H_ + + +#include +// ============================================================================= +#include +#include +#include +#include + +#include "utils/LinphoneEnums.hpp" + +class VideoSourceDescriptorModel : public QObject{ + Q_OBJECT + Q_PROPERTY(bool isScreenSharing READ isScreenSharing NOTIFY videoDescriptorChanged) + Q_PROPERTY(LinphoneEnums::VideoSourceScreenSharingType screenSharingType READ getVideoSourceType NOTIFY videoDescriptorChanged) + Q_PROPERTY(int screenSharingIndex READ getScreenSharingIndex WRITE setScreenSharingDisplay NOTIFY videoDescriptorChanged) +public: + VideoSourceDescriptorModel(); + VideoSourceDescriptorModel(std::shared_ptr desc); + void setScreenSharingDisplay(int index); + void setScreenSharingWindow(void *window); // Get data from DesktopTools. + void *getScreenSharing() const; + + bool isScreenSharing() const; + LinphoneEnums::VideoSourceScreenSharingType getVideoSourceType() const; + int getScreenSharingIndex() const; + + + std::shared_ptr mDesc; + int mScreenIndex = 0; + +signals: + void videoDescriptorChanged(); +}; +#endif diff --git a/linphone-app/src/utils/LinphoneEnums.cpp b/linphone-app/src/utils/LinphoneEnums.cpp index fd119d8fc..49e280647 100644 --- a/linphone-app/src/utils/LinphoneEnums.cpp +++ b/linphone-app/src/utils/LinphoneEnums.cpp @@ -38,6 +38,7 @@ void LinphoneEnums::registerMetaTypes(){ qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); qRegisterMetaType>(); qRegisterMetaType(); @@ -171,3 +172,11 @@ void LinphoneEnums::fromString(const QString& transportType, LinphoneEnums::Tran else *transport = TransportTypeDtls; } + +linphone::VideoSourceScreenSharingType LinphoneEnums::toLinphone(const LinphoneEnums::VideoSourceScreenSharingType& type){ + return static_cast(type); +} +LinphoneEnums::VideoSourceScreenSharingType LinphoneEnums::fromLinphone(const linphone::VideoSourceScreenSharingType& type){ + return static_cast(type); +} + diff --git a/linphone-app/src/utils/LinphoneEnums.hpp b/linphone-app/src/utils/LinphoneEnums.hpp index b90b2c392..86d099fdc 100644 --- a/linphone-app/src/utils/LinphoneEnums.hpp +++ b/linphone-app/src/utils/LinphoneEnums.hpp @@ -214,6 +214,17 @@ linphone::TransportType toLinphone(const LinphoneEnums::TransportType& type); LinphoneEnums::TransportType fromLinphone(const linphone::TransportType& type); QString toString(const LinphoneEnums::TransportType& type); void fromString(const QString& transportType, LinphoneEnums::TransportType *transport); + +enum VideoSourceScreenSharingType{ + VideoSourceScreenSharingTypeArea = int(linphone::VideoSourceScreenSharingType::Area), + VideoSourceScreenSharingTypeDisplay = int(linphone::VideoSourceScreenSharingType::Display), + VideoSourceScreenSharingTypeWindow = int(linphone::VideoSourceScreenSharingType::Window) +}; +Q_ENUM_NS(VideoSourceScreenSharingType) + +linphone::VideoSourceScreenSharingType toLinphone(const LinphoneEnums::VideoSourceScreenSharingType& type); +LinphoneEnums::VideoSourceScreenSharingType fromLinphone(const linphone::VideoSourceScreenSharingType& type); + } @@ -230,6 +241,7 @@ Q_DECLARE_METATYPE(LinphoneEnums::ParticipantDeviceState) Q_DECLARE_METATYPE(LinphoneEnums::RecorderState) Q_DECLARE_METATYPE(LinphoneEnums::TunnelMode) Q_DECLARE_METATYPE(LinphoneEnums::TransportType) +Q_DECLARE_METATYPE(LinphoneEnums::VideoSourceScreenSharingType) Q_DECLARE_METATYPE(std::shared_ptr) Q_DECLARE_METATYPE(linphone::Call::State) diff --git a/linphone-app/src/utils/Utils.cpp b/linphone-app/src/utils/Utils.cpp index 69f36ff20..ac772687d 100644 --- a/linphone-app/src/utils/Utils.cpp +++ b/linphone-app/src/utils/Utils.cpp @@ -680,6 +680,12 @@ bool Utils::isMe(const std::shared_ptr& address){ }else return address ? CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->weakEqual(address) : false; } +bool Utils::isLocal(const std::shared_ptr& conference, const std::shared_ptr& device) { + auto deviceAddress = device->getAddress(); + auto callAddress = conference->getMe()->getAddress(); + auto gruuAddress = CoreManager::getInstance()->getAccountSettingsModel()->findAccount(callAddress)->getContactAddress(); + return deviceAddress->equal(gruuAddress); +} bool Utils::isAnimatedImage(const QString& path){ if(path.isEmpty()) return false; diff --git a/linphone-app/src/utils/Utils.hpp b/linphone-app/src/utils/Utils.hpp index e7624b080..bf2b84fce 100644 --- a/linphone-app/src/utils/Utils.hpp +++ b/linphone-app/src/utils/Utils.hpp @@ -195,6 +195,8 @@ public: static QString computeUserAgent(const std::shared_ptr& config); static bool isMe(const std::shared_ptr& address); + static bool isLocal(const std::shared_ptr& conference, const std::shared_ptr& device); + static void deleteAllUserData(); static void deleteAllUserDataOffline();// When we are out of all events and core is not running (aka in main()) diff --git a/linphone-app/ui/modules/Common/Form/Buttons/AbstractTextButton.qml b/linphone-app/ui/modules/Common/Form/Buttons/AbstractTextButton.qml index 4265de04f..5bac5334c 100644 --- a/linphone-app/ui/modules/Common/Form/Buttons/AbstractTextButton.qml +++ b/linphone-app/ui/modules/Common/Form/Buttons/AbstractTextButton.qml @@ -26,10 +26,12 @@ Item { property color borderColorPressed property alias text: button.text + property alias textColor: button.textColor property bool enabled: true property bool showBorder : false property alias toggled : button.checked - + property alias button: button + property alias radius: button.radius property alias capitalization : button.capitalization //Additional size around text @@ -81,16 +83,18 @@ Item { Button { id: button property int capitalization + property color textColor: _getTextColor() + property int radius: AbstractTextButtonStyle.background.radius background: Rectangle { color: _getBackgroundColor() - radius: AbstractTextButtonStyle.background.radius + radius: button.radius border.color: _getBorderColor() border.width: (showBorder ? 1 : 0) } contentItem: Text { - color: _getTextColor() + color: button.textColor font { bold: true pointSize: AbstractTextButtonStyle.text.pointSize diff --git a/linphone-app/ui/modules/Common/Form/RadioButton.qml b/linphone-app/ui/modules/Common/Form/RadioButton.qml index 33e015bcd..379786e67 100644 --- a/linphone-app/ui/modules/Common/Form/RadioButton.qml +++ b/linphone-app/ui/modules/Common/Form/RadioButton.qml @@ -16,7 +16,10 @@ Control.RadioButton{ font.weight: checked ? RadioButtonStyle.selectedWeight : RadioButtonStyle.weight font.pointSize: RadioButtonStyle.pointSize spacing: 10 - FontMetrics{id: fontMetrics} + FontMetrics{ + id: fontMetrics + font: radio.font + } MouseArea{ anchors.fill:parent @@ -29,7 +32,8 @@ Control.RadioButton{ height: fontMetrics.height - 5 width: height x: parent.leftPadding - y: parent.height / 2 - height / 2 + //y: parent.height / 2 - (textItem.lineCount > 1 ? height / 2 : 0) + y: height / 2 radius: width/2 border.color: RadioButtonStyle.colorModel.color property bool checked: parent.checked @@ -44,14 +48,15 @@ Control.RadioButton{ } } contentItem: Text{ + id: textItem text: parent.text font: parent.font width: parent.width - (parent.indicator.width + parent.spacing) - height: implicitHeight - y:0 + //height: implicitHeight + //y:0 // Override unwanted auto changes - onYChanged: y = 0 - onHeightChanged: height=implicitHeight + //onYChanged: y = 0 + //onHeightChanged: height=implicitHeight //--------------------------------------- color: RadioButtonStyle.colorModel.color verticalAlignment: Text.AlignVCenter @@ -59,4 +64,4 @@ Control.RadioButton{ wrapMode: Text.WordWrap elide: Text.ElideRight } -} \ No newline at end of file +} diff --git a/linphone-app/ui/modules/Common/Image/RoundedImage.qml b/linphone-app/ui/modules/Common/Image/RoundedImage.qml index 998e9956f..90a7f36b1 100644 --- a/linphone-app/ui/modules/Common/Image/RoundedImage.qml +++ b/linphone-app/ui/modules/Common/Image/RoundedImage.qml @@ -12,12 +12,13 @@ Item { property color backgroundColor: '#00000000' property color foregroundColor: '#00000000' readonly property alias status: image.status + property int radius: width/2 Rectangle { id: backgroundArea anchors.fill: parent color: item.backgroundColor - radius: width/2 + radius: item.radius } Image { id: image @@ -36,6 +37,6 @@ Item { anchors.fill: parent visible: color != 'transparent' color: item.foregroundColor - radius: width/2 + radius: item.radius } } diff --git a/linphone-app/ui/modules/Linphone/Camera/CameraItem.qml b/linphone-app/ui/modules/Linphone/Camera/CameraItem.qml index d5da3db02..a893e032f 100644 --- a/linphone-app/ui/modules/Linphone/Camera/CameraItem.qml +++ b/linphone-app/ui/modules/Linphone/Camera/CameraItem.qml @@ -25,13 +25,15 @@ Item { property bool hideCamera: false property bool isPaused: false property bool deactivateCamera: true + property bool isThumbnail: false + property bool isDeviceVideoEnabled: container.currentDevice && (isThumbnail ? container.currentDevice.thumbnailVideoEnabled : container.currentDevice.videoEnabled) property bool isVideoEnabled: !deactivateCamera && (!callModel || callModel.videoEnabled) && (!container.currentDevice || ( callModel && container.currentDevice && - ( (! (container.currentDevice.isMe && container.currentDevice.isLocal) && container.currentDevice.videoEnabled) + ( (! (container.currentDevice.isMe && container.currentDevice.isLocal) && isDeviceVideoEnabled) || (container.currentDevice.isMe && container.currentDevice.isLocal && callModel.cameraEnabled)))) property bool a : callModel && callModel.videoEnabled - property bool b: container.currentDevice && container.currentDevice.videoEnabled + property bool b: isDeviceVideoEnabled property bool c: container.currentDevice && container.currentDevice.isMe && container.currentDevice.isLocal property bool d : callModel && callModel.cameraEnabled property bool isReady: cameraLoader.item && cameraLoader.item.isReady diff --git a/linphone-app/ui/modules/Linphone/Camera/CameraView.qml b/linphone-app/ui/modules/Linphone/Camera/CameraView.qml index e781cd1ae..5269d4289 100644 --- a/linphone-app/ui/modules/Linphone/Camera/CameraView.qml +++ b/linphone-app/ui/modules/Linphone/Camera/CameraView.qml @@ -21,6 +21,7 @@ Item{ property alias isPreview: camera.isPreview property alias isFullscreen: camera.isFullscreen property alias isCameraFromDevice: camera.isCameraFromDevice + property alias isThumbnail: camera.isThumbnail property alias qmlName: camera.qmlName property bool showCloseButton: false property bool showActiveSpeakerOverlay: true diff --git a/linphone-app/ui/modules/Linphone/Menus/IncallMenu.qml b/linphone-app/ui/modules/Linphone/Menus/IncallMenu.qml index e01d7a3c7..ed8b1a6ba 100644 --- a/linphone-app/ui/modules/Linphone/Menus/IncallMenu.qml +++ b/linphone-app/ui/modules/Linphone/Menus/IncallMenu.qml @@ -11,6 +11,7 @@ import Linphone.Styles 1.0 import LinphoneEnums 1.0 import UtilsCpp 1.0 +import DesktopTools 1.0 import App.Styles 1.0 @@ -23,6 +24,8 @@ Rectangle{ property ParticipantModel me: conferenceModel ? conferenceModel.localParticipant : null property bool isMeAdmin: me && me.adminStatus property bool isParticipantsMenu: false + property bool isScreenSharingMenu: false + property bool screenSharingAvailable: conferenceModel && (!conferenceModel.isScreenSharingEnabled || conferenceModel.isLocalScreenSharingEnabled) signal close() signal layoutChanging(int layoutMode) @@ -40,13 +43,18 @@ Rectangle{ //: 'Invite participants' : Menu title to invite participants in admin mode. mainItem.isMeAdmin ? qsTr('incallMenuInvite') //: 'Participants list' : Menu title to show participants in non-admin mode. - : qsTr('incallMenuParticipants') + : qsTr('incallMenuParticipants'), + "Partage d'écran" ] function showParticipantsMenu(){ contentsStack.push(participantsMenu, {title:Qt.binding(function() { return mainItem.menuTitles[2]})}) visible = true } + function showScreenSharingMenu(){ + contentsStack.push(screenSharingMenu, {title:Qt.binding(function() { return mainItem.menuTitles[3]})}) + visible = true + } onVisibleChanged: if(!visible && contentsStack.nViews > 1) { contentsStack.pop() } @@ -59,6 +67,7 @@ Rectangle{ } } ButtonGroup{id: modeGroup} + ButtonGroup{id: screenSharingGroup} ColumnLayout{ anchors.fill: parent // HEADER @@ -134,7 +143,12 @@ Rectangle{ { titleIndex: 2 , icon: IncallMenuStyle.settingsIcons.participantsIcon , nextPage:participantsMenu - , visible: mainItem.callModel && mainItem.callModel.isConference} + , visible: mainItem.callModel && mainItem.callModel.isConference}, + + { titleIndex: 3 + , icon: IncallMenuStyle.settingsIcons.screenSharingIcon + , nextPage: screenSharingMenu + , visible: mainItem.screenSharingAvailable && SettingsModel.videoAvailable} ] delegate: Borders{ @@ -226,11 +240,12 @@ Rectangle{ Layout.fillWidth: true Repeater{ //: 'Mosaic mode' : Grid layout for video conference. - model: [{text: qsTr('incallMenuGridLayout'), icon: IncallMenuStyle.modeIcons.gridIcon, value:LinphoneEnums.ConferenceLayoutGrid} + model: [{text: qsTr('incallMenuGridLayout'), icon: IncallMenuStyle.modeIcons.gridIcon, value:LinphoneEnums.ConferenceLayoutGrid, enabled: (!mainItem.conferenceModel + || (mainItem.conferenceModel.participantDeviceCount <= SettingsModel.conferenceMaxThumbnails+1 && !mainItem.conferenceModel.isScreenSharingEnabled))} //: 'Active speaker mode' : Active speaker layout for video conference. - , {text: qsTr('incallMenuActiveSpeakerLayout'), icon: IncallMenuStyle.modeIcons.activeSpeakerIcon, value:LinphoneEnums.ConferenceLayoutActiveSpeaker} + , {text: qsTr('incallMenuActiveSpeakerLayout'), icon: IncallMenuStyle.modeIcons.activeSpeakerIcon, value:LinphoneEnums.ConferenceLayoutActiveSpeaker, enabled: true} //: 'Audio only mode' : Audio only layout for video conference. - , {text: qsTr('incallMenuAudioLayout'), icon: IncallMenuStyle.modeIcons.audioOnlyIcon, value:LinphoneEnums.ConferenceLayoutAudioOnly} + , {text: qsTr('incallMenuAudioLayout'), icon: IncallMenuStyle.modeIcons.audioOnlyIcon, value:LinphoneEnums.ConferenceLayoutAudioOnly, enabled: true} ] delegate: Borders{ @@ -238,7 +253,8 @@ Rectangle{ bottomWidth: IncallMenuStyle.list.border.width Layout.preferredHeight: Math.max(layoutIcon.height, radio.contentItem.implicitHeight) + 20 Layout.fillWidth: true - enabled: mainItem.callModel && !mainItem.callModel.updating + enabled: mainItem.callModel && !mainItem.callModel.updating && modelData.enabled + opacity: enabled ? 1.0 : 0.5 MouseArea{ anchors.fill: parent onClicked: radio.clicked() @@ -310,5 +326,130 @@ Rectangle{ Component.onDestruction: mainItem.isParticipantsMenu = false } } +//----------------------------------------------------------------------------------------------------------------------------- + Component{ + id: screenSharingMenu + ColumnLayout{ + id: screenSharingItem + property VideoSourceDescriptorModel desc: mainItem.callModel.videoSourceDescriptorModel + property string title + Layout.fillHeight: true + Layout.fillWidth: true + RadioButton{ + id: displayRadioButton + Layout.fillWidth: true + Layout.leftMargin: 15 + text: "Partager l'intégralité de l'écran" + font.pointSize: IncallMenuStyle.list.pointSize + ButtonGroup.group: screenSharingGroup + //checked: screenList.selectedIndex >= 0 + checked: screenSharingItem.desc && screenSharingItem.desc.isScreenSharing && screenSharingItem.desc.screenSharingType == LinphoneEnums.VideoSourceScreenSharingTypeDisplay + onClicked: { + screenSharingItem.desc.screenSharingIndex = 0 + if( mainItem.conferenceModel.isLocalScreenSharingEnabled) + mainItem.callModel.setVideoSourceDescriptorModel(screenSharingItem.desc) + } + } + + ListView{ + id: screenList + property int selectedIndex: displayRadioButton.checked ? screenSharingItem.desc.screenSharingIndex : -1 + Layout.fillWidth: true + Layout.leftMargin: 15 + Layout.preferredWidth: parent.width + Layout.preferredHeight: 100 + orientation: ListView.Horizontal + model: ScreenProxyModel{} + spacing: 10 + delegate:Rectangle{ + width: 114 + 10 + height: 100 + border.color: 'red' + border.width: index == screenList.selectedIndex ? 1 : 0 + radius: 10 + ColumnLayout{ + anchors.fill: parent + anchors.margins: 5 + RoundedImage{ + Layout.preferredWidth: 114 + Layout.preferredHeight: 64 + backgroundColor: 'white' + source: 'image://screen/'+index + radius: 10 + } + Text{ + Layout.fillWidth: true + text: modelData.name + font.pointSize: IncallMenuStyle.list.pointSize + color: IncallMenuStyle.list.colorModel.color + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + MouseArea{ + anchors.fill: parent + onClicked: { + screenSharingItem.desc.screenSharingIndex = index + if( mainItem.conferenceModel.isLocalScreenSharingEnabled) + mainItem.callModel.setVideoSourceDescriptorModel(screenSharingItem.desc) + } + } + } + } + Rectangle{ + Layout.fillWidth: true + Layout.preferredHeight: IncallMenuStyle.list.border.width + color: IncallMenuStyle.list.border.colorModel.color + } + RadioButton{ + id: windowSharingRadioButton + Layout.fillWidth: true + Layout.leftMargin: 15 + text: "Partager une fenêtre" + font.pointSize: IncallMenuStyle.list.pointSize + ButtonGroup.group: screenSharingGroup + checked: screenSharingItem.desc && screenSharingItem.desc.isScreenSharing && screenSharingItem.desc.screenSharingType == LinphoneEnums.VideoSourceScreenSharingTypeWindow//screenList.selectedIndex < 0 + onClicked: DesktopTools.getWindowIdFromMouse(screenSharingItem.desc) + Connections{ + target: DesktopTools + onWindowIdSelectionEnded: if( mainItem.conferenceModel.isLocalScreenSharingEnabled) + mainItem.callModel.setVideoSourceDescriptorModel(screenSharingItem.desc) + } + } + Rectangle{ + Layout.fillWidth: true + Layout.preferredHeight: IncallMenuStyle.list.border.width + color: IncallMenuStyle.list.border.colorModel.color + } + Item{// Spacer + Layout.fillWidth: true + Layout.fillHeight: true + } + Item{// Item encapsulation because of a bug on width update when changing text + Layout.fillWidth: true + Layout.preferredHeight: screenSharingButton.fitHeight + Layout.margins: 20 + TextButtonB{ + id: screenSharingButton + anchors.fill: parent + visible: mainItem.screenSharingAvailable + enabled: displayRadioButton.checked || windowSharingRadioButton.checked + text: mainItem.conferenceModel && mainItem.conferenceModel.isLocalScreenSharingEnabled + //: 'Stop' : Text button to stop the screen sharing. + ? qsTr('incallMenuScreenSharingStop') + //: 'Share' : Text button to start the screen sharing. + : qsTr('incallMenuScreenSharingStart') + capitalization: Font.AllUppercase + onClicked: mainItem.conferenceModel.toggleScreenSharing() + Connections{ + target: mainItem.conferenceModel + onLocalScreenSharingChanged: (enabled) => {if(enabled) mainItem.callModel.setVideoSourceDescriptorModel(screenSharingItem.desc) } + } + } + } + Component.onCompleted: mainItem.isScreenSharingMenu = true + Component.onDestruction: mainItem.isScreenSharingMenu = false + } + } } } diff --git a/linphone-app/ui/modules/Linphone/Sticker/CameraSticker.qml b/linphone-app/ui/modules/Linphone/Sticker/CameraSticker.qml index a5b633269..542191e7f 100644 --- a/linphone-app/ui/modules/Linphone/Sticker/CameraSticker.qml +++ b/linphone-app/ui/modules/Linphone/Sticker/CameraSticker.qml @@ -23,6 +23,7 @@ DecorationSticker{ property alias isCameraFromDevice: camera.isCameraFromDevice property alias isReady: camera.isReady property alias isVideoEnabled: camera.isVideoEnabled + property alias isThumbnail: camera.isThumbnail property alias cameraQmlName: camera.qmlName property bool showCloseButton: false property bool showActiveSpeakerOverlay: true diff --git a/linphone-app/ui/modules/Linphone/Sticker/Sticker.qml b/linphone-app/ui/modules/Linphone/Sticker/Sticker.qml index 0a1b539d3..2703f892b 100644 --- a/linphone-app/ui/modules/Linphone/Sticker/Sticker.qml +++ b/linphone-app/ui/modules/Linphone/Sticker/Sticker.qml @@ -37,6 +37,7 @@ Item{ property alias deactivateCamera: camera.deactivateCamera readonly property alias isVideoEnabled: camera.isVideoEnabled property alias cameraQmlName: camera.cameraQmlName + property alias isThumbnail: camera.isThumbnail property alias image: avatar.image property alias avatarBackgroundColor: avatar.avatarBackgroundColor diff --git a/linphone-app/ui/modules/Linphone/Styles/Menus/IncallMenuStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Menus/IncallMenuStyle.qml index 570f30792..b7c760845 100644 --- a/linphone-app/ui/modules/Linphone/Styles/Menus/IncallMenuStyle.qml +++ b/linphone-app/ui/modules/Linphone/Styles/Menus/IncallMenuStyle.qml @@ -45,6 +45,8 @@ QtObject { property string audioOnlyIcon: 'conference_audio_only_custom' property string mediaIcon: 'micro_on_custom' property string participantsIcon: 'participants_custom' + property string screenSharingIcon: 'screen_sharing_custom' + property int width: 40 property int height: 40 } diff --git a/linphone-app/ui/views/App/Calls/Incall.qml b/linphone-app/ui/views/App/Calls/Incall.qml index ef83a4384..5d4124b82 100644 --- a/linphone-app/ui/views/App/Calls/Incall.qml +++ b/linphone-app/ui/views/App/Calls/Incall.qml @@ -9,6 +9,7 @@ import Linphone 1.0 import LinphoneEnums 1.0 import UtilsCpp 1.0 +import DesktopTools 1.0 import App.Styles 1.0 @@ -28,6 +29,8 @@ Rectangle { property bool previewIsReady : false property bool isFullScreen: false // Use this variable to test if we are in fullscreen. Do not test _fullscreen : we need to clean memory before having the window (see .js file) property bool layoutChanging: false + property bool isLocalScreenSharingEnabled: conferenceModel && conferenceModel.isLocalScreenSharingEnabled + property bool isScreenSharingEnabled: conferenceModel && conferenceModel.isScreenSharingEnabled property var _fullscreen: null on_FullscreenChanged: if( !_fullscreen) isFullScreen = false @@ -251,12 +254,41 @@ Rectangle { } } // Mode buttons + TextButtonB{ + id: screenSharingButton + visible: mainItem.isScreenSharingEnabled + Layout.preferredWidth: fitWidth + Icon{ + id: screenSharingIcon + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 10 + icon: IncallStyle.buttons.screenSharing.icon + iconSize: IncallStyle.buttons.screenSharing.iconSize + overwriteColor: screenSharingButton.textColor + } + button.leftPadding: screenSharingIcon.width + addHeight: 15 + addWidth: 75 + radius: height/4 + text: mainItem.isLocalScreenSharingEnabled ? "Arrêter la présentation" : "Présentation en cours" + onClicked: if(mainItem.isLocalScreenSharingEnabled) conferenceModel.toggleScreenSharing() + } ActionButton{ + visible: !screenSharingButton.visible && callModel && mainItem.conferenceModel && callModel.videoEnabled isCustom: true backgroundRadius: width/2 colorSet: IncallStyle.buttons.screenSharing - visible: false //TODO + toggled: rightMenu.visible && rightMenu.isScreenSharingMenu + + onClicked: { + if(toggled) + rightMenu.visible = false + else + rightMenu.showScreenSharingMenu() + } } + ActionButton { id: recordingSwitch isCustom: true @@ -637,10 +669,20 @@ Rectangle { onClicked: rightMenu.visible = !rightMenu.visible } } + Connections{ + target: DesktopTools + onWindowIdSelectionStarted: window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), { + descriptionText: "Click on the window that you want to share." + , showButtonOnly: 42 + , buttonTexts : [''] + }) + onWindowIdSelectionEnded: window.detachVirtualWindow() + } // --------------------------------------------------------------------------- // TelKeypad. // --------------------------------------------------------------------------- + CallStatistics { id: callStatistics diff --git a/linphone-app/ui/views/App/Calls/IncallActiveSpeaker.qml b/linphone-app/ui/views/App/Calls/IncallActiveSpeaker.qml index 7b7579a01..868d243df 100644 --- a/linphone-app/ui/views/App/Calls/IncallActiveSpeaker.qml +++ b/linphone-app/ui/views/App/Calls/IncallActiveSpeaker.qml @@ -27,14 +27,15 @@ Item { property bool cameraEnabled: true property bool isConference: callModel && callModel.isConference property bool isConferenceReady: isConference && callModel.conferenceModel && callModel.conferenceModel.isReady - + property ConferenceModel conferenceModel: callModel && callModel.conferenceModel + property bool isScreenSharingEnabled: conferenceModel && conferenceModel.isScreenSharingEnabled + property bool isLocalScreenSharingEnabled: conferenceModel && conferenceModel.isLocalScreenSharingEnabled property int participantCount: isConference ? allDevices.count + 1 : 2 // +me. allDevices==0 if !conference property ParticipantDeviceProxyModel participantDevices : ParticipantDeviceProxyModel { id: allDevices callModel: mainItem.callModel - showMe: false - + showMe: false onConferenceCreated: cameraView.resetCamera() } @@ -59,7 +60,7 @@ Item { || !mainItem.isConferenceReady : (callModel && (callModel.pausedByUser || callModel.status === CallModel.CallStatusPaused || !callModel.videoEnabled) ) || currentDevice && !currentDevice.videoEnabled - isPreview: !preview.visible && mainItem.participantCount == 1 + isPreview: !preview.visible && mainItem.participantCount == 1 && !isScreenSharingEnabled onIsPreviewChanged: {cameraView.resetCamera() } isCameraFromDevice: isPreview isPaused: isPreview && callModel.pausedByUser @@ -86,7 +87,7 @@ Item { height: visible ? miniViews.cellHeight : 0 width: 16 * height / 9 - visible: mainItem.isConferenceReady && allDevices.count >= 1 + visible: mainItem.isConferenceReady && (allDevices.count >= 1 || mainItem.isLocalScreenSharingEnabled) || (!mainItem.isConference && mainItem.callModel && mainItem.callModel.cameraEnabled)// use videoEnabled if we want to show the preview sticker Loader{ @@ -152,7 +153,7 @@ Item { id: miniViews property int cellHeight: 150 anchors.fill: parent - model : mainItem.isConference && mainItem.participantDevices.count > 1 ? mainItem.participantDevices : [] + model : /*mainItem.isConference && mainItem.participantDevices.count > 1 ? */mainItem.participantDevices //: [] spacing: 0 verticalLayoutDirection: ListView.BottomToTop fitCacheToContent: false @@ -162,7 +163,7 @@ Item { delegate:Item{ height: visible ? miniViews.cellHeight + 15 : 0 width: visible ? miniViews.width : 0 - visible: cameraView.currentDevice != modelData + visible: cameraView.currentDevice != modelData || mainItem.isScreenSharingEnabled clip:false Sticker{ id: miniView @@ -172,8 +173,9 @@ Item { anchors.rightMargin: 3 anchors.bottomMargin: 18 cameraQmlName: 'S_'+index + isThumbnail: true deactivateCamera: (!mainItem.isConferenceReady || !mainItem.isConference) - && (index <0 || !mainItem.cameraEnabled || (!modelData.videoEnabled) || (callModel && callModel.pausedByUser) ) + && (index <0 || !mainItem.cameraEnabled || (!modelData.thumbnailVideoEnabled) || (callModel && callModel.pausedByUser) ) currentDevice: modelData.isPreview ? null : modelData callModel: modelData.isPreview ? null : mainItem.callModel isCameraFromDevice: mainItem.isConference diff --git a/linphone-app/ui/views/App/Calls/IncallFullscreen.qml b/linphone-app/ui/views/App/Calls/IncallFullscreen.qml index 32508112e..0cf87d932 100644 --- a/linphone-app/ui/views/App/Calls/IncallFullscreen.qml +++ b/linphone-app/ui/views/App/Calls/IncallFullscreen.qml @@ -38,6 +38,8 @@ Window { console.info('[QML] Call becomes not ready : exit fullscreen') window.exit() } + property bool isLocalScreenSharingEnabled: conferenceModel && conferenceModel.isLocalScreenSharingEnabled + property bool isScreenSharingEnabled: conferenceModel && conferenceModel.isScreenSharingEnabled // --------------------------------------------------------------------------- function exit (cb) { @@ -223,11 +225,39 @@ Window { font.pointSize: IncallStyle.title.pointSize } // Mode buttons + TextButtonB{ + id: screenSharingButton + visible: window.isScreenSharingEnabled + Layout.preferredWidth: fitWidth + Icon{ + id: screenSharingIcon + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 10 + icon: IncallStyle.buttons.screenSharing.icon + iconSize: IncallStyle.buttons.screenSharing.iconSize + overwriteColor: screenSharingButton.textColor + } + button.leftPadding: screenSharingIcon.width + addHeight: 15 + addWidth: 75 + radius: height/4 + text: window.isLocalScreenSharingEnabled ? "Arrêter la présentation" : "Présentation en cours" + onClicked: if(window.isLocalScreenSharingEnabled) conferenceModel.toggleScreenSharing() + } ActionButton{ + visible: !screenSharingButton.visible && callModel && window.conferenceModel && callModel.videoEnabled isCustom: true backgroundRadius: width/2 colorSet: IncallStyle.buttons.screenSharing - visible: false //TODO + toggled: rightMenu.visible && rightMenu.isScreenSharingMenu + + onClicked: { + if(toggled) + rightMenu.visible = false + else + rightMenu.showScreenSharingMenu() + } } ActionButton { id: recordingSwitch diff --git a/linphone-app/ui/views/App/Settings/Dialogs/SettingsVideoPreview.qml b/linphone-app/ui/views/App/Settings/Dialogs/SettingsVideoPreview.qml index c728d2686..6e39981ef 100644 --- a/linphone-app/ui/views/App/Settings/Dialogs/SettingsVideoPreview.qml +++ b/linphone-app/ui/views/App/Settings/Dialogs/SettingsVideoPreview.qml @@ -3,6 +3,7 @@ import QtGraphicalEffects 1.12 import Common 1.0 import Linphone 1.0 +import DesktopTools 1.0 import App.Styles 1.0 @@ -11,6 +12,8 @@ import App.Styles 1.0 DialogPlus { id: dialog + + buttons: [ TextButtonB { text: qsTr('confirm') @@ -26,8 +29,9 @@ DialogPlus { width: SettingsVideoPreviewStyle.width // --------------------------------------------------------------------------- - Item{ + MouseArea{ anchors.fill: parent + onClicked: DesktopTools.getWindowIdFromMouse() CameraView{ id: previewLoader anchors.centerIn: parent diff --git a/linphone-app/ui/views/App/Settings/SettingsVideo.qml b/linphone-app/ui/views/App/Settings/SettingsVideo.qml index 00e29665a..36978329a 100644 --- a/linphone-app/ui/views/App/Settings/SettingsVideo.qml +++ b/linphone-app/ui/views/App/Settings/SettingsVideo.qml @@ -5,6 +5,8 @@ import Common 1.0 import Linphone 1.0 import LinphoneEnums 1.0 import Utils 1.0 +import Units 1.0 +import DesktopTools 1.0 import App.Styles 1.0 @@ -288,6 +290,7 @@ TabContainer { } } FormLine { + width: parent.width FormGroup { //: 'Default video layout' : Label to choose the default layout in video conference. label: qsTr('videoLayout') @@ -303,6 +306,17 @@ TabContainer { onActivated: SettingsModel.videoConferenceLayout = model[index].value } } + FormGroup { + label: 'Maximum thumbnails' + + NumericField { + maxValue: 60 + minValue: 0 + text: SettingsModel.conferenceMaxThumbnails + + onEditingFinished: SettingsModel.conferenceMaxThumbnails = text + } + } } } } diff --git a/linphone-app/ui/views/App/Styles/Calls/IncallStyle.qml b/linphone-app/ui/views/App/Styles/Calls/IncallStyle.qml index 21a2e0077..d5de421c1 100644 --- a/linphone-app/ui/views/App/Styles/Calls/IncallStyle.qml +++ b/linphone-app/ui/views/App/Styles/Calls/IncallStyle.qml @@ -226,9 +226,12 @@ QtObject { property var backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 's_n_b_bg') property var backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 's_h_b_bg') property var backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 's_p_b_bg') + property var backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_c', icon, 's_p_b_bg') property var foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 's_n_b_fg') property var foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 's_h_b_fg') property var foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 's_p_b_fg') + property var foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_c', icon, 's_p_b_fg') + } property QtObject record: QtObject { property int iconSize: 40 diff --git a/linphone-sdk b/linphone-sdk index e310a0606..119c43076 160000 --- a/linphone-sdk +++ b/linphone-sdk @@ -1 +1 @@ -Subproject commit e310a060639474dd333239810d86d14db5f9c83d +Subproject commit 119c43076dbfc48ee25642c3bff52b975b08194e