From 2402bb2f253fcf834ce60e2bf42079ff937212c2 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Thu, 2 Feb 2017 12:07:17 +0100 Subject: [PATCH] feat(ui/views/App/Calls/Incall): supports set/unset video in call --- linphone-desktop/assets/languages/en.ts | 8 +++ linphone-desktop/assets/languages/fr.ts | 8 +++ .../src/components/call/CallModel.cpp | 61 +++++++++++++++---- .../src/components/call/CallModel.hpp | 14 ++--- .../views/App/Calls/AbstractStartingCall.qml | 2 + .../ui/views/App/Calls/CallsWindow.qml | 25 ++++++-- .../ui/views/App/Calls/Incall.qml | 45 ++++++++++---- .../ui/views/App/Calls/OutgoingCall.qml | 11 +--- 8 files changed, 127 insertions(+), 47 deletions(-) diff --git a/linphone-desktop/assets/languages/en.ts b/linphone-desktop/assets/languages/en.ts index e246e3f03..79e1678ff 100644 --- a/linphone-desktop/assets/languages/en.ts +++ b/linphone-desktop/assets/languages/en.ts @@ -363,6 +363,14 @@ Server url not configured. saveScreenshotTitle + + acceptVideoDescription + + + + acceptVideoTitle + + MainWindow diff --git a/linphone-desktop/assets/languages/fr.ts b/linphone-desktop/assets/languages/fr.ts index 4e26fbdf4..13d702994 100644 --- a/linphone-desktop/assets/languages/fr.ts +++ b/linphone-desktop/assets/languages/fr.ts @@ -351,6 +351,14 @@ Url du serveur non configurée. saveScreenshotTitle + + acceptVideoDescription + + + + acceptVideoTitle + + IncomingCall diff --git a/linphone-desktop/src/components/call/CallModel.cpp b/linphone-desktop/src/components/call/CallModel.cpp index a4729a313..b670ce4c9 100644 --- a/linphone-desktop/src/components/call/CallModel.cpp +++ b/linphone-desktop/src/components/call/CallModel.cpp @@ -36,6 +36,20 @@ CallModel::CallModel (shared_ptr linphone_call) { m_paused_by_user = false; break; + case linphone::CallStateUpdatedByRemote: { + shared_ptr core = CoreManager::getInstance()->getCore(); + + if ( + !m_linphone_call->getCurrentParams()->videoEnabled() && + m_linphone_call->getRemoteParams()->videoEnabled() + ) { + CoreManager::getInstance()->getCore()->deferCallUpdate(m_linphone_call); + emit videoRequested(); + } + } + + break; + default: break; } @@ -63,6 +77,16 @@ void CallModel::transfer () { // TODO } +void CallModel::acceptVideoRequest () { + shared_ptr params = m_linphone_call->getCurrentParams()->copy(); + params->enableVideo(true); + CoreManager::getInstance()->getCore()->acceptCallUpdate(m_linphone_call, params); +} + +void CallModel::rejectVideoRequest () { + CoreManager::getInstance()->getCore()->acceptCallUpdate(m_linphone_call, m_linphone_call->getCurrentParams()); +} + // ----------------------------------------------------------------------------- QString CallModel::getSipAddress () const { @@ -135,6 +159,15 @@ bool CallModel::getPausedByUser () const { } void CallModel::setPausedByUser (bool status) { + switch (m_linphone_call->getState()) { + case linphone::CallStateConnected: + case linphone::CallStateStreamsRunning: + case linphone::CallStatePaused: + case linphone::CallStatePausedByRemote: + break; + default: return; + } + if (status) { if (!m_paused_by_user) CoreManager::getInstance()->getCore()->pauseCall(m_linphone_call); @@ -146,20 +179,24 @@ void CallModel::setPausedByUser (bool status) { CoreManager::getInstance()->getCore()->resumeCall(m_linphone_call); } -bool CallModel::getVideoInputEnabled () const { - shared_ptr params = m_linphone_call->getRemoteParams(); - return params && params->videoEnabled() && getStatus() == CallStatusConnected; -} - -void CallModel::setVideoInputEnabled (bool status) { - // TODO -} - -bool CallModel::getVideoOutputEnabled () const { +bool CallModel::getVideoEnabled () const { shared_ptr params = m_linphone_call->getCurrentParams(); return params && params->videoEnabled() && getStatus() == CallStatusConnected; } -void CallModel::setVideoOutputEnabled (bool status) { - // TODO +void CallModel::setVideoEnabled (bool status) { + switch (m_linphone_call->getState()) { + case linphone::CallStateConnected: + case linphone::CallStateStreamsRunning: + break; + default: return; + } + + if (status == getVideoEnabled()) + return; + + shared_ptr params = CoreManager::getInstance()->getCore()->createCallParams(m_linphone_call); + params->enableVideo(status); + + CoreManager::getInstance()->getCore()->updateCall(m_linphone_call, params); } diff --git a/linphone-desktop/src/components/call/CallModel.hpp b/linphone-desktop/src/components/call/CallModel.hpp index 8ed51a543..6af866b95 100644 --- a/linphone-desktop/src/components/call/CallModel.hpp +++ b/linphone-desktop/src/components/call/CallModel.hpp @@ -16,8 +16,7 @@ class CallModel : public QObject { Q_PROPERTY(float quality READ getQuality CONSTANT); // Same idea. Q_PROPERTY(bool microMuted READ getMicroMuted WRITE setMicroMuted NOTIFY microMutedChanged); Q_PROPERTY(bool pausedByUser READ getPausedByUser WRITE setPausedByUser NOTIFY statusChanged); - Q_PROPERTY(bool videoInputEnabled READ getVideoInputEnabled WRITE setVideoInputEnabled NOTIFY statusChanged); - Q_PROPERTY(bool videoOutputEnabled READ getVideoOutputEnabled WRITE setVideoOutputEnabled NOTIFY statusChanged); + Q_PROPERTY(bool videoEnabled READ getVideoEnabled WRITE setVideoEnabled NOTIFY statusChanged); public: enum CallStatus { @@ -43,9 +42,13 @@ public: Q_INVOKABLE void terminate (); Q_INVOKABLE void transfer (); + Q_INVOKABLE void acceptVideoRequest (); + Q_INVOKABLE void rejectVideoRequest (); + signals: void statusChanged (CallStatus status); void microMutedChanged (bool status); + void videoRequested (); private: QString getSipAddress () const; @@ -64,11 +67,8 @@ private: bool getPausedByUser () const; void setPausedByUser (bool status); - bool getVideoInputEnabled () const; - void setVideoInputEnabled (bool status); - - bool getVideoOutputEnabled () const; - void setVideoOutputEnabled (bool status); + bool getVideoEnabled () const; + void setVideoEnabled (bool status); bool m_micro_muted = false; bool m_paused_by_remote = false; diff --git a/linphone-desktop/ui/views/App/Calls/AbstractStartingCall.qml b/linphone-desktop/ui/views/App/Calls/AbstractStartingCall.qml index c317e19ff..6656e61e1 100644 --- a/linphone-desktop/ui/views/App/Calls/AbstractStartingCall.qml +++ b/linphone-desktop/ui/views/App/Calls/AbstractStartingCall.qml @@ -10,6 +10,8 @@ import App.Styles 1.0 // ============================================================================= Rectangle { + property var call + default property alias _actionArea: actionArea.data property var _contactObserver: SipAddressesModel.getContactObserver(sipAddress) diff --git a/linphone-desktop/ui/views/App/Calls/CallsWindow.qml b/linphone-desktop/ui/views/App/Calls/CallsWindow.qml index bba66a3da..2d5dc970f 100644 --- a/linphone-desktop/ui/views/App/Calls/CallsWindow.qml +++ b/linphone-desktop/ui/views/App/Calls/CallsWindow.qml @@ -15,11 +15,10 @@ Window { // --------------------------------------------------------------------------- + property var call: calls.selectedCall readonly property bool chatIsOpened: !rightPaned.isClosed() - // `{}` is a workaround to avoid `TypeError: Cannot read property...` in `Incall` component. - property var call: calls.selectedCall || {} - property string sipAddress: call.sipAddress || '' + property string sipAddress: call ? call.sipAddress : '' // --------------------------------------------------------------------------- @@ -122,19 +121,28 @@ Window { Component { id: incomingCall - IncomingCall {} + IncomingCall { + call: window.call + } } Component { id: outgoingCall - OutgoingCall {} + OutgoingCall { + call: window.call + } } Component { id: incall - Incall {} + Incall { + // `{}` is a workaround to avoid `TypeError: Cannot read property...` in `Incall` component. + call: window.call || ({ + videoEnabled: false + }) + } } Component { @@ -151,7 +159,12 @@ Window { childA: Loader { anchors.fill: parent + sourceComponent: { + if (!window.call) { + return null + } + var status = window.call.status if (status == null) { return null diff --git a/linphone-desktop/ui/views/App/Calls/Incall.qml b/linphone-desktop/ui/views/App/Calls/Incall.qml index 5f043a695..37079d30f 100644 --- a/linphone-desktop/ui/views/App/Calls/Incall.qml +++ b/linphone-desktop/ui/views/App/Calls/Incall.qml @@ -17,13 +17,36 @@ Rectangle { // --------------------------------------------------------------------------- + property var call + property var _contactObserver: SipAddressesModel.getContactObserver(sipAddress) - property var _call: call // --------------------------------------------------------------------------- color: CallStyle.backgroundColor + // --------------------------------------------------------------------------- + // Handle video requests. + // --------------------------------------------------------------------------- + + SmartConnect { + Component.onCompleted: this.connect(call, 'videoRequested', function () { + Utils.openConfirmDialog(window, { + descriptionText: qsTr('acceptVideoDescription'), + exitHandler: function (status) { + if (status) { + call.acceptVideoRequest() + } else { + call.rejectVideoRequest() + } + }, + title: qsTr('acceptVideoTitle') + }) + }) + } + + // --------------------------------------------------------------------------- + ColumnLayout { anchors { fill: parent @@ -85,7 +108,7 @@ Rectangle { id: cameraActions anchors.right: parent.right - active: Boolean(call.videoInputEnabled) && call.status !== CallModel.CallStatusEnded + active: call.videoEnabled && call.status !== CallModel.CallStatusEnded sourceComponent: ActionBar { iconSize: CallStyle.header.iconSize @@ -200,7 +223,7 @@ Rectangle { Camera { height: container.height width: container.width - call: incall._call + call: incall.call } } @@ -208,7 +231,7 @@ Rectangle { id: cameraLoader anchors.centerIn: parent - sourceComponent: call.videoInputEnabled ? camera : avatar + sourceComponent: call.videoEnabled ? camera : avatar } } @@ -241,15 +264,11 @@ Rectangle { } ActionSwitch { - icon: 'speaker' - iconSize: CallStyle.actionArea.iconSize - onClicked: enabled = !enabled - } - - ActionSwitch { + enabled: call.videoEnabled icon: 'camera' iconSize: CallStyle.actionArea.iconSize - onClicked: enabled = !enabled + + onClicked: call.videoEnabled = !enabled } ActionButton { @@ -266,9 +285,9 @@ Rectangle { width: CallStyle.actionArea.userVideo.width isPreview: true + visible: incall.width >= CallStyle.actionArea.lowWidth && call.videoEnabled - call: incall._call - visible: Boolean(incall.width >= CallStyle.actionArea.lowWidth && call.videoOutputEnabled) + Component.onCompleted: call = incall.call } ActionBar { diff --git a/linphone-desktop/ui/views/App/Calls/OutgoingCall.qml b/linphone-desktop/ui/views/App/Calls/OutgoingCall.qml index 119f5d884..ca8bc46f6 100644 --- a/linphone-desktop/ui/views/App/Calls/OutgoingCall.qml +++ b/linphone-desktop/ui/views/App/Calls/OutgoingCall.qml @@ -10,7 +10,7 @@ import App.Styles 1.0 AbstractStartingCall { GridLayout { - columns: parent.width < CallStyle.actionArea.lowWidth && call.videoOutputEnabled ? 1 : 2 + columns: parent.width < CallStyle.actionArea.lowWidth && call.videoEnabled ? 1 : 2 rowSpacing: ActionBarStyle.spacing anchors { @@ -26,13 +26,6 @@ AbstractStartingCall { onClicked: call.microMuted = enabled } - - ActionSwitch { - icon: 'speaker' - iconSize: CallStyle.actionArea.iconSize - - onClicked: enabled = !enabled - } } Item { @@ -40,7 +33,7 @@ AbstractStartingCall { height: CallStyle.actionArea.userVideo.height width: CallStyle.actionArea.userVideo.width - visible: call.videoOutputEnabled + visible: call.videoEnabled } ActionBar {