From 1ed1f391134acee4e4ef31465d9a26c8eb2432f8 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Fri, 15 Mar 2024 10:32:56 +0100 Subject: [PATCH] Call Conference --- Linphone/core/App.cpp | 6 +- Linphone/core/CMakeLists.txt | 1 + Linphone/core/call/CallCore.cpp | 28 + Linphone/core/call/CallCore.hpp | 11 + Linphone/core/conference/ConferenceCore.cpp | 546 +++--------------- Linphone/core/conference/ConferenceCore.hpp | 278 +++------ Linphone/core/conference/ConferenceGui.cpp | 47 ++ Linphone/core/conference/ConferenceGui.hpp | 44 ++ Linphone/model/call/CallModel.cpp | 9 + Linphone/model/call/CallModel.hpp | 4 + Linphone/model/conference/ConferenceModel.cpp | 1 + Linphone/view/App/CallsWindow.qml | 11 +- .../view/Layout/Contact/ContactLayout.qml | 4 +- Linphone/view/Page/Main/MeetingPage.qml | 35 +- 14 files changed, 321 insertions(+), 704 deletions(-) create mode 100644 Linphone/core/conference/ConferenceGui.cpp create mode 100644 Linphone/core/conference/ConferenceGui.hpp diff --git a/Linphone/core/App.cpp b/Linphone/core/App.cpp index 25d1f8423..676e0023d 100644 --- a/Linphone/core/App.cpp +++ b/Linphone/core/App.cpp @@ -40,9 +40,10 @@ #include "core/call/CallList.hpp" #include "core/call/CallProxy.hpp" #include "core/camera/CameraGui.hpp" -#include "core/fps-counter/FPSCounter.hpp" +#include "core/conference/ConferenceGui.hpp" #include "core/conference/ConferenceInfoGui.hpp" #include "core/conference/ConferenceInfoProxy.hpp" +#include "core/fps-counter/FPSCounter.hpp" #include "core/friend/FriendCore.hpp" #include "core/friend/FriendGui.hpp" #include "core/logger/QtLogger.hpp" @@ -206,6 +207,9 @@ void App::initCppInterfaces() { qmlRegisterType(Constants::MainQmlUri, 1, 0, "CallProxy"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "CallHistoryProxy"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "CallGui"); + qmlRegisterUncreatableType(Constants::MainQmlUri, 1, 0, "ConferenceCore", + QLatin1String("Uncreatable")); + qmlRegisterType(Constants::MainQmlUri, 1, 0, "ConferenceGui"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "FriendGui"); qmlRegisterUncreatableType(Constants::MainQmlUri, 1, 0, "FriendCore", QLatin1String("Uncreatable")); qmlRegisterType(Constants::MainQmlUri, 1, 0, "MagicSearchProxy"); diff --git a/Linphone/core/CMakeLists.txt b/Linphone/core/CMakeLists.txt index dc6383c7b..f3e187238 100644 --- a/Linphone/core/CMakeLists.txt +++ b/Linphone/core/CMakeLists.txt @@ -37,6 +37,7 @@ list(APPEND _LINPHONEAPP_SOURCES core/variant/VariantList.cpp core/conference/ConferenceCore.cpp + core/conference/ConferenceGui.cpp core/conference/ConferenceInfoCore.cpp core/conference/ConferenceInfoGui.cpp core/conference/ConferenceInfoList.cpp diff --git a/Linphone/core/call/CallCore.cpp b/Linphone/core/call/CallCore.cpp index a4214e090..41992c719 100644 --- a/Linphone/core/call/CallCore.cpp +++ b/Linphone/core/call/CallCore.cpp @@ -20,6 +20,8 @@ #include "CallCore.hpp" #include "core/App.hpp" +#include "core/conference/ConferenceCore.hpp" +#include "core/conference/ConferenceGui.hpp" #include "model/tool/ToolModel.hpp" #include "tool/Utils.hpp" #include "tool/thread/SafeConnection.hpp" @@ -66,6 +68,11 @@ CallCore::CallCore(const std::shared_ptr &call) : QObject(nullpt mIsSecured = (mEncryption == LinphoneEnums::MediaEncryption::Zrtp && tokenVerified) || mEncryption == LinphoneEnums::MediaEncryption::Srtp || mEncryption == LinphoneEnums::MediaEncryption::Dtls; + auto conference = call->getConference(); + mIsConference = conference != nullptr; + if (mIsConference) { + mConference = ConferenceCore::create(conference); + } mPaused = mState == LinphoneEnums::CallState::Pausing || mState == LinphoneEnums::CallState::Paused || mState == LinphoneEnums::CallState::PausedByRemote; mRemoteVideoEnabled = call->getRemoteParams() && call->getRemoteParams()->videoEnabled(); @@ -230,6 +237,11 @@ void CallCore::setSelf(QSharedPointer me) { } }); }); + mCallModelConnection->makeConnectToModel(&CallModel::conferenceChanged, [this]() { + auto conference = mCallModel->getMonitor()->getConference(); + QSharedPointer core = conference ? ConferenceCore::create(conference) : nullptr; + mCallModelConnection->invokeToCore([this, core]() { setConference(core); }); + }); mCallModelConnection->makeConnectToCore(&CallCore::lAccept, [this](bool withVideo) { mCallModelConnection->invokeToModel([this, withVideo]() { mCallModel->accept(withVideo); }); }); @@ -360,6 +372,22 @@ void CallCore::setIsSecured(bool secured) { } } +bool CallCore::isConference() const { + return mIsConference; +} + +ConferenceGui *CallCore::getConferenceGui() const { + return mConference ? new ConferenceGui(mConference) : nullptr; +} + +void CallCore::setConference(const QSharedPointer &conference) { + if (mConference != conference) { + mConference = conference; + mIsConference = (mConference != nullptr); + emit conferenceChanged(); + } +} + QString CallCore::getLocalSas() { return mLocalSas; } diff --git a/Linphone/core/call/CallCore.hpp b/Linphone/core/call/CallCore.hpp index 275308126..a1f6b5c9e 100644 --- a/Linphone/core/call/CallCore.hpp +++ b/Linphone/core/call/CallCore.hpp @@ -21,6 +21,8 @@ #ifndef CALL_CORE_H_ #define CALL_CORE_H_ +#include "core/conference/ConferenceCore.hpp" +#include "core/conference/ConferenceGui.hpp" #include "model/call/CallModel.hpp" #include "tool/LinphoneEnums.hpp" #include "tool/thread/SafeConnection.hpp" @@ -43,6 +45,7 @@ class CallCore : public QObject, public AbstractObject { Q_PROPERTY(bool paused READ getPaused WRITE lSetPaused NOTIFY pausedChanged) Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT) Q_PROPERTY(bool isSecured READ isSecured NOTIFY securityUpdated) + Q_PROPERTY(bool isConference READ isConference NOTIFY conferenceChanged) Q_PROPERTY(LinphoneEnums::MediaEncryption encryption READ getEncryption NOTIFY securityUpdated) Q_PROPERTY(QString localSas READ getLocalSas WRITE setLocalSas MEMBER mLocalSas NOTIFY localSasChanged) Q_PROPERTY(QString remoteSas WRITE setRemoteSas MEMBER mRemoteSas NOTIFY remoteSasChanged) @@ -57,6 +60,7 @@ class CallCore : public QObject, public AbstractObject { microphoneVolumeGainChanged) Q_PROPERTY(float microVolume READ getMicrophoneVolume WRITE setMicrophoneVolume NOTIFY microphoneVolumeChanged) Q_PROPERTY(LinphoneEnums::CallState transferState READ getTransferState NOTIFY transferStateChanged) + Q_PROPERTY(ConferenceGui *conference READ getConferenceGui NOTIFY conferenceChanged) public: // Should be call from model Thread. Will be automatically in App thread after initialization @@ -97,6 +101,10 @@ public: bool isSecured() const; void setIsSecured(bool secured); + bool isConference() const; + ConferenceGui *getConferenceGui() const; + void setConference(const QSharedPointer &conference); + QString getLocalSas(); void setLocalSas(const QString &sas); QString getRemoteSas(); @@ -155,6 +163,7 @@ signals: void speakerVolumeGainChanged(); void microphoneVolumeChanged(); void microphoneVolumeGainChanged(); + void conferenceChanged(); // Linphone commands void lAccept(bool withVideo); // Accept an incoming call @@ -194,6 +203,7 @@ signals: */ private: std::shared_ptr mCallModel; + QSharedPointer mConference; LinphoneEnums::CallStatus mStatus; LinphoneEnums::CallState mState; LinphoneEnums::CallState mTransferState; @@ -202,6 +212,7 @@ private: QString mLastErrorMessage; QString mPeerAddress; bool mIsSecured; + bool mIsConference = false; int mDuration = 0; bool mSpeakerMuted; bool mMicrophoneMuted; diff --git a/Linphone/core/conference/ConferenceCore.cpp b/Linphone/core/conference/ConferenceCore.cpp index f1d3319c1..1f37332ed 100644 --- a/Linphone/core/conference/ConferenceCore.cpp +++ b/Linphone/core/conference/ConferenceCore.cpp @@ -1,481 +1,81 @@ -// /* -// * Copyright (c) 2010-2024 Belledonne Communications SARL. -// * -// * This file is part of linphone-desktop -// * (see https://www.linphone.org). -// * -// * 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 3 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, see . -// */ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 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, see . + */ -// #include "CallCore.hpp" -// #include "core/App.hpp" -// #include "model/tool/ToolModel.hpp" -// #include "tool/Utils.hpp" -// #include "tool/thread/SafeConnection.hpp" +#include "ConferenceCore.hpp" +#include "core/App.hpp" +#include "tool/Utils.hpp" +#include "tool/thread/SafeConnection.hpp" -// DEFINE_ABSTRACT_OBJECT(CallCore) +DEFINE_ABSTRACT_OBJECT(ConferenceCore) -// QVariant createDeviceVariant(const QString &id, const QString &name) { -// QVariantMap map; -// map.insert("id", id); -// map.insert("name", name); -// return map; -// } +QSharedPointer ConferenceCore::create(const std::shared_ptr &conference) { + auto sharedPointer = QSharedPointer(new ConferenceCore(conference), &QObject::deleteLater); + sharedPointer->setSelf(sharedPointer); + sharedPointer->moveToThread(App::getInstance()->thread()); + return sharedPointer; +} +ConferenceCore::ConferenceCore(const std::shared_ptr &conference) { + App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership); + // Should be call from model Thread + mustBeInLinphoneThread(getClassName()); + mSubject = Utils::coreStringToAppString(conference->getSubject()); +} +ConferenceCore::~ConferenceCore() { + mustBeInMainThread("~" + getClassName()); + emit mConferenceModel->removeListener(); +} -// QSharedPointer CallCore::create(const std::shared_ptr &call) { -// auto sharedPointer = QSharedPointer(new CallCore(call), &QObject::deleteLater); -// sharedPointer->setSelf(sharedPointer); -// sharedPointer->moveToThread(App::getInstance()->thread()); -// return sharedPointer; -// } +void ConferenceCore::setSelf(QSharedPointer me) { + mConferenceModelConnection = QSharedPointer>( + new SafeConnection(me, mConferenceModel), &QObject::deleteLater); + // mCallModelConnection->makeConnectToCore(&CallCore::lSetMicrophoneMuted, [this](bool isMuted) { + // mCallModelConnection->invokeToModel([this, isMuted]() { mCallModel->setMicrophoneMuted(isMuted); }); + // }); +} -// CallCore::CallCore(const std::shared_ptr &call) : QObject(nullptr) { -// qDebug() << "[CallCore] new" << this; -// App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership); -// // Should be call from model Thread -// mustBeInLinphoneThread(getClassName()); -// mDir = LinphoneEnums::fromLinphone(call->getDir()); -// mCallModel = Utils::makeQObject_ptr(call); -// mCallModel->setSelf(mCallModel); -// mDuration = call->getDuration(); -// mMicrophoneMuted = call->getMicrophoneMuted(); -// mSpeakerMuted = call->getSpeakerMuted(); -// mCameraEnabled = call->cameraEnabled(); -// mState = LinphoneEnums::fromLinphone(call->getState()); -// mPeerAddress = Utils::coreStringToAppString(call->getRemoteAddress()->asStringUriOnly()); -// mStatus = LinphoneEnums::fromLinphone(call->getCallLog()->getStatus()); -// mTransferState = LinphoneEnums::fromLinphone(call->getTransferState()); -// auto token = Utils::coreStringToAppString(mCallModel->getAuthenticationToken()); -// auto localToken = mDir == LinphoneEnums::CallDir::Incoming ? token.left(2).toUpper() : token.right(2).toUpper(); -// auto remoteToken = mDir == LinphoneEnums::CallDir::Outgoing ? token.left(2).toUpper() : token.right(2).toUpper(); -// mEncryption = LinphoneEnums::fromLinphone(call->getParams()->getMediaEncryption()); -// auto tokenVerified = call->getAuthenticationTokenVerified(); -// mLocalSas = localToken; -// mRemoteSas = remoteToken; -// mIsSecured = (mEncryption == LinphoneEnums::MediaEncryption::Zrtp && tokenVerified) || -// mEncryption == LinphoneEnums::MediaEncryption::Srtp || -// mEncryption == LinphoneEnums::MediaEncryption::Dtls; -// mPaused = mState == LinphoneEnums::CallState::Pausing || mState == LinphoneEnums::CallState::Paused || -// mState == LinphoneEnums::CallState::PausedByRemote; -// mRemoteVideoEnabled = call->getRemoteParams() && call->getRemoteParams()->videoEnabled(); -// mRecording = call->getParams() && call->getParams()->isRecording(); -// mRemoteRecording = call->getRemoteParams() && call->getRemoteParams()->isRecording(); -// mSpeakerVolumeGain = mCallModel->getSpeakerVolumeGain(); -// // TODO : change this with settings value when settings done -// if (mSpeakerVolumeGain < 0) { -// call->setSpeakerVolumeGain(0.5); -// mSpeakerVolumeGain = 0.5; -// } -// mMicrophoneVolumeGain = call->getMicrophoneVolumeGain(); -// // TODO : change this with settings value when settings done -// if (mMicrophoneVolumeGain < 0) { -// call->setMicrophoneVolumeGain(0.5); -// mMicrophoneVolumeGain = 0.5; -// } -// mMicrophoneVolume = call->getRecordVolume(); -// mRecordable = mState == LinphoneEnums::CallState::StreamsRunning; -// } +bool ConferenceCore::updateLocalParticipant() { // true if changed + return false; +} -// CallCore::~CallCore() { -// qDebug() << "[CallCore] delete" << this; -// mustBeInMainThread("~" + getClassName()); -// emit mCallModel->removeListener(); -// } +QString ConferenceCore::getSubject() const { + return mSubject; +} +QDateTime ConferenceCore::getStartDate() const { + return mStartDate; +} -// void CallCore::setSelf(QSharedPointer me) { -// mCallModelConnection = QSharedPointer>( -// new SafeConnection(me, mCallModel), &QObject::deleteLater); -// mCallModelConnection->makeConnectToCore(&CallCore::lSetMicrophoneMuted, [this](bool isMuted) { -// mCallModelConnection->invokeToModel([this, isMuted]() { mCallModel->setMicrophoneMuted(isMuted); }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::microphoneMutedChanged, [this](bool isMuted) { -// mCallModelConnection->invokeToCore([this, isMuted]() { setMicrophoneMuted(isMuted); }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::remoteVideoEnabledChanged, [this](bool enabled) { -// mCallModelConnection->invokeToCore([this, enabled]() { setRemoteVideoEnabled(enabled); }); -// }); -// mCallModelConnection->makeConnectToCore(&CallCore::lSetSpeakerMuted, [this](bool isMuted) { -// mCallModelConnection->invokeToModel([this, isMuted]() { mCallModel->setSpeakerMuted(isMuted); }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::speakerMutedChanged, [this](bool isMuted) { -// mCallModelConnection->invokeToCore([this, isMuted]() { setSpeakerMuted(isMuted); }); -// }); -// mCallModelConnection->makeConnectToCore(&CallCore::lSetCameraEnabled, [this](bool enabled) { -// mCallModelConnection->invokeToModel([this, enabled]() { mCallModel->setCameraEnabled(enabled); }); -// }); -// mCallModelConnection->makeConnectToCore(&CallCore::lStartRecording, [this]() { -// mCallModelConnection->invokeToModel([this]() { mCallModel->startRecording(); }); -// }); -// mCallModelConnection->makeConnectToCore(&CallCore::lStopRecording, [this]() { -// mCallModelConnection->invokeToModel([this]() { mCallModel->stopRecording(); }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::recordingChanged, [this](bool recording) { -// mCallModelConnection->invokeToCore([this, recording]() { setRecording(recording); }); -// }); -// mCallModelConnection->makeConnectToCore(&CallCore::lVerifyAuthenticationToken, [this](bool verified) { -// mCallModelConnection->invokeToModel( -// [this, verified]() { mCallModel->setAuthenticationTokenVerified(verified); }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::authenticationTokenVerifiedChanged, [this](bool verified) { -// mCallModelConnection->invokeToCore([this, verified]() { setIsSecured(verified); }); -// }); -// mCallModelConnection->makeConnectToModel( -// &CallModel::remoteRecording, [this](const std::shared_ptr &call, bool recording) { -// mCallModelConnection->invokeToCore([this, recording]() { setRemoteRecording(recording); }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::cameraEnabledChanged, [this](bool enabled) { -// mCallModelConnection->invokeToCore([this, enabled]() { setCameraEnabled(enabled); }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::durationChanged, [this](int duration) { -// mCallModelConnection->invokeToCore([this, duration]() { setDuration(duration); }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::microphoneVolumeChanged, [this](float volume) { -// mCallModelConnection->invokeToCore([this, volume]() { setMicrophoneVolume(volume); }); -// }); -// mCallModelConnection->makeConnectToModel( -// &CallModel::stateChanged, [this](linphone::Call::State state, const std::string &message) { -// mCallModelConnection->invokeToCore([this, state, message]() { -// setState(LinphoneEnums::fromLinphone(state), Utils::coreStringToAppString(message)); -// }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::statusChanged, [this](linphone::Call::Status status) { -// mCallModelConnection->invokeToCore([this, status]() { setStatus(LinphoneEnums::fromLinphone(status)); }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::stateChanged, -// [this](linphone::Call::State state, const std::string &message) { -// mCallModelConnection->invokeToCore([this, state]() { -// setRecordable(state == linphone::Call::State::StreamsRunning); -// }); -// }); -// mCallModelConnection->makeConnectToCore(&CallCore::lSetPaused, [this](bool paused) { -// mCallModelConnection->invokeToModel([this, paused]() { mCallModel->setPaused(paused); }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::pausedChanged, [this](bool paused) { -// mCallModelConnection->invokeToCore([this, paused]() { setPaused(paused); }); -// }); +Q_INVOKABLE qint64 ConferenceCore::getElapsedSeconds() const { + return 0; +} +// Q_INVOKABLE ParticipantModel *getLocalParticipant() const; +// ParticipantListModel *getParticipantListModel() const; +// std::list> +// getParticipantList() const; // SDK exclude me. We want to get ALL participants. +int ConferenceCore::getParticipantDeviceCount() const { + return 0; +} -// mCallModelConnection->makeConnectToCore(&CallCore::lTransferCall, [this](const QString &address) { -// mCallModelConnection->invokeToModel( -// [this, address]() { mCallModel->transferTo(ToolModel::interpretUrl(address)); }); -// }); -// 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->makeConnectToModel( -// &CallModel::encryptionChanged, -// [this](const std::shared_ptr &call, bool on, const std::string &authenticationToken) { -// auto encryption = LinphoneEnums::fromLinphone(call->getCurrentParams()->getMediaEncryption()); -// auto tokenVerified = mCallModel->getAuthenticationTokenVerified(); -// auto token = Utils::coreStringToAppString(mCallModel->getAuthenticationToken()); -// mCallModelConnection->invokeToCore([this, call, encryption, tokenVerified, token]() { -// if (token.size() == 4) { -// auto localToken = -// mDir == LinphoneEnums::CallDir::Incoming ? token.left(2).toUpper() : token.right(2).toUpper(); -// auto remoteToken = -// mDir == LinphoneEnums::CallDir::Outgoing ? token.left(2).toUpper() : token.right(2).toUpper(); -// setLocalSas(localToken); -// setRemoteSas(remoteToken); -// } -// setEncryption(encryption); -// setIsSecured((encryption == LinphoneEnums::MediaEncryption::Zrtp && tokenVerified) || -// encryption == LinphoneEnums::MediaEncryption::Srtp || -// encryption == LinphoneEnums::MediaEncryption::Dtls); -// }); -// }); -// mCallModelConnection->makeConnectToCore(&CallCore::lSetSpeakerVolumeGain, [this](float gain) { -// mCallModelConnection->invokeToModel([this, gain]() { mCallModel->setSpeakerVolumeGain(gain); }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::speakerVolumeGainChanged, [this](float gain) { -// mCallModelConnection->invokeToCore([this, gain]() { setSpeakerVolumeGain(gain); }); -// }); -// mCallModelConnection->makeConnectToCore(&CallCore::lSetMicrophoneVolumeGain, [this](float gain) { -// mCallModelConnection->invokeToModel([this, gain]() { mCallModel->setMicrophoneVolumeGain(gain); }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::microphoneVolumeGainChanged, [this](float gain) { -// mCallModelConnection->invokeToCore([this, gain]() { setMicrophoneVolumeGain(gain); }); -// }); -// mCallModelConnection->makeConnectToCore(&CallCore::lSetInputAudioDevice, [this](const QString &id) { -// mCallModelConnection->invokeToModel([this, id]() { -// if (auto device = ToolModel::findAudioDevice(id)) { -// mCallModel->setInputAudioDevice(device); -// } -// }); -// }); -// mCallModelConnection->makeConnectToModel(&CallModel::inputAudioDeviceChanged, [this](const std::string &id) { -// mCallModelConnection->invokeToCore([this, id]() {}); -// }); -// mCallModelConnection->makeConnectToCore(&CallCore::lSetOutputAudioDevice, [this](const QString &id) { -// mCallModelConnection->invokeToModel([this, id]() { -// if (auto device = ToolModel::findAudioDevice(id)) { -// mCallModel->setOutputAudioDevice(device); -// } -// }); -// }); -// mCallModelConnection->makeConnectToCore(&CallCore::lAccept, [this](bool withVideo) { -// mCallModelConnection->invokeToModel([this, withVideo]() { mCallModel->accept(withVideo); }); -// }); -// mCallModelConnection->makeConnectToCore( -// &CallCore::lDecline, [this]() { mCallModelConnection->invokeToModel([this]() { mCallModel->decline(); }); }); -// mCallModelConnection->makeConnectToCore(&CallCore::lTerminate, [this]() { -// mCallModelConnection->invokeToModel([this]() { mCallModel->terminate(); }); -// }); -// mCallModelConnection->makeConnectToCore(&CallCore::lTerminateAllCalls, [this]() { -// mCallModelConnection->invokeToModel([this]() { mCallModel->terminateAllCalls(); }); -// }); -// } - -// QString CallCore::getPeerAddress() const { -// return mPeerAddress; -// } - -// LinphoneEnums::CallStatus CallCore::getStatus() const { -// return mStatus; -// } - -// void CallCore::setStatus(LinphoneEnums::CallStatus status) { -// mustBeInMainThread(log().arg(Q_FUNC_INFO)); -// if (mStatus != status) { -// mStatus = status; -// emit statusChanged(mStatus); -// } -// } - -// LinphoneEnums::CallDir CallCore::getDir() const { -// return mDir; -// } - -// void CallCore::setDir(LinphoneEnums::CallDir dir) { -// mustBeInMainThread(log().arg(Q_FUNC_INFO)); -// if (mDir != dir) { -// mDir = dir; -// emit dirChanged(mDir); -// } -// } - -// LinphoneEnums::CallState CallCore::getState() const { -// return mState; -// } - -// void CallCore::setState(LinphoneEnums::CallState state, const QString &message) { -// mustBeInMainThread(log().arg(Q_FUNC_INFO)); -// if (mState != state) { -// mState = state; -// if (state == LinphoneEnums::CallState::Error) setLastErrorMessage(message); -// emit stateChanged(mState); -// } -// } - -// QString CallCore::getLastErrorMessage() const { -// return mLastErrorMessage; -// } -// void CallCore::setLastErrorMessage(const QString &message) { -// if (mLastErrorMessage != message) { -// mLastErrorMessage = message; -// emit lastErrorMessageChanged(); -// } -// } - -// int CallCore::getDuration() { -// return mDuration; -// } - -// void CallCore::setDuration(int duration) { -// if (mDuration != duration) { -// mDuration = duration; -// emit durationChanged(mDuration); -// } -// } - -// bool CallCore::getSpeakerMuted() const { -// return mSpeakerMuted; -// } - -// void CallCore::setSpeakerMuted(bool isMuted) { -// if (mSpeakerMuted != isMuted) { -// mSpeakerMuted = isMuted; -// emit speakerMutedChanged(); -// } -// } - -// bool CallCore::getMicrophoneMuted() const { -// return mMicrophoneMuted; -// } - -// void CallCore::setMicrophoneMuted(bool isMuted) { -// if (mMicrophoneMuted != isMuted) { -// mMicrophoneMuted = isMuted; -// emit microphoneMutedChanged(); -// } -// } - -// bool CallCore::getCameraEnabled() const { -// return mCameraEnabled; -// } - -// void CallCore::setCameraEnabled(bool enabled) { -// if (mCameraEnabled != enabled) { -// mCameraEnabled = enabled; -// emit cameraEnabledChanged(); -// } -// } - -// bool CallCore::getPaused() const { -// return mPaused; -// } - -// void CallCore::setPaused(bool paused) { -// if (mPaused != paused) { -// mPaused = paused; -// emit pausedChanged(); -// } -// } - -// bool CallCore::isSecured() const { -// return mIsSecured; -// } - -// void CallCore::setIsSecured(bool secured) { -// if (mIsSecured != secured) { -// mIsSecured = secured; -// emit securityUpdated(); -// } -// } - -// QString CallCore::getLocalSas() { -// return mLocalSas; -// } - -// QString CallCore::getRemoteSas() { -// return mRemoteSas; -// } - -// void CallCore::setLocalSas(const QString &sas) { -// if (mLocalSas != sas) { -// mLocalSas = sas; -// emit localSasChanged(); -// } -// } - -// void CallCore::setRemoteSas(const QString &sas) { -// if (mRemoteSas != sas) { -// mRemoteSas = sas; -// emit remoteSasChanged(); -// } -// } - -// LinphoneEnums::MediaEncryption CallCore::getEncryption() const { -// return mEncryption; -// } - -// void CallCore::setEncryption(LinphoneEnums::MediaEncryption encryption) { -// if (mEncryption != encryption) { -// mEncryption = encryption; -// emit securityUpdated(); -// } -// } - -// bool CallCore::getRemoteVideoEnabled() const { -// return mRemoteVideoEnabled; -// } - -// void CallCore::setRemoteVideoEnabled(bool enabled) { -// if (mRemoteVideoEnabled != enabled) { -// mRemoteVideoEnabled = enabled; -// emit remoteVideoEnabledChanged(mRemoteVideoEnabled); -// } -// } - -// bool CallCore::getRecording() const { -// return mRecording; -// } -// void CallCore::setRecording(bool recording) { -// if (mRecording != recording) { -// mRecording = recording; -// emit recordingChanged(); -// } -// } - -// bool CallCore::getRemoteRecording() const { -// return mRemoteRecording; -// } -// void CallCore::setRemoteRecording(bool recording) { -// if (mRemoteRecording != recording) { -// mRemoteRecording = recording; -// emit remoteRecordingChanged(); -// } -// } - -// bool CallCore::getRecordable() const { -// return mRecordable; -// } -// void CallCore::setRecordable(bool recordable) { -// if (mRecordable != recordable) { -// mRecordable = recordable; -// emit recordableChanged(); -// } -// } - -// float CallCore::getSpeakerVolumeGain() const { -// return mSpeakerVolumeGain; -// } -// void CallCore::setSpeakerVolumeGain(float gain) { -// if (mSpeakerVolumeGain != gain) { -// mSpeakerVolumeGain = gain; -// emit speakerVolumeGainChanged(); -// } -// } - -// float CallCore::getMicrophoneVolume() const { -// return mMicrophoneVolume; -// } -// void CallCore::setMicrophoneVolume(float vol) { -// if (mMicrophoneVolume != vol) { -// mMicrophoneVolume = vol; -// emit microphoneVolumeChanged(); -// } -// } - -// float CallCore::getMicrophoneVolumeGain() const { -// return mMicrophoneVolumeGain; -// } -// void CallCore::setMicrophoneVolumeGain(float gain) { -// if (mMicrophoneVolumeGain != gain) { -// mMicrophoneVolumeGain = gain; -// emit microphoneVolumeGainChanged(); -// } -// } - -// LinphoneEnums::CallState CallCore::getTransferState() const { -// return mTransferState; -// } - -// void CallCore::setTransferState(LinphoneEnums::CallState state, const QString &message) { -// if (mTransferState != state) { -// mTransferState = state; -// if (state == LinphoneEnums::CallState::Error) setLastErrorMessage(message); -// emit transferStateChanged(); -// } -// } - -// std::shared_ptr CallCore::getModel() const { -// return mCallModel; -// } +void ConferenceCore::setIsReady(bool state) { + mustBeInMainThread(log().arg(Q_FUNC_INFO)); + if (mIsReady != state) { + mIsReady = state; + isReadyChanged(); + } +} diff --git a/Linphone/core/conference/ConferenceCore.hpp b/Linphone/core/conference/ConferenceCore.hpp index b2b8953ac..f84ca408f 100644 --- a/Linphone/core/conference/ConferenceCore.hpp +++ b/Linphone/core/conference/ConferenceCore.hpp @@ -1,224 +1,80 @@ -// /* -// * Copyright (c) 2010-2024 Belledonne Communications SARL. -// * -// * This file is part of linphone-desktop -// * (see https://www.linphone.org). -// * -// * 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 3 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, see . -// */ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 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, see . + */ -// #ifndef CONFERENCE_CORE_H_ -// #define CONFERENCE_CORE_H_ +#ifndef CONFERENCE_CORE_H_ +#define CONFERENCE_CORE_H_ -// #include "model/conference/ConferenceModel.hpp" -// #include "tool/LinphoneEnums.hpp" -// #include "tool/thread/SafeConnection.hpp" -// #include -// #include -// #include +#include "model/conference/ConferenceModel.hpp" +#include "tool/LinphoneEnums.hpp" +#include "tool/thread/SafeConnection.hpp" +#include +#include +#include +#include -// class ConferenceCore : public QObject, public AbstractObject { -// Q_OBJECT +class ConferenceCore : public QObject, public AbstractObject { + Q_OBJECT +public: + Q_PROPERTY(QString subject READ getSubject NOTIFY subjectChanged) + Q_PROPERTY(QDateTime startDate READ getStartDate CONSTANT) + // Q_PROPERTY(ParticipantListModel* participants READ getParticipantListModel CONSTANT) + // Q_PROPERTY(ParticipantModel* localParticipant READ getLocalParticipant NOTIFY localParticipantChanged) + Q_PROPERTY(bool isReady MEMBER mIsReady WRITE setIsReady NOTIFY isReadyChanged) + Q_PROPERTY(int participantDeviceCount READ getParticipantDeviceCount NOTIFY participantDeviceCountChanged) -// // Q_PROPERTY(QString peerDisplayName MEMBER mPeerDisplayName) -// Q_PROPERTY(LinphoneEnums::ConferenceStatus status READ getStatus NOTIFY statusChanged) -// Q_PROPERTY(LinphoneEnums::ConferenceDir dir READ getDir NOTIFY dirChanged) -// Q_PROPERTY(LinphoneEnums::ConferenceState state READ getState NOTIFY stateChanged) -// Q_PROPERTY(QString lastErrorMessage READ getLastErrorMessage NOTIFY lastErrorMessageChanged) -// Q_PROPERTY(int duration READ getDuration NOTIFY durationChanged) -// Q_PROPERTY(bool speakerMuted READ getSpeakerMuted WRITE lSetSpeakerMuted NOTIFY speakerMutedChanged) -// Q_PROPERTY(bool microphoneMuted READ getMicrophoneMuted WRITE lSetMicrophoneMuted NOTIFY microphoneMutedChanged) -// Q_PROPERTY(bool cameraEnabled READ getCameraEnabled WRITE lSetCameraEnabled NOTIFY cameraEnabledChanged) -// Q_PROPERTY(bool paused READ getPaused WRITE lSetPaused NOTIFY pausedChanged) -// Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT) -// Q_PROPERTY(bool isSecured READ isSecured NOTIFY securityUpdated) -// Q_PROPERTY(LinphoneEnums::MediaEncryption encryption READ getEncryption NOTIFY securityUpdated) -// Q_PROPERTY(QString localSas READ getLocalSas WRITE setLocalSas MEMBER mLocalSas NOTIFY localSasChanged) -// Q_PROPERTY(QString remoteSas WRITE setRemoteSas MEMBER mRemoteSas NOTIFY remoteSasChanged) -// Q_PROPERTY( -// bool remoteVideoEnabled READ getRemoteVideoEnabled WRITE setRemoteVideoEnabled NOTIFY remoteVideoEnabledChanged) -// Q_PROPERTY(bool recording READ getRecording WRITE setRecording NOTIFY recordingChanged) -// Q_PROPERTY(bool remoteRecording READ getRemoteRecording WRITE setRemoteRecording NOTIFY remoteRecordingChanged) -// Q_PROPERTY(bool recordable READ getRecordable WRITE setRecordable NOTIFY recordableChanged) -// Q_PROPERTY( -// float speakerVolumeGain READ getSpeakerVolumeGain WRITE setSpeakerVolumeGain NOTIFY speakerVolumeGainChanged) -// Q_PROPERTY(float microphoneVolumeGain READ getMicrophoneVolumeGain WRITE setMicrophoneVolumeGain NOTIFY -// microphoneVolumeGainChanged) -// Q_PROPERTY(float microVolume READ getMicrophoneVolume WRITE setMicrophoneVolume NOTIFY microphoneVolumeChanged) -// Q_PROPERTY(LinphoneEnums::ConferenceState transferState READ getTransferState NOTIFY transferStateChanged) + // Should be call from model Thread. Will be automatically in App thread after initialization + static QSharedPointer create(const std::shared_ptr &conference); + ConferenceCore(const std::shared_ptr &conference); + ~ConferenceCore(); + void setSelf(QSharedPointer me); -// public: -// // Should be call from model Thread. Will be automatically in App thread after initialization -// static QSharedPointer create(const std::shared_ptr &call); -// ConferenceCore(const std::shared_ptr &call); -// ~ConferenceCore(); -// void setSelf(QSharedPointer me); + bool updateLocalParticipant(); // true if changed -// QString getPeerAddress() const; + QString getSubject() const; + QDateTime getStartDate() const; + Q_INVOKABLE qint64 getElapsedSeconds() const; + // Q_INVOKABLE ParticipantModel *getLocalParticipant() const; + // ParticipantListModel *getParticipantListModel() const; + // std::list> + // getParticipantList() const; // SDK exclude me. We want to get ALL participants. + int getParticipantDeviceCount() const; -// LinphoneEnums::ConferenceStatus getStatus() const; -// void setStatus(LinphoneEnums::ConferenceStatus status); + void setIsReady(bool state); -// LinphoneEnums::ConferenceDir getDir() const; -// void setDir(LinphoneEnums::ConferenceDir dir); + //--------------------------------------------------------------------------- -// LinphoneEnums::ConferenceState getState() const; -// void setState(LinphoneEnums::ConferenceState state, const QString &message); +signals: + void subjectChanged(); + void isReadyChanged(); + void participantDeviceCountChanged(); -// QString getLastErrorMessage() const; -// void setLastErrorMessage(const QString &message); +private: + QSharedPointer> mConferenceModelConnection; + std::shared_ptr mConferenceModel; -// int getDuration(); -// void setDuration(int duration); + bool mIsReady = false; + QString mSubject; + QDateTime mStartDate = QDateTime::currentDateTime(); -// bool getSpeakerMuted() const; -// void setSpeakerMuted(bool isMuted); + DECLARE_ABSTRACT_OBJECT +}; -// bool getMicrophoneMuted() const; -// void setMicrophoneMuted(bool isMuted); - -// bool getCameraEnabled() const; -// void setCameraEnabled(bool enabled); - -// bool getPaused() const; -// void setPaused(bool paused); - -// bool isSecured() const; -// void setIsSecured(bool secured); - -// QString getLocalSas(); -// void setLocalSas(const QString &sas); -// QString getRemoteSas(); -// void setRemoteSas(const QString &sas); - -// LinphoneEnums::MediaEncryption getEncryption() const; -// void setEncryption(LinphoneEnums::MediaEncryption encryption); - -// bool getRemoteVideoEnabled() const; -// void setRemoteVideoEnabled(bool enabled); - -// bool getRecording() const; -// void setRecording(bool recording); - -// bool getRemoteRecording() const; -// void setRemoteRecording(bool recording); - -// bool getRecordable() const; -// void setRecordable(bool recordable); - -// float getSpeakerVolumeGain() const; -// void setSpeakerVolumeGain(float gain); - -// float getMicrophoneVolumeGain() const; -// void setMicrophoneVolumeGain(float gain); - -// float getMicrophoneVolume() const; -// void setMicrophoneVolume(float vol); - -// QString getInputDeviceName() const; -// void setInputDeviceName(const QString &id); - -// LinphoneEnums::ConferenceState getTransferState() const; -// void setTransferState(LinphoneEnums::ConferenceState state, const QString &message); - -// std::shared_ptr getModel() const; - -// signals: -// void statusChanged(LinphoneEnums::ConferenceStatus status); -// void stateChanged(LinphoneEnums::ConferenceState state); -// void dirChanged(LinphoneEnums::ConferenceDir dir); -// void lastErrorMessageChanged(); -// void durationChanged(int duration); -// void speakerMutedChanged(); -// void microphoneMutedChanged(); -// void cameraEnabledChanged(); -// void pausedChanged(); -// void transferStateChanged(); -// void securityUpdated(); -// void localSasChanged(); -// void remoteSasChanged(); -// void remoteVideoEnabledChanged(bool remoteVideoEnabled); -// void recordingChanged(); -// void remoteRecordingChanged(); -// void recordableChanged(); -// void speakerVolumeGainChanged(); -// void microphoneVolumeChanged(); -// void microphoneVolumeGainChanged(); - -// // Linphone commands -// void lAccept(bool withVideo); // Accept an incoming call -// void lDecline(); // Decline an incoming call -// void lTerminate(); // Hangup a call -// void lTerminateAllConferences(); // Hangup all calls -// void lSetSpeakerMuted(bool muted); -// void lSetMicrophoneMuted(bool isMuted); -// void lSetCameraEnabled(bool enabled); -// void lSetPaused(bool paused); -// void lTransferConference(const QString &dest); -// void lStartRecording(); -// void lStopRecording(); -// void lVerifyAuthenticationToken(bool verified); -// void lSetSpeakerVolumeGain(float gain); -// void lSetMicrophoneVolumeGain(float gain); -// void lSetInputAudioDevice(const QString &id); -// void lSetOutputAudioDevice(const QString &id); - -// /* TODO -// Q_INVOKABLE void acceptWithVideo(); - -// Q_INVOKABLE void askForTransfer(); -// Q_INVOKABLE void askForAttendedTransfer(); -// Q_INVOKABLE bool transferTo(const QString &sipAddress); -// Q_INVOKABLE bool transferToAnother(const QString &peerAddress); - -// Q_INVOKABLE bool getRemoteVideoEnabled() const; -// Q_INVOKABLE void acceptVideoRequest(); -// Q_INVOKABLE void rejectVideoRequest(); - -// Q_INVOKABLE void takeSnapshot(); - -// Q_INVOKABLE void sendDtmf(const QString &dtmf); -// Q_INVOKABLE void verifyAuthenticationToken(bool verify); -// Q_INVOKABLE void updateStreams(); -// */ -// private: -// std::shared_ptr mConferenceModel; -// LinphoneEnums::ConferenceStatus mStatus; -// LinphoneEnums::ConferenceState mState; -// LinphoneEnums::ConferenceState mTransferState; -// LinphoneEnums::ConferenceDir mDir; -// LinphoneEnums::MediaEncryption mEncryption; -// QString mLastErrorMessage; -// QString mPeerAddress; -// bool mIsSecured; -// int mDuration = 0; -// bool mSpeakerMuted; -// bool mMicrophoneMuted; -// bool mCameraEnabled; -// bool mPaused = false; -// bool mRemoteVideoEnabled = false; -// bool mRecording = false; -// bool mRemoteRecording = false; -// bool mRecordable = false; -// QString mLocalSas; -// QString mRemoteSas; -// float mSpeakerVolumeGain; -// float mMicrophoneVolume; -// float mMicrophoneVolumeGain; -// QSharedPointer> mConferenceModelConnection; - -// DECLARE_ABSTRACT_OBJECT -// }; -// Q_DECLARE_METATYPE(ConferenceCore *) -// #endif +Q_DECLARE_METATYPE(ConferenceCore *) +#endif diff --git a/Linphone/core/conference/ConferenceGui.cpp b/Linphone/core/conference/ConferenceGui.cpp new file mode 100644 index 000000000..2bbd004ed --- /dev/null +++ b/Linphone/core/conference/ConferenceGui.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 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, see . + */ + +#include "ConferenceGui.hpp" +#include "ConferenceCore.hpp" +#include "core/App.hpp" + +DEFINE_ABSTRACT_OBJECT(ConferenceGui) + +ConferenceGui::ConferenceGui() { + qDebug() << "[ConferenceGui] new" << this; + mCore = ConferenceCore::create(nullptr); + App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); + if (isInLinphoneThread()) moveToThread(App::getInstance()->thread()); +} +ConferenceGui::ConferenceGui(QSharedPointer core) { + qDebug() << "[ConferenceGui] new" << this; + App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); + mCore = core; + if (isInLinphoneThread()) moveToThread(App::getInstance()->thread()); +} + +ConferenceGui::~ConferenceGui() { + mustBeInMainThread("~" + getClassName()); + qDebug() << "[ConferenceGui] delete" << this; +} + +ConferenceCore *ConferenceGui::getCore() const { + return mCore.get(); +} diff --git a/Linphone/core/conference/ConferenceGui.hpp b/Linphone/core/conference/ConferenceGui.hpp new file mode 100644 index 000000000..62f77ca6f --- /dev/null +++ b/Linphone/core/conference/ConferenceGui.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 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, see . + */ + +#ifndef CONFERENCE_GUI_H_ +#define CONFERENCE_GUI_H_ + +#include "tool/AbstractObject.hpp" +#include +#include + +class ConferenceCore; + +class ConferenceGui : public QObject, public AbstractObject { + Q_OBJECT + + Q_PROPERTY(ConferenceCore *core READ getCore CONSTANT) + +public: + ConferenceGui(); + ConferenceGui(QSharedPointer core); + ~ConferenceGui(); + ConferenceCore *getCore() const; + QSharedPointer mCore; + DECLARE_ABSTRACT_OBJECT +}; + +#endif diff --git a/Linphone/model/call/CallModel.cpp b/Linphone/model/call/CallModel.cpp index 969bddbff..d9aa61d34 100644 --- a/Linphone/model/call/CallModel.cpp +++ b/Linphone/model/call/CallModel.cpp @@ -30,6 +30,7 @@ DEFINE_ABSTRACT_OBJECT(CallModel) CallModel::CallModel(const std::shared_ptr &call, QObject *parent) : ::Listener(call, parent) { + qDebug() << "[CallModel] new" << this; mustBeInLinphoneThread(getClassName()); mDurationTimer.setInterval(1000); mDurationTimer.setSingleShot(false); @@ -227,6 +228,13 @@ std::string CallModel::getAuthenticationToken() const { return token; } +void CallModel::setConference(const std::shared_ptr &conference) { + if (mConference != conference) { + mConference = conference; + emit conferenceChanged(); + } +} + void CallModel::onDtmfReceived(const std::shared_ptr &call, int dtmf) { emit dtmfReceived(call, dtmf); } @@ -263,6 +271,7 @@ void CallModel::onStateChanged(const std::shared_ptr &call, auto params = call->getRemoteParams(); emit remoteVideoEnabledChanged(params && params->videoEnabled()); emit cameraEnabledChanged(call->cameraEnabled()); + setConference(call->getConference()); } emit stateChanged(state, message); } diff --git a/Linphone/model/call/CallModel.hpp b/Linphone/model/call/CallModel.hpp index 5d4d45b3f..1cdb79d63 100644 --- a/Linphone/model/call/CallModel.hpp +++ b/Linphone/model/call/CallModel.hpp @@ -52,6 +52,7 @@ public: std::shared_ptr getInputAudioDevice() const; void setOutputAudioDevice(const std::shared_ptr &id); std::shared_ptr getOutputAudioDevice() const; + void setConference(const std::shared_ptr &conference); void setPaused(bool paused); void transferTo(const std::shared_ptr &address); @@ -80,10 +81,13 @@ signals: void microphoneVolumeGainChanged(float volume); void inputAudioDeviceChanged(const std::string &id); void outputAudioDeviceChanged(const std::string &id); + void conferenceChanged(); private: QTimer mDurationTimer; QTimer mMicroVolumeTimer; + std::shared_ptr mConference; + DECLARE_ABSTRACT_OBJECT //-------------------------------------------------------------------------------- diff --git a/Linphone/model/conference/ConferenceModel.cpp b/Linphone/model/conference/ConferenceModel.cpp index 38232b1f1..e200a4f6d 100644 --- a/Linphone/model/conference/ConferenceModel.cpp +++ b/Linphone/model/conference/ConferenceModel.cpp @@ -30,6 +30,7 @@ DEFINE_ABSTRACT_OBJECT(ConferenceModel) ConferenceModel::ConferenceModel(const std::shared_ptr &conference, QObject *parent) : ::Listener(conference, parent) { mustBeInLinphoneThread(getClassName()); + qDebug() << "[ConferenceModel] new" << this; } ConferenceModel::~ConferenceModel() { diff --git a/Linphone/view/App/CallsWindow.qml b/Linphone/view/App/CallsWindow.qml index f04ccca01..38e4497d3 100644 --- a/Linphone/view/App/CallsWindow.qml +++ b/Linphone/view/App/CallsWindow.qml @@ -15,6 +15,7 @@ Window { // modality: Qt.WindowModal property CallGui call + property ConferenceGui conference: call && call.core.conference || null property bool callTerminatedByUser: false Connections { @@ -46,7 +47,7 @@ Window { } } else if (callState === LinphoneEnums.CallState.Error || callState === LinphoneEnums.CallState.End) { - endCall(call) + callEnded(call) } } property var transferState: call.core.transferState @@ -78,10 +79,12 @@ Window { function endCall(callToFinish) { if (callToFinish) callToFinish.core.lTerminate() + } + function callEnded(){ if (!callsModel.haveCall) { bottomButtonsLayout.setButtonsEnabled(false) autoCloseWindow.restart() - } else if (callToFinish.core === mainWindow.call.core) { + } else { mainWindow.call = callsModel.currentCall } } @@ -230,7 +233,9 @@ Window { : (mainWindow.call.core.state === LinphoneEnums.CallState.Paused || mainWindow.call.core.state === LinphoneEnums.CallState.PausedByRemote) ? qsTr("Appel mis en pause") - : EnumsToStringCpp.dirToString(mainWindow.call.core.dir) + qsTr(" call") + : mainWindow.conference + ? mainWindow.conference.core.subject + : EnumsToStringCpp.dirToString(mainWindow.call.core.dir) + qsTr(" call") color: DefaultStyle.grey_0 font { pixelSize: 22 * DefaultStyle.dp diff --git a/Linphone/view/Layout/Contact/ContactLayout.qml b/Linphone/view/Layout/Contact/ContactLayout.qml index 699bd3099..415449313 100644 --- a/Linphone/view/Layout/Contact/ContactLayout.qml +++ b/Linphone/view/Layout/Contact/ContactLayout.qml @@ -128,7 +128,7 @@ ColumnLayout { label: qsTr("Appel") property var callObj button.onClicked: { - var addr = UtilsCpp.generateLinphoneSipAddress(mainItem.contact.core.defaultAddress) + var addr = UtilsCpp.generateLinphoneSipAddress(mainItem.contactAddress) callObj = UtilsCpp.createCall(addr) } } @@ -153,7 +153,7 @@ ColumnLayout { label: qsTr("Appel Video") property var callObj button.onClicked: { - var addr = UtilsCpp.generateLinphoneSipAddress(mainItem.contact.core.defaultAddress) + var addr = UtilsCpp.generateLinphoneSipAddress(mainItem.contactAddress) callObj = UtilsCpp.createCall(addr) console.log("[CallPage.qml] TODO : enable video") } diff --git a/Linphone/view/Page/Main/MeetingPage.qml b/Linphone/view/Page/Main/MeetingPage.qml index ef370d3fb..04d04af94 100644 --- a/Linphone/view/Page/Main/MeetingPage.qml +++ b/Linphone/view/Page/Main/MeetingPage.qml @@ -216,7 +216,7 @@ AbstractMainPage { Layout.preferredHeight: 24 * DefaultStyle.dp } Text { - text: mainItem.selectedConference.core.subject + text: mainItem.selectedConference && mainItem.selectedConference.core.subject font { pixelSize: 20 * DefaultStyle.dp weight: 800 * DefaultStyle.dp @@ -287,7 +287,7 @@ AbstractMainPage { } Button { Layout.fillWidth: true - text: mainItem.selectedConference.core.uri + text: mainItem.selectedConference && mainItem.selectedConference.core.uri textSize: 14 * DefaultStyle.dp textWeight: 400 * DefaultStyle.dp underline: true @@ -314,10 +314,12 @@ AbstractMainPage { source: AppIcons.clock } Text { - text: UtilsCpp.toDateString(mainItem.selectedConference.core.dateTimeUtc) - + " | " + UtilsCpp.toDateHourString(mainItem.selectedConference.core.dateTimeUtc) - + " - " - + UtilsCpp.toDateHourString(mainItem.selectedConference.core.endDateTime) + text: mainItem.selectedConference + ? UtilsCpp.toDateString(mainItem.selectedConference.core.dateTimeUtc) + + " | " + UtilsCpp.toDateHourString(mainItem.selectedConference.core.dateTimeUtc) + + " - " + + UtilsCpp.toDateHourString(mainItem.selectedConference.core.endDateTime) + : '' font { pixelSize: 14 * DefaultStyle.dp capitalization: Font.Capitalize @@ -332,7 +334,7 @@ AbstractMainPage { source: AppIcons.globe } Text { - text: qsTr("Time zone: ") + mainItem.selectedConference.core.timeZoneModel.displayName + ", " + mainItem.selectedConference.core.timeZoneModel.countryName + text: qsTr("Time zone: ") + (mainItem.selectedConference && (mainItem.selectedConference.core.timeZoneModel.displayName + ", " + mainItem.selectedConference.core.timeZoneModel.countryName)) font { pixelSize: 14 * DefaultStyle.dp capitalization: Font.Capitalize @@ -342,7 +344,7 @@ AbstractMainPage { } } Section { - visible: mainItem.selectedConference.core.description.length != 0 + visible: mainItem.selectedConference && mainItem.selectedConference.core.description.length != 0 content: RowLayout { spacing: 8 * DefaultStyle.dp EffectImage { @@ -352,7 +354,7 @@ AbstractMainPage { colorizationColor: DefaultStyle.main2_600 } Text { - text: mainItem.selectedConference.core.description + text: mainItem.selectedConference && mainItem.selectedConference.core.description Layout.fillWidth: true font { pixelSize: 14 * DefaultStyle.dp @@ -373,10 +375,10 @@ AbstractMainPage { Avatar { Layout.preferredWidth: 45 * DefaultStyle.dp Layout.preferredHeight: 45 * DefaultStyle.dp - address: mainItem.selectedConference.core.organizerAddress + address: mainItem.selectedConference && mainItem.selectedConference.core.organizerAddress } Text { - text: mainItem.selectedConference.core.organizerName + text: mainItem.selectedConference && mainItem.selectedConference.core.organizerName font { pixelSize: 14 * DefaultStyle.dp capitalization: Font.Capitalize @@ -400,7 +402,7 @@ AbstractMainPage { id: participantList Layout.preferredHeight: Math.min(184 * DefaultStyle.dp, contentHeight) Layout.fillWidth: true - model: mainItem.selectedConference.core.participants + model: mainItem.selectedConference && mainItem.selectedConference.core.participants || [] clip: true delegate: RowLayout { height: 56 * DefaultStyle.dp @@ -420,7 +422,7 @@ AbstractMainPage { } Text { text: qsTr("Organizer") - visible: mainItem.selectedConference.core.organizerAddress === modelData.address + visible: mainItem.selectedConference && mainItem.selectedConference.core.organizerAddress === modelData.address color: DefaultStyle.main2_400 font { pixelSize: 12 * DefaultStyle.dp @@ -432,11 +434,16 @@ AbstractMainPage { } } Button { + property var callObj Layout.fillWidth: true text: qsTr("Rejoindre la réunion") topPadding: 11 * DefaultStyle.dp bottomPadding: 11 * DefaultStyle.dp - onClicked: console.log("TODO: join conf", mainItem.selectedConference.core.subject) + onClicked: { + console.log("TODO: join conf", mainItem.selectedConference.core.subject) + console.log(mainItem.selectedConference.core.uri) + callObj = UtilsCpp.createCall(mainItem.selectedConference.core.uri) + } } } }