diff --git a/Linphone/core/call/CallCore.cpp b/Linphone/core/call/CallCore.cpp index 3305f1e13..cce85f5fa 100644 --- a/Linphone/core/call/CallCore.cpp +++ b/Linphone/core/call/CallCore.cpp @@ -280,20 +280,17 @@ void CallCore::setSelf(QSharedPointer me) { mCallModelConnection->invokeToCore([this, paused]() { setPaused(paused); }); }); - mCallModelConnection->makeConnectToCore(&CallCore::lTransferCall, [this](const QString &address) { - mCallModelConnection->invokeToModel( - [this, address]() { mCallModel->transferTo(ToolModel::interpretUrl(address)); }); + mCallModelConnection->makeConnectToCore(&CallCore::lTransferCall, [this](QString address) { + mCallModelConnection->invokeToModel([this, address]() { + auto linAddr = ToolModel::interpretUrl(address); + if (linAddr) mCallModel->transferTo(linAddr); + }); }); mCallModelConnection->makeConnectToModel( &CallModel::transferStateChanged, [this](const std::shared_ptr &call, linphone::Call::State state) { - mCallModelConnection->invokeToCore([this, state]() { - QString message; - if (state == linphone::Call::State::Error) { - message = "L'appel n'a pas pu être transféré."; - } - setTransferState(LinphoneEnums::fromLinphone(state), message); - }); + mCallModelConnection->invokeToCore( + [this, state]() { setTransferState(LinphoneEnums::fromLinphone(state)); }); }); mCallModelConnection->makeConnectToModel( &CallModel::encryptionChanged, @@ -715,10 +712,9 @@ LinphoneEnums::CallState CallCore::getTransferState() const { return mTransferState; } -void CallCore::setTransferState(LinphoneEnums::CallState state, const QString &message) { +void CallCore::setTransferState(LinphoneEnums::CallState state) { if (mTransferState != state) { mTransferState = state; - if (state == LinphoneEnums::CallState::Error) setLastErrorMessage(message); emit transferStateChanged(); } } diff --git a/Linphone/core/call/CallCore.hpp b/Linphone/core/call/CallCore.hpp index cce46c929..a9caa77ef 100644 --- a/Linphone/core/call/CallCore.hpp +++ b/Linphone/core/call/CallCore.hpp @@ -217,7 +217,7 @@ public: void setInputDeviceName(const QString &id); LinphoneEnums::CallState getTransferState() const; - void setTransferState(LinphoneEnums::CallState state, const QString &message); + void setTransferState(LinphoneEnums::CallState state); LinphoneEnums::ConferenceLayout getConferenceVideoLayout() const; void setConferenceVideoLayout(LinphoneEnums::ConferenceLayout layout); @@ -276,7 +276,7 @@ signals: void lSetLocalVideoEnabled(bool enabled); void lSetVideoEnabled(bool enabled); void lSetPaused(bool paused); - void lTransferCall(QString &est); + void lTransferCall(QString address); void lStartRecording(); void lStopRecording(); void lCheckAuthenticationTokenSelected(const QString &token); diff --git a/Linphone/view/App/AppWindow.qml b/Linphone/view/App/AppWindow.qml index f29dc185f..199c65f57 100644 --- a/Linphone/view/App/AppWindow.qml +++ b/Linphone/view/App/AppWindow.qml @@ -34,6 +34,8 @@ ApplicationWindow { id: startCallPopup property FriendGui contact property bool videoEnabled + // if currentCall, transfer call to contact + property CallGui currentCall onContactChanged: { console.log("contact changed", contact) } @@ -119,7 +121,10 @@ ApplicationWindow { anchors.fill: parent hoverEnabled: true cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor - onClicked: UtilsCpp.createCall(modelData.address, {'localVideoEnabled': startCallPopup.videoEnabled}) + onClicked: { + if (startCallPopup.currentCall) startCallPopup.currentCall.core.lTransferCall(modelData.address) + else UtilsCpp.createCall(modelData.address, {'localVideoEnabled': startCallPopup.videoEnabled}) + } } } } @@ -127,7 +132,7 @@ ApplicationWindow { } function startCallWithContact(contact, videoEnabled, parentItem) { - if (parentItem == undefined) parentItem = mainWindow + if (parentItem == undefined) parentItem = mainWindow.contentItem startCallPopup.parent = parentItem if (contact) { console.log("START CALL WITH", contact.core.displayName, "addresses count", contact.core.allAddresses.length) @@ -147,6 +152,28 @@ ApplicationWindow { } } + function transferCallToContact(call, contact, parentItem) { + if (!call || !contact) return + if (parentItem == undefined) parentItem = mainWindow.contentItem + startCallPopup.parent = parentItem + if (contact) { + console.log("TRANSFER CALL TO", contact.core.displayName, "addresses count", contact.core.allAddresses.length, call) + if (contact.core.allAddresses.length > 1) { + startCallPopup.contact = contact + startCallPopup.currentCall = call + startCallPopup.open() + + } else { + var addressToCall = contact.core.defaultAddress.length === 0 + ? contact.core.phoneNumbers.length === 0 + ? "" + : contact.core.phoneNumbers[0].address + : contact.core.defaultAddress + if (addressToCall.length != 0) call.core.lTransferCall(contact.core.defaultAddress) + } + } + } + function removeFromPopupLayout(index) { popupLayout.popupList.splice(index, 1) } diff --git a/Linphone/view/App/CallsWindow.qml b/Linphone/view/App/CallsWindow.qml index 7c7e95aae..ebfde3706 100644 --- a/Linphone/view/App/CallsWindow.qml +++ b/Linphone/view/App/CallsWindow.qml @@ -42,8 +42,7 @@ AppWindow { onTransferStateChanged: { console.log("Transfer state:", transferState) if (transferState === LinphoneEnums.CallState.Error) { - transferErrorPopup.visible = true - + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Le transfert d'appel a échoué"), false, mainWindow) } else if (transferState === LinphoneEnums.CallState.Connected){ var mainWin = UtilsCpp.getMainWindow() @@ -202,46 +201,26 @@ AppWindow { padding: 20 * DefaultStyle.dp underlineColor: DefaultStyle.main1_500_main radius: 15 * DefaultStyle.dp + width: 278 * DefaultStyle.dp + height: 115 * DefaultStyle.dp contentItem: ColumnLayout { spacing: 0 BusyIndicator{ + Layout.preferredWidth: 33 * DefaultStyle.dp + Layout.preferredHeight: 33 * DefaultStyle.dp Layout.alignment: Qt.AlignHCenter } Text { Layout.alignment: Qt.AlignHCenter text: qsTr("Transfert en cours, veuillez patienter") + font { + pixelSize: 14 * DefaultStyle.dp + weight: 400 * DefaultStyle.dp + } } } } - Timer { - id: autoClosePopup - interval: 2000 - onTriggered: { - transferErrorPopup.close() - } - } - Popup { - id: transferErrorPopup - onVisibleChanged: if (visible) autoClosePopup.restart() - closePolicy: Control.Popup.NoAutoClose - x : parent.x + parent.width - width - y : parent.y + parent.height - height - rightMargin: 20 * DefaultStyle.dp - bottomMargin: 20 * DefaultStyle.dp - padding: 20 * DefaultStyle.dp - underlineColor: DefaultStyle.danger_500main - radius: 0 - contentItem: ColumnLayout { - spacing: 0 - Text { - text: qsTr("Erreur de transfert") - } - Text { - Layout.alignment: Qt.AlignHCenter - text: qsTr("Le transfert d'appel a échoué.") - } - } - } + /************************* CONTENT ********************************/ Rectangle { anchors.fill: parent @@ -349,21 +328,25 @@ AppWindow { EffectImage { Layout.preferredWidth: 15 * DefaultStyle.dp Layout.preferredHeight: 15 * DefaultStyle.dp - colorizationColor: mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp - ? DefaultStyle.info_500_main - : mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp - ? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified - ? DefaultStyle.warning_600 - : DefaultStyle.info_500_main - : DefaultStyle.grey_0 + colorizationColor: mainWindow.call + ? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp + ? DefaultStyle.info_500_main + : mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp + ? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified + ? DefaultStyle.warning_600 + : DefaultStyle.info_500_main + : DefaultStyle.grey_0 + : "transparent" visible: mainWindow.call && mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning - imageSource: mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp + imageSource: mainWindow.call + ? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp ? AppIcons.lockSimple : mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp ? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified ? AppIcons.warningCircle : AppIcons.lockKey : AppIcons.lockSimpleOpen + : "" } Text { text: mainWindow.call && mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning @@ -502,6 +485,7 @@ AppWindow { Item { Control.StackView.onActivated: rightPanel.headerTitleText = qsTr("Transfert d'appel") CallContactsLists { + id: callcontactslist anchors.fill: parent anchors.topMargin: 21 * DefaultStyle.dp anchors.leftMargin: 16 * DefaultStyle.dp @@ -509,8 +493,8 @@ AppWindow { groupCallVisible: false searchBarColor: DefaultStyle.grey_0 searchBarBorderColor: DefaultStyle.grey_200 - onCallButtonPressed: (address) => { - mainWindow.call.core.lTransferCall(address) + onSelectedContactChanged: { + if (selectedContact) mainWindow.transferCallToContact(mainWindow.call, selectedContact, callcontactslist) } } } diff --git a/Linphone/view/App/Layout/MainLayout.qml b/Linphone/view/App/Layout/MainLayout.qml index a0cba37f0..e1811a169 100644 --- a/Linphone/view/App/Layout/MainLayout.qml +++ b/Linphone/view/App/Layout/MainLayout.qml @@ -19,19 +19,17 @@ Item { property bool helpHidden: true signal addAccountRequest() + signal openNewCall() + signal createContactRequested(string name, string address) function goToNewCall() { tabbar.currentIndex = 0 - callPage.goToNewCall() - } - - function transferCallSucceed() { - transferSucceedPopup.open() + mainItem.openNewCall() } function createContact(name, address) { tabbar.currentIndex = 1 - contactPage.createContact(name, address) + mainItem.createContactRequested(name, address) } AccountProxy { @@ -46,54 +44,6 @@ Item { transferSucceedPopup.close() } } - Popup { - id: transferSucceedPopup - onVisibleChanged: if (visible) autoClosePopup.restart() - closePolicy: Control.Popup.NoAutoClose - x : parent.x + parent.width - width - y : parent.y + parent.height - height - rightMargin: 20 * DefaultStyle.dp - bottomMargin: 20 * DefaultStyle.dp - padding: 20 * DefaultStyle.dp - underlineColor: DefaultStyle.success_500main - radius: 0 - contentItem: RowLayout { - spacing: 15 * DefaultStyle.dp - EffectImage { - imageSource: AppIcons.smiley - colorizationColor: DefaultStyle.success_500main - Layout.preferredWidth: 32 * DefaultStyle.dp - Layout.preferredHeight: 32 * DefaultStyle.dp - width: 32 * DefaultStyle.dp - height: 32 * DefaultStyle.dp - } - Rectangle { - Layout.preferredWidth: 1 * DefaultStyle.dp - Layout.preferredHeight: parent.height - color: DefaultStyle.main2_200 - } - ColumnLayout { - Text { - text: qsTr("Appel transféré") - color: DefaultStyle.success_500main - font { - pixelSize: 16 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp - } - } - Text { - Layout.alignment: Qt.AlignHCenter - Layout.fillWidth: true - text: qsTr("Votre correspondant a été transféré au contact sélectionné") - color: DefaultStyle.main2_500main - font { - pixelSize: 12 * DefaultStyle.dp - weight: 300 * DefaultStyle.dp - } - } - } - } - } Item{ anchors.fill: parent ColumnLayout{ @@ -417,12 +367,24 @@ Item { currentIndex: tabbar.currentIndex CallPage { id: callPage + Connections { + target: mainItem + onOpenNewCall: callPage.goToNewCall() + } onCreateContactRequested: (name, address) => { mainItem.createContact(name, address) } } ContactPage{ id: contactPage + Connections { + target: mainItem + onCreateContactRequested: (name, address) => { + contactPage.createContact(name, address) + } + } + + } Item{} //ConversationPage{} diff --git a/Linphone/view/App/Main.qml b/Linphone/view/App/Main.qml index b3f6f3f86..7bfb46141 100644 --- a/Linphone/view/App/Main.qml +++ b/Linphone/view/App/Main.qml @@ -30,7 +30,7 @@ AppWindow { } function transferCallSucceed() { mainWindowStackView.replace(mainPage, StackView.Immediate) - mainWindowStackView.currentItem.transferCallSucceed() + UtilsCpp.showInformationPopup(qsTr("Appel transféré"), qsTr("Votre correspondant a été transféré au contact sélectionné")) } function initStackViewItem() { if (accountProxy.haveAccount) mainWindowStackView.replace(mainPage, StackView.Immediate) diff --git a/Linphone/view/Item/Call/CallContactsLists.qml b/Linphone/view/Item/Call/CallContactsLists.qml index c300184cd..708077c08 100644 --- a/Linphone/view/Item/Call/CallContactsLists.qml +++ b/Linphone/view/Item/Call/CallContactsLists.qml @@ -12,8 +12,10 @@ Item { property bool groupCallVisible property color searchBarColor: DefaultStyle.grey_100 property color searchBarBorderColor: "transparent" + property alias searchBar: searchBar signal callButtonPressed(string address) signal groupCallCreationRequested() + property FriendGui selectedContact property NumericPad numPad clip: true @@ -117,7 +119,7 @@ Item { model: MagicSearchProxy { searchText: searchBar.text.length === 0 ? "*" : searchBar.text } - onSelectedContactChanged: mainWindow.startCallWithContact(selectedContact, false, mainItem.parent) + onSelectedContactChanged: mainItem.selectedContact = selectedContact } } ColumnLayout { @@ -142,7 +144,7 @@ Item { sourceFlags: LinphoneEnums.MagicSearchSource.All aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend } - onSelectedContactChanged: mainWindow.startCallWithContact(selectedContact, false, mainItem.parent) + onSelectedContactChanged: mainItem.selectedContact = selectedContact } } Item { diff --git a/Linphone/view/Item/Contact/ContactEdition.qml b/Linphone/view/Item/Contact/ContactEdition.qml index 0ab4f9e29..353608090 100644 --- a/Linphone/view/Item/Contact/ContactEdition.qml +++ b/Linphone/view/Item/Contact/ContactEdition.qml @@ -272,7 +272,7 @@ RightPanelLayout { } ErrorText { id: addressesErrorText - wrapMode: Qt.WordWrap + wrapMode: Text.WordWrap elide: Text.ElideRight Layout.fillWidth: true } diff --git a/Linphone/view/Page/Main/CallPage.qml b/Linphone/view/Page/Main/CallPage.qml index 21e9283b0..5ccdb0031 100644 --- a/Linphone/view/Page/Main/CallPage.qml +++ b/Linphone/view/Page/Main/CallPage.qml @@ -23,6 +23,7 @@ AbstractMainPage { property bool isRegistered: account ? account.core.registrationState == LinphoneEnums.RegistrationState.Ok : false property int selectedParticipantsCount signal startGroupCallRequested() + signal createCallFromSearchBarRequested() signal createContactRequested(string name, string address) Connections { @@ -94,7 +95,7 @@ AbstractMainPage { width: parent.width height: parent.height onLaunchCall: { - UtilsCpp.createCall(searchBar.text) + mainItem.createCallFromSearchBarRequested() // TODO : auto completion instead of sip linphone } } @@ -408,15 +409,21 @@ AbstractMainPage { ColumnLayout { Control.StackView.onActivated: titleLoader.sourceComponent = newCallTitle CallContactsLists { + id: callContactsList Layout.fillWidth: true Layout.fillHeight: true numPad: numericPad groupCallVisible: true searchBarColor: DefaultStyle.grey_100 + onSelectedContactChanged: mainWindow.startCallWithContact(selectedContact, false, callContactsList) onGroupCallCreationRequested: { console.log("groupe call requetsed") listStackView.push(groupCallItem) } + Connections { + target: mainItem + onCreateCallFromSearchBarRequested: UtilsCpp.createCall(callContactsList.searchBar.text) + } } } }