diff --git a/Linphone/core/call/CallCore.cpp b/Linphone/core/call/CallCore.cpp index 9837af33c..5a68eb3ed 100644 --- a/Linphone/core/call/CallCore.cpp +++ b/Linphone/core/call/CallCore.cpp @@ -199,17 +199,18 @@ void CallCore::setSelf(QSharedPointer me) { mCallModelConnection->makeConnectToCore(&CallCore::lStopRecording, [this]() { mCallModelConnection->invokeToModel([this]() { mCallModel->stopRecording(); }); }); - mCallModelConnection->makeConnectToModel(&CallModel::recordingChanged, [this](bool recording) { - mCallModelConnection->invokeToCore([this, recording]() { - setRecording(recording); - if (recording == false) { - Utils::showInformationPopup(tr("Enregistrement terminé"), - tr("L'appel a été enregistré dans le fichier : %1") - .arg(QString::fromStdString(mCallModel->getRecordFile())), - true, App::getInstance()->getCallsWindow()); - } - }); - }); + mCallModelConnection->makeConnectToModel( + &CallModel::recordingChanged, [this](const std::shared_ptr &call, bool recording) { + mCallModelConnection->invokeToCore([this, recording]() { + setRecording(recording); + if (recording == false) { + Utils::showInformationPopup(tr("Enregistrement terminé"), + tr("L'appel a été enregistré dans le fichier : %1") + .arg(QString::fromStdString(mCallModel->getRecordFile())), + true, App::getInstance()->getCallsWindow()); + } + }); + }); mCallModelConnection->makeConnectToCore(&CallCore::lCheckAuthenticationTokenSelected, [this](const QString &token) { mCallModelConnection->invokeToModel([this, token]() { mCallModel->checkAuthenticationToken(token); }); }); @@ -224,10 +225,17 @@ void CallCore::setSelf(QSharedPointer me) { emit tokenVerified(); }); }); - mCallModelConnection->makeConnectToModel( - &CallModel::remoteRecording, [this](const std::shared_ptr &call, bool recording) { - mCallModelConnection->invokeToCore([this, recording]() { setRemoteRecording(recording); }); - }); + mCallModelConnection->makeConnectToModel(&CallModel::remoteRecording, + [this](const std::shared_ptr &call, bool recording) { + bool confRecording = false; + if (call->getConference()) { + confRecording = call->getConference()->isRecording(); + } + mCallModelConnection->invokeToCore([this, recording, confRecording]() { + if (mConference) mConference->setRecording(confRecording); + setRemoteRecording(recording); + }); + }); mCallModelConnection->makeConnectToModel(&CallModel::localVideoEnabledChanged, [this](bool enabled) { mCallModelConnection->invokeToCore([this, enabled]() { setLocalVideoEnabled(enabled); }); }); diff --git a/Linphone/core/conference/ConferenceCore.cpp b/Linphone/core/conference/ConferenceCore.cpp index 3ef608ccf..a2903fa0a 100644 --- a/Linphone/core/conference/ConferenceCore.cpp +++ b/Linphone/core/conference/ConferenceCore.cpp @@ -41,6 +41,7 @@ ConferenceCore::ConferenceCore(const std::shared_ptr &conf mParticipantDeviceCount = conference->getParticipantDeviceList().size(); mIsLocalScreenSharing = mConferenceModel->isLocalScreenSharing(); mIsScreenSharingEnabled = mConferenceModel->isScreenSharingEnabled(); + mIsRecording = conference->isRecording(); auto me = conference->getMe(); if (me) { mMe = ParticipantCore::create(me); @@ -105,6 +106,17 @@ Q_INVOKABLE qint64 ConferenceCore::getElapsedSeconds() const { return 0; } +bool ConferenceCore::isRecording() const { + return mIsRecording; +} + +void ConferenceCore::setRecording(bool recording) { + if (mIsRecording != recording) { + mIsRecording = recording; + emit isRecordingChanged(); + } +} + void ConferenceCore::setParticipantDeviceCount(int count) { if (mParticipantDeviceCount != count) { mParticipantDeviceCount = count; diff --git a/Linphone/core/conference/ConferenceCore.hpp b/Linphone/core/conference/ConferenceCore.hpp index bb53d43af..5eb39c896 100644 --- a/Linphone/core/conference/ConferenceCore.hpp +++ b/Linphone/core/conference/ConferenceCore.hpp @@ -40,6 +40,7 @@ public: // Q_PROPERTY(ParticipantDeviceList *participantDevices READ getParticipantDeviceList CONSTANT) // Q_PROPERTY(ParticipantModel* localParticipant READ getLocalParticipant NOTIFY localParticipantChanged) Q_PROPERTY(bool isReady MEMBER mIsReady WRITE setIsReady NOTIFY isReadyChanged) + Q_PROPERTY(bool isRecording READ isRecording WRITE setRecording NOTIFY isRecordingChanged) Q_PROPERTY(QString subject READ getSubject WRITE setSubject NOTIFY subjectChanged) Q_PROPERTY(bool isLocalScreenSharing MEMBER mIsLocalScreenSharing WRITE setIsLocalScreenSharing NOTIFY @@ -65,6 +66,9 @@ public: int getParticipantDeviceCount() const; void setParticipantDeviceCount(int count); + bool isRecording() const; + void setRecording(bool recording); + ParticipantDeviceCore *getActiveSpeaker() const; ParticipantDeviceGui *getActiveSpeakerGui() const; ParticipantGui *getMeGui() const; @@ -86,6 +90,7 @@ signals: void participantDeviceCountChanged(); void activeSpeakerChanged(); void subjectChanged(); + void isRecordingChanged(); void lToggleScreenSharing(); @@ -97,6 +102,7 @@ private: int mParticipantDeviceCount = 0; bool mIsReady = false; + bool mIsRecording = false; bool mIsLocalScreenSharing = false; bool mIsScreenSharingEnabled = false; QString mSubject; diff --git a/Linphone/core/conference/ConferenceInfoCore.cpp b/Linphone/core/conference/ConferenceInfoCore.cpp index 4e08eeb33..2c8064a87 100644 --- a/Linphone/core/conference/ConferenceInfoCore.cpp +++ b/Linphone/core/conference/ConferenceInfoCore.cpp @@ -542,6 +542,7 @@ void ConferenceInfoCore::writeIntoModel(std::shared_ptr mod model->setDateTime(mIsScheduled ? mDateTime : QDateTime()); model->setDuration(mDuration); model->setSubject(mSubject); + model->enableInvite(mInviteEnabled); if (!mOrganizerAddress.isEmpty()) { model->setOrganizer(mOrganizerAddress); lDebug() << "Use of " << mOrganizerAddress; diff --git a/Linphone/model/call/CallModel.cpp b/Linphone/model/call/CallModel.cpp index 1ad568318..9d9ff739b 100644 --- a/Linphone/model/call/CallModel.cpp +++ b/Linphone/model/call/CallModel.cpp @@ -180,13 +180,13 @@ void CallModel::setLocalVideoEnabled(bool enabled) { void CallModel::startRecording() { mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); mMonitor->startRecording(); - emit recordingChanged(mMonitor->getParams()->isRecording()); + emit recordingChanged(mMonitor, mMonitor->getParams()->isRecording()); } void CallModel::stopRecording() { mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); mMonitor->stopRecording(); - emit recordingChanged(mMonitor->getParams()->isRecording()); + emit recordingChanged(mMonitor, mMonitor->getParams()->isRecording()); } void CallModel::setRecordFile(const std::string &path) { @@ -484,4 +484,4 @@ void CallModel::onRemoteRecording(const std::shared_ptr &call, b void CallModel::onAuthenticationTokenVerified(const std::shared_ptr &call, bool verified) { emit authenticationTokenVerified(call, verified); -} +} \ No newline at end of file diff --git a/Linphone/model/call/CallModel.hpp b/Linphone/model/call/CallModel.hpp index d245a89de..2e87d60c7 100644 --- a/Linphone/model/call/CallModel.hpp +++ b/Linphone/model/call/CallModel.hpp @@ -97,7 +97,7 @@ signals: void pausedChanged(bool paused); void remoteVideoEnabledChanged(bool remoteVideoEnabled); void localVideoEnabledChanged(bool enabled); - void recordingChanged(bool recording); + void recordingChanged(const std::shared_ptr &call, bool recording); void speakerVolumeGainChanged(float volume); void microphoneVolumeGainChanged(float volume); void inputAudioDeviceChanged(const std::string &id); diff --git a/Linphone/model/conference/ConferenceModel.cpp b/Linphone/model/conference/ConferenceModel.cpp index a0fa42883..7bd1b554a 100644 --- a/Linphone/model/conference/ConferenceModel.cpp +++ b/Linphone/model/conference/ConferenceModel.cpp @@ -143,6 +143,7 @@ void ConferenceModel::toggleScreenSharing() { if (enable) { params->setConferenceVideoLayout(linphone::Conference::Layout::ActiveSpeaker); params->enableVideo(true); + params->enableCamera(false); auto videoDirection = params->getVideoDirection(); if (videoDirection != linphone::MediaDirection::SendOnly && videoDirection != linphone::MediaDirection::SendRecv) diff --git a/Linphone/model/tool/ToolModel.cpp b/Linphone/model/tool/ToolModel.cpp index 53c8e61e3..cbbd5624d 100644 --- a/Linphone/model/tool/ToolModel.cpp +++ b/Linphone/model/tool/ToolModel.cpp @@ -139,6 +139,9 @@ bool ToolModel::createCall(const QString &sipAddress, std::shared_ptr params = core->createCallParams(nullptr); CallModel::activateLocalVideo(params, nullptr, localVideoEnabled); + bool micEnabled = options.contains("microEnabled") ? options["microEnabled"].toBool() : true; + params->enableMic(micEnabled); + params->setMediaEncryption(mediaEncryption); if (Utils::coreStringToAppString(params->getRecordFile()).isEmpty()) { diff --git a/Linphone/view/App/AppWindow.qml b/Linphone/view/App/AppWindow.qml index 6b83b25ef..0fc564ee4 100644 --- a/Linphone/view/App/AppWindow.qml +++ b/Linphone/view/App/AppWindow.qml @@ -7,6 +7,8 @@ import SettingsCpp 1.0 ApplicationWindow { id: mainWindow + width: Math.min(1512 * DefaultStyle.dp, Screen.desktopAvailableWidth) + height: Math.min(982 * DefaultStyle.dp, Screen.desktopAvailableHeight) MouseArea { anchors.fill: parent diff --git a/Linphone/view/App/CallsWindow.qml b/Linphone/view/App/CallsWindow.qml index 76160bc45..d4559b136 100644 --- a/Linphone/view/App/CallsWindow.qml +++ b/Linphone/view/App/CallsWindow.qml @@ -9,9 +9,7 @@ import SettingsCpp 1.0 import DesktopToolsCpp 1.0 AppWindow { - id: mainWindow - width: 1512 * DefaultStyle.dp - height: 982 * DefaultStyle.dp + id: mainWindow flags: Qt.Window // modality: Qt.WindowModal @@ -204,8 +202,9 @@ AppWindow { height: 115 * DefaultStyle.dp Connections { target: mainWindow - function ontransferStateChanged() { - if (mainWindow.transferState === LinphoneEnums.CallState.Error + function onTransferStateChanged() { + if (mainWindow.transferState === LinphoneEnums.CallState.OutgoingInit) waitingPopup.open() + else if (mainWindow.transferState === LinphoneEnums.CallState.Error || mainWindow.transferState === LinphoneEnums.CallState.End || mainWindow.transferState === LinphoneEnums.CallState.Released || mainWindow.transferState === LinphoneEnums.CallState.Connected) @@ -281,7 +280,7 @@ AppWindow { id: callStatusText text: (mainWindow.callState === LinphoneEnums.CallState.End || mainWindow.callState === LinphoneEnums.CallState.Released) ? qsTr("End of the call") - : mainWindow.call.core.paused + : mainWindow.call && mainWindow.call.core.paused || (mainWindow.callState === LinphoneEnums.CallState.Paused || mainWindow.callState === LinphoneEnums.CallState.PausedByRemote) ? (mainWindow.conference ? qsTr('Réunion mise ') : qsTr('Appel mis')) + qsTr(" en pause") @@ -416,7 +415,7 @@ AppWindow { hoverEnabled: true cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor onClicked: { - if (rightPanel.visible) rightPanel.visible = false + if (rightPanel.visible && rightPanel.contentStackView.currentItem.objectName === "statsPanel") rightPanel.visible = false else { rightPanel.visible = true rightPanel.replace(statsPanel) @@ -427,7 +426,11 @@ AppWindow { } Control.Control { - visible: mainWindow.call && (mainWindow.call.core.recording || mainWindow.call.core.remoteRecording) + visible: mainWindow.call + ? !!mainWindow.conference + ? mainWindow.conference.core.isRecording + : (mainWindow.call.core.recording || mainWindow.call.core.remoteRecording) + : false anchors.centerIn: parent leftPadding: 14 * DefaultStyle.dp rightPadding: 14 * DefaultStyle.dp @@ -508,7 +511,6 @@ AppWindow { searchBarBorderColor: DefaultStyle.grey_200 onSelectedContactChanged: { if (selectedContact) mainWindow.transferCallToContact(mainWindow.call, selectedContact, callcontactslist) - waitingPopup.open() } } } @@ -1013,6 +1015,7 @@ AppWindow { Component { id: statsPanel ColumnLayout { + property string objectName: "statsPanel" spacing: 20 * DefaultStyle.dp Control.StackView.onActivated: { rightPanel.headerTitleText = qsTr("Statistiques") @@ -1071,6 +1074,8 @@ AppWindow { Layout.topMargin: 13 * DefaultStyle.dp Layout.leftMargin: 16 * DefaultStyle.dp Layout.rightMargin: 16 * DefaultStyle.dp + + visible: mainWindow.call && (mainWindow.call.core.localVideoEnabled || mainWindow.call.core.remoteVideoEnabled) contentItem: ColumnLayout { spacing: 12 * DefaultStyle.dp @@ -1341,6 +1346,7 @@ AppWindow { } CheckableButton { iconUrl: AppIcons.screencast + visible: !!mainWindow.conference checkedColor: DefaultStyle.main2_400 Layout.preferredWidth: 55 * DefaultStyle.dp Layout.preferredHeight: 55 * DefaultStyle.dp @@ -1480,6 +1486,7 @@ AppWindow { } MenuButton { checkable: true + visible: mainWindow.call && !mainWindow.conference enabled: mainWindow.call && mainWindow.call.core.recordable icon.source: AppIcons.recordFill icon.width: 32 * DefaultStyle.dp diff --git a/Linphone/view/App/Layout/MainLayout.qml b/Linphone/view/App/Layout/MainLayout.qml index dc6f31288..a1215eabc 100644 --- a/Linphone/view/App/Layout/MainLayout.qml +++ b/Linphone/view/App/Layout/MainLayout.qml @@ -273,14 +273,13 @@ Item { background.visible: false Layout.preferredWidth: 54 * DefaultStyle.dp Layout.preferredHeight: width + popup.padding: 14 * DefaultStyle.dp contentItem: Avatar { id: avatar height: avatarButton.height width: avatarButton.width account: accountProxy.defaultAccount } - popup.x: width - popup.width - popup.padding: 0 popup.contentItem: ColumnLayout { Accounts { id: accounts @@ -293,8 +292,8 @@ Item { id: settingsButton Layout.preferredWidth: 24 * DefaultStyle.dp Layout.preferredHeight: 24 * DefaultStyle.dp - popup.x: width - popup.width popup.width: 271 * DefaultStyle.dp + popup.padding: 14 * DefaultStyle.dp popup.contentItem: ColumnLayout { spacing: 20 * DefaultStyle.dp IconLabelButton { diff --git a/Linphone/view/App/Main.qml b/Linphone/view/App/Main.qml index f2105c30d..54936656e 100644 --- a/Linphone/view/App/Main.qml +++ b/Linphone/view/App/Main.qml @@ -1,5 +1,6 @@ import QtQuick 2.15 import QtQuick.Layouts 1.3 +import QtQuick.Window import QtQuick.Controls import Linphone import UtilsCpp 1.0 @@ -7,8 +8,7 @@ import SettingsCpp 1.0 AppWindow { id: mainWindow - width: 1512 * DefaultStyle.dp - height: 982 * DefaultStyle.dp + // height: 982 * DefaultStyle.dp visible: true title: qsTr("Linphone") // TODO : handle this bool when security mode is implemented diff --git a/Linphone/view/Item/Call/Menu/ScreencastPanel.qml b/Linphone/view/Item/Call/Menu/ScreencastPanel.qml index 729b72d79..edb23a08c 100644 --- a/Linphone/view/Item/Call/Menu/ScreencastPanel.qml +++ b/Linphone/view/Item/Call/Menu/ScreencastPanel.qml @@ -110,10 +110,11 @@ ColumnLayout { height: 219 * DefaultStyle.dp screenIndex: index onClicked: {//screensLayout.selectedIndex = index - mainItem.desc.core.screenSharingIndex = index - if( mainItem.conference.core.isLocalScreenSharing) - mainItem.call.core.videoSourceDescriptor = mainItem.desc - } + screensLayout.currentIndex = index + mainItem.desc.core.screenSharingIndex = index + if( mainItem.conference.core.isLocalScreenSharing) + mainItem.call.core.videoSourceDescriptor = mainItem.desc + } selected: //screensLayout.selectedIndex === index mainItem.desc.core.screenSharingIndex === index } @@ -126,6 +127,7 @@ ColumnLayout { id: windowsList mode: ScreenList.WINDOWS } + currentIndex: -1 onVisibleChanged: if(visible) windowsList.update() cellWidth: width / 2 cellHeight: (112 + 15) * DefaultStyle.dp @@ -139,10 +141,11 @@ ColumnLayout { displayScreen: false screenIndex: index onClicked: { - mainItem.desc.core.windowId = $modelData.windowId - if( mainItem.conference.core.isLocalScreenSharing) - mainItem.call.core.videoSourceDescriptor = mainItem.desc - } + windowsLayout.currentIndex = index + mainItem.desc.core.windowId = $modelData.windowId + if( mainItem.conference.core.isLocalScreenSharing) + mainItem.call.core.videoSourceDescriptor = mainItem.desc + } selected: mainItem.desc.core.windowId == $modelData.windowId //onClicked: screensLayout.selectedIndex = index @@ -153,6 +156,7 @@ ColumnLayout { } Button { visible: mainItem.screenSharingAvailable + enabled: windowsLayout.currentIndex !== -1 || screensLayout.currentIndex !== -1 text: mainItem.conference && mainItem.conference.core.isLocalScreenSharing ? qsTr("Stop") : qsTr("Partager") diff --git a/Linphone/view/Item/PopupButton.qml b/Linphone/view/Item/PopupButton.qml index 95dd01256..4db746961 100644 --- a/Linphone/view/Item/PopupButton.qml +++ b/Linphone/view/Item/PopupButton.qml @@ -55,12 +55,12 @@ Button { // Do not use popup.height as it is not consistent. var position = mainItem.mapToItem(mainItem.Window.contentItem, mainItem.x + popup.implicitContentWidth + popup.padding, mainItem.y + mainItem.height + popup.implicitContentHeight + popup.padding) if (position.y >= mainItem.Window.height) { - y = -mainItem.height - popup.implicitContentHeight + y = -mainItem.height - popup.implicitContentHeight - popup.padding }else { y = mainItem.height + popup.padding } if (position.x >= mainItem.Window.width) { - x = -popup.implicitContentWidth + x = mainItem.width - Math.max(popup.width, popup.implicitContentWidth) } else { x = 0 } diff --git a/Linphone/view/Page/Main/ContactPage.qml b/Linphone/view/Page/Main/ContactPage.qml index 8cca63691..0fe2c9ae9 100644 --- a/Linphone/view/Page/Main/ContactPage.qml +++ b/Linphone/view/Page/Main/ContactPage.qml @@ -36,7 +36,7 @@ AbstractMainPage { friendGui.core.givenName = UtilsCpp.getGivenNameFromFullName(name) friendGui.core.familyName = UtilsCpp.getFamilyNameFromFullName(name) friendGui.core.defaultAddress = address - if (rightPanelStackView.currentItem && rightPanelStackView.currentItem.objectName != "contactEdition") + if (!rightPanelStackView.currentItem || rightPanelStackView.currentItem.objectName != "contactEdition") rightPanelStackView.push(contactEdition, {"contact": friendGui, "title": qsTr("Nouveau contact"), "saveButtonText": qsTr("Créer")}) } diff --git a/Linphone/view/Page/Main/MeetingPage.qml b/Linphone/view/Page/Main/MeetingPage.qml index 330b04536..8c14fe872 100644 --- a/Linphone/view/Page/Main/MeetingPage.qml +++ b/Linphone/view/Page/Main/MeetingPage.qml @@ -28,6 +28,8 @@ AbstractMainPage { } } + onNoItemButtonPressed: editConference() + function editConference(confInfoGui = null) { var isCreation = !confInfoGui if (isCreation) {