diff --git a/Linphone/core/participant/ParticipantCore.cpp b/Linphone/core/participant/ParticipantCore.cpp index 2324a8ef8..0f8387d44 100644 --- a/Linphone/core/participant/ParticipantCore.cpp +++ b/Linphone/core/participant/ParticipantCore.cpp @@ -87,7 +87,7 @@ int ParticipantCore::getDeviceCount() const { } bool ParticipantCore::isMe() const { - return true; // Utils::isMe(getSipAddress()); + return Utils::isMe(mSipAddress); } QString ParticipantCore::getSipAddress() const { @@ -121,7 +121,7 @@ void ParticipantCore::setCreationTime(const QDateTime &date) { } } -bool ParticipantCore::getAdminStatus() const { +bool ParticipantCore::isAdmin() const { return mAdminStatus; } @@ -129,10 +129,10 @@ bool ParticipantCore::isFocus() const { return mIsFocus; } -void ParticipantCore::setAdminStatus(const bool &status) { +void ParticipantCore::setIsAdmin(const bool &status) { if (status != mAdminStatus) { mAdminStatus = status; - emit adminStatusChanged(); + emit isAdminChanged(); } } diff --git a/Linphone/core/participant/ParticipantCore.hpp b/Linphone/core/participant/ParticipantCore.hpp index 52eb501b8..ff675f588 100644 --- a/Linphone/core/participant/ParticipantCore.hpp +++ b/Linphone/core/participant/ParticipantCore.hpp @@ -41,7 +41,7 @@ class ParticipantCore : public QObject, public AbstractObject { // Q_PROPERTY(FriendCore *friendCore READ getFriendCore CONSTANT) Q_PROPERTY(QString sipAddress READ getSipAddress WRITE setSipAddress NOTIFY sipAddressChanged) Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged) - Q_PROPERTY(bool adminStatus READ getAdminStatus WRITE setAdminStatus NOTIFY adminStatusChanged) + Q_PROPERTY(bool isAdmin READ isAdmin WRITE setIsAdmin NOTIFY isAdminChanged) Q_PROPERTY(bool isMe READ isMe CONSTANT) Q_PROPERTY(QDateTime creationTime READ getCreationTime CONSTANT) Q_PROPERTY(bool focus READ isFocus CONSTANT) @@ -62,7 +62,7 @@ public: QString getDisplayName() const; QString getSipAddress() const; QDateTime getCreationTime() const; - bool getAdminStatus() const; + bool isAdmin() const; bool isFocus() const; int getSecurityLevel() const; int getDeviceCount() const; @@ -72,7 +72,7 @@ public: void setSipAddress(const QString &address); void setDisplayName(const QString &name); void setCreationTime(const QDateTime &date); - void setAdminStatus(const bool &status); + void setIsAdmin(const bool &status); void setIsFocus(const bool &focus); void setSecurityLevel(int level); @@ -88,10 +88,7 @@ signals: void securityLevelChanged(); void deviceSecurityLevelChanged(std::shared_ptr device); void sipAddressChanged(); - void updateAdminStatus( - const std::shared_ptr participant, - const bool &isAdmin); // Split in two signals in order to sequancialize execution between SDK and GUI - void adminStatusChanged(); + void isAdminChanged(); void isFocusChanged(); void deviceCountChanged(); void invitingChanged(); @@ -99,6 +96,7 @@ signals: void displayNameChanged(); void lStartInvitation(const int &secs); + void lSetIsAdmin(bool status); void invitationTimeout(ParticipantCore *model); diff --git a/Linphone/core/participant/ParticipantDeviceCore.cpp b/Linphone/core/participant/ParticipantDeviceCore.cpp index df7d25f0f..6788963ae 100644 --- a/Linphone/core/participant/ParticipantDeviceCore.cpp +++ b/Linphone/core/participant/ParticipantDeviceCore.cpp @@ -20,6 +20,7 @@ #include "ParticipantDeviceCore.hpp" #include "core/App.hpp" +#include "model/object/VariantObject.hpp" #include "model/tool/ToolModel.hpp" #include "tool/Utils.hpp" #include @@ -42,16 +43,22 @@ ParticipantDeviceCore::ParticipantDeviceCore(const std::shared_ptrmEngine->setObjectOwnership(this, QQmlEngine::CppOwnership); mustBeInLinphoneThread(getClassName()); mName = Utils::coreStringToAppString(device->getName()); - mDisplayName = Utils::coreStringToAppString(device->getAddress()->getDisplayName()); - mAddress = Utils::coreStringToAppString(device->getAddress()->asStringUriOnly()); + auto deviceAddress = device->getAddress(); + mUniqueAddress = Utils::coreStringToAppString(deviceAddress->asString()); + mAddress = Utils::coreStringToAppString(deviceAddress->asStringUriOnly()); + mDisplayName = Utils::coreStringToAppString(deviceAddress->getDisplayName()); + if (mDisplayName.isEmpty()) { + auto name = Utils::getDisplayName(mAddress); + if (name) mDisplayName = name->getValue().toString(); + } mIsMuted = device->getIsMuted(); mIsMe = isMe; mIsSpeaking = device->getIsSpeaking(); mParticipantDeviceModel = Utils::makeQObject_ptr(device); mParticipantDeviceModel->setSelf(mParticipantDeviceModel); mState = LinphoneEnums::fromLinphone(device->getState()); - qDebug() << "Address = " << Utils::coreStringToAppString(device->getAddress()->asStringUriOnly()); - mIsLocal = ToolModel::findAccount(device->getAddress()) != nullptr; // TODO set local + qDebug() << "Address = " << Utils::coreStringToAppString(deviceAddress->asStringUriOnly()); + mIsLocal = ToolModel::findAccount(deviceAddress) != nullptr; // TODO set local // mCall = callModel; // if (mCall) connect(mCall, &CallModel::statusChanged, this, &ParticipantDeviceCore::onCallStatusChanged); mIsVideoEnabled = mParticipantDeviceModel->isVideoEnabled(); @@ -116,6 +123,10 @@ QString ParticipantDeviceCore::getAddress() const { return mAddress; } +QString ParticipantDeviceCore::getUniqueAddress() const { + return mUniqueAddress; +} + bool ParticipantDeviceCore::getPaused() const { return mIsPaused; } diff --git a/Linphone/core/participant/ParticipantDeviceCore.hpp b/Linphone/core/participant/ParticipantDeviceCore.hpp index 9443abb64..ce62415ef 100644 --- a/Linphone/core/participant/ParticipantDeviceCore.hpp +++ b/Linphone/core/participant/ParticipantDeviceCore.hpp @@ -37,6 +37,7 @@ class ParticipantDeviceCore : public QObject, public AbstractObject { Q_PROPERTY(QString displayName READ getDisplayName CONSTANT) Q_PROPERTY(QString name READ getName CONSTANT) Q_PROPERTY(QString address READ getAddress CONSTANT) + Q_PROPERTY(QString uniqueAddress READ getUniqueAddress CONSTANT) Q_PROPERTY(int securityLevel READ getSecurityLevel NOTIFY securityLevelChanged) Q_PROPERTY(time_t timeOfJoining READ getTimeOfJoining CONSTANT) Q_PROPERTY(bool videoEnabled READ isVideoEnabled NOTIFY videoEnabledChanged) @@ -63,6 +64,7 @@ public: QString getName() const; QString getDisplayName() const; QString getAddress() const; + QString getUniqueAddress() const; int getSecurityLevel() const; time_t getTimeOfJoining() const; bool isVideoEnabled() const; @@ -112,6 +114,7 @@ signals: private: QString mName; QString mDisplayName; + QString mUniqueAddress; QString mAddress; bool mIsMe = false; bool mIsLocal = false; diff --git a/Linphone/core/participant/ParticipantDeviceList.cpp b/Linphone/core/participant/ParticipantDeviceList.cpp index 85580f3ab..c83ce6ab0 100644 --- a/Linphone/core/participant/ParticipantDeviceList.cpp +++ b/Linphone/core/participant/ParticipantDeviceList.cpp @@ -22,6 +22,7 @@ #include "core/App.hpp" #include "core/participant/ParticipantDeviceCore.hpp" #include "core/participant/ParticipantDeviceGui.hpp" +#include "tool/Utils.hpp" #include #include @@ -77,6 +78,18 @@ void ParticipantDeviceList::setDevices(QList ParticipantDeviceList::findDeviceByUniqueAddress(const QString &address) { + qDebug() << "address to find" << address; + auto found = std::find_if(mList.begin(), mList.end(), [address](const QSharedPointer &obj) { + auto device = qobject_cast>(obj); + qDebug() << "address" << device->getUniqueAddress(); + return device && device->getUniqueAddress() == address; + }); + if (found != mList.end()) { + return qobject_cast>(*found); + } else return nullptr; +} + void ParticipantDeviceList::setConferenceModel(const std::shared_ptr &conferenceModel) { mustBeInMainThread(log().arg(Q_FUNC_INFO)); mConferenceModel = conferenceModel; @@ -116,6 +129,16 @@ void ParticipantDeviceList::setSelf(QSharedPointer me) { this->add(deviceCore); }); }); + mConferenceModelConnection->makeConnectToModel( + &ConferenceModel::participantDeviceRemoved, + [this](const std::shared_ptr &participantDevice) { + QString uniqueAddress = Utils::coreStringToAppString(participantDevice->getAddress()->asString()); + auto deviceCore = findDeviceByUniqueAddress(uniqueAddress); + mConferenceModelConnection->invokeToCore([this, deviceCore]() { + qDebug() << "[ParticipantDeviceList] : remove a device"; + this->remove(deviceCore); + }); + }); mConferenceModelConnection->makeConnectToModel( &ConferenceModel::conferenceStateChanged, [this](linphone::Conference::State state) { qDebug() << "[ParticipantDeviceList] new state = " << (int)state; diff --git a/Linphone/core/participant/ParticipantDeviceList.hpp b/Linphone/core/participant/ParticipantDeviceList.hpp index 3a012890e..ae665eb85 100644 --- a/Linphone/core/participant/ParticipantDeviceList.hpp +++ b/Linphone/core/participant/ParticipantDeviceList.hpp @@ -43,6 +43,7 @@ public: QSharedPointer getMe() const; void setDevices(QList> devices); + QSharedPointer findDeviceByUniqueAddress(const QString &address); void setConferenceModel(const std::shared_ptr &conferenceModel); void setSelf(QSharedPointer me); diff --git a/Linphone/core/participant/ParticipantList.cpp b/Linphone/core/participant/ParticipantList.cpp index 2cbdcafae..003fad24a 100644 --- a/Linphone/core/participant/ParticipantList.cpp +++ b/Linphone/core/participant/ParticipantList.cpp @@ -36,55 +36,14 @@ QSharedPointer ParticipantList::create() { return model; } -// ParticipantList::ParticipantList(ChatRoomModel *chatRoomModel, QObject *parent) : ProxyListModel(parent) { -// if (chatRoomModel) { -// mChatRoomModel = chatRoomModel; - -// connect(mChatRoomModel, &ChatRoomModel::securityEvent, this, &ParticipantList::onSecurityEvent); -// connect(mChatRoomModel, &ChatRoomModel::conferenceJoined, this, &ParticipantList::onConferenceJoined); -// connect(mChatRoomModel, &ChatRoomModel::participantAdded, this, -// QOverload &>::of( -// &ParticipantList::onParticipantAdded)); -// connect(mChatRoomModel, &ChatRoomModel::participantRemoved, this, -// QOverload &>::of( -// &ParticipantList::onParticipantRemoved)); -// connect(mChatRoomModel, &ChatRoomModel::participantAdminStatusChanged, this, -// QOverload &>::of( -// &ParticipantList::onParticipantAdminStatusChanged)); -// connect(mChatRoomModel, &ChatRoomModel::participantDeviceAdded, this, -// &ParticipantList::onParticipantDeviceAdded); -// connect(mChatRoomModel, &ChatRoomModel::participantDeviceRemoved, this, -// &ParticipantList::onParticipantDeviceRemoved); -// connect(mChatRoomModel, &ChatRoomModel::participantRegistrationSubscriptionRequested, this, -// &ParticipantList::onParticipantRegistrationSubscriptionRequested); -// connect(mChatRoomModel, &ChatRoomModel::participantRegistrationUnsubscriptionRequested, this, -// &ParticipantList::onParticipantRegistrationUnsubscriptionRequested); - -// updateParticipants(); -// } -// } - -// ParticipantList::ParticipantList(ConferenceModel *conferenceModel, QObject *parent) : ListProxy(parent) { -// if (conferenceModel) { -// mConferenceModel = conferenceModel; - -// connect(mConferenceModel, &ConferenceModel::participantAdded, this, -// QOverload &>::of( -// &ParticipantList::onParticipantAdded)); -// connect(mConferenceModel, &ConferenceModel::participantRemoved, this, -// QOverload &>::of( -// &ParticipantList::onParticipantRemoved)); -// connect(mConferenceModel, &ConferenceModel::participantAdminStatusChanged, this, -// QOverload &>::of( -// &ParticipantList::onParticipantAdminStatusChanged)); -// connect(mConferenceModel, &ConferenceModel::conferenceStateChanged, this, -// &ParticipantList::onStateChanged); - -// updateParticipants(); -// } -// } +QSharedPointer ParticipantList::create(const std::shared_ptr &conferenceModel) { + auto model = create(); + model->setConferenceModel(conferenceModel); + return model; +} ParticipantList::ParticipantList(QObject *parent) : ListProxy(parent) { + App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership); } ParticipantList::~ParticipantList() { @@ -94,33 +53,74 @@ ParticipantList::~ParticipantList() { } void ParticipantList::setSelf(QSharedPointer me) { - mModelConnection = QSharedPointer>( + if (mConferenceModelConnection) mConferenceModelConnection->disconnect(); + mConferenceModelConnection = QSharedPointer>( new SafeConnection(me, mConferenceModel), &QObject::deleteLater); - - mModelConnection->makeConnectToCore(&ParticipantList::lUpdateParticipants, [this] { - mModelConnection->invokeToModel([this]() { - QList> *participantList = new QList>(); - mustBeInLinphoneThread(getClassName()); - std::list> participants; - participants = mConferenceModel->getMonitor()->getParticipantList(); - for (auto it : participants) { - auto model = ParticipantCore::create(it); - participantList->push_back(model); - } - mModelConnection->invokeToCore([this, participantList]() { - mustBeInMainThread(getClassName()); - resetData(); - add(*participantList); - delete participantList; + if (mConferenceModel) { + mConferenceModelConnection->makeConnectToCore(&ParticipantList::lUpdateParticipants, [this] { + mConferenceModelConnection->invokeToModel([this]() { + QList> *participantList = new QList>(); + mustBeInLinphoneThread(getClassName()); + std::list> participants; + participants = mConferenceModel->getMonitor()->getParticipantList(); + for (auto it : participants) { + auto model = ParticipantCore::create(it); + participantList->push_back(model); + } + auto me = mConferenceModel->getMonitor()->getMe(); + auto meModel = ParticipantCore::create(me); + participantList->push_back(meModel); + mConferenceModelConnection->invokeToCore([this, participantList]() { + mustBeInMainThread(getClassName()); + resetData(); + add(*participantList); + delete participantList; + }); }); }); - }); - mModelConnection->makeConnectToModel(&ConferenceModel::participantAdded, &ParticipantList::lUpdateParticipants); - mModelConnection->makeConnectToModel(&ConferenceModel::participantRemoved, &ParticipantList::lUpdateParticipants); + mConferenceModelConnection->makeConnectToCore( + &ParticipantList::lSetParticipantAdminStatus, [this](ParticipantCore *participant, bool status) { + auto address = participant->getSipAddress(); + mConferenceModelConnection->invokeToModel([this, address, status] { + auto participants = mConferenceModel->getMonitor()->getParticipantList(); + for (auto &participant : participants) { + if (Utils::coreStringToAppString(participant->getAddress()->asStringUriOnly()) == address) { + mConferenceModel->setParticipantAdminStatus(participant, status); + return; + } + } + }); + }); + + mConferenceModelConnection->makeConnectToModel(&ConferenceModel::participantAdminStatusChanged, + &ParticipantList::lUpdateParticipants); + + mConferenceModelConnection->makeConnectToModel(&ConferenceModel::participantAdded, + &ParticipantList::lUpdateParticipants); + mConferenceModelConnection->makeConnectToModel(&ConferenceModel::participantRemoved, + &ParticipantList::lUpdateParticipants); + } emit lUpdateParticipants(); } +void ParticipantList::setConferenceModel(const std::shared_ptr &conferenceModel) { + mustBeInMainThread(log().arg(Q_FUNC_INFO)); + mConferenceModel = conferenceModel; + qDebug() << "[ParticipantList] : set Conference " << mConferenceModel.get(); + if (mConferenceModelConnection && mConferenceModelConnection->mCore.lock()) { // Unsure to get myself + auto oldConnect = mConferenceModelConnection->mCore; // Setself rebuild safepointer + setSelf(mConferenceModelConnection->mCore.mQData); // reset connections + oldConnect.unlock(); + } + beginResetModel(); + mList.clear(); + endResetModel(); + if (mConferenceModel) { + emit lUpdateParticipants(); + } +} + QVariant ParticipantList::data(const QModelIndex &index, int role) const { int row = index.row(); if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant(); @@ -138,48 +138,6 @@ std::list> ParticipantList::getParticipants() return participants; } -QString ParticipantList::addressesToString() const { - QStringList txt; - for (auto item : mList) { - auto participant = item.objectCast(); - if (participant) { - - // chat room yet. - txt << participant->getSipAddress(); - // txt << Utils::toDisplayString(Utils::coreStringToAppString(address->asStringUriOnly()), - // CoreModel::getInstance()->getSettingsModel()->getSipDisplayMode()); - } - } - if (txt.size() > 0) txt.removeFirst(); // Remove me - return txt.join(", "); -} - -QString ParticipantList::displayNamesToString() const { - QStringList txt; - for (auto item : mList) { - auto participant = item.objectCast(); - if (participant) { - QString displayName = participant->getSipAddress(); - if (displayName != "") txt << displayName; - } - } - if (txt.size() > 0) txt.removeFirst(); // Remove me - return txt.join(", "); -} - -QString ParticipantList::usernamesToString() const { - QStringList txt; - for (auto item : mList) { - auto participant = item.objectCast(); - if (participant) { - auto username = participant->getDisplayName(); - txt << username; - } - } - if (txt.size() > 0) txt.removeFirst(); // Remove me - return txt.join(", "); -} - bool ParticipantList::contains(const QString &address) const { auto testAddress = ToolModel::interpretUrl(address); bool exists = false; @@ -313,94 +271,95 @@ void ParticipantList::remove(ParticipantCore *participant) { //------------------------------------------------------------- -void ParticipantList::setAdminStatus(const std::shared_ptr participant, const bool &isAdmin) { - // if (mChatRoomModel) mChatRoomModel->getChatRoom()->setParticipantAdminStatus(participant, isAdmin); - // if (mConferenceModel) mConferenceModel->getConference()->setParticipantAdminStatus(participant, isAdmin); -} +// void ParticipantList::setAdminStatus(const std::shared_ptr participant, const bool &isAdmin) { +// // if (mChatRoomModel) mChatRoomModel->getChatRoom()->setParticipantAdminStatus(participant, isAdmin); +// // if (mConferenceModel) mConferenceModel->getConference()->setParticipantAdminStatus(participant, isAdmin); +// } -void ParticipantList::onSecurityEvent(const std::shared_ptr &eventLog) { - auto address = eventLog->getParticipantAddress(); - if (address) { - // auto participant = getParticipant(address); - // if (participant) { - // emit participant->securityLevelChanged(); - // } - } else { - address = eventLog->getDeviceAddress(); - // Looping on all participant ensure to get all devices. Can be optimized if Device address is unique : Gain - // 2n operations. - if (address) emit deviceSecurityLevelChanged(address); - } -} +// void ParticipantList::onSecurityEvent(const std::shared_ptr &eventLog) { +// auto address = eventLog->getParticipantAddress(); +// if (address) { +// // auto participant = getParticipant(address); +// // if (participant) { +// // emit participant->securityLevelChanged(); +// // } +// } else { +// address = eventLog->getDeviceAddress(); +// // Looping on all participant ensure to get all devices. Can be optimized if Device address is unique : Gain +// // 2n operations. +// if (address) emit deviceSecurityLevelChanged(address); +// } +// } -void ParticipantList::onConferenceJoined() { - // updateParticipants(); -} +// void ParticipantList::onConferenceJoined() { +// // updateParticipants(); +// } -void ParticipantList::onParticipantAdded(const std::shared_ptr &eventLog) { - qDebug() << "onParticipantAdded event: " << eventLog->getParticipantAddress()->asString().c_str(); - // add(eventLog->getParticipantAddress()); -} +// void ParticipantList::onParticipantAdded(const std::shared_ptr &eventLog) { +// qDebug() << "onParticipantAdded event: " << eventLog->getParticipantAddress()->asString().c_str(); +// // add(eventLog->getParticipantAddress()); +// } -void ParticipantList::onParticipantAdded(const std::shared_ptr &participant) { - qDebug() << "onParticipantAdded part: " << participant->getAddress()->asString().c_str(); - // add(participant); -} +// void ParticipantList::onParticipantAdded(const std::shared_ptr &participant) { +// qDebug() << "onParticipantAdded part: " << participant->getAddress()->asString().c_str(); +// // add(participant); +// } -void ParticipantList::onParticipantAdded(const std::shared_ptr &address) { - qDebug() << "onParticipantAdded addr: " << address->asString().c_str(); - // add(address); -} +// void ParticipantList::onParticipantAdded(const std::shared_ptr &address) { +// qDebug() << "onParticipantAdded addr: " << address->asString().c_str(); +// // add(address); +// } -void ParticipantList::onParticipantRemoved(const std::shared_ptr &eventLog) { - onParticipantRemoved(eventLog->getParticipantAddress()); -} +// void ParticipantList::onParticipantRemoved(const std::shared_ptr &eventLog) { +// onParticipantRemoved(eventLog->getParticipantAddress()); +// } -void ParticipantList::onParticipantRemoved(const std::shared_ptr &participant) { - // auto p = getParticipant(participant); - // if (p) remove(p.get()); -} +// void ParticipantList::onParticipantRemoved(const std::shared_ptr &participant) { +// // auto p = getParticipant(participant); +// // if (p) remove(p.get()); +// } -void ParticipantList::onParticipantRemoved(const std::shared_ptr &address) { - // auto participant = getParticipant(address); - // if (participant) remove(participant.get()); -} +// void ParticipantList::onParticipantRemoved(const std::shared_ptr &address) { +// // auto participant = getParticipant(address); +// // if (participant) remove(participant.get()); +// } -void ParticipantList::onParticipantAdminStatusChanged(const std::shared_ptr &eventLog) { - onParticipantAdminStatusChanged(eventLog->getParticipantAddress()); -} -void ParticipantList::onParticipantAdminStatusChanged(const std::shared_ptr &participant) { - // auto p = getParticipant(participant); - // if (participant) emit p->adminStatusChanged(); // Request to participant to update its status from its data -} -void ParticipantList::onParticipantAdminStatusChanged(const std::shared_ptr &address) { - // auto participant = getParticipant(address); - // if (participant) - // emit participant->adminStatusChanged(); // Request to participant to update its status from its data -} -void ParticipantList::onParticipantDeviceAdded(const std::shared_ptr &eventLog) { - // auto participant = getParticipant(eventLog->getParticipantAddress()); - // if (participant) { - // emit participant->deviceCountChanged(); - // } -} -void ParticipantList::onParticipantDeviceRemoved(const std::shared_ptr &eventLog) { - // auto participant = getParticipant(eventLog->getParticipantAddress()); - // if (participant) { - // emit participant->deviceCountChanged(); - // } -} -void ParticipantList::onParticipantRegistrationSubscriptionRequested( - const std::shared_ptr &participantAddress) { -} -void ParticipantList::onParticipantRegistrationUnsubscriptionRequested( - const std::shared_ptr &participantAddress) { -} +// void ParticipantList::onParticipantAdminStatusChanged(const std::shared_ptr &eventLog) { +// onParticipantAdminStatusChanged(eventLog->getParticipantAddress()); +// } +// void ParticipantList::onParticipantAdminStatusChanged(const std::shared_ptr +// &participant) { +// // auto p = getParticipant(participant); +// // if (participant) emit p->adminStatusChanged(); // Request to participant to update its status from its data +// } +// void ParticipantList::onParticipantAdminStatusChanged(const std::shared_ptr &address) { +// // auto participant = getParticipant(address); +// // if (participant) +// // emit participant->adminStatusChanged(); // Request to participant to update its status from its data +// } +// void ParticipantList::onParticipantDeviceAdded(const std::shared_ptr &eventLog) { +// // auto participant = getParticipant(eventLog->getParticipantAddress()); +// // if (participant) { +// // emit participant->deviceCountChanged(); +// // } +// } +// void ParticipantList::onParticipantDeviceRemoved(const std::shared_ptr &eventLog) { +// // auto participant = getParticipant(eventLog->getParticipantAddress()); +// // if (participant) { +// // emit participant->deviceCountChanged(); +// // } +// } +// void ParticipantList::onParticipantRegistrationSubscriptionRequested( +// const std::shared_ptr &participantAddress) { +// } +// void ParticipantList::onParticipantRegistrationUnsubscriptionRequested( +// const std::shared_ptr &participantAddress) { +// } -void ParticipantList::onStateChanged() { - // if (mConferenceModel) { - // if (mConferenceModel->getConference()->getState() == linphone::Conference::State::Created) { - // updateParticipants(); - // } - // } -} +// void ParticipantList::onStateChanged() { +// // if (mConferenceModel) { +// // if (mConferenceModel->getConference()->getState() == linphone::Conference::State::Created) { +// // updateParticipants(); +// // } +// // } +// } diff --git a/Linphone/core/participant/ParticipantList.hpp b/Linphone/core/participant/ParticipantList.hpp index 898356c9b..2fcd5ac74 100644 --- a/Linphone/core/participant/ParticipantList.hpp +++ b/Linphone/core/participant/ParticipantList.hpp @@ -33,6 +33,7 @@ class ParticipantList : public ListProxy, public AbstractObject { Q_OBJECT public: static QSharedPointer create(); + static QSharedPointer create(const std::shared_ptr &conferenceModel); // ParticipantList(ChatRoomModel *chatRoomModel, QObject *parent = Q_NULLPTR); // ParticipantList(ConferenceModel *conferenceModel, QObject *parent = Q_NULLPTR); @@ -42,10 +43,6 @@ public: void setSelf(QSharedPointer me); // Q_PROPERTY(ChatRoomModel *chatRoomModel READ getChatRoomModel CONSTANT) - Q_PROPERTY(QString addressesToString READ addressesToString NOTIFY participantsChanged) - Q_PROPERTY(QString displayNamesToString READ displayNamesToString NOTIFY participantsChanged) - Q_PROPERTY(QString usernamesToString READ usernamesToString NOTIFY participantsChanged) - void reset(); // void updateParticipants(); // Update list from Chat Room // const QSharedPointer @@ -56,35 +53,32 @@ public: Q_INVOKABLE void remove(ParticipantCore *participant); std::list> getParticipants() const; - Q_INVOKABLE QString addressesToString() const; - Q_INVOKABLE QString displayNamesToString() const; - Q_INVOKABLE QString usernamesToString() const; - bool contains(const QString &address) const; + void setConferenceModel(const std::shared_ptr &conferenceModel); + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; -public slots: - void setAdminStatus(const std::shared_ptr participant, const bool &isAdmin); + // public slots: + // void setAdminStatus(const std::shared_ptr participant, const bool &isAdmin); - void onSecurityEvent(const std::shared_ptr &eventLog); - void onConferenceJoined(); - void onParticipantAdded(const std::shared_ptr &participant); - void onParticipantAdded(const std::shared_ptr &eventLog); - void onParticipantAdded(const std::shared_ptr &address); - void onParticipantRemoved(const std::shared_ptr &participant); - void onParticipantRemoved(const std::shared_ptr &eventLog); - void onParticipantRemoved(const std::shared_ptr &address); - void onParticipantAdminStatusChanged(const std::shared_ptr &participant); - void onParticipantAdminStatusChanged(const std::shared_ptr &eventLog); - void onParticipantAdminStatusChanged(const std::shared_ptr &address); - void onParticipantDeviceAdded(const std::shared_ptr &eventLog); - void onParticipantDeviceRemoved(const std::shared_ptr &eventLog); - void - onParticipantRegistrationSubscriptionRequested(const std::shared_ptr &participantAddress); - void onParticipantRegistrationUnsubscriptionRequested( - const std::shared_ptr &participantAddress); - void onStateChanged(); + // void onSecurityEvent(const std::shared_ptr &eventLog); + // void onConferenceJoined(); + // void onParticipantAdded(const std::shared_ptr &participant); + // void onParticipantAdded(const std::shared_ptr &eventLog); + // void onParticipantAdded(const std::shared_ptr &address); + // void onParticipantRemoved(const std::shared_ptr &participant); + // void onParticipantRemoved(const std::shared_ptr &eventLog); + // void onParticipantRemoved(const std::shared_ptr &address); + // void onParticipantAdminStatusChanged(const std::shared_ptr &participant); + // void onParticipantAdminStatusChanged(const std::shared_ptr &eventLog); + // void onParticipantAdminStatusChanged(const std::shared_ptr &address); + // void onParticipantDeviceAdded(const std::shared_ptr &eventLog); + // void onParticipantDeviceRemoved(const std::shared_ptr &eventLog); + // void + // onParticipantRegistrationSubscriptionRequested(const std::shared_ptr + // &participantAddress); void onParticipantRegistrationUnsubscriptionRequested( const std::shared_ptr &participantAddress); void onStateChanged(); signals: void securityLevelChanged(); @@ -92,10 +86,11 @@ signals: void participantsChanged(); void lUpdateParticipants(); + void lSetParticipantAdminStatus(ParticipantCore *participant, bool status); private: std::shared_ptr mConferenceModel; - QSharedPointer> mModelConnection; + QSharedPointer> mConferenceModelConnection; // ChatRoomModel *mChatRoomModel = nullptr; // ConferenceCore *mConferenceCore = nullptr; diff --git a/Linphone/core/participant/ParticipantProxy.cpp b/Linphone/core/participant/ParticipantProxy.cpp index f01c9005d..0d2adb2a0 100644 --- a/Linphone/core/participant/ParticipantProxy.cpp +++ b/Linphone/core/participant/ParticipantProxy.cpp @@ -19,6 +19,7 @@ */ #include "ParticipantProxy.hpp" +#include "ParticipantList.hpp" // #include "core/conference/ConferenceCore.hpp" #include "model/core/CoreModel.hpp" @@ -31,19 +32,50 @@ // ============================================================================= -// ----------------------------------------------------------------------------- +DEFINE_ABSTRACT_OBJECT(ParticipantProxy) ParticipantProxy::ParticipantProxy(QObject *parent) : SortFilterProxy(parent) { - mList = ParticipantList::create(); - setSourceModel(mList.get()); + mParticipants = ParticipantList::create(); connect(this, &ParticipantProxy::chatRoomModelChanged, this, &ParticipantProxy::countChanged); connect(this, &ParticipantProxy::conferenceModelChanged, this, &ParticipantProxy::countChanged); + setSourceModel(mParticipants.get()); } ParticipantProxy::~ParticipantProxy() { setSourceModel(nullptr); } +CallGui *ParticipantProxy::getCurrentCall() const { + return mCurrentCall; +} + +void ParticipantProxy::setCurrentCall(CallGui *call) { + qDebug() << "[ParticipantProxy] set current call " << this << " => " << call; + if (mCurrentCall != call) { + CallCore *callCore = nullptr; + if (mCurrentCall) { + callCore = mCurrentCall->getCore(); + if (callCore) callCore->disconnect(mParticipants.get()); + callCore = nullptr; + } + mCurrentCall = call; + if (mCurrentCall) callCore = mCurrentCall->getCore(); + if (callCore) { + connect(callCore, &CallCore::conferenceChanged, mParticipants.get(), [this]() { + auto conference = mCurrentCall->getCore()->getConferenceCore(); + qDebug() << "[ParticipantDeviceProxy] set conference " << this << " => " << conference; + mParticipants->setConferenceModel(conference ? conference->getModel() : nullptr); + // mParticipants->lSetConferenceModel(conference ? conference->getModel() : nullptr); + }); + auto conference = callCore->getConferenceCore(); + qDebug() << "[ParticipantDeviceProxy] set conference " << this << " => " << conference; + mParticipants->setConferenceModel(conference ? conference->getModel() : nullptr); + // mParticipants->lSetConferenceModel(conference ? conference->getModel() : nullptr); + } + emit currentCallChanged(); + } +} + // ChatRoomModel *ParticipantProxy::getChatRoomModel() const { // return mChatRoomModel; // } @@ -52,21 +84,6 @@ ParticipantProxy::~ParticipantProxy() { // return mConferenceModel; // } -QStringList ParticipantProxy::getSipAddresses() const { - QStringList participants; - for (int i = 0; i < mList->rowCount(); ++i) - participants << mList->getAt(i)->getSipAddress(); - return participants; -} - -QVariantList ParticipantProxy::getParticipants() const { - QVariantList participants; - ParticipantList *list = qobject_cast(sourceModel()); - for (int i = 0; i < list->rowCount(); ++i) - participants << QVariant::fromValue(list->getAt(i).get()); - return participants; -} - bool ParticipantProxy::getShowMe() const { return mShowMe; } @@ -173,10 +190,14 @@ void ParticipantProxy::setShowMe(const bool &show) { void ParticipantProxy::removeParticipant(ParticipantCore *participant) { if (participant) { - mList->remove(participant); + mParticipants->remove(participant); } } +void ParticipantProxy::setParticipantAdminStatus(ParticipantCore *participant, bool status) { + emit mParticipants->lSetParticipantAdminStatus(participant, status); +} + // ----------------------------------------------------------------------------- bool ParticipantProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { diff --git a/Linphone/core/participant/ParticipantProxy.hpp b/Linphone/core/participant/ParticipantProxy.hpp index a49ae7328..e01888bba 100644 --- a/Linphone/core/participant/ParticipantProxy.hpp +++ b/Linphone/core/participant/ParticipantProxy.hpp @@ -22,6 +22,9 @@ #define PARTICIPANT_PROXY_H_ #include "../proxy/SortFilterProxy.hpp" +#include "core/call/CallGui.hpp" +#include "tool/AbstractObject.hpp" + #include class ParticipantCore; @@ -33,23 +36,24 @@ class ConferenceInfoModel; class QWindow; -class ParticipantProxy : public SortFilterProxy { +class ParticipantProxy : public SortFilterProxy, public AbstractObject { Q_OBJECT - + Q_PROPERTY(CallGui *currentCall READ getCurrentCall WRITE setCurrentCall NOTIFY currentCallChanged) Q_PROPERTY(bool showMe READ getShowMe WRITE setShowMe NOTIFY showMeChanged) public: ParticipantProxy(QObject *parent = Q_NULLPTR); ~ParticipantProxy(); + CallGui *getCurrentCall() const; + void setCurrentCall(CallGui *callGui); + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; // ChatRoomModel *getChatRoomModel() const; // ConferenceModel *getConferenceModel() const; - Q_INVOKABLE QStringList getSipAddresses() const; - Q_INVOKABLE QVariantList getParticipants() const; bool getShowMe() const; // void setChatRoomModel(ChatRoomModel *chatRoomModel); @@ -58,6 +62,7 @@ public: // Q_INVOKABLE void addAddress(const QString &address); Q_INVOKABLE void removeParticipant(ParticipantCore *participant); + Q_INVOKABLE void setParticipantAdminStatus(ParticipantCore *participant, bool status); Q_INVOKABLE void setAddresses(ConferenceInfoModel *conferenceInfoModel); signals: @@ -68,12 +73,14 @@ signals: void showMeChanged(); void addressAdded(QString sipAddress); void addressRemoved(QString sipAddress); + void currentCallChanged(); private: // ChatRoomModel *mChatRoomModel = nullptr; - // ConferenceModel *mConferenceModel = nullptr; bool mShowMe = true; - QSharedPointer mList; + CallGui *mCurrentCall = nullptr; + QSharedPointer mParticipants; + DECLARE_ABSTRACT_OBJECT }; #endif // PARTICIPANT_PROXY_H_ diff --git a/Linphone/model/conference/ConferenceModel.cpp b/Linphone/model/conference/ConferenceModel.cpp index 2476a4cb6..6fcf4200a 100644 --- a/Linphone/model/conference/ConferenceModel.cpp +++ b/Linphone/model/conference/ConferenceModel.cpp @@ -117,6 +117,10 @@ void ConferenceModel::setRecordFile(const std::string &path) { // return volume; // } +void ConferenceModel::setParticipantAdminStatus(const std::shared_ptr participant, bool status) { + mMonitor->setParticipantAdminStatus(participant, status); +} + void ConferenceModel::setInputAudioDevice(const std::shared_ptr &device) { mMonitor->setInputAudioDevice(device); std::string deviceName; @@ -149,12 +153,12 @@ void ConferenceModel::onActiveSpeakerParticipantDevice( void ConferenceModel::onParticipantAdded(const std::shared_ptr &conference, const std::shared_ptr &participant) { - qDebug() << "onParticipantAdded: " << participant->getAddress()->asString().c_str(); + // qDebug() << "onParticipantAdded: " << participant->getAddress()->asString().c_str(); emit participantAdded(participant); } void ConferenceModel::onParticipantRemoved(const std::shared_ptr &conference, const std::shared_ptr &participant) { - qDebug() << "onParticipantRemoved"; + // qDebug() << "onParticipantRemoved"; emit participantRemoved(participant); } void ConferenceModel::onParticipantDeviceAdded(const std::shared_ptr &conference, diff --git a/Linphone/model/conference/ConferenceModel.hpp b/Linphone/model/conference/ConferenceModel.hpp index 3986189a6..9bc080b3c 100644 --- a/Linphone/model/conference/ConferenceModel.hpp +++ b/Linphone/model/conference/ConferenceModel.hpp @@ -43,6 +43,7 @@ public: void startRecording(); void stopRecording(); void setRecordFile(const std::string &path); + void setParticipantAdminStatus(const std::shared_ptr participant, bool status); void setInputAudioDevice(const std::shared_ptr &id); std::shared_ptr getInputAudioDevice() const; void setOutputAudioDevice(const std::shared_ptr &id); diff --git a/Linphone/model/participant/ParticipantModel.cpp b/Linphone/model/participant/ParticipantModel.cpp index d9f1447f2..a775253b0 100644 --- a/Linphone/model/participant/ParticipantModel.cpp +++ b/Linphone/model/participant/ParticipantModel.cpp @@ -28,8 +28,8 @@ DEFINE_ABSTRACT_OBJECT(ParticipantModel) ParticipantModel::ParticipantModel(std::shared_ptr linphoneParticipant, QObject *parent) : QObject(parent) { - assert(mParticipant); mParticipant = linphoneParticipant; + assert(mParticipant); } ParticipantModel::~ParticipantModel() { diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index a2eecc146..f1ded08b3 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -1201,15 +1201,5 @@ bool Utils::isMe(const QString &address) { // QDateTime dateTime(QDateTime::fromString(date, "yyyy-MM-dd hh:mm:ss")); // bool Utils::isMe(const QString &address) { -// return !address.isEmpty() ? isMe(Utils::interpretUrl(address)) : false; -// } - -// bool Utils::isMe(const std::shared_ptr &address) { -// if (!CoreModel::getInstance() -// ->getCore() -// ->getDefaultAccount()) { // Default account is selected : Me is all local accounts. -// return CoreModel::getInstance()->getAccountSettingsModel()->findAccount(address) != nullptr; -// } else -// return address ? CoreModel::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->weakEqual(address) -// : false; +// return !address.isEmpty() ? isMe(ToolModel::interpretUrl(address)) : false; // } diff --git a/Linphone/view/App/CallsWindow.qml b/Linphone/view/App/CallsWindow.qml index de8f504a1..79ef4ab24 100644 --- a/Linphone/view/App/CallsWindow.qml +++ b/Linphone/view/App/CallsWindow.qml @@ -131,7 +131,6 @@ Window { } } - component BottomButton : Button { id: bottomButton required property string enabledIcon @@ -379,7 +378,7 @@ Window { id: rightPanelTitle anchors.verticalCenter: parent.verticalCenter width: rightPanel.width - color: DefaultStyle.main2_700 + color: mainWindow.conference ? DefaultStyle.main1_500_main : DefaultStyle.main2_700 // text: qsTr("Transfert d'appel") font { pixelSize: 16 * DefaultStyle.dp @@ -581,6 +580,28 @@ Window { call: mainWindow.call } } + Component { + id: participantListPanel + StackLayout { + id: participantsStack + currentIndex: 0 + Control.StackView.onActivated: rightPanelTitle.text = qsTr("Participants (%1)").arg(count) + onCurrentIndexChanged: { + if (index === 0) rightPanelTitle.text = qsTr("Participants (%1)").arg(count) + else rightPanelTitle.text = qsTr("Ajouter des participants") + } + ParticipantList { + call: mainWindow.call + onCountChanged: if (Control.StackView.status === Control.StackView.Active) { + rightPanelTitle.text = qsTr("Participants (%1)").arg(count) + } + onAddParticipantRequested: participantsStack.currentIndex = 1 + } + AddParticipantLayout { + conferenceInfoGui: mainWindow.conferenceInfo + } + } + } } } } @@ -783,6 +804,21 @@ Window { Layout.preferredHeight: 55 * DefaultStyle.dp onCheckedChanged: mainWindow.call.core.lSetMicrophoneMuted(!mainWindow.call.core.microphoneMuted) } + CheckableButton { + iconUrl: AppIcons.usersTwo + checked: mainWindow.call && mainWindow.call.core.microphoneMuted + checkedColor: DefaultStyle.main2_400 + Layout.preferredWidth: 55 * DefaultStyle.dp + Layout.preferredHeight: 55 * DefaultStyle.dp + onCheckedChanged: { + if (checked) { + rightPanel.visible = true + rightPanel.replace(participantListPanel) + } else { + rightPanel.visible = false + } + } + } PopupButton { id: moreOptionsButton Layout.preferredWidth: 55 * DefaultStyle.dp diff --git a/Linphone/view/CMakeLists.txt b/Linphone/view/CMakeLists.txt index 5c389b28b..9dd8cbfa0 100644 --- a/Linphone/view/CMakeLists.txt +++ b/Linphone/view/CMakeLists.txt @@ -27,6 +27,9 @@ list(APPEND _LINPHONEAPP_QML_FILES view/Item/Notification/Notification.qml view/Item/Notification/NotificationReceivedCall.qml + view/Item/Participant/ParticipantDeviceList.qml + view/Item/Participant/ParticipantList.qml + view/Item/Prototype/CanvasCircle.qml view/Item/Contact/Avatar.qml diff --git a/Linphone/view/Item/Button.qml b/Linphone/view/Item/Button.qml index c0c2087a1..8dc82e144 100644 --- a/Linphone/view/Item/Button.qml +++ b/Linphone/view/Item/Button.qml @@ -13,6 +13,7 @@ Control.Button { property bool inversedColors: false property int textSize: 18 * DefaultStyle.dp property int textWeight: 600 * DefaultStyle.dp + property color textColor: DefaultStyle.grey_0 property bool underline: false property bool shadowEnabled: false property var contentImageColor @@ -63,6 +64,37 @@ Control.Button { } } + component ButtonText: Text { + visible: mainItem.text != undefined + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + width: mainItem.text != undefined ? implicitWidth : 0 + height: implicitHeight + wrapMode: Text.WrapAnywhere + Layout.fillWidth: true + Layout.fillHeight: true + text: mainItem.text + maximumLineCount: 1 + color: inversedColors ? mainItem.color : mainItem.textColor + font { + pixelSize: mainItem.textSize + weight: mainItem.textWeight + family: DefaultStyle.defaultFont + capitalization: mainItem.capitalization + underline: mainItem.underline + } + } + + component ButtonImage: EffectImage { + visible: mainItem.icon.source != undefined + Layout.fillWidth: true + Layout.fillHeight: true + imageSource: mainItem.icon.source + imageWidth: mainItem.icon.width + imageHeight: mainItem.icon.height + colorizationColor: mainItem.contentImageColor + } + contentItem: StackLayout { currentIndex: mainItem.text.length != 0 && mainItem.icon.source != undefined ? 0 @@ -74,65 +106,12 @@ Control.Button { width: mainItem.width RowLayout { - spacing: 5 * DefaultStyle.dp - EffectImage { - visible: mainItem.icon.source != undefined - Layout.fillWidth: true - Layout.fillHeight: true - imageSource: mainItem.icon.source - imageWidth: mainItem.icon.width - imageHeight: mainItem.icon.height - colorizationColor: mainItem.contentImageColor - } - Text { - visible: mainItem.text != undefined - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - width: mainItem.text != undefined ? implicitWidth : 0 - height: implicitHeight - wrapMode: Text.WrapAnywhere - Layout.fillWidth: true - Layout.fillHeight: true - text: mainItem.text - maximumLineCount: 1 - color: inversedColors ? mainItem.color : DefaultStyle.grey_0 - font { - pixelSize: mainItem.textSize - weight: mainItem.textWeight - family: DefaultStyle.defaultFont - capitalization: mainItem.capitalization - underline: mainItem.underline - } - } - } - Text { - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - Layout.alignment: Qt.AlignCenter - Layout.fillWidth: true - Layout.fillHeight: true - height: implicitHeight - wrapMode: Text.WrapAnywhere - text: mainItem.text - maximumLineCount: 1 - color: inversedColors ? mainItem.color : DefaultStyle.grey_0 - font { - pixelSize: mainItem.textSize - weight: mainItem.textWeight - family: DefaultStyle.defaultFont - capitalization: mainItem.capitalization - underline: mainItem.underline - } - } - EffectImage { - Layout.alignment: Qt.AlignCenter - Layout.fillWidth: true - Layout.fillHeight: true - imageSource: mainItem.icon.source - imageWidth: mainItem.icon.width - imageHeight: mainItem.icon.height - colorizationColor: mainItem.contentImageColor + spacing: 10 * DefaultStyle.dp + ButtonImage{} + ButtonText{} } + ButtonText {} + ButtonImage{} Item { Layout.fillWidth : true Layout.fillHeight : true diff --git a/Linphone/view/Item/Participant/ParticipantDeviceList.qml b/Linphone/view/Item/Participant/ParticipantDeviceList.qml new file mode 100644 index 000000000..32bc3bbf7 --- /dev/null +++ b/Linphone/view/Item/Participant/ParticipantDeviceList.qml @@ -0,0 +1,80 @@ +import QtQuick 2.7 +import QtQuick.Layouts 1.3 + +import Linphone +import UtilsCpp 1.0 + +ListView { + id: mainItem + Layout.preferredHeight: contentHeight + height: contentHeight + visible: contentHeight > 0 + clip: true + rightMargin: 5 * DefaultStyle.dp + spacing: 5 * DefaultStyle.dp + + property string searchBarText + + property CallGui call + + property bool hoverEnabled: true + // dots popup menu + property bool contactMenuVisible: true + // call, video call etc menu + property bool actionMenuVisible: true + property bool initialHeadersVisible: true + property bool displayNameCapitalization: true + + property ConferenceInfoGui confInfoGui + + currentIndex: -1 + + model: ParticipantDeviceProxy { + id: participantDevices + currentCall: mainItem.call + } + + delegate: Item { + height: 56 * DefaultStyle.dp + width: mainItem.width + + RowLayout { + id: participantDelegate + anchors.left: parent.left + anchors.leftMargin: 10 * DefaultStyle.dp + anchors.right: parent.right + anchors.rightMargin: 10 * DefaultStyle.dp + anchors.verticalCenter: parent.verticalCenter + spacing: 10 * DefaultStyle.dp + z: 1 + Avatar { + Layout.preferredWidth: 45 * DefaultStyle.dp + Layout.preferredHeight: 45 * DefaultStyle.dp + address: modelData.core.address + } + Text { + text: modelData.core.displayName + font.pixelSize: 14 * DefaultStyle.dp + font.capitalization: mainItem.displayNameCapitalization ? Font.Capitalize : Font.MixedCase + maximumLineCount: 1 + Layout.fillWidth: true + } + } + + // MouseArea { + // id: mouseArea + // hoverEnabled: mainItem.hoverEnabled + // anchors.fill: participantDelegate + // height: mainItem.height + // Rectangle { + // anchors.fill: mouseArea + // opacity: 0.7 + // color: DefaultStyle.main2_100 + // visible: mouseArea.containsMouse || (!mainItem.multiSelectionEnabled && mainItem.currentIndex === index) + // } + // onClicked: { + // mainItem.currentIndex = index + // } + // } + } +} diff --git a/Linphone/view/Item/Participant/ParticipantList.qml b/Linphone/view/Item/Participant/ParticipantList.qml new file mode 100644 index 000000000..27fc9ede2 --- /dev/null +++ b/Linphone/view/Item/Participant/ParticipantList.qml @@ -0,0 +1,125 @@ +import QtQuick 2.7 +import QtQuick.Layouts 1.3 + +import Linphone +import UtilsCpp 1.0 + +ListView { + id: mainItem + Layout.preferredHeight: contentHeight + height: contentHeight + visible: contentHeight > 0 + clip: true + rightMargin: 5 * DefaultStyle.dp + spacing: 5 * DefaultStyle.dp + + property string searchBarText + + property CallGui call + property ParticipantGui me: call.conference ? call.conference.core.me : null + property bool isMeAdmin: me ? me.core.isAdmin : false + + property bool hoverEnabled: true + // dots popup menu + property bool contactMenuVisible: true + // call, video call etc menu + property bool actionMenuVisible: true + property bool initialHeadersVisible: true + property bool displayNameCapitalization: true + + property ConferenceInfoGui confInfoGui + + signal addParticipantRequested() + + currentIndex: -1 + + model: ParticipantProxy { + id: participantModel + currentCall: mainItem.call + } + + delegate: Item { + height: 56 * DefaultStyle.dp + width: mainItem.width + + RowLayout { + id: participantDelegate + anchors.left: parent.left + anchors.leftMargin: 10 * DefaultStyle.dp + anchors.right: parent.right + anchors.rightMargin: 10 * DefaultStyle.dp + anchors.verticalCenter: parent.verticalCenter + spacing: 10 * DefaultStyle.dp + z: 1 + Avatar { + Layout.preferredWidth: 45 * DefaultStyle.dp + Layout.preferredHeight: 45 * DefaultStyle.dp + address: modelData.core.sipAddress + } + Text { + text: modelData.core.displayName + font.pixelSize: 14 * DefaultStyle.dp + font.capitalization: mainItem.displayNameCapitalization ? Font.Capitalize : Font.MixedCase + maximumLineCount: 1 + Layout.fillWidth: true + } + Text { + Layout.alignment: Qt.AlignRight + visible: modelData.core.isAdmin + text: qsTr("Admin") + color: DefaultStyle.main2_400 + font { + pixelSize: 12 * DefaultStyle.dp + weight: 300 * DefaultStyle.dp + } + } + RowLayout { + Layout.alignment: Qt.AlignRight + property bool isMe: modelData.core.isMe + onIsMeChanged: if (isMe) mainItem.me = modelData + enabled: mainItem.isMeAdmin && !modelData.core.isMe + opacity: enabled ? 1.0 : 0 + spacing: 26 * DefaultStyle.dp + Switch { + Component.onCompleted: if (modelData.core.isAdmin) toggle() + onToggled: participantModel.setParticipantAdminStatus(modelData.core, position === 1) + } + Button { + Layout.preferredWidth: 20 * DefaultStyle.dp + Layout.preferredHeight: 20 * DefaultStyle.dp + color: DefaultStyle.main2_100 + pressedColor: DefaultStyle.main2_200 + icon.source: AppIcons.closeX + icon.width: 14 * DefaultStyle.dp + icon.height: 14 * DefaultStyle.dp + onClicked: participantModel.removeParticipant(modelData.core) + } + } + } + } + + footer: Rectangle { + color: DefaultStyle.grey_100 + visible: mainItem.isMeAdmin + height: 74 * DefaultStyle.dp + width: mainItem.width + Button { + anchors.centerIn: parent + height: 40 * DefaultStyle.dp + icon.source: AppIcons.plusCircle + icon.width: 16 * DefaultStyle.dp + icon.height: 16 * DefaultStyle.dp + contentImageColor: DefaultStyle.main1_500_main + text: qsTr("Ajouter des participants") + color: DefaultStyle.main1_100 + textColor: DefaultStyle.main1_500_main + textSize: 15 * DefaultStyle.dp + textWeight: 600 * DefaultStyle.dp + rightPadding: 16 * DefaultStyle.dp + leftPadding: 16 * DefaultStyle.dp + topPadding: 10 * DefaultStyle.dp + bottomPadding: 10 * DefaultStyle.dp + onClicked: mainItem.addParticipantRequested() + } + } +} diff --git a/Linphone/view/Style/DefaultStyle.qml b/Linphone/view/Style/DefaultStyle.qml index 024b150c3..40af8cadb 100644 --- a/Linphone/view/Style/DefaultStyle.qml +++ b/Linphone/view/Style/DefaultStyle.qml @@ -2,6 +2,7 @@ pragma Singleton import QtQuick 2.15 QtObject { + property color main1_100: "#FFEACB" property color main1_500_main: "#FE5E00" property color main1_500_main_darker: "#C94C02"