Commit 22db039c authored by Ronan Abhamon's avatar Ronan Abhamon

feat(ui/views/App/Calls/CallsWindow): supports call transfer

parent 9dda95aa
...@@ -280,6 +280,17 @@ ...@@ -280,6 +280,17 @@
<translation>Video</translation> <translation>Video</translation>
</message> </message>
</context> </context>
<context>
<name>CallTransfer</name>
<message>
<source>cancel</source>
<translation>CANCEL</translation>
</message>
<message>
<source>callTransferDescription</source>
<translation>Do you want to transfer this call ?</translation>
</message>
</context>
<context> <context>
<name>Calls</name> <name>Calls</name>
<message> <message>
......
...@@ -280,6 +280,17 @@ ...@@ -280,6 +280,17 @@
<translation>Vidéo</translation> <translation>Vidéo</translation>
</message> </message>
</context> </context>
<context>
<name>CallTransfer</name>
<message>
<source>cancel</source>
<translation>ANNULER</translation>
</message>
<message>
<source>callTransferDescription</source>
<translation>Voulez-vous transférer cet appel ?</translation>
</message>
</context>
<context> <context>
<name>Calls</name> <name>Calls</name>
<message> <message>
......
...@@ -358,6 +358,7 @@ ...@@ -358,6 +358,7 @@
<file>ui/views/App/Calls/CallsWindow.qml</file> <file>ui/views/App/Calls/CallsWindow.qml</file>
<file>ui/views/App/Calls/ConferenceManager.qml</file> <file>ui/views/App/Calls/ConferenceManager.qml</file>
<file>ui/views/App/Calls/Conference.qml</file> <file>ui/views/App/Calls/Conference.qml</file>
<file>ui/views/App/Calls/Dialogs/CallTransfer.qml</file>
<file>ui/views/App/Calls/EndedCall.qml</file> <file>ui/views/App/Calls/EndedCall.qml</file>
<file>ui/views/App/Calls/IncallFullscreenWindow.qml</file> <file>ui/views/App/Calls/IncallFullscreenWindow.qml</file>
<file>ui/views/App/Calls/Incall.js</file> <file>ui/views/App/Calls/Incall.js</file>
...@@ -408,6 +409,7 @@ ...@@ -408,6 +409,7 @@
<file>ui/views/App/Styles/Calls/CallsWindowStyle.qml</file> <file>ui/views/App/Styles/Calls/CallsWindowStyle.qml</file>
<file>ui/views/App/Styles/Calls/ConferenceManagerStyle.qml</file> <file>ui/views/App/Styles/Calls/ConferenceManagerStyle.qml</file>
<file>ui/views/App/Styles/Calls/ConferenceStyle.qml</file> <file>ui/views/App/Styles/Calls/ConferenceStyle.qml</file>
<file>ui/views/App/Styles/Calls/Dialogs/CallTransferStyle.qml</file>
<file>ui/views/App/Styles/Main/AboutStyle.qml</file> <file>ui/views/App/Styles/Main/AboutStyle.qml</file>
<file>ui/views/App/Styles/Main/Assistant/ActivateLinphoneSipAccountWithEmailStyle.qml</file> <file>ui/views/App/Styles/Main/Assistant/ActivateLinphoneSipAccountWithEmailStyle.qml</file>
<file>ui/views/App/Styles/Main/Assistant/AssistantAbstractViewStyle.qml</file> <file>ui/views/App/Styles/Main/Assistant/AssistantAbstractViewStyle.qml</file>
......
...@@ -135,10 +135,21 @@ void CallModel::terminate () { ...@@ -135,10 +135,21 @@ void CallModel::terminate () {
core->unlockVideoRender(); core->unlockVideoRender();
} }
// -----------------------------------------------------------------------------
void CallModel::askForTransfer () { void CallModel::askForTransfer () {
CoreManager::getInstance()->getCallsListModel()->askForTransfer(this); CoreManager::getInstance()->getCallsListModel()->askForTransfer(this);
} }
bool CallModel::transferTo (const QString &sipAddress) {
bool status = !!mCall->transfer(::Utils::qStringToLinphoneString(sipAddress));
if (status)
qWarning() << QStringLiteral("Unable to transfer: `%1`.").arg(sipAddress);
return status;
}
// -----------------------------------------------------------------------------
void CallModel::acceptVideoRequest () { void CallModel::acceptVideoRequest () {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore(); shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
shared_ptr<linphone::CallParams> params = core->createCallParams(mCall); shared_ptr<linphone::CallParams> params = core->createCallParams(mCall);
......
...@@ -86,7 +86,9 @@ public: ...@@ -86,7 +86,9 @@ public:
Q_INVOKABLE void accept (); Q_INVOKABLE void accept ();
Q_INVOKABLE void acceptWithVideo (); Q_INVOKABLE void acceptWithVideo ();
Q_INVOKABLE void terminate (); Q_INVOKABLE void terminate ();
Q_INVOKABLE void askForTransfer (); Q_INVOKABLE void askForTransfer ();
Q_INVOKABLE bool transferTo (const QString &sipAddress);
Q_INVOKABLE void acceptVideoRequest (); Q_INVOKABLE void acceptVideoRequest ();
Q_INVOKABLE void rejectVideoRequest (); Q_INVOKABLE void rejectVideoRequest ();
......
...@@ -212,18 +212,20 @@ void CallsListModel::removeCall (const shared_ptr<linphone::Call> &call) { ...@@ -212,18 +212,20 @@ void CallsListModel::removeCall (const shared_ptr<linphone::Call> &call) {
return; return;
} }
QTimer::singleShot( QTimer::singleShot(DELAY_BEFORE_REMOVE_CALL, this, [this, callModel] {
DELAY_BEFORE_REMOVE_CALL, this, [this, callModel]() { removeCallCb(callModel);
qInfo() << QStringLiteral("Removing call:") << callModel; });
}
int index = mList.indexOf(callModel);
if (index == -1 || !removeRow(index)) void CallsListModel::removeCallCb (CallModel *callModel) {
qWarning() << QStringLiteral("Unable to remove call:") << callModel; qInfo() << QStringLiteral("Removing call:") << callModel;
if (mList.empty() && ConferenceHelperModel::getInstancesNumber() == 0) { int index = mList.indexOf(callModel);
qInfo() << QStringLiteral("Last call terminated, close calls window."); if (index == -1 || !removeRow(index))
App::getInstance()->getCallsWindow()->close(); qWarning() << QStringLiteral("Unable to remove call:") << callModel;
}
} if (mList.empty() && ConferenceHelperModel::getInstancesNumber() == 0) {
); qInfo() << QStringLiteral("Last call terminated, close calls window.");
App::getInstance()->getCallsWindow()->close();
}
} }
...@@ -64,6 +64,7 @@ private: ...@@ -64,6 +64,7 @@ private:
void addCall (const std::shared_ptr<linphone::Call> &call); void addCall (const std::shared_ptr<linphone::Call> &call);
void removeCall (const std::shared_ptr<linphone::Call> &call); void removeCall (const std::shared_ptr<linphone::Call> &call);
void removeCallCb (CallModel *callModel);
QList<CallModel *> mList; QList<CallModel *> mList;
......
...@@ -38,9 +38,9 @@ using namespace std; ...@@ -38,9 +38,9 @@ using namespace std;
// Schedule a function in app context. // Schedule a function in app context.
void scheduleFunctionInApp (function<void()> func) { void scheduleFunctionInApp (function<void()> func) {
App *app = App::getInstance(); App *app = App::getInstance();
if (QThread::currentThread() != app->thread()) { if (QThread::currentThread() != app->thread())
QTimer::singleShot(0, app, func); QTimer::singleShot(0, app, func);
} else else
func(); func();
} }
...@@ -168,3 +168,52 @@ void CoreHandlers::onRegistrationStateChanged ( ...@@ -168,3 +168,52 @@ void CoreHandlers::onRegistrationStateChanged (
) { ) {
emit registrationStateChanged(proxyConfig, state); emit registrationStateChanged(proxyConfig, state);
} }
void CoreHandlers::onTransferStateChanged (
const shared_ptr<linphone::Core> &,
const shared_ptr<linphone::Call> &call,
linphone::CallState state
) {
switch (state) {
case linphone::CallStateEarlyUpdatedByRemote:
case linphone::CallStateEarlyUpdating:
case linphone::CallStateIdle:
case linphone::CallStateIncomingEarlyMedia:
case linphone::CallStateIncomingReceived:
case linphone::CallStateOutgoingEarlyMedia:
case linphone::CallStateOutgoingRinging:
case linphone::CallStatePaused:
case linphone::CallStatePausedByRemote:
case linphone::CallStatePausing:
case linphone::CallStateRefered:
case linphone::CallStateReleased:
case linphone::CallStateResuming:
case linphone::CallStateStreamsRunning:
case linphone::CallStateUpdatedByRemote:
case linphone::CallStateUpdating:
break; // Nothing.
// 1. Init.
case linphone::CallStateOutgoingInit:
qInfo() << QStringLiteral("Call transfer init.");
break;
// 2. In progress.
case linphone::CallStateOutgoingProgress:
qInfo() << QStringLiteral("Call transfer in progress.");
break;
// 3. Done.
case linphone::CallStateConnected:
qInfo() << QStringLiteral("Call transfer succeeded.");
emit callTransferSucceeded(call);
break;
// 4. Error.
case linphone::CallStateEnd:
case linphone::CallStateError:
qWarning() << QStringLiteral("Call transfer failed.");
emit callTransferFailed(call);
break;
}
}
...@@ -43,6 +43,8 @@ public: ...@@ -43,6 +43,8 @@ public:
signals: signals:
void authenticationRequested (const std::shared_ptr<linphone::AuthInfo> &authInfo); void authenticationRequested (const std::shared_ptr<linphone::AuthInfo> &authInfo);
void callStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::CallState state); void callStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::CallState state);
void callTransferFailed (const std::shared_ptr<linphone::Call> &call);
void callTransferSucceeded (const std::shared_ptr<linphone::Call> &call);
void coreStarted (); void coreStarted ();
void messageReceived (const std::shared_ptr<linphone::ChatMessage> &message); void messageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
void presenceReceived (const QString &sipAddress, const std::shared_ptr<const linphone::PresenceModel> &presenceModel); void presenceReceived (const QString &sipAddress, const std::shared_ptr<const linphone::PresenceModel> &presenceModel);
...@@ -107,6 +109,12 @@ private: ...@@ -107,6 +109,12 @@ private:
const std::string &message const std::string &message
) override; ) override;
void onTransferStateChanged (
const std::shared_ptr<linphone::Core> &core,
const std::shared_ptr<linphone::Call> &call,
linphone::CallState state
) override;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
bool mCoreCreated = false; bool mCoreCreated = false;
......
...@@ -22,7 +22,7 @@ function handleClosing (close) { ...@@ -22,7 +22,7 @@ function handleClosing (close) {
} }
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
descriptionText: qsTr('acceptClosingDescription'), descriptionText: qsTr('acceptClosingDescription')
}, function (status) { }, function (status) {
if (status) { if (status) {
forceClose = true forceClose = true
...@@ -71,5 +71,12 @@ function getContent () { ...@@ -71,5 +71,12 @@ function getContent () {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function handleCallTransferAsked (call) { function handleCallTransferAsked (call) {
console.log('TODO: handle call transfer') if (!call) {
return
}
window.detachVirtualWindow()
window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/CallTransfer.qml'), {
call: call
})
} }
import QtQuick 2.7
import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
import App.Styles 1.0
// =============================================================================
DialogPlus {
id: callTransfer
// ---------------------------------------------------------------------------
property var call
// ---------------------------------------------------------------------------
buttons: [
TextButtonA {
text: qsTr('cancel')
onClicked: exit(0)
}
]
centeredButtons: true
descriptionText: qsTr('callTransferDescription')
height: CallTransferStyle.height
width: CallTransferStyle.width
onCallChanged: !call && exit(0)
// ---------------------------------------------------------------------------
ColumnLayout {
anchors {
fill: parent
leftMargin: CallTransferStyle.leftMargin
rightMargin: CallTransferStyle.rightMargin
}
spacing: 0
Contact {
Layout.fillWidth: true
entry: SipAddressesModel.getSipAddressObserver(call ? call.sipAddress : '')
}
// -------------------------------------------------------------------------
// Address selector.
// -------------------------------------------------------------------------
Item {
Layout.fillHeight: true
Layout.fillWidth: true
ColumnLayout {
anchors.fill: parent
spacing: CallTransferStyle.spacing
TextField {
id: filter
Layout.fillWidth: true
icon: 'search'
onTextChanged: sipAddressesModel.setFilter(text)
}
ScrollableListViewField {
Layout.fillHeight: true
Layout.fillWidth: true
SipAddressesView {
anchors.fill: parent
actions: [{
icon: 'transfer',
handler: function (entry) {
callTransfer.call.transferTo(entry.sipAddress)
exit(1)
}
}]
genSipAddress: filter.text
model: SipAddressesProxyModel {
id: sipAddressesModel
}
onEntryClicked: actions[0].handler(entry)
}
}
}
}
}
}
pragma Singleton
import QtQuick 2.7
// =============================================================================
QtObject {
property int height: 420
property int leftMargin: 35
property int rightMargin: 35
property int spacing: 10
property int width: 450
}
...@@ -9,6 +9,8 @@ singleton CallsWindowStyle 1.0 Calls/CallsWindowStyle.qm ...@@ -9,6 +9,8 @@ singleton CallsWindowStyle 1.0 Calls/CallsWindowStyle.qm
singleton ConferenceManagerStyle 1.0 Calls/ConferenceManagerStyle.qml singleton ConferenceManagerStyle 1.0 Calls/ConferenceManagerStyle.qml
singleton ConferenceStyle 1.0 Calls/ConferenceStyle.qml singleton ConferenceStyle 1.0 Calls/ConferenceStyle.qml
singleton CallTransferStyle 1.0 Calls/Dialogs/CallTransferStyle.qml
singleton ActivateLinphoneSipAccountWithEmailStyle 1.0 Main/Assistant/ActivateLinphoneSipAccountWithEmailStyle.qml singleton ActivateLinphoneSipAccountWithEmailStyle 1.0 Main/Assistant/ActivateLinphoneSipAccountWithEmailStyle.qml
singleton AssistantAbstractViewStyle 1.0 Main/Assistant/AssistantAbstractViewStyle.qml singleton AssistantAbstractViewStyle 1.0 Main/Assistant/AssistantAbstractViewStyle.qml
singleton AssistantHomeStyle 1.0 Main/Assistant/AssistantHomeStyle.qml singleton AssistantHomeStyle 1.0 Main/Assistant/AssistantHomeStyle.qml
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment