From 0722aa64eba45d6aada165cd1e57b9edcba8ad4d Mon Sep 17 00:00:00 2001 From: Nicolas Michon Date: Wed, 15 Jan 2020 14:06:57 +0100 Subject: [PATCH] work in progress --- CMakeLists.txt | 9 +- README.md | 8 +- assets/images/warning.svg | 90 + assets/languages/de.ts | 36 + assets/languages/en.ts | 36 + assets/languages/fr.ts | 1817 ----------------- assets/languages/fr_FR.ts | 36 + assets/languages/ja.ts | 36 + assets/languages/lt.ts | 36 + assets/languages/pt_BR.ts | 36 + assets/languages/ru.ts | 36 + assets/languages/sv.ts | 36 + assets/languages/tr.ts | 36 + cmake_builder/CMakeLists.txt | 6 +- create_appimage.sh | 13 + linphone-sdk | 2 +- resources.qrc | 1 + src/components/call/CallModel.cpp | 5 +- src/components/conference/ConferenceModel.cpp | 3 +- src/components/core/CoreHandlers.cpp | 5 + src/components/core/CoreHandlers.hpp | 6 + .../AbstractEventCountNotifier.cpp | 2 +- src/components/settings/SettingsModel.cpp | 1054 ++++++---- src/components/settings/SettingsModel.hpp | 54 +- .../sip-addresses/SipAddressesModel.cpp | 40 +- .../sip-addresses/SipAddressesModel.hpp | 3 + src/utils/LinphoneUtils.hpp | 11 - src/utils/MediastreamerUtils.cpp | 141 ++ src/utils/MediastreamerUtils.hpp | 102 + ui/modules/Common/Form/ActionButton.qml | 3 +- ui/modules/Common/Form/ActionSwitch.qml | 3 +- ui/modules/Common/Tooltip/Tooltip.qml | 18 +- ui/modules/Common/qmldir | 2 + ui/views/App/Calls/CallsWindow.qml | 2 +- .../Calls/Dialogs/MultimediaParameters.qml | 15 + ui/views/App/Main/ContactEdit.qml | 4 + ui/views/App/Main/Conversation.js | 4 + ui/views/App/Main/Conversation.qml | 7 + ui/views/App/Main/Dialogs/ManageAccounts.qml | 7 + ui/views/App/Main/MainWindow.qml | 4 + ui/views/App/Settings/SettingsAudio.qml | 124 +- ui/views/App/Settings/SettingsWindow.qml | 15 +- .../Styles/Settings/SettingsAudioStyle.qml | 3 + 43 files changed, 1580 insertions(+), 2327 deletions(-) create mode 100644 assets/images/warning.svg delete mode 100644 assets/languages/fr.ts create mode 100755 create_appimage.sh create mode 100644 src/utils/MediastreamerUtils.cpp create mode 100644 src/utils/MediastreamerUtils.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f4f06cf10..c7f865d1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,9 +98,11 @@ set(QT5_PACKAGES_OPTIONAL TextToSpeech) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") find_package(LinphoneCxx CONFIG REQUIRED) +find_package(Linphone CONFIG REQUIRED) find_package(bctoolbox CONFIG REQUIRED) find_package(belcard CONFIG REQUIRED) find_package(Mediastreamer2 CONFIG REQUIRED) +find_package(ortp CONFIG REQUIRED) find_package(Minizip REQUIRED) @@ -156,6 +158,7 @@ set(SOURCES src/components/timeline/TimelineModel.cpp src/components/url-handlers/UrlHandlers.cpp src/utils/LinphoneUtils.cpp + src/utils/MediastreamerUtils.cpp src/utils/QExifImageHeader.cpp src/utils/Utils.cpp ) @@ -215,6 +218,7 @@ set(HEADERS src/components/timeline/TimelineModel.hpp src/components/url-handlers/UrlHandlers.hpp src/utils/LinphoneUtils.hpp + src/utils/MediastreamerUtils.hpp src/utils/QExifImageHeader.hpp src/utils/Utils.hpp ) @@ -367,13 +371,10 @@ else () add_executable(${TARGET_NAME} $ ${MAIN_FILE}) endif () -if (NOT WIN32) - add_dependencies(update_translations check_qml) -endif () set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${EXECUTABLE_NAME}") set(INCLUDED_DIRECTORIES "${LINPHONECXX_INCLUDE_DIRS}" "${BELCARD_INCLUDE_DIRS}" "${BCTOOLBOX_INCLUDE_DIRS}" "${MEDIASTREAMER2_INCLUDE_DIRS}" "${MINIZIP_INCLUDE_DIRS}") -set(LIBRARIES ${BCTOOLBOX_CORE_LIBRARIES} ${BELCARD_LIBRARIES} ${LINPHONECXX_LIBRARIES} ${MINIZIP_LIBRARIES}) +set(LIBRARIES ${BCTOOLBOX_CORE_LIBRARIES} ${BELCARD_LIBRARIES} ${LINPHONE_LIBRARIES} ${LINPHONECXX_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES} ${ORTP_LIBRARIES} ${MINIZIP_LIBRARIES}) foreach (package ${QT5_PACKAGES}) list(APPEND INCLUDED_DIRECTORIES "${Qt5${package}_INCLUDE_DIRS}") diff --git a/README.md b/README.md index 20f6bc054..be471cf59 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,12 @@ Linphone is a free VoIP and video softphone based on the SIP protocol. ## Getting started +Installing dependencies: + +apt-get install libqt53dcore5:amd64 libqt53dextras5:amd64 libqt53dinput5:amd64 libqt53dlogic5:amd64 libqt53dquick5:amd64 libqt53dquickextras5:amd64 libqt53dquickinput5:amd64 libqt53dquickrender5:amd64 libqt53drender5:amd64 libqt5concurrent5:amd64 libqt5core5a:amd64 libqt5dbus5:amd64 libqt5designer5:amd64 libqt5designercomponents5:amd64 libqt5gui5:amd64 libqt5help5:amd64 libqt5multimedia5:amd64 libqt5multimedia5-plugins:amd64 libqt5multimediawidgets5:amd64 libqt5network5:amd64 libqt5opengl5:amd64 libqt5opengl5-dev:amd64 libqt5positioning5:amd64 libqt5printsupport5:amd64 libqt5qml5:amd64 libqt5quick5:amd64 libqt5quickcontrols2-5:amd64 libqt5quickparticles5:amd64 libqt5quicktemplates2-5:amd64 libqt5quicktest5:amd64 libqt5quickwidgets5:amd64 libqt5script5:amd64 libqt5scripttools5:amd64 libqt5sensors5:amd64 libqt5serialport5:amd64 libqt5sql5:amd64 libqt5sql5-sqlite:amd64 libqt5svg5:amd64 libqt5svg5-dev:amd64 libqt5test5:amd64 libqt5webchannel5:amd64 libqt5webengine-data libqt5webenginecore5:amd64 libqt5webenginewidgets5:amd64 libqt5webkit5:amd64 libqt5widgets5:amd64 libqt5x11extras5:amd64 libqt5xml5:amd64 libqt5xmlpatterns5:amd64 qt5-default:amd64 qt5-doc qt5-gtk-platformtheme:amd64 qt5-qmake:amd64 qt5-qmltooling-plugins:amd64 + + + Here are the general instructions to build linphone for desktop. The specific instructions for each build platform is described just below. 1. Install some build tools: `CMake`, `Python` and `Qt5` (_5.9 or newer_). `C++11` support is required! @@ -68,7 +74,7 @@ Before you install packages with Brew, you may have to change directories permis 3. Open a Windows command line (cmd.exe) in the current directory and run: - python prepare.py -G "Visual Studio 14 2015" -DENABLE_DOC=OFF + python prepare.py -G "Visual Studio 15 2017" -DENABLE_DOC=OFF 4. Run the following command in the root directory of linphone-desktop: diff --git a/assets/images/warning.svg b/assets/images/warning.svg new file mode 100644 index 000000000..57e2692d2 --- /dev/null +++ b/assets/images/warning.svg @@ -0,0 +1,90 @@ + + + + + + image/svg+xml + + chat_error + + + + + + chat_error + Created with Sketch. + + + + + + + + + + + + + diff --git a/assets/languages/de.ts b/assets/languages/de.ts index 8278cfa4c..9dbe9c305 100644 --- a/assets/languages/de.ts +++ b/assets/languages/de.ts @@ -615,6 +615,10 @@ Server URL ist nicht konfiguriert. abortEditDescriptionText Möchten Sie die Änderungen an diesem Kontakt verwerfen? + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ Server URL ist nicht konfiguriert. removeAllEntriesDescription Möchten Sie diese Historie wirklich löschen? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -958,6 +974,10 @@ Server URL ist nicht konfiguriert. smartSearchBarTooltip Verwenden das intelligente Suchfeld um Audio- und Videocalls zu starten, Nachrichten zu senden oder Kontakt hinzuzufügen. Geben Sie die SIP-Adresse oder Username Ihres Kontaktes ein. + + newConferenceButton + + MainWindowMenuBar @@ -1152,6 +1172,22 @@ Server URL ist nicht konfiguriert. showAudioCodecsLabel + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat diff --git a/assets/languages/en.ts b/assets/languages/en.ts index b5aabfbff..1d054dbf6 100644 --- a/assets/languages/en.ts +++ b/assets/languages/en.ts @@ -615,6 +615,10 @@ Server url not configured. abortEditDescriptionText Are you sure you want to cancel the contact modification? + + tooltipShowConversation + Show conversation + Contacts @@ -657,6 +661,18 @@ Server url not configured. removeAllEntriesDescription Are you sure you want to clean this history? + + tooltipContactEdit + Edit contact + + + tooltipContactAdd + Add contact + + + cleanHistory + Delete history + CreateAppSipAccount @@ -963,6 +979,10 @@ Click here: <a href="%1">%1</a> calls, send a message or add a new contact. Just enter your friend's SIP address or username. + + newConferenceButton + Start conference call + MainWindowMenuBar @@ -1157,6 +1177,22 @@ your friend's SIP address or username. showAudioCodecsLabel Show audio codecs + + playbackGainLabel + Playback gain + + + captureGainLabel + Capture gain + + + audioTestLabel + Capture level + + + audioSettingsInCallWarning + Audio call in progress: some settings are not available. + SettingsCallsChat diff --git a/assets/languages/fr.ts b/assets/languages/fr.ts deleted file mode 100644 index c23fdb9a6..000000000 --- a/assets/languages/fr.ts +++ /dev/null @@ -1,1817 +0,0 @@ - - - About - - ok - - - - - ActivateAppSipAccountWithEmail - - activateAppSipAccount - - - - confirmAction - - - - activationSteps - - - - - ActivateAppSipAccountWithPhoneNumber - - activateAppSipAccount - - - - confirmAction - - - - activationSteps - - - - - App - - commandLineOptionVerbose - - - - commandLineOptionConfig - - - - applicationDescription - - - - commandLineOptionIconified - - - - commandLineOptionConfigArg - - - - commandLineOptionHelp - - - - commandLineOptionVersion - - - - commandLineOptionCliHelp - - - - commandLineDescription - - - - restore - - - - quit - - - - settings - - - - about - - - - - AssistantAbstractView - - back - - - - - AssistantHome - - useAppSipAccount - - - - useOtherSipAccount - - - - fetchRemoteConfiguration - - - - homeTitle - - - - homeDescription - - - - createAppSipAccount - - - - - AssistantModel - - loginWithUsernameFailed - - - - usernameStatusTooShort - - - - usernameStatusTooLong - - - - usernameStatusInvalidCharacters - - - - usernameStatusInvalid - - - - passwordStatusTooShort - - - - passwordStatusTooLong - - - - passwordStatusInvalidCharacters - - - - passwordStatusMissingCharacters - - - - requestFailed - - - - emailStatusMalformed - - - - emailStatusMalformedInvalidCharacters - - - - cannotSendSms - - - - accountAlreadyExists - - - - smsActivationFailed - - - - emailActivationFailed - - - - phoneNumberStatusInvalid - - - - phoneNumberStatusTooShort - - - - phoneNumberStatusTooLong - - - - phoneNumberStatusInvalidCountryCode - - - - loginWithPhoneNumberFailed - - - - unableToAddAccount - - - - - AuthenticationRequest - - cancel - - - - confirm - - - - identityLabel - - - - passwordLabel - - - - authenticationRequestDescription - - - - userIdLabel - - - - realmLabel - - - - - CallModel - - callStatsCodec - - - - callStatsUploadBandwidth - - - - callStatsDownloadBandwidth - - - - callStatsEstimatedDownloadBandwidth - - - - callStatsIceState - - - - callStatsIpFamily - - - - callStatsSenderLossRate - - - - callStatsReceiverLossRate - - - - callStatsJitterBuffer - - - - callStatsSentVideoDefinition - - - - callStatsReceivedVideoDefinition - - - - iceStateNotActivated - - - - iceStateFailed - - - - iceStateInProgress - - - - iceStateReflexiveConnection - - - - iceStateHostConnection - - - - iceStateRelayConnection - - - - iceStateInvalid - - - - callErrorDeclined - - - - callErrorNotFound - - - - callErrorBusy - - - - callErrorNotAcceptable - - - - callStatsReceivedFramerate - - - - callStatsSentFramerate - - - - - CallSipAddress - - cancel - - - - callSipAddressDescription - - - - - CallStatistics - - audioStatsLabel - - - - videoStatsLabel - - - - - CallTransfer - - cancel - - - - callTransferDescription - - - - - Calls - - acceptAudioCall - - - - acceptVideoCall - - - - terminateCall - - - - resumeCall - - - - transferCall - - - - callPause - - - - - CallsWindow - - callsTitle - - - - acceptClosingDescription - - - - - Chat - - newMessagePlaceholder - - - - noFileTransferUrl - - - - isComposing - - - - - Cli - - appCliDescription - - - - uriCommandLineSyntax - - - - cliCommandLineSyntax - - - - commandsName - - - - showFunctionDescription - - - - callFunctionDescription - - - - initiateConferenceFunctionDescription - - - - joinConferenceFunctionDescription - - - - joinConferenceAsFunctionDescription - - - - - CodecsViewer - - codecMime - - - - codecEncoderDescription - - - - codecEncoderClockRate - - - - codecBitrate - - - - codecRecvFmtp - - - - codecStatus - - - - - Conference - - conferenceTitle - - - - - ConferenceControls - - conference - - - - - ConferenceManager - - conferenceManagerDescription - - - - cancel - - - - confirm - - - - - ConfirmDialog - - cancel - - - - confirm - - - - - ContactEdit - - removeContactDescription - - - - sipAccounts - - - - address - - - - emails - - - - webSites - - - - avatarChooserTitle - - - - companies - - - - save - - - - cancel - - - - sipAccountsPlaceholder - - - - companiesPlaceholder - - - - emailsPlaceholder - - - - webSitesPlaceholder - - - - street - - - - postalCode - - - - country - - - - locality - - - - abortEditDescriptionText - - - - - Contacts - - searchContactPlaceholder - - - - selectAllContacts - - - - selectConnectedContacts - - - - addContact - - - - removeContactDescription - - - - - Conversation - - displayCallsAndMessages - - - - displayCalls - - - - displayMessages - - - - removeAllEntriesDescription - - - - - CreateAppSipAccount - - createAppSipAccountDescription - - - - createAppSipAccountTitle - - - - withPhoneNumber - - - - withEmailAddress - - - - - CreateAppSipAccountWithEmail - - createAppSipAccountTitle - - - - confirmAction - - - - usernameLabel - - - - emailLabel - - - - passwordLabel - - - - passwordConfirmationLabel - - - - passwordConfirmationError - - - - quitWarning - - - - displayNameLabel - - - - - CreateAppSipAccountWithPhoneNumber - - createAppSipAccountTitle - - - - countryLabel - - - - phoneNumberLabel - - - - usernameLabel - - - - displayNameLabel - - - - confirmAction - - - - quitWarning - - - - - DroppableTextArea - - fileChooserTitle - - - - dropYourAttachment - - - - attachmentTooltip - - - - - Event - - incomingCall - - - - outgoingCall - - - - declinedIncomingCall - - - - declinedOutgoingCall - - - - endedCall - - - - missedIncomingCall - - - - missedOutgoingCall - - - - - FetchRemoteConfiguration - - confirmAction - - - - fetchRemoteConfigurationTitle - - - - urlLabel - - - - remoteProvisioningError - - - - remoteProvisioningUpdateDescription - - - - - Home - - howToDescription - - - - howToTitle - - - - inviteDescription - - - - inviteTitle - - - - accountAssistantDescription - - - - accountAssistantTitle - - - - assistantButton - - - - showTooltips - - - - inviteButton - - - - - Incall - - acceptVideoDescription - - - - pendingRequestLabel - - - - securedStringFormat - - - - callNotSecured - - - - takeSnapshotLabel - - - - startRecordingLabel - - - - stopRecordingLabel - - - - - IncallFullscreenWindow - - takeSnapshotLabel - - - - startRecordingLabel - - - - stopRecordingLabel - - - - - InviteFriends - - enterEmailLabel - - - - messageLabel - - - - cancel - - - - confirm - - - - inviteFriendsTitle - - - - defaultMessage - - - - defaultSubject - - - - forcedMessage - - - - - MainWindow - - mainSearchBarPlaceholder - - - - homeEntry - - - - contactsEntry - - - - autoAnswerStatus - - - - smartSearchBarTooltip - - - - - MainWindowMenuBar - - settings - - - - about - - - - quit - - - - - ManageAccounts - - ok - - - - selectPresenceLabel - - - - selectAccountLabel - - - - - Message - - menuCopy - - - - menuPlayMe - - - - - MultimediaParameters - - ok - - - - - Notifier - - newVersionAvailable - - - - newFileMessage - - - - - OnlineInstallerDialog - - confirm - - - - onlineInstallerExtractingDescription - - - - onlineInstallerDownloadingDescription - - - - onlineInstallerFinishedDescription - - - - onlineInstallerFailedDescription - - - - - OutgoingMessage - - messageError - - - - messageRead - - - - messageDelivered - - - - - Presence - - presenceOnline - - - - presenceBusy - - - - presenceDoNotDisturb - - - - presenceOffline - - - - - SettingsAdvanced - - logsTitle - - - - logsFolderLabel - - - - sendLogs - - - - logsUploadUrlLabel - - - - logsUploadFailed - - - - logsEnabledLabel - - - - cleanLogs - - - - cleanLogsDescription - - - - developerSettingsTitle - - - - developerSettingsEnabledLabel - - - - - SettingsAudio - - audioTitle - - - - playbackDeviceLabel - - - - captureDeviceLabel - - - - ringerDeviceLabel - - - - ringLabel - - - - echoCancellationLabel - - - - audioCodecsTitle - - - - showAudioCodecsLabel - - - - - SettingsCallsChat - - fileServerLabel - - - - encryptWithLimeLabel - - - - limeDisabled - - - - limeRequired - - - - limePreferred - - - - chatTitle - - - - callsTitle - - - - encryptionLabel - - - - noEncryption - - - - autoAnswerLabel - - - - autoAnswerDelayLabel - - - - autoAnswerWithVideoLabel - - - - chatEnabledLabel - - - - callRecorderEnabledLabel - - - - chatNotificationSoundEnabledLabel - - - - chatNotificationSoundLabel - - - - conferenceEnabledLabel - - - - contactsTitle - - - - contactsEnabledLabel - - - - muteMicrophoneEnabledLabel - - - - outgoingCallsEnabledLabel - - - - showTelKeypadAutomaticallyLabel - - - - automaticallyRecordCallsLabel - - - - keepCallsWindowInBackgroundLabel - - - - callPauseEnabledLabel - - - - - SettingsNetwork - - sendDtmfsLabel - - - - allowIpV6Label - - - - transportTitle - - - - natAndFirewallTitle - - - - enableIceLabel - - - - stunServerLabel - - - - enableTurnLabel - - - - turnUserLabel - - - - turnPasswordLabel - - - - networkProtocolAndPortsTitle - - - - sipUdpPortLabel - - - - sipTcpPortLabel - - - - audioRtpUdpPortLabel - - - - videoRtpUdpPortLabel - - - - portHeader - - - - randomPortHeader - - - - enabledPortHeader - - - - dscpFieldsTitle - - - - sipFieldLabel - - - - audioRtpStreamFieldLabel - - - - videoRtpStreamFieldLabel - - - - bandwidthControlTitle - - - - downloadSpeedLimitLabel - - - - uploadSpeedLimitLabel - - - - enableAdaptiveRateControlLabel - - - - presenceTitle - - - - rlsUriLabel - - - - rlsUriAuto - - - - rlsUriDisabled - - - - showNetworkSettingsLabel - - - - generalTitle - - - - - SettingsSipAccounts - - defaultIdentityTitle - - - - defaultUsernameLabel - - - - defaultSipAddressLabel - - - - proxyAccountsTitle - - - - eraseAllPasswords - - - - addAccount - - - - editHeader - - - - deleteHeader - - - - deleteAccountDescription - - - - eraseAllPasswordsDescription - - - - defaultDisplayNameLabel - - - - assistantTitle - - - - createAppSipAccountEnabledLabel - - - - useAppSipAccountEnabledLabel - - - - useOtherSipAccountEnabledLabel - - - - fetchRemoteConfigurationEnabledLabel - - - - assistantSupportsPhoneNumbersLabel - - - - - SettingsSipAccountsEdit - - sipAddressLabel - - - - transportLabel - - - - serverAddressLabel - - - - registrationDurationLabel - - - - routeLabel - - - - contactParamsLabel - - - - publishPresenceLabel - - - - avpfIntervalLabel - - - - registerEnabledLabel - - - - avpfEnabledLabel - - - - cancel - - - - confirm - - - - invalidSipAddress - - - - invalidServerAddress - - - - invalidRoute - - - - enableIceLabel - - - - stunServerLabel - - - - enableTurnLabel - - - - turnUserLabel - - - - turnPasswordLabel - - - - natAndFirewallTitle - - - - mainSipAccountSettingsTitle - - - - - SettingsUi - - pathsTitle - - - - savedScreenshotsLabel - - - - savedCallsLabel - - - - languagesTitle - - - - languagesLabel - - - - systemLocale - - - - cleanAvatars - - - - cleanAvatarsDescription - - - - downloadLabel - - - - setLocaleDescription - - - - otherTitle - - - - exitOnCloseLabel - - - - dataTitle - - - - autoStartLabel - - - - - SettingsVideo - - videoInputDeviceLabel - - - - videoFramerateLabel - - - - videoCaptureTitle - - - - videoPresetLabel - - - - presetDefault - - - - presetHighFps - - - - presetCustom - - - - videoSizeLabel - - - - videoCodecsTitle - - - - showCameraPreview - - - - showVideoCodecsLabel - - - - - SettingsVideoPreview - - confirm - - - - - SettingsWindow - - settingsTitle - - - - sipAccountsTab - - - - audioTab - - - - videoTab - - - - callsAndChatTab - - - - networkTab - - - - uiTab - - - - validButton - - - - uiAdvanced - - - - - SmartSearchBar - - addContact - - - - - Timeline - - timelineTitle - - - - - UseAppSipAccount - - confirmAction - - - - useAppSipAccountTitle - - - - useUsernameToLogin - - - - quitWarning - - - - - UseAppSipAccountWithPhoneNumber - - countryLabel - - - - phoneNumberLabel - - - - - UseAppSipAccountWithUsername - - usernameLabel - - - - passwordLabel - - - - - UseOtherSipAccount - - confirmAction - - - - useOtherSipAccountTitle - - - - usernameLabel - - - - displayNameLabel - - - - sipDomainLabel - - - - passwordLabel - - - - transportLabel - - - - addOtherSipAccountError - - - - - ZrtpTokenAuthentication - - confirmSas - - - - codeA - - - - codeB - - - - deny - - - - accept - - - - - linphone-utils - - downloadCodecDescription - - - - \ No newline at end of file diff --git a/assets/languages/fr_FR.ts b/assets/languages/fr_FR.ts index 2bc46ecbe..25529b4ac 100644 --- a/assets/languages/fr_FR.ts +++ b/assets/languages/fr_FR.ts @@ -615,6 +615,10 @@ Url du serveur non configurée. abortEditDescriptionText Êtes-vous sûr de vouloir annuler l'édition du contact ? + + tooltipShowConversation + Allez à la conversation + Contacts @@ -657,6 +661,18 @@ Url du serveur non configurée. removeAllEntriesDescription Êtes-vous sûr de vouloir supprimer cet historique ? + + tooltipContactEdit + Editer le contact + + + tooltipContactAdd + Ajouter le contact + + + cleanHistory + Supprimer l'historique + CreateAppSipAccount @@ -961,6 +977,10 @@ Cliquez ici : <a href="%1">%1</a> smartSearchBarTooltip Utilisez la barre de recherche intelligente pour lancer des appels audio et vidéo, envoyer un message ou ajouter un contact. Entrez simplement l'adresse SIP ou le nom d'utilisateur de votre contact. + + newConferenceButton + Démarrer une conférence + MainWindowMenuBar @@ -1155,6 +1175,22 @@ Cliquez ici : <a href="%1">%1</a> showAudioCodecsLabel Afficher les codecs audio + + playbackGainLabel + Gain de lecture + + + captureGainLabel + Gain de capture + + + audioTestLabel + Niveau micro + + + audioSettingsInCallWarning + Appel en cours: certains paramètres sont inaccessibles + SettingsCallsChat diff --git a/assets/languages/ja.ts b/assets/languages/ja.ts index 828a1b5e8..8e373ed24 100644 --- a/assets/languages/ja.ts +++ b/assets/languages/ja.ts @@ -615,6 +615,10 @@ abortEditDescriptionText + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ removeAllEntriesDescription 履歴をクリアしてよろしいですか? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -958,6 +974,10 @@ smartSearchBarTooltip + + newConferenceButton + + MainWindowMenuBar @@ -1152,6 +1172,22 @@ showAudioCodecsLabel + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat diff --git a/assets/languages/lt.ts b/assets/languages/lt.ts index 7fe322b6a..e29a5cfe8 100644 --- a/assets/languages/lt.ts +++ b/assets/languages/lt.ts @@ -615,6 +615,10 @@ Nesukonfigūruotas serverio url. abortEditDescriptionText + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ Nesukonfigūruotas serverio url. removeAllEntriesDescription Ar tikrai norite išvalyti šią istoriją? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -963,6 +979,10 @@ Spustelėkite čia: <a href="%1">%1</a> garso ir vaizdo skambučius, siųsti žinutę ar pridėti naują kontaktą. Tiesiog, įveskite savo draugo SIP adresą ar naudotojo vardą. + + newConferenceButton + + MainWindowMenuBar @@ -1157,6 +1177,22 @@ Tiesiog, įveskite savo draugo SIP adresą ar naudotojo vardą. showAudioCodecsLabel Rodyti garso kodekus + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat diff --git a/assets/languages/pt_BR.ts b/assets/languages/pt_BR.ts index bdf5c90c3..7a86f5c89 100644 --- a/assets/languages/pt_BR.ts +++ b/assets/languages/pt_BR.ts @@ -615,6 +615,10 @@ URL do servidor não configurado. abortEditDescriptionText Tem certeza de que deseja cancelar a modificação do contato? + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ URL do servidor não configurado. removeAllEntriesDescription Tem certeza de que deseja limpar este histórico? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -963,6 +979,10 @@ Click aqui: <a href="%1">%1</a> enviar uma mensagem ou adicionar um novo contato. Basta entrar o endereço SIP ou nome de usuário do seu amigo. + + newConferenceButton + + MainWindowMenuBar @@ -1157,6 +1177,22 @@ o endereço SIP ou nome de usuário do seu amigo. showAudioCodecsLabel Mostrar codecs de áudio + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat diff --git a/assets/languages/ru.ts b/assets/languages/ru.ts index 4ca562f9a..9d70f67fe 100644 --- a/assets/languages/ru.ts +++ b/assets/languages/ru.ts @@ -615,6 +615,10 @@ abortEditDescriptionText Вы уверены, что хотите отменить изменение контакта? + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ removeAllEntriesDescription Вы уверены, что хотите очистить эту историю? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -961,6 +977,10 @@ smartSearchBarTooltip Используйте умную поисковую строку, чтобы сразу начать аудио или видео вызов, отправить сообщение или добавить новый контакт. Просто введите SIP адрес или имя пользователя вашего контакта. + + newConferenceButton + + MainWindowMenuBar @@ -1155,6 +1175,22 @@ showAudioCodecsLabel Показать Аудио кодаки + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat diff --git a/assets/languages/sv.ts b/assets/languages/sv.ts index fbbbac1b9..40c734e53 100644 --- a/assets/languages/sv.ts +++ b/assets/languages/sv.ts @@ -615,6 +615,10 @@ Serverwebbadressen är inte konfigurerad. abortEditDescriptionText Är du säker på att du vill avbryta kontaktändringen? + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ Serverwebbadressen är inte konfigurerad. removeAllEntriesDescription Är du säker på att du vill rensa den här historiken? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -961,6 +977,10 @@ Klicka här: <a href="%1">%1</a> smartSearchBarTooltip + + newConferenceButton + + MainWindowMenuBar @@ -1155,6 +1175,22 @@ Klicka här: <a href="%1">%1</a> showAudioCodecsLabel Visa ljudkodek + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat diff --git a/assets/languages/tr.ts b/assets/languages/tr.ts index 31562cbfa..c04518e43 100644 --- a/assets/languages/tr.ts +++ b/assets/languages/tr.ts @@ -615,6 +615,10 @@ Sunucu url'si yapılandırılmadı. abortEditDescriptionText Kişi düzenlemesini iptal etmek istediğinize emin misiniz? + + tooltipShowConversation + + Contacts @@ -657,6 +661,18 @@ Sunucu url'si yapılandırılmadı. removeAllEntriesDescription Bu geçmişi temizlemek istediğinize emin misiniz? + + tooltipContactEdit + + + + tooltipContactAdd + + + + cleanHistory + + CreateAppSipAccount @@ -963,6 +979,10 @@ Buraya tıklayın: <a href="%1">%1</a> eklemek için akıllı arama çubuğunu kullanın. Yalnızca arkadaşınızın SIP adresini veya kullanıcı adını girin. + + newConferenceButton + + MainWindowMenuBar @@ -1157,6 +1177,22 @@ arkadaşınızın SIP adresini veya kullanıcı adını girin. showAudioCodecsLabel Ses çözücüleri göster + + playbackGainLabel + + + + captureGainLabel + + + + audioTestLabel + + + + audioSettingsInCallWarning + + SettingsCallsChat diff --git a/cmake_builder/CMakeLists.txt b/cmake_builder/CMakeLists.txt index 3c036264e..41882eb8e 100644 --- a/cmake_builder/CMakeLists.txt +++ b/cmake_builder/CMakeLists.txt @@ -23,6 +23,6 @@ lcb_define_target("linphoneqt" "linphone" "ms2plugins") -if (NOT WIN32 AND NOT APPLE) - lcb_blacklist_dependencies("turbo-jpeg") # turbo-jpeg is already provided by Qt5 so do not build it. -endif () +#if (NOT WIN32 AND NOT APPLE) +# lcb_blacklist_dependencies("turbojpeg") # turbo-jpeg is already provided by Qt5 so do not build it. +#endif () diff --git a/create_appimage.sh b/create_appimage.sh new file mode 100755 index 000000000..371ca0778 --- /dev/null +++ b/create_appimage.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +APP_NAME="linphone" + +BIN_SOURCE_DIR="OUTPUT/desktop" + +WORK_DIR="OUTPUT/AppDir/usr" + +mkdir -p "${WORK_DIR}" + +cp -rfv "${BIN_SOURCE_DIR}"/* "${WORK_DIR}" + +./AppImage/linuxdeployqt-continuous-x86_64.AppImage "${WORK_DIR}/bin/${APP_NAME}" -appimage -bundle-non-qt-libs -verbose=2 diff --git a/linphone-sdk b/linphone-sdk index ef3040683..717a397ce 160000 --- a/linphone-sdk +++ b/linphone-sdk @@ -1 +1 @@ -Subproject commit ef30406833bc49ac92d1a6b520d7fbde801159e6 +Subproject commit 717a397ceae0b5e923aed26398b5ba7d204b67ef diff --git a/resources.qrc b/resources.qrc index bd49023b3..400e612f3 100644 --- a/resources.qrc +++ b/resources.qrc @@ -199,6 +199,7 @@ assets/images/video_call_hovered.svg assets/images/video_call_normal.svg assets/images/video_call_pressed.svg + assets/images/warning.svg ui/modules/Common/Animations/BusyIndicator.qml ui/modules/Common/Constants/Constants.qml ui/modules/Common/Dialog/ConfirmDialog.qml diff --git a/src/components/call/CallModel.cpp b/src/components/call/CallModel.cpp index 6fba9a6d6..f98b7adce 100644 --- a/src/components/call/CallModel.cpp +++ b/src/components/call/CallModel.cpp @@ -33,6 +33,7 @@ #include "components/settings/AccountSettingsModel.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/LinphoneUtils.hpp" +#include "utils/MediastreamerUtils.hpp" #include "utils/Utils.hpp" #include "CallModel.hpp" @@ -469,11 +470,11 @@ float CallModel::getQuality () const { // ----------------------------------------------------------------------------- float CallModel::getSpeakerVu () const { - return LinphoneUtils::computeVu(mCall->getPlayVolume()); + return MediastreamerUtils::computeVu(mCall->getPlayVolume()); } float CallModel::getMicroVu () const { - return LinphoneUtils::computeVu(mCall->getRecordVolume()); + return MediastreamerUtils::computeVu(mCall->getRecordVolume()); } // ----------------------------------------------------------------------------- diff --git a/src/components/conference/ConferenceModel.cpp b/src/components/conference/ConferenceModel.cpp index 8d3638654..74a276320 100644 --- a/src/components/conference/ConferenceModel.cpp +++ b/src/components/conference/ConferenceModel.cpp @@ -28,6 +28,7 @@ #include "components/core/CoreManager.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/LinphoneUtils.hpp" +#include "utils/MediastreamerUtils.hpp" #include "utils/Utils.hpp" #include "ConferenceModel.hpp" @@ -128,7 +129,7 @@ bool ConferenceModel::getRecording () const { // ----------------------------------------------------------------------------- float ConferenceModel::getMicroVu () const { - return LinphoneUtils::computeVu( + return MediastreamerUtils::computeVu( CoreManager::getInstance()->getCore()->getConferenceLocalInputVolume() ); } diff --git a/src/components/core/CoreHandlers.cpp b/src/components/core/CoreHandlers.cpp index c046f15fe..417765d1c 100644 --- a/src/components/core/CoreHandlers.cpp +++ b/src/components/core/CoreHandlers.cpp @@ -125,6 +125,11 @@ void CoreHandlers::onCallStatsUpdated ( call->getData("call-model").updateStats(stats); } +void CoreHandlers::onCallCreated(const shared_ptr &, + const shared_ptr &call) { + emit callCreated(call); +} + void CoreHandlers::onGlobalStateChanged ( const shared_ptr &, linphone::GlobalState gstate, diff --git a/src/components/core/CoreHandlers.hpp b/src/components/core/CoreHandlers.hpp index ed8da73e0..bdb377d91 100644 --- a/src/components/core/CoreHandlers.hpp +++ b/src/components/core/CoreHandlers.hpp @@ -46,6 +46,7 @@ signals: void callStateChanged (const std::shared_ptr &call, linphone::Call::State state); void callTransferFailed (const std::shared_ptr &call); void callTransferSucceeded (const std::shared_ptr &call); + void callCreated(const std::shared_ptr & call); void coreStarted (); void isComposingChanged (const std::shared_ptr &chatRoom); void logsUploadStateChanged (linphone::Core::LogCollectionUploadState state, const std::string &info); @@ -87,6 +88,11 @@ private: const std::shared_ptr &stats ) override; + void onCallCreated( + const std::shared_ptr & lc, + const std::shared_ptr & call + ) override; + void onGlobalStateChanged ( const std::shared_ptr &core, linphone::GlobalState gstate, diff --git a/src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp b/src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp index e03fa5d3d..078ec2a70 100644 --- a/src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp +++ b/src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp @@ -66,7 +66,7 @@ void AbstractEventCountNotifier::internalnotifyEventCount () { n = n > 99 ? 99 : n; notifyEventCount(CoreManager::getInstance()->getSettingsModel()->getChatEnabled() ? n : 0); - emit eventCountChanged(mUnreadMessageCount); + emit eventCountChanged(n); } // ----------------------------------------------------------------------------- diff --git a/src/components/settings/SettingsModel.cpp b/src/components/settings/SettingsModel.cpp index 3db31d1e9..b5d311ff7 100644 --- a/src/components/settings/SettingsModel.cpp +++ b/src/components/settings/SettingsModel.cpp @@ -22,11 +22,14 @@ #include +#include +#include + #include "app/logger/Logger.hpp" #include "app/paths/Paths.hpp" #include "components/core/CoreManager.hpp" #include "utils/Utils.hpp" - +#include "utils/MediastreamerUtils.hpp" #include "SettingsModel.hpp" // ============================================================================= @@ -34,287 +37,424 @@ using namespace std; namespace { - constexpr char DefaultRlsUri[] = "sips:rls@sip.linphone.org"; - constexpr char DefaultLogsEmail[] = "linphone-desktop@belledonne-communications.com"; + constexpr char DefaultRlsUri[] = "sips:rls@sip.linphone.org"; + constexpr char DefaultLogsEmail[] = "linphone-desktop@belledonne-communications.com"; } const string SettingsModel::UiSection("ui"); SettingsModel::SettingsModel (QObject *parent) : QObject(parent) { - mConfig = CoreManager::getInstance()->getCore()->getConfig(); - configureRlsUri(); + CoreManager *coreManager = CoreManager::getInstance(); + mConfig = coreManager->getCore()->getConfig(); + + QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::callCreated, + this, &SettingsModel::handleCallCreated); + QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::callStateChanged, + this, &SettingsModel::handleCallStateChanged); + configureRlsUri(); +} + +void SettingsModel::settingsWindowClosing(void) { + onSettingsTabChanged(-1); +} + +//Provides tabbar per-tab setup/teardown mecanism for specific settings views +void SettingsModel::onSettingsTabChanged(int idx) { + int prevIdx = mCurrentSettingsTab; + mCurrentSettingsTab = idx; + + switch (prevIdx) { + case 0://sip + break; + case 1://audio + closeAudioSettings(); + break; + case 2://video + break; + case 3://call + break; + case 4://ui + break; + case 5://advanced + break; + default: + break; + } + switch (idx) { + case 0://sip + break; + case 1://audio + accessAudioSettings(); + break; + case 2://video + accessVideoSettings(); + break; + case 3://call + break; + case 4://ui + break; + case 5://advanced + break; + default: + break; + } } // ============================================================================= // Assistant. // ============================================================================= - bool SettingsModel::getUseAppSipAccountEnabled () const { - return !!mConfig->getInt(UiSection, "use_app_sip_account_enabled", 1); - } +bool SettingsModel::getUseAppSipAccountEnabled () const { + return !!mConfig->getInt(UiSection, "use_app_sip_account_enabled", 1); +} - void SettingsModel::setUseAppSipAccountEnabled (bool status) { - mConfig->setInt(UiSection, "use_app_sip_account_enabled", status); - emit useAppSipAccountEnabledChanged(status); - } +void SettingsModel::setUseAppSipAccountEnabled (bool status) { + mConfig->setInt(UiSection, "use_app_sip_account_enabled", status); + emit useAppSipAccountEnabledChanged(status); +} - bool SettingsModel::getUseOtherSipAccountEnabled () const { - return !!mConfig->getInt(UiSection, "use_other_sip_account_enabled", 1); - } +bool SettingsModel::getUseOtherSipAccountEnabled () const { + return !!mConfig->getInt(UiSection, "use_other_sip_account_enabled", 1); +} - void SettingsModel::setUseOtherSipAccountEnabled (bool status) { - mConfig->setInt(UiSection, "use_other_sip_account_enabled", status); - emit useOtherSipAccountEnabledChanged(status); - } +void SettingsModel::setUseOtherSipAccountEnabled (bool status) { + mConfig->setInt(UiSection, "use_other_sip_account_enabled", status); + emit useOtherSipAccountEnabledChanged(status); +} - bool SettingsModel::getCreateAppSipAccountEnabled () const { - return !!mConfig->getInt(UiSection, "create_app_sip_account_enabled", 1); - } +bool SettingsModel::getCreateAppSipAccountEnabled () const { + return !!mConfig->getInt(UiSection, "create_app_sip_account_enabled", 1); +} - void SettingsModel::setCreateAppSipAccountEnabled (bool status) { - mConfig->setInt(UiSection, "create_app_sip_account_enabled", status); - emit createAppSipAccountEnabledChanged(status); - } +void SettingsModel::setCreateAppSipAccountEnabled (bool status) { + mConfig->setInt(UiSection, "create_app_sip_account_enabled", status); + emit createAppSipAccountEnabledChanged(status); +} - bool SettingsModel::getFetchRemoteConfigurationEnabled () const { - return !!mConfig->getInt(UiSection, "fetch_remote_configuration_enabled", 1); - } +bool SettingsModel::getFetchRemoteConfigurationEnabled () const { + return !!mConfig->getInt(UiSection, "fetch_remote_configuration_enabled", 1); +} - void SettingsModel::setFetchRemoteConfigurationEnabled (bool status) { - mConfig->setInt(UiSection, "fetch_remote_configuration_enabled", status); - emit fetchRemoteConfigurationEnabledChanged(status); - } +void SettingsModel::setFetchRemoteConfigurationEnabled (bool status) { + mConfig->setInt(UiSection, "fetch_remote_configuration_enabled", status); + emit fetchRemoteConfigurationEnabledChanged(status); +} - // --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- - bool SettingsModel::getAssistantSupportsPhoneNumbers () const { - return !!mConfig->getInt(UiSection, "assistant_supports_phone_numbers", 1); - } +bool SettingsModel::getAssistantSupportsPhoneNumbers () const { + return !!mConfig->getInt(UiSection, "assistant_supports_phone_numbers", 1); +} - void SettingsModel::setAssistantSupportsPhoneNumbers (bool status) { - mConfig->setInt(UiSection, "assistant_supports_phone_numbers", status); - emit assistantSupportsPhoneNumbersChanged(status); - } +void SettingsModel::setAssistantSupportsPhoneNumbers (bool status) { + mConfig->setInt(UiSection, "assistant_supports_phone_numbers", status); + emit assistantSupportsPhoneNumbersChanged(status); +} // ============================================================================= // Audio. // ============================================================================= +void SettingsModel::createCaptureGraph() { + if (mSimpleCaptureGraph) { + delete mSimpleCaptureGraph; + mSimpleCaptureGraph = nullptr; + } + if (!mSimpleCaptureGraph) { + mSimpleCaptureGraph = + new MediastreamerUtils::SimpleCaptureGraph(Utils::appStringToCoreString(getCaptureDevice()), + Utils::appStringToCoreString(getPlaybackDevice())); + } + mSimpleCaptureGraph->start(); + emit captureGraphRunningChanged(getCaptureGraphRunning()); +} + +//Force a call on the 'detect' method of all audio filters, updating new or removed devices +void SettingsModel::accessAudioSettings() { + CoreManager::getInstance()->getCore()->reloadSoundDevices(); + emit captureDevicesChanged(getCaptureDevices()); + emit playbackDevicesChanged(getPlaybackDevices()); + emit playbackDeviceChanged(getPlaybackDevice()); + emit captureDeviceChanged(getCaptureDevice()); + emit ringerDeviceChanged(getRingerDevice()); + + if (!getIsInCall()) { + createCaptureGraph(); + } +} + +void SettingsModel::closeAudioSettings() { + if (mSimpleCaptureGraph) { + if (mSimpleCaptureGraph->isRunning()) { + mSimpleCaptureGraph->stop(); + } + delete mSimpleCaptureGraph; + mSimpleCaptureGraph = nullptr; + } + emit captureGraphRunningChanged(getCaptureGraphRunning()); +} + +bool SettingsModel::getCaptureGraphRunning() { + return mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning() && !getIsInCall(); +} + +float SettingsModel::getMicVolume() { + float v = 0.0; + + if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { + v = mSimpleCaptureGraph->getCaptureVolume(); + } + return v; +} + +float SettingsModel::getPlaybackGain() const { + float dbGain = CoreManager::getInstance()->getCore()->getPlaybackGainDb(); + return MediastreamerUtils::dbToLinear(dbGain); +} + +void SettingsModel::setPlaybackGain(float gain) { + if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { + mSimpleCaptureGraph->setPlaybackGain(gain); + } +} + +float SettingsModel::getCaptureGain() const { + float dbGain = CoreManager::getInstance()->getCore()->getMicGainDb(); + return MediastreamerUtils::dbToLinear(dbGain); +} + +void SettingsModel::setCaptureGain(float gain) { + if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { + mSimpleCaptureGraph->setCaptureGain(gain); + } +} + QStringList SettingsModel::getCaptureDevices () const { - shared_ptr core = CoreManager::getInstance()->getCore(); - QStringList list; + shared_ptr core = CoreManager::getInstance()->getCore(); + QStringList list; - for (const auto &device : core->getSoundDevicesList()) { - if (core->soundDeviceCanCapture(device)) - list << Utils::coreStringToAppString(device); - } - - return list; + for (const auto &device : core->getSoundDevicesList()) { + if (core->soundDeviceCanCapture(device)) + list << Utils::coreStringToAppString(device); + } + return list; } QStringList SettingsModel::getPlaybackDevices () const { - shared_ptr core = CoreManager::getInstance()->getCore(); - QStringList list; + shared_ptr core = CoreManager::getInstance()->getCore(); + QStringList list; - for (const auto &device : core->getSoundDevicesList()) - if (core->soundDeviceCanPlayback(device)) - list << Utils::coreStringToAppString(device); + for (const auto &device : core->getSoundDevicesList()) { + if (core->soundDeviceCanPlayback(device)) { + list << Utils::coreStringToAppString(device); + } + } - return list; + return list; } // ----------------------------------------------------------------------------- QString SettingsModel::getCaptureDevice () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getCaptureDevice() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getCaptureDevice() + ); } void SettingsModel::setCaptureDevice (const QString &device) { - CoreManager::getInstance()->getCore()->setCaptureDevice( - Utils::appStringToCoreString(device) - ); - emit captureDeviceChanged(device); + CoreManager::getInstance()->getCore()->setCaptureDevice( + Utils::appStringToCoreString(device) + ); + emit captureDeviceChanged(device); + if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { + createCaptureGraph(); + } } // ----------------------------------------------------------------------------- QString SettingsModel::getPlaybackDevice () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getPlaybackDevice() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getPlaybackDevice() + ); } void SettingsModel::setPlaybackDevice (const QString &device) { - CoreManager::getInstance()->getCore()->setPlaybackDevice( - Utils::appStringToCoreString(device) - ); - emit playbackDeviceChanged(device); + CoreManager::getInstance()->getCore()->setPlaybackDevice( + Utils::appStringToCoreString(device) + ); + emit playbackDeviceChanged(device); } // ----------------------------------------------------------------------------- QString SettingsModel::getRingerDevice () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getRingerDevice() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getRingerDevice() + ); } void SettingsModel::setRingerDevice (const QString &device) { - CoreManager::getInstance()->getCore()->setRingerDevice( - Utils::appStringToCoreString(device) - ); - emit ringerDeviceChanged(device); + CoreManager::getInstance()->getCore()->setRingerDevice( + Utils::appStringToCoreString(device) + ); + emit ringerDeviceChanged(device); } // ----------------------------------------------------------------------------- QString SettingsModel::getRingPath () const { - return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getRing()); + return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getRing()); } void SettingsModel::setRingPath (const QString &path) { - QString cleanedPath = QDir::cleanPath(path); + QString cleanedPath = QDir::cleanPath(path); - CoreManager::getInstance()->getCore()->setRing( - Utils::appStringToCoreString(cleanedPath) - ); + CoreManager::getInstance()->getCore()->setRing( + Utils::appStringToCoreString(cleanedPath) + ); - emit ringPathChanged(cleanedPath); + emit ringPathChanged(cleanedPath); } // ----------------------------------------------------------------------------- bool SettingsModel::getEchoCancellationEnabled () const { - return CoreManager::getInstance()->getCore()->echoCancellationEnabled(); + return CoreManager::getInstance()->getCore()->echoCancellationEnabled(); } void SettingsModel::setEchoCancellationEnabled (bool status) { - CoreManager::getInstance()->getCore()->enableEchoCancellation(status); - emit echoCancellationEnabledChanged(status); + CoreManager::getInstance()->getCore()->enableEchoCancellation(status); + emit echoCancellationEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getShowAudioCodecs () const { - return !!mConfig->getInt(UiSection, "show_audio_codecs", 1); + return !!mConfig->getInt(UiSection, "show_audio_codecs", 1); } void SettingsModel::setShowAudioCodecs (bool status) { - mConfig->setInt(UiSection, "show_audio_codecs", status); - emit showAudioCodecsChanged(status); + mConfig->setInt(UiSection, "show_audio_codecs", status); + emit showAudioCodecsChanged(status); } + // ============================================================================= // Video. // ============================================================================= +//Force a call on the 'detect' method of all video filters, updating new or removed devices +void SettingsModel::accessVideoSettings() { + CoreManager::getInstance()->getCore()->reloadVideoDevices(); + emit videoDevicesChanged(getVideoDevices()); +} + QStringList SettingsModel::getVideoDevices () const { - QStringList list; + QStringList list; - for (const auto &device : CoreManager::getInstance()->getCore()->getVideoDevicesList()) - list << Utils::coreStringToAppString(device); + for (const auto &device : CoreManager::getInstance()->getCore()->getVideoDevicesList()) + list << Utils::coreStringToAppString(device); - return list; + return list; } // ----------------------------------------------------------------------------- QString SettingsModel::getVideoDevice () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getVideoDevice() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getVideoDevice() + ); } void SettingsModel::setVideoDevice (const QString &device) { - CoreManager::getInstance()->getCore()->setVideoDevice( - Utils::appStringToCoreString(device) - ); - emit videoDeviceChanged(device); + CoreManager::getInstance()->getCore()->setVideoDevice( + Utils::appStringToCoreString(device) + ); + emit videoDeviceChanged(device); } // ----------------------------------------------------------------------------- QString SettingsModel::getVideoPreset () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getVideoPreset() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getVideoPreset() + ); } void SettingsModel::setVideoPreset (const QString &preset) { - CoreManager::getInstance()->getCore()->setVideoPreset( - Utils::appStringToCoreString(preset) - ); - emit videoPresetChanged(preset); + CoreManager::getInstance()->getCore()->setVideoPreset( + Utils::appStringToCoreString(preset) + ); + emit videoPresetChanged(preset); } // ----------------------------------------------------------------------------- int SettingsModel::getVideoFramerate () const { - return int(CoreManager::getInstance()->getCore()->getPreferredFramerate()); + return int(CoreManager::getInstance()->getCore()->getPreferredFramerate()); } void SettingsModel::setVideoFramerate (int framerate) { - CoreManager::getInstance()->getCore()->setPreferredFramerate(float(framerate)); - emit videoFramerateChanged(framerate); + CoreManager::getInstance()->getCore()->setPreferredFramerate(float(framerate)); + emit videoFramerateChanged(framerate); } // ----------------------------------------------------------------------------- static inline QVariantMap createMapFromVideoDefinition (const shared_ptr &definition) { - QVariantMap map; + QVariantMap map; - if (!definition) { - Q_ASSERT(!CoreManager::getInstance()->getCore()->videoSupported()); + if (!definition) { + Q_ASSERT(!CoreManager::getInstance()->getCore()->videoSupported()); - map["name"] = QStringLiteral("Bad EGG"); - map["width"] = QStringLiteral("?????"); - map["height"] = QStringLiteral("?????"); + map["name"] = QStringLiteral("Bad EGG"); + map["width"] = QStringLiteral("?????"); + map["height"] = QStringLiteral("?????"); - return map; - } + return map; + } - map["name"] = Utils::coreStringToAppString(definition->getName()); - map["width"] = definition->getWidth(); - map["height"] = definition->getHeight(); - map["__definition"] = QVariant::fromValue(definition); + map["name"] = Utils::coreStringToAppString(definition->getName()); + map["width"] = definition->getWidth(); + map["height"] = definition->getHeight(); + map["__definition"] = QVariant::fromValue(definition); - return map; + return map; } QVariantList SettingsModel::getSupportedVideoDefinitions () const { - QVariantList list; - for (const auto &definition : linphone::Factory::get()->getSupportedVideoDefinitions()) - list << createMapFromVideoDefinition(definition); - return list; + QVariantList list; + for (const auto &definition : linphone::Factory::get()->getSupportedVideoDefinitions()) + list << createMapFromVideoDefinition(definition); + return list; } QVariantMap SettingsModel::getVideoDefinition () const { - return createMapFromVideoDefinition(CoreManager::getInstance()->getCore()->getPreferredVideoDefinition()); + return createMapFromVideoDefinition(CoreManager::getInstance()->getCore()->getPreferredVideoDefinition()); } void SettingsModel::setVideoDefinition (const QVariantMap &definition) { - CoreManager::getInstance()->getCore()->setPreferredVideoDefinition( - definition.value("__definition").value>()->clone() - ); + CoreManager::getInstance()->getCore()->setPreferredVideoDefinition( + definition.value("__definition").value>()->clone() + ); - emit videoDefinitionChanged(definition); + emit videoDefinitionChanged(definition); } bool SettingsModel::getVideoSupported () const { - return CoreManager::getInstance()->getCore()->videoSupported(); + return CoreManager::getInstance()->getCore()->videoSupported(); } // ----------------------------------------------------------------------------- bool SettingsModel::getShowVideoCodecs () const { - return !!mConfig->getInt(UiSection, "show_video_codecs", 1); + return !!mConfig->getInt(UiSection, "show_video_codecs", 1); } void SettingsModel::setShowVideoCodecs (bool status) { - mConfig->setInt(UiSection, "show_video_codecs", status); - emit showVideoCodecsChanged(status); + mConfig->setInt(UiSection, "show_video_codecs", status); + emit showVideoCodecsChanged(status); } // ============================================================================= @@ -322,221 +462,221 @@ void SettingsModel::setShowVideoCodecs (bool status) { // ============================================================================= bool SettingsModel::getAutoAnswerStatus () const { - return !!mConfig->getInt(UiSection, "auto_answer", 0); + return !!mConfig->getInt(UiSection, "auto_answer", 0); } void SettingsModel::setAutoAnswerStatus (bool status) { - mConfig->setInt(UiSection, "auto_answer", status); - emit autoAnswerStatusChanged(status); + mConfig->setInt(UiSection, "auto_answer", status); + emit autoAnswerStatusChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getAutoAnswerVideoStatus () const { - return !!mConfig->getInt(UiSection, "auto_answer_with_video", 0); + return !!mConfig->getInt(UiSection, "auto_answer_with_video", 0); } void SettingsModel::setAutoAnswerVideoStatus (bool status) { - mConfig->setInt(UiSection, "auto_answer_with_video", status); - emit autoAnswerVideoStatusChanged(status); + mConfig->setInt(UiSection, "auto_answer_with_video", status); + emit autoAnswerVideoStatusChanged(status); } // ----------------------------------------------------------------------------- int SettingsModel::getAutoAnswerDelay () const { - return mConfig->getInt(UiSection, "auto_answer_delay", 0); + return mConfig->getInt(UiSection, "auto_answer_delay", 0); } void SettingsModel::setAutoAnswerDelay (int delay) { - mConfig->setInt(UiSection, "auto_answer_delay", delay); - emit autoAnswerDelayChanged(delay); + mConfig->setInt(UiSection, "auto_answer_delay", delay); + emit autoAnswerDelayChanged(delay); } // ----------------------------------------------------------------------------- bool SettingsModel::getShowTelKeypadAutomatically () const { - return !!mConfig->getInt(UiSection, "show_tel_keypad_automatically", 0); + return !!mConfig->getInt(UiSection, "show_tel_keypad_automatically", 0); } void SettingsModel::setShowTelKeypadAutomatically (bool status) { - mConfig->setInt(UiSection, "show_tel_keypad_automatically", status); - emit showTelKeypadAutomaticallyChanged(status); + mConfig->setInt(UiSection, "show_tel_keypad_automatically", status); + emit showTelKeypadAutomaticallyChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getKeepCallsWindowInBackground () const { - return !!mConfig->getInt(UiSection, "keep_calls_window_in_background", 0); + return !!mConfig->getInt(UiSection, "keep_calls_window_in_background", 0); } void SettingsModel::setKeepCallsWindowInBackground (bool status) { - mConfig->setInt(UiSection, "keep_calls_window_in_background", status); - emit keepCallsWindowInBackgroundChanged(status); + mConfig->setInt(UiSection, "keep_calls_window_in_background", status); + emit keepCallsWindowInBackgroundChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getOutgoingCallsEnabled () const { - return !!mConfig->getInt(UiSection, "outgoing_calls_enabled", 1); + return !!mConfig->getInt(UiSection, "outgoing_calls_enabled", 1); } void SettingsModel::setOutgoingCallsEnabled (bool status) { - mConfig->setInt(UiSection, "outgoing_calls_enabled", status); - emit outgoingCallsEnabledChanged(status); + mConfig->setInt(UiSection, "outgoing_calls_enabled", status); + emit outgoingCallsEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getCallRecorderEnabled () const { - return !!mConfig->getInt(UiSection, "call_recorder_enabled", 1); + return !!mConfig->getInt(UiSection, "call_recorder_enabled", 1); } void SettingsModel::setCallRecorderEnabled (bool status) { - mConfig->setInt(UiSection, "call_recorder_enabled", status); - emit callRecorderEnabledChanged(status); + mConfig->setInt(UiSection, "call_recorder_enabled", status); + emit callRecorderEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getAutomaticallyRecordCalls () const { - return !!mConfig->getInt(UiSection, "automatically_record_calls", 0); + return !!mConfig->getInt(UiSection, "automatically_record_calls", 0); } void SettingsModel::setAutomaticallyRecordCalls (bool status) { - mConfig->setInt(UiSection, "automatically_record_calls", status); - emit automaticallyRecordCallsChanged(status); + mConfig->setInt(UiSection, "automatically_record_calls", status); + emit automaticallyRecordCallsChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getCallPauseEnabled () const { - return !!mConfig->getInt(UiSection, "call_pause_enabled", 1); + return !!mConfig->getInt(UiSection, "call_pause_enabled", 1); } void SettingsModel::setCallPauseEnabled (bool status) { - mConfig->setInt(UiSection, "call_pause_enabled", status); - emit callPauseEnabledChanged(status); + mConfig->setInt(UiSection, "call_pause_enabled", status); + emit callPauseEnabledChanged(status); } bool SettingsModel::getMuteMicrophoneEnabled () const { - return !!mConfig->getInt(UiSection, "mute_microphone_enabled", 1); + return !!mConfig->getInt(UiSection, "mute_microphone_enabled", 1); } void SettingsModel::setMuteMicrophoneEnabled (bool status) { - mConfig->setInt(UiSection, "mute_microphone_enabled", status); - emit muteMicrophoneEnabledChanged(status); + mConfig->setInt(UiSection, "mute_microphone_enabled", status); + emit muteMicrophoneEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getChatEnabled () const { - return !!mConfig->getInt(UiSection, "chat_enabled", 1); + return !!mConfig->getInt(UiSection, "chat_enabled", 1); } void SettingsModel::setChatEnabled (bool status) { - mConfig->setInt(UiSection, "chat_enabled", status); - emit chatEnabledChanged(status); + mConfig->setInt(UiSection, "chat_enabled", status); + emit chatEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getConferenceEnabled () const { - return !!mConfig->getInt(UiSection, "conference_enabled", 1); + return !!mConfig->getInt(UiSection, "conference_enabled", 1); } void SettingsModel::setConferenceEnabled (bool status) { - mConfig->setInt(UiSection, "conference_enabled", status); - emit conferenceEnabledChanged(status); + mConfig->setInt(UiSection, "conference_enabled", status); + emit conferenceEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getChatNotificationSoundEnabled () const { - return !!mConfig->getInt(UiSection, "chat_sound_notification_enabled", 1); + return !!mConfig->getInt(UiSection, "chat_sound_notification_enabled", 1); } void SettingsModel::setChatNotificationSoundEnabled (bool status) { - mConfig->setInt(UiSection, "chat_sound_notification_enabled", status); - emit chatNotificationSoundEnabledChanged(status); + mConfig->setInt(UiSection, "chat_sound_notification_enabled", status); + emit chatNotificationSoundEnabledChanged(status); } // ----------------------------------------------------------------------------- QString SettingsModel::getChatNotificationSoundPath () const { - static const string defaultFile = linphone::Factory::get()->getSoundResourcesDir() + "/incoming_chat.wav"; - return Utils::coreStringToAppString(mConfig->getString(UiSection, "chat_sound_notification_file", defaultFile)); + static const string defaultFile = linphone::Factory::get()->getSoundResourcesDir() + "/incoming_chat.wav"; + return Utils::coreStringToAppString(mConfig->getString(UiSection, "chat_sound_notification_file", defaultFile)); } void SettingsModel::setChatNotificationSoundPath (const QString &path) { - QString cleanedPath = QDir::cleanPath(path); - mConfig->setString(UiSection, "chat_sound_notification_file", Utils::appStringToCoreString(cleanedPath)); - emit chatNotificationSoundPathChanged(cleanedPath); + QString cleanedPath = QDir::cleanPath(path); + mConfig->setString(UiSection, "chat_sound_notification_file", Utils::appStringToCoreString(cleanedPath)); + emit chatNotificationSoundPathChanged(cleanedPath); } // ----------------------------------------------------------------------------- QString SettingsModel::getFileTransferUrl () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getFileTransferServer() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getFileTransferServer() + ); } void SettingsModel::setFileTransferUrl (const QString &url) { - CoreManager::getInstance()->getCore()->setFileTransferServer( - Utils::appStringToCoreString(url) - ); - emit fileTransferUrlChanged(url); + CoreManager::getInstance()->getCore()->setFileTransferServer( + Utils::appStringToCoreString(url) + ); + emit fileTransferUrlChanged(url); } // ----------------------------------------------------------------------------- bool SettingsModel::getLimeIsSupported () const { - return CoreManager::getInstance()->getCore()->limeAvailable(); + return CoreManager::getInstance()->getCore()->limeAvailable(); } // ----------------------------------------------------------------------------- static inline QVariant buildEncryptionDescription (SettingsModel::MediaEncryption encryption, const char *description) { - return QVariantList() << encryption << description; + return QVariantList() << encryption << description; } QVariantList SettingsModel::getSupportedMediaEncryptions () const { - shared_ptr core = CoreManager::getInstance()->getCore(); - QVariantList list; + shared_ptr core = CoreManager::getInstance()->getCore(); + QVariantList list; - if (core->mediaEncryptionSupported(linphone::MediaEncryption::SRTP)) - list << buildEncryptionDescription(MediaEncryptionSrtp, "SRTP"); + if (core->mediaEncryptionSupported(linphone::MediaEncryption::SRTP)) + list << buildEncryptionDescription(MediaEncryptionSrtp, "SRTP"); - if (core->mediaEncryptionSupported(linphone::MediaEncryption::ZRTP)) - list << buildEncryptionDescription(MediaEncryptionZrtp, "ZRTP"); + if (core->mediaEncryptionSupported(linphone::MediaEncryption::ZRTP)) + list << buildEncryptionDescription(MediaEncryptionZrtp, "ZRTP"); - return list; + return list; } // ----------------------------------------------------------------------------- SettingsModel::MediaEncryption SettingsModel::getMediaEncryption () const { - return static_cast( - CoreManager::getInstance()->getCore()->getMediaEncryption() - ); + return static_cast( + CoreManager::getInstance()->getCore()->getMediaEncryption() + ); } void SettingsModel::setMediaEncryption (MediaEncryption encryption) { - if (encryption == getMediaEncryption()) - return; + if (encryption == getMediaEncryption()) + return; - if (encryption != SettingsModel::MediaEncryptionZrtp) - setLimeState(SettingsModel::LimeStateDisabled); + if (encryption != SettingsModel::MediaEncryptionZrtp) + setLimeState(SettingsModel::LimeStateDisabled); - CoreManager::getInstance()->getCore()->setMediaEncryption( - static_cast(encryption) - ); - if (mandatoryMediaEncryptionEnabled() && encryption == SettingsModel::MediaEncryptionNone) { - //Disable mandatory encryption if none is selected - enableMandatoryMediaEncryption(false); - } + CoreManager::getInstance()->getCore()->setMediaEncryption( + static_cast(encryption) + ); + if (mandatoryMediaEncryptionEnabled() && encryption == SettingsModel::MediaEncryptionNone) { + //Disable mandatory encryption if none is selected + enableMandatoryMediaEncryption(false); + } - emit mediaEncryptionChanged(encryption); + emit mediaEncryptionChanged(encryption); } bool SettingsModel::mandatoryMediaEncryptionEnabled () const { @@ -559,34 +699,34 @@ void SettingsModel::enableMandatoryMediaEncryption(bool mandatory) { // ----------------------------------------------------------------------------- SettingsModel::LimeState SettingsModel::getLimeState () const { - return static_cast( - CoreManager::getInstance()->getCore()->limeEnabled() - ); + return static_cast( + CoreManager::getInstance()->getCore()->limeEnabled() + ); } void SettingsModel::setLimeState (LimeState state) { - if (state == getLimeState()) - return; + if (state == getLimeState()) + return; - if (state != SettingsModel::LimeStateDisabled) - setMediaEncryption(SettingsModel::MediaEncryptionZrtp); + if (state != SettingsModel::LimeStateDisabled) + setMediaEncryption(SettingsModel::MediaEncryptionZrtp); - CoreManager::getInstance()->getCore()->enableLime( - static_cast(state) - ); + CoreManager::getInstance()->getCore()->enableLime( + static_cast(state) + ); - emit limeStateChanged(state); + emit limeStateChanged(state); } // ----------------------------------------------------------------------------- bool SettingsModel::getContactsEnabled () const { - return !!mConfig->getInt(UiSection, "contacts_enabled", 1); + return !!mConfig->getInt(UiSection, "contacts_enabled", 1); } void SettingsModel::setContactsEnabled (bool status) { - mConfig->setInt(UiSection, "contacts_enabled", status); - emit contactsEnabledChanged(status); + mConfig->setInt(UiSection, "contacts_enabled", status); + emit contactsEnabledChanged(status); } // ============================================================================= @@ -594,347 +734,347 @@ void SettingsModel::setContactsEnabled (bool status) { // ============================================================================= bool SettingsModel::getShowNetworkSettings () const { - return !!mConfig->getInt(UiSection, "show_network_settings", 1); + return !!mConfig->getInt(UiSection, "show_network_settings", 1); } void SettingsModel::setShowNetworkSettings (bool status) { - mConfig->setInt(UiSection, "show_network_settings", status); - emit showNetworkSettingsChanged(status); + mConfig->setInt(UiSection, "show_network_settings", status); + emit showNetworkSettingsChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getUseSipInfoForDtmfs () const { - return CoreManager::getInstance()->getCore()->getUseInfoForDtmf(); + return CoreManager::getInstance()->getCore()->getUseInfoForDtmf(); } void SettingsModel::setUseSipInfoForDtmfs (bool status) { - shared_ptr core = CoreManager::getInstance()->getCore(); + shared_ptr core = CoreManager::getInstance()->getCore(); - if (status) { - core->setUseRfc2833ForDtmf(false); - core->setUseInfoForDtmf(true); - } else { - core->setUseInfoForDtmf(false); - core->setUseRfc2833ForDtmf(true); - } + if (status) { + core->setUseRfc2833ForDtmf(false); + core->setUseInfoForDtmf(true); + } else { + core->setUseInfoForDtmf(false); + core->setUseRfc2833ForDtmf(true); + } - emit dtmfsProtocolChanged(); + emit dtmfsProtocolChanged(); } // ----------------------------------------------------------------------------- bool SettingsModel::getUseRfc2833ForDtmfs () const { - return CoreManager::getInstance()->getCore()->getUseRfc2833ForDtmf(); + return CoreManager::getInstance()->getCore()->getUseRfc2833ForDtmf(); } void SettingsModel::setUseRfc2833ForDtmfs (bool status) { - shared_ptr core = CoreManager::getInstance()->getCore(); + shared_ptr core = CoreManager::getInstance()->getCore(); - if (status) { - core->setUseInfoForDtmf(false); - core->setUseRfc2833ForDtmf(true); - } else { - core->setUseRfc2833ForDtmf(false); - core->setUseInfoForDtmf(true); - } + if (status) { + core->setUseInfoForDtmf(false); + core->setUseRfc2833ForDtmf(true); + } else { + core->setUseRfc2833ForDtmf(false); + core->setUseInfoForDtmf(true); + } - emit dtmfsProtocolChanged(); + emit dtmfsProtocolChanged(); } // ----------------------------------------------------------------------------- bool SettingsModel::getIpv6Enabled () const { - return CoreManager::getInstance()->getCore()->ipv6Enabled(); + return CoreManager::getInstance()->getCore()->ipv6Enabled(); } void SettingsModel::setIpv6Enabled (bool status) { - CoreManager::getInstance()->getCore()->enableIpv6(status); - emit ipv6EnabledChanged(status); + CoreManager::getInstance()->getCore()->enableIpv6(status); + emit ipv6EnabledChanged(status); } // ----------------------------------------------------------------------------- int SettingsModel::getDownloadBandwidth () const { - return CoreManager::getInstance()->getCore()->getDownloadBandwidth(); + return CoreManager::getInstance()->getCore()->getDownloadBandwidth(); } void SettingsModel::setDownloadBandwidth (int bandwidth) { - CoreManager::getInstance()->getCore()->setDownloadBandwidth(bandwidth); - emit downloadBandWidthChanged(getDownloadBandwidth()); + CoreManager::getInstance()->getCore()->setDownloadBandwidth(bandwidth); + emit downloadBandWidthChanged(getDownloadBandwidth()); } // ----------------------------------------------------------------------------- int SettingsModel::getUploadBandwidth () const { - return CoreManager::getInstance()->getCore()->getUploadBandwidth(); + return CoreManager::getInstance()->getCore()->getUploadBandwidth(); } void SettingsModel::setUploadBandwidth (int bandwidth) { - CoreManager::getInstance()->getCore()->setUploadBandwidth(bandwidth); - emit uploadBandWidthChanged(getUploadBandwidth()); + CoreManager::getInstance()->getCore()->setUploadBandwidth(bandwidth); + emit uploadBandWidthChanged(getUploadBandwidth()); } // ----------------------------------------------------------------------------- bool SettingsModel::getAdaptiveRateControlEnabled () const { - return CoreManager::getInstance()->getCore()->adaptiveRateControlEnabled(); + return CoreManager::getInstance()->getCore()->adaptiveRateControlEnabled(); } void SettingsModel::setAdaptiveRateControlEnabled (bool status) { - CoreManager::getInstance()->getCore()->enableAdaptiveRateControl(status); - emit adaptiveRateControlEnabledChanged(status); + CoreManager::getInstance()->getCore()->enableAdaptiveRateControl(status); + emit adaptiveRateControlEnabledChanged(status); } // ----------------------------------------------------------------------------- int SettingsModel::getTcpPort () const { - return CoreManager::getInstance()->getCore()->getTransports()->getTcpPort(); + return CoreManager::getInstance()->getCore()->getTransports()->getTcpPort(); } void SettingsModel::setTcpPort (int port) { - shared_ptr core = CoreManager::getInstance()->getCore(); - shared_ptr transports = core->getTransports(); + shared_ptr core = CoreManager::getInstance()->getCore(); + shared_ptr transports = core->getTransports(); - transports->setTcpPort(port); - core->setTransports(transports); + transports->setTcpPort(port); + core->setTransports(transports); - emit tcpPortChanged(port); + emit tcpPortChanged(port); } // ----------------------------------------------------------------------------- int SettingsModel::getUdpPort () const { - return CoreManager::getInstance()->getCore()->getTransports()->getUdpPort(); + return CoreManager::getInstance()->getCore()->getTransports()->getUdpPort(); } void SettingsModel::setUdpPort (int port) { - shared_ptr core = CoreManager::getInstance()->getCore(); - shared_ptr transports = core->getTransports(); + shared_ptr core = CoreManager::getInstance()->getCore(); + shared_ptr transports = core->getTransports(); - transports->setUdpPort(port); - core->setTransports(transports); + transports->setUdpPort(port); + core->setTransports(transports); - emit udpPortChanged(port); + emit udpPortChanged(port); } // ----------------------------------------------------------------------------- QList SettingsModel::getAudioPortRange () const { - shared_ptr range = CoreManager::getInstance()->getCore()->getAudioPortsRange(); - return QList() << range->getMin() << range->getMax(); + shared_ptr range = CoreManager::getInstance()->getCore()->getAudioPortsRange(); + return QList() << range->getMin() << range->getMax(); } void SettingsModel::setAudioPortRange (const QList &range) { - shared_ptr core = CoreManager::getInstance()->getCore(); - int a = range[0]; - int b = range[1]; + shared_ptr core = CoreManager::getInstance()->getCore(); + int a = range[0]; + int b = range[1]; - if (b == -1) - core->setAudioPort(a); - else - core->setAudioPortRange(a, b); + if (b == -1) + core->setAudioPort(a); + else + core->setAudioPortRange(a, b); - emit audioPortRangeChanged(a, b); + emit audioPortRangeChanged(a, b); } // ----------------------------------------------------------------------------- QList SettingsModel::getVideoPortRange () const { - shared_ptr range = CoreManager::getInstance()->getCore()->getVideoPortsRange(); - return QList() << range->getMin() << range->getMax(); + shared_ptr range = CoreManager::getInstance()->getCore()->getVideoPortsRange(); + return QList() << range->getMin() << range->getMax(); } void SettingsModel::setVideoPortRange (const QList &range) { - shared_ptr core = CoreManager::getInstance()->getCore(); - int a = range[0]; - int b = range[1]; + shared_ptr core = CoreManager::getInstance()->getCore(); + int a = range[0]; + int b = range[1]; - if (b == -1) - core->setVideoPort(a); - else - core->setVideoPortRange(a, b); + if (b == -1) + core->setVideoPort(a); + else + core->setVideoPortRange(a, b); - emit videoPortRangeChanged(a, b); + emit videoPortRangeChanged(a, b); } // ----------------------------------------------------------------------------- bool SettingsModel::getIceEnabled () const { - return CoreManager::getInstance()->getCore()->getNatPolicy()->iceEnabled(); + return CoreManager::getInstance()->getCore()->getNatPolicy()->iceEnabled(); } void SettingsModel::setIceEnabled (bool status) { - shared_ptr natPolicy = CoreManager::getInstance()->getCore()->getNatPolicy(); + shared_ptr natPolicy = CoreManager::getInstance()->getCore()->getNatPolicy(); - natPolicy->enableIce(status); - natPolicy->enableStun(status); + natPolicy->enableIce(status); + natPolicy->enableStun(status); - emit iceEnabledChanged(status); + emit iceEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getTurnEnabled () const { - return CoreManager::getInstance()->getCore()->getNatPolicy()->turnEnabled(); + return CoreManager::getInstance()->getCore()->getNatPolicy()->turnEnabled(); } void SettingsModel::setTurnEnabled (bool status) { - CoreManager::getInstance()->getCore()->getNatPolicy()->enableTurn(status); - emit turnEnabledChanged(status); + CoreManager::getInstance()->getCore()->getNatPolicy()->enableTurn(status); + emit turnEnabledChanged(status); } // ----------------------------------------------------------------------------- QString SettingsModel::getStunServer () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServer() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServer() + ); } void SettingsModel::setStunServer (const QString &stunServer) { - CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServer( - Utils::appStringToCoreString(stunServer) - ); + CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServer( + Utils::appStringToCoreString(stunServer) + ); } // ----------------------------------------------------------------------------- QString SettingsModel::getTurnUser () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServerUsername() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServerUsername() + ); } void SettingsModel::setTurnUser (const QString &user) { - CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServerUsername( - Utils::appStringToCoreString(user) - ); + CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServerUsername( + Utils::appStringToCoreString(user) + ); - emit turnUserChanged(user); + emit turnUserChanged(user); } // ----------------------------------------------------------------------------- QString SettingsModel::getTurnPassword () const { - shared_ptr core(CoreManager::getInstance()->getCore()); - shared_ptr natPolicy(core->getNatPolicy()); - shared_ptr authInfo(core->findAuthInfo( - "", - natPolicy->getStunServerUsername(), - natPolicy->getStunServer() - )); - return authInfo ? Utils::coreStringToAppString(authInfo->getPassword()) : QString(""); + shared_ptr core(CoreManager::getInstance()->getCore()); + shared_ptr natPolicy(core->getNatPolicy()); + shared_ptr authInfo(core->findAuthInfo( + "", + natPolicy->getStunServerUsername(), + natPolicy->getStunServer() + )); + return authInfo ? Utils::coreStringToAppString(authInfo->getPassword()) : QString(""); } void SettingsModel::setTurnPassword (const QString &password) { - shared_ptr core(CoreManager::getInstance()->getCore()); - shared_ptr natPolicy(core->getNatPolicy()); + shared_ptr core(CoreManager::getInstance()->getCore()); + shared_ptr natPolicy(core->getNatPolicy()); - const string &turnUser(natPolicy->getStunServerUsername()); - shared_ptr authInfo(core->findAuthInfo("", turnUser, natPolicy->getStunServer())); - if (authInfo) { - shared_ptr clonedAuthInfo(authInfo->clone()); - clonedAuthInfo->setPassword(Utils::appStringToCoreString(password)); + const string &turnUser(natPolicy->getStunServerUsername()); + shared_ptr authInfo(core->findAuthInfo("", turnUser, natPolicy->getStunServer())); + if (authInfo) { + shared_ptr clonedAuthInfo(authInfo->clone()); + clonedAuthInfo->setPassword(Utils::appStringToCoreString(password)); - core->addAuthInfo(clonedAuthInfo); - core->removeAuthInfo(authInfo); - } else - core->addAuthInfo(linphone::Factory::get()->createAuthInfo( - turnUser, - turnUser, - Utils::appStringToCoreString(password), - "", - "", - "" - )); + core->addAuthInfo(clonedAuthInfo); + core->removeAuthInfo(authInfo); + } else + core->addAuthInfo(linphone::Factory::get()->createAuthInfo( + turnUser, + turnUser, + Utils::appStringToCoreString(password), + "", + "", + "" + )); - emit turnPasswordChanged(password); + emit turnPasswordChanged(password); } // ----------------------------------------------------------------------------- int SettingsModel::getDscpSip () const { - return CoreManager::getInstance()->getCore()->getSipDscp(); + return CoreManager::getInstance()->getCore()->getSipDscp(); } void SettingsModel::setDscpSip (int dscp) { - CoreManager::getInstance()->getCore()->setSipDscp(dscp); - emit dscpSipChanged(dscp); + CoreManager::getInstance()->getCore()->setSipDscp(dscp); + emit dscpSipChanged(dscp); } int SettingsModel::getDscpAudio () const { - return CoreManager::getInstance()->getCore()->getAudioDscp(); + return CoreManager::getInstance()->getCore()->getAudioDscp(); } void SettingsModel::setDscpAudio (int dscp) { - CoreManager::getInstance()->getCore()->setAudioDscp(dscp); - emit dscpAudioChanged(dscp); + CoreManager::getInstance()->getCore()->setAudioDscp(dscp); + emit dscpAudioChanged(dscp); } int SettingsModel::getDscpVideo () const { - return CoreManager::getInstance()->getCore()->getVideoDscp(); + return CoreManager::getInstance()->getCore()->getVideoDscp(); } void SettingsModel::setDscpVideo (int dscp) { - CoreManager::getInstance()->getCore()->setVideoDscp(dscp); - emit dscpVideoChanged(dscp); + CoreManager::getInstance()->getCore()->setVideoDscp(dscp); + emit dscpVideoChanged(dscp); } // ----------------------------------------------------------------------------- bool SettingsModel::getRlsUriEnabled () const { - return !!mConfig->getInt(UiSection, "rls_uri_enabled", true); + return !!mConfig->getInt(UiSection, "rls_uri_enabled", true); } void SettingsModel::setRlsUriEnabled (bool status) { - mConfig->setInt(UiSection, "rls_uri_enabled", status); - mConfig->setString("sip", "rls_uri", status ? DefaultRlsUri : ""); - emit rlsUriEnabledChanged(status); + mConfig->setInt(UiSection, "rls_uri_enabled", status); + mConfig->setString("sip", "rls_uri", status ? DefaultRlsUri : ""); + emit rlsUriEnabledChanged(status); } static string getRlsUriDomain () { - static string domain; - if (!domain.empty()) - return domain; + static string domain; + if (!domain.empty()) + return domain; - shared_ptr linphoneAddress = CoreManager::getInstance()->getCore()->createAddress(DefaultRlsUri); - Q_CHECK_PTR(linphoneAddress); - domain = linphoneAddress->getDomain(); - return domain; + shared_ptr linphoneAddress = CoreManager::getInstance()->getCore()->createAddress(DefaultRlsUri); + Q_CHECK_PTR(linphoneAddress); + domain = linphoneAddress->getDomain(); + return domain; } void SettingsModel::configureRlsUri () { - // Ensure rls uri is empty. - if (!getRlsUriEnabled()) { - mConfig->setString("sip", "rls_uri", ""); - return; - } + // Ensure rls uri is empty. + if (!getRlsUriEnabled()) { + mConfig->setString("sip", "rls_uri", ""); + return; + } - // Set rls uri if necessary. - const string domain = getRlsUriDomain(); - for (const auto &proxyConfig : CoreManager::getInstance()->getCore()->getProxyConfigList()) - if (proxyConfig->getDomain() == domain) { - mConfig->setString("sip", "rls_uri", DefaultRlsUri); - return; - } + // Set rls uri if necessary. + const string domain = getRlsUriDomain(); + for (const auto &proxyConfig : CoreManager::getInstance()->getCore()->getProxyConfigList()) + if (proxyConfig->getDomain() == domain) { + mConfig->setString("sip", "rls_uri", DefaultRlsUri); + return; + } - mConfig->setString("sip", "rls_uri", ""); + mConfig->setString("sip", "rls_uri", ""); } void SettingsModel::configureRlsUri (const shared_ptr &proxyConfig) { - if (!getRlsUriEnabled()) { - mConfig->setString("sip", "rls_uri", ""); - return; - } + if (!getRlsUriEnabled()) { + mConfig->setString("sip", "rls_uri", ""); + return; + } - const string domain = getRlsUriDomain(); - if (proxyConfig->getDomain() == domain) { - mConfig->setString("sip", "rls_uri", DefaultRlsUri); - return; - } + const string domain = getRlsUriDomain(); + if (proxyConfig->getDomain() == domain) { + mConfig->setString("sip", "rls_uri", DefaultRlsUri); + return; + } - mConfig->setString("sip", "rls_uri", ""); + mConfig->setString("sip", "rls_uri", ""); } // ============================================================================= @@ -942,77 +1082,77 @@ void SettingsModel::configureRlsUri (const shared_ptrgetString(UiSection, "saved_screenshots_folder", Paths::getCapturesDirPath()) - ) - ) + QDir::separator(); + return QDir::cleanPath( + Utils::coreStringToAppString( + mConfig->getString(UiSection, "saved_screenshots_folder", Paths::getCapturesDirPath()) + ) + ) + QDir::separator(); } void SettingsModel::setSavedScreenshotsFolder (const QString &folder) { - QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); - mConfig->setString(UiSection, "saved_screenshots_folder", Utils::appStringToCoreString(cleanedFolder)); - emit savedScreenshotsFolderChanged(cleanedFolder); + QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); + mConfig->setString(UiSection, "saved_screenshots_folder", Utils::appStringToCoreString(cleanedFolder)); + emit savedScreenshotsFolderChanged(cleanedFolder); } // ----------------------------------------------------------------------------- static inline string getLegacySavedCallsFolder (const shared_ptr &config) { - return config->getString(SettingsModel::UiSection, "saved_videos_folder", Paths::getCapturesDirPath()); + return config->getString(SettingsModel::UiSection, "saved_videos_folder", Paths::getCapturesDirPath()); } QString SettingsModel::getSavedCallsFolder () const { - return QDir::cleanPath( - Utils::coreStringToAppString( - mConfig->getString(UiSection, "saved_calls_folder", getLegacySavedCallsFolder(mConfig)) - ) - ) + QDir::separator(); + return QDir::cleanPath( + Utils::coreStringToAppString( + mConfig->getString(UiSection, "saved_calls_folder", getLegacySavedCallsFolder(mConfig)) + ) + ) + QDir::separator(); } void SettingsModel::setSavedCallsFolder (const QString &folder) { - QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); - mConfig->setString(UiSection, "saved_calls_folder", Utils::appStringToCoreString(cleanedFolder)); - emit savedCallsFolderChanged(cleanedFolder); + QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); + mConfig->setString(UiSection, "saved_calls_folder", Utils::appStringToCoreString(cleanedFolder)); + emit savedCallsFolderChanged(cleanedFolder); } // ----------------------------------------------------------------------------- QString SettingsModel::getDownloadFolder () const { - return QDir::cleanPath( - Utils::coreStringToAppString( - mConfig->getString(UiSection, "download_folder", Paths::getDownloadDirPath()) - ) - ) + QDir::separator(); + return QDir::cleanPath( + Utils::coreStringToAppString( + mConfig->getString(UiSection, "download_folder", Paths::getDownloadDirPath()) + ) + ) + QDir::separator(); } void SettingsModel::setDownloadFolder (const QString &folder) { - QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); - mConfig->setString(UiSection, "download_folder", Utils::appStringToCoreString(cleanedFolder)); - emit downloadFolderChanged(cleanedFolder); + QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); + mConfig->setString(UiSection, "download_folder", Utils::appStringToCoreString(cleanedFolder)); + emit downloadFolderChanged(cleanedFolder); } // ----------------------------------------------------------------------------- QString SettingsModel::getRemoteProvisioning () const { - return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getProvisioningUri()); + return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getProvisioningUri()); } void SettingsModel::setRemoteProvisioning (const QString &remoteProvisioning) { - if (!CoreManager::getInstance()->getCore()->setProvisioningUri(Utils::appStringToCoreString(remoteProvisioning))) - emit remoteProvisioningChanged(remoteProvisioning); - else - emit remoteProvisioningNotChanged(remoteProvisioning); + if (!CoreManager::getInstance()->getCore()->setProvisioningUri(Utils::appStringToCoreString(remoteProvisioning))) + emit remoteProvisioningChanged(remoteProvisioning); + else + emit remoteProvisioningNotChanged(remoteProvisioning); } // ----------------------------------------------------------------------------- bool SettingsModel::getExitOnClose () const { - return !!mConfig->getInt(UiSection, "exit_on_close", 0); + return !!mConfig->getInt(UiSection, "exit_on_close", 0); } void SettingsModel::setExitOnClose (bool value) { - mConfig->setInt(UiSection, "exit_on_close", value); - emit exitOnCloseChanged(value); + mConfig->setInt(UiSection, "exit_on_close", value); + emit exitOnCloseChanged(value); } // ============================================================================= @@ -1020,85 +1160,97 @@ void SettingsModel::setExitOnClose (bool value) { // ============================================================================= QString SettingsModel::getLogsFolder () const { - return getLogsFolder(mConfig); + return getLogsFolder(mConfig); } void SettingsModel::setLogsFolder (const QString &folder) { - // Do not update path in linphone core. - // Just update the config file. - mConfig->setString(UiSection, "logs_folder", Utils::appStringToCoreString(folder)); + // Do not update path in linphone core. + // Just update the config file. + mConfig->setString(UiSection, "logs_folder", Utils::appStringToCoreString(folder)); - emit logsFolderChanged(folder); + emit logsFolderChanged(folder); } // ----------------------------------------------------------------------------- QString SettingsModel::getLogsUploadUrl () const { - return Utils::coreStringToAppString( - CoreManager::getInstance()->getCore()->getLogCollectionUploadServerUrl() - ); + return Utils::coreStringToAppString( + CoreManager::getInstance()->getCore()->getLogCollectionUploadServerUrl() + ); } void SettingsModel::setLogsUploadUrl (const QString &url) { - CoreManager::getInstance()->getCore()->setLogCollectionUploadServerUrl( - Utils::appStringToCoreString(url) - ); + CoreManager::getInstance()->getCore()->setLogCollectionUploadServerUrl( + Utils::appStringToCoreString(url) + ); - emit logsUploadUrlChanged(getLogsUploadUrl()); + emit logsUploadUrlChanged(getLogsUploadUrl()); } // ----------------------------------------------------------------------------- bool SettingsModel::getLogsEnabled () const { - return getLogsEnabled(mConfig); + return getLogsEnabled(mConfig); } void SettingsModel::setLogsEnabled (bool status) { - mConfig->setInt(UiSection, "logs_enabled", status); - Logger::getInstance()->enable(status); - emit logsEnabledChanged(status); + mConfig->setInt(UiSection, "logs_enabled", status); + Logger::getInstance()->enable(status); + emit logsEnabledChanged(status); } // --------------------------------------------------------------------------- QString SettingsModel::getLogsEmail () const { - return Utils::coreStringToAppString( - mConfig->getString(UiSection, "logs_email", DefaultLogsEmail) - ); + return Utils::coreStringToAppString( + mConfig->getString(UiSection, "logs_email", DefaultLogsEmail) + ); } void SettingsModel::setLogsEmail (const QString &email) { - mConfig->setString(UiSection, "logs_email", Utils::appStringToCoreString(email)); - emit logsEmailChanged(email); + mConfig->setString(UiSection, "logs_email", Utils::appStringToCoreString(email)); + emit logsEmailChanged(email); } // --------------------------------------------------------------------------- QString SettingsModel::getLogsFolder (const shared_ptr &config) { - return Utils::coreStringToAppString(config - ? config->getString(UiSection, "logs_folder", Paths::getLogsDirPath()) - : Paths::getLogsDirPath()); + return Utils::coreStringToAppString(config + ? config->getString(UiSection, "logs_folder", Paths::getLogsDirPath()) + : Paths::getLogsDirPath()); } bool SettingsModel::getLogsEnabled (const shared_ptr &config) { - return config ? config->getInt(UiSection, "logs_enabled", false) : false; + return config ? config->getInt(UiSection, "logs_enabled", false) : false; } // --------------------------------------------------------------------------- bool SettingsModel::getDeveloperSettingsEnabled () const { - #ifdef DEBUG - return !!mConfig->getInt(UiSection, "developer_settings", 0); - #else - return false; - #endif // ifdef DEBUG +#ifdef DEBUG + return !!mConfig->getInt(UiSection, "developer_settings", 0); +#else + return false; +#endif // ifdef DEBUG } void SettingsModel::setDeveloperSettingsEnabled (bool status) { - #ifdef DEBUG - mConfig->setInt(UiSection, "developer_settings", status); - emit developerSettingsEnabledChanged(status); - #else - qWarning() << QStringLiteral("Unable to change developer settings mode in release version."); - #endif // ifdef DEBUG +#ifdef DEBUG + mConfig->setInt(UiSection, "developer_settings", status); + emit developerSettingsEnabledChanged(status); +#else + qWarning() << QStringLiteral("Unable to change developer settings mode in release version."); +#endif // ifdef DEBUG +} + +void SettingsModel::handleCallCreated(const shared_ptr &call) { + emit isInCallChanged(getIsInCall()); +} + +void SettingsModel::handleCallStateChanged(const shared_ptr &call, linphone::Call::State state) { + emit isInCallChanged(getIsInCall()); +} + +bool SettingsModel::getIsInCall() const { + return CoreManager::getInstance()->getCore()->getCallsNb() != 0; } diff --git a/src/components/settings/SettingsModel.hpp b/src/components/settings/SettingsModel.hpp index 704e7b449..150ca2de4 100644 --- a/src/components/settings/SettingsModel.hpp +++ b/src/components/settings/SettingsModel.hpp @@ -24,8 +24,11 @@ #define SETTINGS_MODEL_H_ #include +#include #include +#include "components/core/CoreHandlers.hpp" + // ============================================================================= class SettingsModel : public QObject { @@ -46,8 +49,13 @@ class SettingsModel : public QObject { // Audio. -------------------------------------------------------------------- - Q_PROPERTY(QStringList captureDevices READ getCaptureDevices CONSTANT); - Q_PROPERTY(QStringList playbackDevices READ getPlaybackDevices CONSTANT); + Q_PROPERTY(bool captureGraphRunning READ getCaptureGraphRunning NOTIFY captureGraphRunningChanged); + + Q_PROPERTY(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); @@ -61,7 +69,7 @@ class SettingsModel : public QObject { // Video. -------------------------------------------------------------------- - Q_PROPERTY(QStringList videoDevices READ getVideoDevices CONSTANT); + Q_PROPERTY(QStringList videoDevices READ getVideoDevices NOTIFY videoDevicesChanged); Q_PROPERTY(QString videoDevice READ getVideoDevice WRITE setVideoDevice NOTIFY videoDeviceChanged); @@ -171,6 +179,8 @@ class SettingsModel : public QObject { 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), @@ -193,6 +203,9 @@ public: // METHODS. // =========================================================================== + Q_INVOKABLE void onSettingsTabChanged(int idx); + Q_INVOKABLE void settingsWindowClosing(void); + // Assistant. ---------------------------------------------------------------- bool getCreateAppSipAccountEnabled () const; @@ -212,6 +225,19 @@ public: // Audio. -------------------------------------------------------------------- + void createCaptureGraph(); + 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; @@ -235,6 +261,9 @@ public: // Video. -------------------------------------------------------------------- + //Called from qml when accessing audio settings panel + Q_INVOKABLE void accessVideoSettings(); + QStringList getVideoDevices () const; QString getVideoDevice () const; @@ -424,6 +453,11 @@ public: bool getDeveloperSettingsEnabled () const; void setDeveloperSettingsEnabled (bool status); + void handleCallCreated(const std::shared_ptr &call); + void handleCallStateChanged(const std::shared_ptr &call, linphone::Call::State state); + + bool getIsInCall() const; + static const std::string UiSection; // =========================================================================== @@ -442,6 +476,14 @@ signals: // 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); @@ -454,6 +496,7 @@ signals: // Video. -------------------------------------------------------------------- + void videoDevicesChanged (const QStringList &devices); void videoDeviceChanged (const QString &device); void videoPresetChanged (const QString &preset); @@ -548,7 +591,12 @@ signals: bool developerSettingsEnabledChanged (bool status); + bool isInCallChanged(bool); + private: + int mCurrentSettingsTab = 0; + MediastreamerUtils::SimpleCaptureGraph *mSimpleCaptureGraph = nullptr; + std::shared_ptr mConfig; }; diff --git a/src/components/sip-addresses/SipAddressesModel.cpp b/src/components/sip-addresses/SipAddressesModel.cpp index 353c99742..9cfa60f97 100644 --- a/src/components/sip-addresses/SipAddressesModel.cpp +++ b/src/components/sip-addresses/SipAddressesModel.cpp @@ -451,6 +451,14 @@ void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, ].timestamp = callLog->getStatus() == linphone::Call::Status::Success ? QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000) : QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000); + + if (callLog->getStatus() == linphone::Call::Status::Missed) { + for (auto &observer : mObservers.values(callLog->getPeerAddress()->asStringUriOnly())) { + if (observer->getLocalAddress() == callLog->getLocalAddress()->asStringUriOnly()) { + observer->setUnreadMessageCount(1); + } + } + } } void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const shared_ptr &message) { @@ -561,18 +569,17 @@ void SipAddressesModel::initSipAddressesFromCalls () { const QString localAddress(Utils::coreStringToAppString(callLog->getLocalAddress()->asStringUriOnly())); switch (callLog->getStatus()) { - case linphone::Call::Status::Aborted: - case linphone::Call::Status::EarlyAborted: - return; // Ignore aborted calls. + case linphone::Call::Status::Aborted: + case linphone::Call::Status::EarlyAborted: + return; // Ignore aborted calls. + case linphone::Call::Status::AcceptedElsewhere: + case linphone::Call::Status::DeclinedElsewhere: + return; // Ignore accepted calls on other device. + case linphone::Call::Status::Success: + case linphone::Call::Status::Declined: - case linphone::Call::Status::AcceptedElsewhere: - case linphone::Call::Status::DeclinedElsewhere: - return; // Ignore accepted calls on other device. - - case linphone::Call::Status::Success: - case linphone::Call::Status::Missed: - case linphone::Call::Status::Declined: - break; + case linphone::Call::Status::Missed: + break; } ConferenceId conferenceId{ peerAddress, localAddress }; @@ -617,9 +624,10 @@ void SipAddressesModel::updateObservers (const QString &sipAddress, const Presen } void SipAddressesModel::updateObservers (const QString &peerAddress, const QString &localAddress, int messageCount) { - for (auto &observer : mObservers.values(peerAddress)) - if (observer->getLocalAddress() == localAddress) { - observer->setUnreadMessageCount(messageCount); - return; - } + for (auto &observer : mObservers.values(peerAddress)) { + if (observer->getLocalAddress() == localAddress) { + observer->setUnreadMessageCount(messageCount); + return; + } + } } diff --git a/src/components/sip-addresses/SipAddressesModel.hpp b/src/components/sip-addresses/SipAddressesModel.hpp index c0fd41aad..d304dbabf 100644 --- a/src/components/sip-addresses/SipAddressesModel.hpp +++ b/src/components/sip-addresses/SipAddressesModel.hpp @@ -114,6 +114,9 @@ private: void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr &call); void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr &message); + + //NMN TODO bind to missedCall event and implement void addOrUpdateSipAddress + template void addOrUpdateSipAddress (const QString &sipAddress, T data); diff --git a/src/utils/LinphoneUtils.hpp b/src/utils/LinphoneUtils.hpp index b6c5fbb33..c360167c8 100644 --- a/src/utils/LinphoneUtils.hpp +++ b/src/utils/LinphoneUtils.hpp @@ -30,17 +30,6 @@ class QString; namespace LinphoneUtils { - inline float computeVu (float volume) { - constexpr float VuMin = -20.f; - constexpr float VuMax = 4.f; - - if (volume < VuMin) - return 0.f; - if (volume > VuMax) - return 1.f; - - return (volume - VuMin) / (VuMax - VuMin); - } linphone::TransportType stringToTransportType (const QString &transport); diff --git a/src/utils/MediastreamerUtils.cpp b/src/utils/MediastreamerUtils.cpp new file mode 100644 index 000000000..52d2d8b2d --- /dev/null +++ b/src/utils/MediastreamerUtils.cpp @@ -0,0 +1,141 @@ +/* + * MediastreamerUtils.cpp + * Copyright (C) 2017-2019 Belledonne Communications, Grenoble, France + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Created on: Nov 6, 2019 + * Author: Nicolas Michon + */ + +#include "linphone/linphonecore.h" +#include "mediastreamer2/msvolume.h" +#include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/msticker.h" +#include "components/core/CoreManager.hpp" +#include "MediastreamerUtils.hpp" + +using namespace MediastreamerUtils; + +SimpleCaptureGraph::SimpleCaptureGraph(const std::string &capture, const std::string &playback) + : captureCardId(capture), playbackCardId(playback) +{ + LinphoneCore *ccore = CoreManager::getInstance()->getCore()->cPtr(); + msFactory = linphone_core_get_ms_factory(ccore); + + playbackCard = ms_snd_card_manager_get_card(ms_factory_get_snd_card_manager(msFactory), playbackCardId.c_str()); + captureCard = ms_snd_card_manager_get_card(ms_factory_get_snd_card_manager(msFactory), captureCardId.c_str()); + + init(); +} + +SimpleCaptureGraph::~SimpleCaptureGraph() +{ + destroy(); +} + +void SimpleCaptureGraph::init() { + if (!audioCapture) { + audioCapture = ms_snd_card_create_reader(captureCard); + } + if (!audioSink) { + audioSink = ms_snd_card_create_writer(playbackCard); + } + if (!captureVolumeFilter) { + captureVolumeFilter = ms_factory_create_filter(msFactory, MS_VOLUME_ID); + } + if (!playbackVolumeFilter) { + playbackVolumeFilter = ms_factory_create_filter(msFactory, MS_VOLUME_ID); + } + + ms_filter_link(audioCapture, 0, captureVolumeFilter, 0); + ms_filter_link(captureVolumeFilter, 0, playbackVolumeFilter, 0); + ms_filter_link(playbackVolumeFilter, 0, audioSink, 0); + + //Mute playback + float muteGain = 0.0f; + ms_filter_call_method(playbackVolumeFilter, MS_VOLUME_SET_GAIN, &muteGain); + + ticker = ms_ticker_new(); + running = false; +} + +void SimpleCaptureGraph::start() { + if (!running) { + ms_ticker_attach(ticker, audioCapture); + running = true; + } +} + +void SimpleCaptureGraph::stop() { + if (running) { + ms_ticker_detach(ticker, audioCapture); + running = false; + } +} + +void SimpleCaptureGraph::destroy() { + if (running) { + stop(); + } + ms_ticker_destroy(ticker); + ms_filter_unlink(audioCapture, 0, captureVolumeFilter, 0); + ms_filter_unlink(captureVolumeFilter, 0, playbackVolumeFilter, 0); + ms_filter_unlink(playbackVolumeFilter, 0, audioSink, 0); + + ms_free(audioCapture); + ms_free(captureVolumeFilter); + ms_free(audioSink); + ms_free(playbackVolumeFilter); +} + +float SimpleCaptureGraph::getCaptureGain() { + float gain = 0.0f; + + if (isRunning() && audioCapture) { + ms_filter_call_method(audioCapture, MS_AUDIO_CAPTURE_GET_VOLUME_GAIN, &gain); + } + return gain; +} + +void SimpleCaptureGraph::setCaptureGain(float gain) { + if (isRunning() && audioCapture) { + ms_filter_call_method(audioCapture, MS_AUDIO_CAPTURE_SET_VOLUME_GAIN, &gain); + } +} + +float SimpleCaptureGraph::getPlaybackGain() { + float gain = 0.0f; + if (isRunning() && audioSink) { + ms_filter_call_method(audioSink, MS_AUDIO_PLAYBACK_GET_VOLUME_GAIN, &gain); + } + return gain; +} + +void SimpleCaptureGraph::setPlaybackGain(float gain) { + if (isRunning() && audioSink) { + ms_filter_call_method(audioSink, MS_AUDIO_PLAYBACK_SET_VOLUME_GAIN, &gain); + } +} + +float SimpleCaptureGraph::getCaptureVolume() { + float vol = 0; + + if (captureVolumeFilter) { + ms_filter_call_method(captureVolumeFilter, MS_VOLUME_GET, &vol); + vol = MediastreamerUtils::dbToLinear(vol); + } + return vol; +} diff --git a/src/utils/MediastreamerUtils.hpp b/src/utils/MediastreamerUtils.hpp new file mode 100644 index 000000000..35ed99bcf --- /dev/null +++ b/src/utils/MediastreamerUtils.hpp @@ -0,0 +1,102 @@ +/* + * MediastreamerUtils.hpp + * Copyright (C) 2017-2019 Belledonne Communications, Grenoble, France + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Created on: Nov 6, 2019 + * Author: Nicolas Michon + */ + +#ifndef MEDIASTREAMER_UTILS_H_ +#define MEDIASTREAMER_UTILS_H_ + +#include + +#include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/msvolume.h" +#include "mediastreamer2/msfilter.h" +#include "mediastreamer2/msticker.h" +#include + +// ============================================================================= + +namespace MediastreamerUtils { + + inline float computeVu (float volume) { + constexpr float VuMin = -20.f; + constexpr float VuMax = 4.f; + + if (volume < VuMin) + return 0.f; + if (volume > VuMax) + return 1.f; + + return (volume - VuMin) / (VuMax - VuMin); + } + + inline float dbToLinear(float volume) { + return static_cast(pow(10, volume / 10)); + } + + inline float linearToDb(float volume) { + if (volume == 0.0f) { + return MS_VOLUME_DB_LOWEST; + } + return static_cast(10 * log10(volume)); + } + + //Simple mediastreamer audio capture graph + //Used to get current microphone volume in audio settings + class SimpleCaptureGraph { + public: + SimpleCaptureGraph(const std::string &captureCardId, const std::string &playbackCardId); + ~SimpleCaptureGraph(); + + void start(); + void stop(); + + float getCaptureVolume(); + + float getCaptureGain(); + float getPlaybackGain(); + void setCaptureGain(float volume); + void setPlaybackGain(float volume); + + bool isRunning() const { + return running; + } + protected: + void init(); + void destroy(); + + bool running = false; + + std::string captureCardId; + std::string playbackCardId; + + MSFilter *audioSink = nullptr; + MSFilter *audioCapture = nullptr; + MSFilter *captureVolumeFilter = nullptr; + MSFilter *playbackVolumeFilter = nullptr; + MSTicker *ticker = nullptr; + MSSndCard *playbackCard = nullptr; + MSSndCard *captureCard = nullptr; + MSFactory *msFactory = nullptr; + }; + +} + +#endif // ifndef MEDIASTREAMER_UTILS_H_ diff --git a/ui/modules/Common/Form/ActionButton.qml b/ui/modules/Common/Form/ActionButton.qml index ca621e24d..1d03184de 100644 --- a/ui/modules/Common/Form/ActionButton.qml +++ b/ui/modules/Common/Form/ActionButton.qml @@ -17,6 +17,7 @@ Item { property bool useStates: true property int iconSize // Optional. readonly property alias hovered: button.hovered + property alias text: button.text // If `useStates` = true, the used icons are: // `icon`_pressed, `icon`_hovered and `icon`_normal. @@ -51,7 +52,7 @@ Item { // --------------------------------------------------------------------------- height: iconSize || parent.iconSize || parent.height - width: iconSize || parent.iconSize || parent.height + width: iconSize || parent.iconSize || parent.width Button { id: button diff --git a/ui/modules/Common/Form/ActionSwitch.qml b/ui/modules/Common/Form/ActionSwitch.qml index 541953bef..88d86f23e 100644 --- a/ui/modules/Common/Form/ActionSwitch.qml +++ b/ui/modules/Common/Form/ActionSwitch.qml @@ -5,6 +5,7 @@ import QtQuick 2.7 Item { property alias updating: actionButton.updating property alias useStates: actionButton.useStates + property alias text: actionButton.text property bool enabled: true property int iconSize // Optionnal. property string icon @@ -16,7 +17,7 @@ Item { // --------------------------------------------------------------------------- height: iconSize || parent.iconSize || parent.height - width: iconSize || parent.iconSize || parent.height + width: iconSize || parent.iconSize || parent.width ActionButton { id: actionButton diff --git a/ui/modules/Common/Tooltip/Tooltip.qml b/ui/modules/Common/Tooltip/Tooltip.qml index 7c9967d5d..1ebcd43ed 100644 --- a/ui/modules/Common/Tooltip/Tooltip.qml +++ b/ui/modules/Common/Tooltip/Tooltip.qml @@ -1,5 +1,5 @@ -import QtQuick 2.7 -import QtQuick.Controls 2.2 +import QtQuick 2.7 as Core +import QtQuick.Controls 2.2 as Core import Common 1.0 import Common.Styles 1.0 @@ -7,7 +7,7 @@ import Utils 1.0 // ============================================================================= -ToolTip { +Core.ToolTip { id: tooltip property var _edge: 'left' @@ -78,7 +78,7 @@ ToolTip { // --------------------------------------------------------------------------- - background: Item { + background: Core.Item { id: container layer { @@ -86,7 +86,7 @@ ToolTip { effect: PopupShadow {} } - Rectangle { + Core.Rectangle { anchors { fill: parent margins: TooltipStyle.margins @@ -97,10 +97,10 @@ ToolTip { // Do not use `Icon` component to access to `implicitHeight` // and `implicitWidth`. - Image { + Core.Image { id: icon - fillMode: Image.PreserveAspectFit + fillMode: Core.Image.PreserveAspectFit height: TooltipStyle.arrowSize source: _edge ? Utils.resolveImageUri('tooltip_arrow_' + _edge) @@ -111,11 +111,11 @@ ToolTip { width: TooltipStyle.arrowSize z: Constants.zMax - onStatusChanged: status === Image.Ready && _setArrowPosition() + onStatusChanged: status === Core.Image.Ready && _setArrowPosition() } } - contentItem: Text { + contentItem: Core.Text { id: text color: TooltipStyle.color diff --git a/ui/modules/Common/qmldir b/ui/modules/Common/qmldir index bb3ae4d55..5f8e5a071 100644 --- a/ui/modules/Common/qmldir +++ b/ui/modules/Common/qmldir @@ -81,6 +81,8 @@ PopupShadow 1.0 Popup/PopupShadow.qml TooltipArea 1.0 Tooltip/TooltipArea.qml +ToolTip 1.0 Tooltip/Tooltip.qml + ScrollableListView 1.0 View/ScrollableListView.qml ApplicationWindow 1.0 Window/ApplicationWindow.qml diff --git a/ui/views/App/Calls/CallsWindow.qml b/ui/views/App/Calls/CallsWindow.qml index 6282ec2c0..5d9951928 100644 --- a/ui/views/App/Calls/CallsWindow.qml +++ b/ui/views/App/Calls/CallsWindow.qml @@ -17,7 +17,7 @@ Window { // --------------------------------------------------------------------------- - // `{}` is a workaround to avoid `TypeError: Cannot read property...`. + // `{}` is a workaround to avoid `TypeError: Cannot read property...` when calls list is empty readonly property var call: calls.selectedCall || ({ callError: '', isOutgoing: true, diff --git a/ui/views/App/Calls/Dialogs/MultimediaParameters.qml b/ui/views/App/Calls/Dialogs/MultimediaParameters.qml index 5effa2331..3118616d1 100644 --- a/ui/views/App/Calls/Dialogs/MultimediaParameters.qml +++ b/ui/views/App/Calls/Dialogs/MultimediaParameters.qml @@ -1,4 +1,5 @@ import QtQuick 2.7 +import QtQuick.Controls 2.7 import QtQuick.Layouts 1.3 import Common 1.0 @@ -67,10 +68,17 @@ DialogPlus { } Slider { + id: playbackSlider width: parent.width Component.onCompleted: value = call.speakerVolumeGain onPositionChanged: call.speakerVolumeGain = position + + ToolTip { + parent: playbackSlider.handle + visible: playbackSlider.pressed + text: (playbackSlider.value * 100).toFixed(0) + " %" + } } } } @@ -103,10 +111,17 @@ DialogPlus { } Slider { + id: captureSlider width: parent.width Component.onCompleted: value = call.microVolumeGain onPositionChanged: call.microVolumeGain = position + + ToolTip { + parent: captureSlider.handle + visible: captureSlider.pressed + text: "+ " + (captureSlider.value * 100).toFixed(0) + " %" + } } } } diff --git a/ui/views/App/Main/ContactEdit.qml b/ui/views/App/Main/ContactEdit.qml index d63ca9f53..0e870f8c9 100644 --- a/ui/views/App/Main/ContactEdit.qml +++ b/ui/views/App/Main/ContactEdit.qml @@ -129,6 +129,10 @@ ColumnLayout { icon: 'history' onClicked: sipAddressesMenu.open() + + TooltipArea { + text: qsTr('tooltipShowConversation') + } } } diff --git a/ui/views/App/Main/Conversation.js b/ui/views/App/Main/Conversation.js index 28fc8beef..978a27d3f 100644 --- a/ui/views/App/Main/Conversation.js +++ b/ui/views/App/Main/Conversation.js @@ -28,6 +28,10 @@ function getEditIcon () { return conversation._sipAddressObserver.contact ? 'contact_edit' : 'contact_add' } +function getEditTooltipText() { + return conversation._sipAddressObserver.contact ? qsTr('tooltipContactEdit') : qsTr('tooltipContactAdd') +} + function getUsername () { return LinphoneUtils.getContactUsername(conversation._sipAddressObserver) } diff --git a/ui/views/App/Main/Conversation.qml b/ui/views/App/Main/Conversation.qml index 22180797a..0d36b8fcf 100644 --- a/ui/views/App/Main/Conversation.qml +++ b/ui/views/App/Main/Conversation.qml @@ -100,6 +100,9 @@ ColumnLayout { onClicked: window.setView('ContactEdit', { sipAddress: conversation.peerAddress }) + TooltipArea { + text: Logic.getEditTooltipText() + } } ActionButton { @@ -107,6 +110,10 @@ ColumnLayout { iconSize: ConversationStyle.bar.actions.edit.iconSize onClicked: Logic.removeAllEntries() + + TooltipArea { + text: qsTr('cleanHistory') + } } } } diff --git a/ui/views/App/Main/Dialogs/ManageAccounts.qml b/ui/views/App/Main/Dialogs/ManageAccounts.qml index 790a1cfae..2a3f78411 100644 --- a/ui/views/App/Main/Dialogs/ManageAccounts.qml +++ b/ui/views/App/Main/Dialogs/ManageAccounts.qml @@ -81,6 +81,13 @@ DialogPlus { itemIcon: Logic.getItemIcon(flattenedModel) width: parent.width + ActionButton { + icon: 'options' + iconSize: 30 + anchors.fill: parent + //TODO handle click and jump to proxy config settings + } + onClicked: { container.currentIndex = index AccountSettingsModel.setDefaultProxyConfig(flattenedModel.proxyConfig) diff --git a/ui/views/App/Main/MainWindow.qml b/ui/views/App/Main/MainWindow.qml index 35af3699e..9661c6a0f 100644 --- a/ui/views/App/Main/MainWindow.qml +++ b/ui/views/App/Main/MainWindow.qml @@ -180,6 +180,10 @@ ApplicationWindow { visible: SettingsModel.conferenceEnabled onClicked: Logic.openConferenceManager() + + TooltipArea { + text: qsTr('newConferenceButton') + } } ActionButton { diff --git a/ui/views/App/Settings/SettingsAudio.qml b/ui/views/App/Settings/SettingsAudio.qml index b59634377..d160ad7cc 100644 --- a/ui/views/App/Settings/SettingsAudio.qml +++ b/ui/views/App/Settings/SettingsAudio.qml @@ -1,4 +1,6 @@ -import QtQuick 2.7 +import QtQuick 2.7 as Core +import QtQuick.Controls 2.7 as Core +import QtQuick.Layouts 1.10 as Core import Common 1.0 import Linphone 1.0 @@ -9,7 +11,7 @@ import App.Styles 1.0 // ============================================================================= TabContainer { - Column { + Core.Column { spacing: SettingsWindowStyle.forms.spacing width: parent.width @@ -21,6 +23,28 @@ TabContainer { title: qsTr('audioTitle') width: parent.width + //Warning if in call + FormLine { + visible: SettingsModel.isInCall + + FormGroup { + Core.RowLayout { + spacing: SettingsAudioStyle.warningMessage.iconSize + Icon { + icon: 'warning' + iconSize: SettingsAudioStyle.warningMessage.iconSize + anchors { + rightMargin: SettingsAudioStyle.warningMessage.iconSize + leftMargin: SettingsAudioStyle.warningMessage.iconSize + } + } + Core.Text { + text: qsTr('audioSettingsInCallWarning') + } + } + } + } + FormLine { FormGroup { label: qsTr('playbackDeviceLabel') @@ -36,6 +60,28 @@ TabContainer { } } + FormLine { + FormGroup { + label: qsTr('playbackGainLabel') + enabled: !SettingsModel.isInCall + + Slider { + id: playbackSlider + width: parent.width + enabled: !SettingsModel.isInCall + + Core.Component.onCompleted: value = SettingsModel.playbackGain + onPositionChanged: SettingsModel.playbackGain = position + + Core.ToolTip { + parent: playbackSlider.handle + visible: playbackSlider.pressed + text: (playbackSlider.value * 100).toFixed(0) + " %" + } + } + } + } + FormLine { FormGroup { label: qsTr('captureDeviceLabel') @@ -51,11 +97,83 @@ TabContainer { } } + FormLine { + FormGroup { + label: qsTr('captureGainLabel') + + Slider { + id: captureSlider + width: parent.width + enabled: !SettingsModel.isInCall + + Core.Component.onCompleted: value = SettingsModel.captureGain + onPositionChanged: SettingsModel.captureGain = position + + Core.ToolTip { + parent: captureSlider.handle + visible: captureSlider.pressed + text: (captureSlider.value * 100).toFixed(0) + " %" + } + } + } + } + + FormLine { + FormGroup { + id: audioTestRow + label: qsTr('audioTestLabel') + visible: !SettingsModel.isInCall + + Core.Slider { + id: audioTestSlider + + enabled: false + width: parent.width + anchors { + leftMargin: SettingsAudioStyle.ringPlayer.leftMargin + } + + background: Core.Rectangle { + x: audioTestSlider.leftPadding + y: audioTestSlider.topPadding + audioTestSlider.availableHeight / 2 - height / 2 + implicitWidth: 200 + implicitHeight: 8 + width: audioTestSlider.availableWidth + height: implicitHeight + radius: 2 + color: "#bdbebf" + + Core.Rectangle { + width: audioTestSlider.visualPosition * parent.width + height: parent.height + color: audioTestSlider.value > 0.8 ? "#ff0000" : "#21be2b" + radius: 2 + } + } + + //Empty slider handle + handle: Core.Text { + text: '' + visible: false + } + + Core.Timer { + interval: 50 + repeat: true + running: SettingsModel.captureGraphRunning + + onTriggered: parent.value = SettingsModel.getMicVolume() + } + } + } + } + FormLine { FormGroup { label: qsTr('ringerDeviceLabel') ComboBox { + enabled: !SettingsModel.isInCall currentIndex: Utils.findIndex(model, function (device) { return device === SettingsModel.ringerDevice }) @@ -108,7 +226,7 @@ TabContainer { } } - Loader { + Core.Loader { id: ringPlayer active: window.visible diff --git a/ui/views/App/Settings/SettingsWindow.qml b/ui/views/App/Settings/SettingsWindow.qml index d3261a266..374f3a81a 100644 --- a/ui/views/App/Settings/SettingsWindow.qml +++ b/ui/views/App/Settings/SettingsWindow.qml @@ -19,6 +19,8 @@ ApplicationWindow { title: qsTr('settingsTitle') + onClosing: SettingsModel.settingsWindowClosing() + // --------------------------------------------------------------------------- Shortcut { @@ -48,16 +50,21 @@ ApplicationWindow { TabBar { id: tabBar + onCurrentIndexChanged: SettingsModel.onSettingsTabChanged(currentIndex) + TabButton { iconName: 'settings_sip_accounts' text: qsTr('sipAccountsTab') width: implicitWidth - } + //onClicked: SettingsModel.settingsButtonClicked("sip") + } TabButton { iconName: 'settings_audio' text: qsTr('audioTab') width: implicitWidth + //onClicked: SettingsModel.accessAudioSettings() + //onClicked: SettingsModel.settingsButtonClicked("audio") } TabButton { @@ -65,12 +72,15 @@ ApplicationWindow { iconName: 'settings_video' text: qsTr('videoTab') width: implicitWidth + //onClicked: SettingsModel.accessVideoSettings() + //onClicked: SettingsModel.settingsButtonClicked("video") } TabButton { iconName: 'settings_call' text: qsTr('callsAndChatTab') width: implicitWidth + //onClicked: SettingsModel.settingsButtonClicked("call") } TabButton { @@ -78,18 +88,21 @@ ApplicationWindow { iconName: 'settings_network' text: qsTr('networkTab') width: implicitWidth + //onClicked: SettingsModel.settingsButtonClicked("network") } TabButton { iconName: 'settings_advanced' text: qsTr('uiTab') width: implicitWidth + //onClicked: SettingsModel.settingsButtonClicked("ui") } TabButton { iconName: 'settings_advanced' text: qsTr('uiAdvanced') width: implicitWidth + //onClicked: SettingsModel.settingsButtonClicked("advanced") } } diff --git a/ui/views/App/Styles/Settings/SettingsAudioStyle.qml b/ui/views/App/Styles/Settings/SettingsAudioStyle.qml index 00b85aa34..a7145c284 100644 --- a/ui/views/App/Styles/Settings/SettingsAudioStyle.qml +++ b/ui/views/App/Styles/Settings/SettingsAudioStyle.qml @@ -7,4 +7,7 @@ QtObject { property QtObject ringPlayer: QtObject { property int leftMargin: 10 } + property QtObject warningMessage: QtObject { + property int iconSize: 20 + } }