Add participants view in video conference, and admin mode.

Fix ConferenceModel object synchronization.
Use Me() and participantList to get local participant in ConferenceModel
This commit is contained in:
Julien Wadel 2022-05-07 19:18:34 +02:00
parent cc8057a0d2
commit a3554153d5
26 changed files with 550 additions and 84 deletions

View file

@ -381,13 +381,15 @@
<file>ui/modules/Linphone/Styles/qmldir</file>
<file>ui/modules/Linphone/Styles/TelKeypad/TelKeypadStyle.qml</file>
<file>ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml</file>
<file>ui/modules/Linphone/Styles/View/SipAddressesViewStyle.qml</file>
<file>ui/modules/Linphone/Styles/View/ParticipantsListViewStyle.qml</file>
<file>ui/modules/Linphone/Styles/View/ParticipantsViewStyle.qml</file>
<file>ui/modules/Linphone/Styles/View/SipAddressesViewStyle.qml</file>
<file>ui/modules/Linphone/TelKeypad/TelKeypadButton.qml</file>
<file>ui/modules/Linphone/TelKeypad/TelKeypad.js</file>
<file>ui/modules/Linphone/TelKeypad/TelKeypad.qml</file>
<file>ui/modules/Linphone/Timeline/Timeline.js</file>
<file>ui/modules/Linphone/Timeline/Timeline.qml</file>
<file>ui/modules/Linphone/View/ParticipantsListView.qml</file>
<file>ui/modules/Linphone/View/ParticipantsView.qml</file>
<file>ui/modules/Linphone/View/SipAddressesView.qml</file>
<file>ui/scripts/LinphoneUtils/linphone-utils.js</file>

View file

@ -161,7 +161,7 @@ ChatRoomModel * CallModel::getChatRoomModel() const{
}
ConferenceModel * CallModel::getConferenceModel(){
return getConferenceSharedModel().get();
return mConferenceModel.get();
}
QSharedPointer<ConferenceModel> CallModel::getConferenceSharedModel(){

View file

@ -121,7 +121,7 @@ public:
ContactModel *getContactModel() const;
ChatRoomModel * getChatRoomModel() const;
Q_INVOKABLE ConferenceModel* getConferenceModel();
ConferenceModel* getConferenceModel();
QSharedPointer<ConferenceModel> getConferenceSharedModel();
bool isInConference () const {

View file

@ -323,6 +323,8 @@ QVariantMap CallsListModel::createChatRoom(const QString& subject, const int& se
}
if( address)
chatRoomParticipants.push_back( address );
else
qWarning() << "Failed to add participant to conference, bad address : " << (participant ? participant->getSipAddress() : p.toString());
}
params->enableEncryption(securityLevel>0);

View file

@ -1189,7 +1189,7 @@ void ChatRoomModel::onParticipantAdded(const std::shared_ptr<linphone::ChatRoom>
if( e != events.end() )
insertNotice(*e);
updateLastUpdateTime();
emit participantAdded(chatRoom, eventLog);
emit participantAdded(eventLog);
emit fullPeerAddressChanged();
}
@ -1199,7 +1199,7 @@ void ChatRoomModel::onParticipantRemoved(const std::shared_ptr<linphone::ChatRoo
if( e != events.end() )
insertNotice(*e);
updateLastUpdateTime();
emit participantRemoved(chatRoom, eventLog);
emit participantRemoved(eventLog);
emit fullPeerAddressChanged();
}
@ -1209,7 +1209,7 @@ void ChatRoomModel::onParticipantAdminStatusChanged(const std::shared_ptr<linpho
if( e != events.end() )
insertNotice(*e);
updateLastUpdateTime();
emit participantAdminStatusChanged(chatRoom, eventLog);
emit participantAdminStatusChanged(eventLog);
emit isMeAdminChanged(); // It is not the case all the time but calling getters is not a heavy request
}
@ -1242,12 +1242,12 @@ void ChatRoomModel::onUndecryptableMessageReceived(const std::shared_ptr<linphon
void ChatRoomModel::onParticipantDeviceAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
updateLastUpdateTime();
emit participantDeviceAdded(chatRoom, eventLog);
emit participantDeviceAdded(eventLog);
}
void ChatRoomModel::onParticipantDeviceRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
updateLastUpdateTime();
emit participantDeviceRemoved(chatRoom, eventLog);
emit participantDeviceRemoved(eventLog);
}
void ChatRoomModel::onConferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
@ -1264,7 +1264,7 @@ void ChatRoomModel::onConferenceJoined(const std::shared_ptr<linphone::ChatRoom>
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount()); // Update message count. In the case of joining conference, the conference id was not valid thus, the missing count was not about the chat room but a global one.
updateLastUpdateTime();
emit usernameChanged();
emit conferenceJoined(chatRoom, eventLog);
emit conferenceJoined(eventLog);
emit isReadOnlyChanged();
}
@ -1281,7 +1281,7 @@ void ChatRoomModel::onConferenceLeft(const std::shared_ptr<linphone::ChatRoom> &
insertNotice(*e);
}
updateLastUpdateTime();
emit conferenceLeft(chatRoom, eventLog);
emit conferenceLeft(eventLog);
emit isReadOnlyChanged();
}
}
@ -1308,11 +1308,11 @@ void ChatRoomModel::onConferenceAddressGeneration(const std::shared_ptr<linphone
void ChatRoomModel::onParticipantRegistrationSubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress){
updateLastUpdateTime();
emit participantRegistrationSubscriptionRequested(chatRoom, participantAddress);
emit participantRegistrationSubscriptionRequested(participantAddress);
}
void ChatRoomModel::onParticipantRegistrationUnsubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress){
emit participantRegistrationUnsubscriptionRequested(chatRoom, participantAddress);
emit participantRegistrationUnsubscriptionRequested(participantAddress);
}
void ChatRoomModel::onChatMessageShouldBeStored(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){

View file

@ -266,16 +266,16 @@ signals:
// Chat Room listener callbacks
void securityEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantDeviceAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantDeviceRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantAdminStatusChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantRegistrationSubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress);
void participantRegistrationUnsubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress);
void conferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void conferenceLeft(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void securityEvent(const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantAdded(const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantRemoved(const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantDeviceAdded(const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantDeviceRemoved(const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantAdminStatusChanged(const std::shared_ptr<const linphone::EventLog> & eventLog);
void participantRegistrationSubscriptionRequested(const std::shared_ptr<const linphone::Address> & participantAddress);
void participantRegistrationUnsubscriptionRequested(const std::shared_ptr<const linphone::Address> & participantAddress);
void conferenceJoined(const std::shared_ptr<const linphone::EventLog> & eventLog);
void conferenceLeft(const std::shared_ptr<const linphone::EventLog> & eventLog);
private:

View file

@ -42,7 +42,7 @@ ConferenceListener::~ConferenceListener(){
// LINPHONE LISTENERS
//-----------------------------------------------------------------------------------------------------------------------
void ConferenceListener::onParticipantAdded(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::Participant> & participant){
qDebug() << "onParticipantAdded";
qDebug() << "onParticipantAdded: " << participant->getAddress()->asString().c_str();
emit participantAdded(participant);
}
void ConferenceListener::onParticipantRemoved(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::Participant> & participant){
@ -61,6 +61,7 @@ void ConferenceListener::onParticipantDeviceRemoved(const std::shared_ptr<linpho
}
void ConferenceListener::onParticipantAdminStatusChanged(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::Participant> & participant){
qDebug() << "onParticipantAdminStatusChanged";
emit participantAdminStatusChanged(participant);
}
void ConferenceListener::onParticipantDeviceLeft(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice){
qDebug() << "onParticipantDeviceLeft";
@ -97,4 +98,4 @@ void ConferenceListener::onAudioDeviceChanged(const std::shared_ptr<linphone::Co
}
//-----------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------

View file

@ -37,9 +37,9 @@ public:
// LINPHONE LISTENERS
virtual void onParticipantAdded(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::Participant> & participant) override;
virtual void onParticipantRemoved(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::Participant> & participant) override;
virtual void onParticipantAdminStatusChanged(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::Participant> & participant) override;
virtual void onParticipantDeviceAdded(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice) override;
virtual void onParticipantDeviceRemoved(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice) override;
virtual void onParticipantAdminStatusChanged(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::Participant> & participant) override;
virtual void onParticipantDeviceLeft(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & device) override;
virtual void onParticipantDeviceJoined(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & device) override;
virtual void onParticipantDeviceMediaCapabilityChanged(const std::shared_ptr<linphone::Conference> & conference, const std::shared_ptr<const linphone::ParticipantDevice> & device) override;
@ -53,6 +53,7 @@ public:
signals:
void participantAdded(const std::shared_ptr<const linphone::Participant> & participant);
void participantRemoved(const std::shared_ptr<const linphone::Participant> & participant);
void participantAdminStatusChanged(const std::shared_ptr<const linphone::Participant> & participant);
void participantDeviceAdded(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceRemoved(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceLeft(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);

View file

@ -39,6 +39,7 @@
void ConferenceModel::connectTo(ConferenceListener * listener){
connect(listener, &ConferenceListener::participantAdded, this, &ConferenceModel::onParticipantAdded);
connect(listener, &ConferenceListener::participantRemoved, this, &ConferenceModel::onParticipantRemoved);
connect(listener, &ConferenceListener::participantAdminStatusChanged, this, &ConferenceModel::onParticipantAdminStatusChanged);
connect(listener, &ConferenceListener::participantDeviceAdded, this, &ConferenceModel::onParticipantDeviceAdded);
connect(listener, &ConferenceListener::participantDeviceRemoved, this, &ConferenceModel::onParticipantDeviceRemoved);
connect(listener, &ConferenceListener::participantDeviceLeft, this, &ConferenceModel::onParticipantDeviceLeft);
@ -59,6 +60,8 @@ QSharedPointer<ConferenceModel> ConferenceModel::create(std::shared_ptr<linphone
ConferenceModel::ConferenceModel (std::shared_ptr<linphone::Conference> conference, QObject *parent) : QObject(parent) {
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
mConference = conference;
//updateLocalParticipant();
mParticipantListModel = QSharedPointer<ParticipantListModel>::create(this);
mConferenceListener = std::make_shared<ConferenceListener>();
connectTo(mConferenceListener.get());
mConference->addListener(mConferenceListener);
@ -68,6 +71,21 @@ ConferenceModel::~ConferenceModel(){
mConference->removeListener(mConferenceListener);
}
bool ConferenceModel::updateLocalParticipant(){
bool changed = false;
// First try to use findParticipant
auto localParticipant = mConference->findParticipant(mConference->getCall()->getCallLog()->getLocalAddress());
// Me is not in participants, use Me().
if( !localParticipant)
localParticipant = mConference->getMe();
if( localParticipant){
mLocalParticipant = QSharedPointer<ParticipantModel>::create(localParticipant);
qWarning() << "Is Admin: " << localParticipant->isAdmin() << " " << mLocalParticipant->getAdminStatus();
changed = true;
}
return changed;
}
std::shared_ptr<linphone::Conference> ConferenceModel::getConference()const{
return mConference;
}
@ -84,17 +102,40 @@ qint64 ConferenceModel::getElapsedSeconds() const {
return getStartDate().secsTo(QDateTime::currentDateTime());
}
ParticipantModel* ConferenceModel::getLocalParticipant() const{
if( mLocalParticipant) {
qWarning() << "LocalParticipant admin : " << mLocalParticipant->getAdminStatus() << " " << (mLocalParticipant->getParticipant() ? mLocalParticipant->getParticipant()->isAdmin() : -1);
}else
qWarning() << "NULL";
return mLocalParticipant.get();
}
ParticipantListModel* ConferenceModel::getParticipants() const{
return mParticipantListModel.get();
}
//-----------------------------------------------------------------------------------------------------------------------
// LINPHONE LISTENERS
//-----------------------------------------------------------------------------------------------------------------------
void ConferenceModel::onParticipantAdded(const std::shared_ptr<const linphone::Participant> & participant){
qDebug() << "Me devices : " << mConference->getMe()->getDevices().size();
qDebug() << "Added call, participant count: " << mConference->getParticipantList().size();
if(!mLocalParticipant){
if(updateLocalParticipant())
emit localParticipantChanged();
}
emit participantAdded(participant);
}
void ConferenceModel::onParticipantRemoved(const std::shared_ptr<const linphone::Participant> & participant){
qDebug() << "Me devices : " << mConference->getMe()->getDevices().size();
emit participantRemoved(participant);
}
void ConferenceModel::onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::Participant> & participant){
qWarning() << "onParticipantAdminStatusChanged: " << participant->getAddress()->asString().c_str();
if(participant == mLocalParticipant->getParticipant())
emit mLocalParticipant->adminStatusChanged();
emit participantAdminStatusChanged(participant);
}
void ConferenceModel::onParticipantDeviceAdded(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice){
qDebug() << "Me devices : " << mConference->getMe()->getDevices().size();
emit participantDeviceAdded(participantDevice);
@ -130,4 +171,4 @@ void ConferenceModel::onSubjectChanged(const std::string& string){
}
//-----------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------

View file

@ -28,7 +28,10 @@
#include <QDateTime>
#include <QString>
#include "components/participant/ParticipantModel.hpp"
class ConferenceListener;
class ParticipantListModel;
class ConferenceModel : public QObject{
Q_OBJECT
@ -36,19 +39,26 @@ public:
Q_PROPERTY(QString subject READ getSubject NOTIFY subjectChanged)
Q_PROPERTY(QDateTime startDate READ getStartDate CONSTANT)
Q_PROPERTY(ParticipantListModel* participants READ getParticipants CONSTANT)
Q_PROPERTY(ParticipantModel* localParticipant READ getLocalParticipant NOTIFY localParticipantChanged)
static QSharedPointer<ConferenceModel> create(std::shared_ptr<linphone::Conference> chatRoom, QObject *parent = Q_NULLPTR);
ConferenceModel(std::shared_ptr<linphone::Conference> content, QObject *parent = Q_NULLPTR);
virtual ~ConferenceModel();
bool updateLocalParticipant(); // true if changed
std::shared_ptr<linphone::Conference> getConference()const;
QString getSubject() const;
QDateTime getStartDate() const;
Q_INVOKABLE qint64 getElapsedSeconds() const;
Q_INVOKABLE ParticipantModel* getLocalParticipant() const;
ParticipantListModel* getParticipants() const;
virtual void onParticipantAdded(const std::shared_ptr<const linphone::Participant> & participant);
virtual void onParticipantRemoved(const std::shared_ptr<const linphone::Participant> & participant);
virtual void onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::Participant> & participant);
virtual void onParticipantDeviceAdded(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
virtual void onParticipantDeviceRemoved(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
virtual void onParticipantDeviceLeft(const std::shared_ptr<const linphone::ParticipantDevice> & device);
@ -61,8 +71,10 @@ public:
//---------------------------------------------------------------------------
signals:
void localParticipantChanged();
void participantAdded(const std::shared_ptr<const linphone::Participant> & participant);
void participantRemoved(const std::shared_ptr<const linphone::Participant> & participant);
void participantAdminStatusChanged(const std::shared_ptr<const linphone::Participant> & participant);
void participantDeviceAdded(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceRemoved(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
void participantDeviceLeft(const std::shared_ptr<const linphone::ParticipantDevice> & participantDevice);
@ -78,6 +90,9 @@ private:
std::shared_ptr<linphone::Conference> mConference;
std::shared_ptr<ConferenceListener> mConferenceListener;
QSharedPointer<ParticipantModel> mLocalParticipant;
QSharedPointer<ParticipantListModel> mParticipantListModel;
};
Q_DECLARE_METATYPE(QSharedPointer<ConferenceModel>)

View file

@ -176,7 +176,7 @@ QSharedPointer<ParticipantDeviceModel> ParticipantDeviceListModel::get(std::shar
bool ParticipantDeviceListModel::isMe(std::shared_ptr<linphone::ParticipantDevice> deviceToCheck)const{
if(mCallModel){
auto devices = mCallModel->getConferenceModel()->getConference()->getMe()->getDevices();
auto devices = mCallModel->getConferenceSharedModel()->getConference()->getMe()->getDevices();
auto deviceToCheckAddress = deviceToCheck->getAddress();
for(auto device : devices){
if(deviceToCheckAddress == device->getAddress())
@ -328,4 +328,4 @@ void ParticipantDeviceListModel::onParticipantDeviceIsSpeakingChanged(const std:
void ParticipantDeviceListModel::onParticipantDeviceSpeaking(){
emit participantSpeaking(qobject_cast<ParticipantDeviceModel*>(sender()));
}
}

View file

@ -21,6 +21,7 @@
#include "components/core/CoreManager.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "components/sip-addresses/SipAddressesModel.hpp"
#include "components/conference/ConferenceModel.hpp"
#include "utils/Utils.hpp"
#include "ParticipantListModel.hpp"
@ -39,21 +40,42 @@ ParticipantListModel::ParticipantListModel (ChatRoomModel * chatRoomModel, QObje
connect(mChatRoomModel, &ChatRoomModel::conferenceJoined, this, &ParticipantListModel::onConferenceJoined);
connect(mChatRoomModel, &ChatRoomModel::participantAdded, this, &ParticipantListModel::onParticipantAdded);
connect(mChatRoomModel, &ChatRoomModel::participantRemoved, this, &ParticipantListModel::onParticipantRemoved);
connect(mChatRoomModel, &ChatRoomModel::participantAdded, this, QOverload<const std::shared_ptr<const linphone::EventLog> &>::of(&ParticipantListModel::onParticipantAdded));
connect(mChatRoomModel, &ChatRoomModel::participantRemoved, this, QOverload<const std::shared_ptr<const linphone::EventLog> &>::of(&ParticipantListModel::onParticipantRemoved));
connect(mChatRoomModel, &ChatRoomModel::participantAdminStatusChanged, this, QOverload<const std::shared_ptr<const linphone::EventLog> &>::of(&ParticipantListModel::onParticipantAdminStatusChanged));
connect(mChatRoomModel, &ChatRoomModel::participantDeviceAdded, this, &ParticipantListModel::onParticipantDeviceAdded);
connect(mChatRoomModel, &ChatRoomModel::participantDeviceRemoved, this, &ParticipantListModel::onParticipantDeviceRemoved);
connect(mChatRoomModel, &ChatRoomModel::participantAdminStatusChanged, this, &ParticipantListModel::onParticipantAdminStatusChanged);
connect(mChatRoomModel, &ChatRoomModel::participantRegistrationSubscriptionRequested, this, &ParticipantListModel::onParticipantRegistrationSubscriptionRequested);
connect(mChatRoomModel, &ChatRoomModel::participantRegistrationUnsubscriptionRequested, this, &ParticipantListModel::onParticipantRegistrationUnsubscriptionRequested);
updateParticipants();
}
}
ParticipantListModel::ParticipantListModel (ConferenceModel * conferenceModel, QObject *parent) : ProxyListModel(parent) {
if( conferenceModel) {
mConferenceModel = conferenceModel;//CoreManager::getInstance()->getChatRoomModel(chatRoomModel);
connect(mConferenceModel, &ConferenceModel::participantAdded, this, QOverload<const std::shared_ptr<const linphone::Participant> &>::of(&ParticipantListModel::onParticipantAdded));
connect(mConferenceModel, &ConferenceModel::participantRemoved, this, QOverload<const std::shared_ptr<const linphone::Participant> &>::of(&ParticipantListModel::onParticipantRemoved));
connect(mConferenceModel, &ConferenceModel::participantAdminStatusChanged, this, QOverload<const std::shared_ptr<const linphone::Participant> &>::of(&ParticipantListModel::onParticipantAdminStatusChanged));
//connect(mConferenceModel, &ConferenceModel::participantDeviceAdded, this, &ParticipantListModel::onParticipantDeviceAdded);
//connect(mConferenceModel, &ConferenceModel::participantDeviceRemoved, this, &ParticipantListModel::onParticipantDeviceRemoved);
updateParticipants();
}
}
ParticipantListModel::~ParticipantListModel(){
mList.clear();
mChatRoomModel = nullptr;
mConferenceModel = nullptr;
}
// -----------------------------------------------------------------------------
@ -62,6 +84,10 @@ ChatRoomModel *ParticipantListModel::getChatRoomModel() const{
return mChatRoomModel;
}
ConferenceModel *ParticipantListModel::getConferenceModel() const{
return mConferenceModel;
}
std::list<std::shared_ptr<linphone::Address>> ParticipantListModel::getParticipants()const{
std::list<std::shared_ptr<linphone::Address>> participants;
for(auto participant : mList){
@ -119,11 +145,16 @@ bool ParticipantListModel::contains(const QString& address) const{
// -----------------------------------------------------------------------------
void ParticipantListModel::updateParticipants () {
if( mChatRoomModel) {
if( mChatRoomModel || mConferenceModel) {
bool changed = false;
auto dbParticipants = mChatRoomModel->getChatRoom()->getParticipants();
auto me = mChatRoomModel->getChatRoom()->getMe();
dbParticipants.push_front(me);
auto dbParticipants = (mChatRoomModel ? mChatRoomModel->getChatRoom()->getParticipants() : mConferenceModel->getConference()->getParticipantList());
std::shared_ptr<linphone::Participant> me;
if( mChatRoomModel )
me = mChatRoomModel->getChatRoom()->getMe();
else if( mConferenceModel->getLocalParticipant())
me = mConferenceModel->getLocalParticipant()->getParticipant();
if(me)
dbParticipants.push_front(me);
//Remove left participants
//for(auto participant : mList){
@ -186,6 +217,16 @@ void ParticipantListModel::add (QSharedPointer<ParticipantModel> participant){
emit participantsChanged();
}
void ParticipantListModel::add(const std::shared_ptr<const linphone::Participant> & participant){
auto unconstParticipant = (mChatRoomModel ? mChatRoomModel->getChatRoom()->findParticipant(participant->getAddress()) : mConferenceModel->getConference()->findParticipant(participant->getAddress()));
if( unconstParticipant)
add(QSharedPointer<ParticipantModel>::create(unconstParticipant));
}
void ParticipantListModel::add(const std::shared_ptr<const linphone::Address> & participantAddress){
add((mChatRoomModel ? mChatRoomModel->getChatRoom()->findParticipant(participantAddress) : mConferenceModel->getConference()->findParticipant(participantAddress)));
}
void ParticipantListModel::remove (ParticipantModel *model) {
QString address = model->getSipAddress();
int index = 0;
@ -217,15 +258,30 @@ const QSharedPointer<ParticipantModel> ParticipantListModel::getParticipant(cons
}else
return nullptr;
}
const QSharedPointer<ParticipantModel> ParticipantListModel::getParticipant(const std::shared_ptr<const linphone::Participant>& pParticipant) const{
if(pParticipant){
auto itParticipant = std::find_if(mList.begin(), mList.end(), [pParticipant] (const QSharedPointer<QObject>& participant){
return participant.objectCast<ParticipantModel>()->getParticipant() == pParticipant;
});
if( itParticipant == mList.end())
return nullptr;
else
return itParticipant->objectCast<ParticipantModel>();
}else
return nullptr;
}
//-------------------------------------------------------------
void ParticipantListModel::setAdminStatus(const std::shared_ptr<linphone::Participant> participant, const bool& isAdmin){
mChatRoomModel->getChatRoom()->setParticipantAdminStatus(participant, isAdmin);
if(mChatRoomModel)
mChatRoomModel->getChatRoom()->setParticipantAdminStatus(participant, isAdmin);
if(mConferenceModel)
mConferenceModel->getConference()->setParticipantAdminStatus(participant, isAdmin);
}
void ParticipantListModel::onSecurityEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog) {
void ParticipantListModel::onSecurityEvent(const std::shared_ptr<const linphone::EventLog> & eventLog) {
auto address = eventLog->getParticipantAddress();
if(address) {
auto participant = getParticipant(address);
@ -240,37 +296,66 @@ void ParticipantListModel::onSecurityEvent(const std::shared_ptr<linphone::ChatR
}
}
void ParticipantListModel::onConferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
updateParticipants();
}
void ParticipantListModel::onParticipantAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
void ParticipantListModel::onConferenceJoined(){
updateParticipants();
}
void ParticipantListModel::onParticipantRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
updateParticipants();
void ParticipantListModel::onParticipantAdded(const std::shared_ptr<const linphone::EventLog> & eventLog){
qWarning() << "onParticipantAdded event: " << eventLog->getParticipantAddress()->asString().c_str();
add(eventLog->getParticipantAddress());
}
void ParticipantListModel::onParticipantAdminStatusChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
auto participant = getParticipant(eventLog->getParticipantAddress());
if( participant){
emit participant->adminStatusChanged();// Request to participant to update its status from its data
}
void ParticipantListModel::onParticipantAdded(const std::shared_ptr<const linphone::Participant> & participant){
qWarning() << "onParticipantAdded part: " << participant->getAddress()->asString().c_str();
add(participant);
}
void ParticipantListModel::onParticipantDeviceAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
void ParticipantListModel::onParticipantAdded(const std::shared_ptr<const linphone::Address>& address){
qWarning() << "onParticipantAdded addr: " << address->asString().c_str();
add(address);
}
void ParticipantListModel::onParticipantRemoved(const std::shared_ptr<const linphone::EventLog> & eventLog){
onParticipantRemoved(eventLog->getParticipantAddress());
}
void ParticipantListModel::onParticipantRemoved(const std::shared_ptr<const linphone::Participant> & participant){
auto p = getParticipant(participant);
if(p)
remove(p.get());
}
void ParticipantListModel::onParticipantRemoved(const std::shared_ptr<const linphone::Address>& address){
auto participant = getParticipant(address);
if(participant)
remove(participant.get());
}
void ParticipantListModel::onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::EventLog> & eventLog){
onParticipantAdminStatusChanged(eventLog->getParticipantAddress());
}
void ParticipantListModel::onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::Participant> & participant){
auto p = getParticipant(participant);
if( participant) emit p->adminStatusChanged();// Request to participant to update its status from its data
}
void ParticipantListModel::onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::Address>& address ){
auto participant = getParticipant(address);
if( participant) emit participant->adminStatusChanged();// Request to participant to update its status from its data
}
void ParticipantListModel::onParticipantDeviceAdded(const std::shared_ptr<const linphone::EventLog> & eventLog){
auto participant = getParticipant(eventLog->getParticipantAddress());
if( participant){
emit participant->deviceCountChanged();
}
}
void ParticipantListModel::onParticipantDeviceRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
void ParticipantListModel::onParticipantDeviceRemoved(const std::shared_ptr<const linphone::EventLog> & eventLog){
auto participant = getParticipant(eventLog->getParticipantAddress());
if( participant){
emit participant->deviceCountChanged();
}
}
void ParticipantListModel::onParticipantRegistrationSubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress){
void ParticipantListModel::onParticipantRegistrationSubscriptionRequested(const std::shared_ptr<const linphone::Address> & participantAddress){
}
void ParticipantListModel::onParticipantRegistrationUnsubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress){
void ParticipantListModel::onParticipantRegistrationUnsubscriptionRequested(const std::shared_ptr<const linphone::Address> & participantAddress){
}

View file

@ -26,12 +26,15 @@
#include "components/chat-room/ChatRoomModel.hpp"
#include "app/proxyModel/ProxyListModel.hpp"
class ConferenceModel;
// =============================================================================
class ParticipantListModel : public ProxyListModel {
Q_OBJECT
public:
ParticipantListModel (ChatRoomModel * chatRoomModel, QObject *parent = Q_NULLPTR);
ParticipantListModel (ConferenceModel * conferenceModel, QObject *parent = Q_NULLPTR);
virtual ~ParticipantListModel();
Q_PROPERTY(ChatRoomModel* chatRoomModel READ getChatRoomModel CONSTANT)
@ -43,12 +46,16 @@ public:
void update();
void selectAll(const bool& selected);
const QSharedPointer<ParticipantModel> getParticipant(const std::shared_ptr<const linphone::Address>& address) const;
const QSharedPointer<ParticipantModel> getParticipant(const std::shared_ptr<const linphone::Participant>& participant) const;
void add (QSharedPointer<ParticipantModel> participant);
void add(const std::shared_ptr<const linphone::Participant> & participant);
void add(const std::shared_ptr<const linphone::Address> & participantAddress);
void updateParticipants(); // Update list from Chat Room
// Remove a chatroom
Q_INVOKABLE void remove (ParticipantModel *importer);
Q_INVOKABLE ChatRoomModel* getChatRoomModel() const;
Q_INVOKABLE ConferenceModel* getConferenceModel() const;
std::list<std::shared_ptr<linphone::Address>> getParticipants()const;
Q_INVOKABLE QString addressesToString()const;
@ -60,15 +67,21 @@ public:
public slots:
void setAdminStatus(const std::shared_ptr<linphone::Participant> participant, const bool& isAdmin);
void onSecurityEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void onConferenceJoined(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantAdminStatusChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantDeviceAdded(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantDeviceRemoved(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantRegistrationSubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress);
void onParticipantRegistrationUnsubscriptionRequested(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::Address> & participantAddress);
void onSecurityEvent(const std::shared_ptr<const linphone::EventLog> & eventLog);
void onConferenceJoined();
void onParticipantAdded(const std::shared_ptr<const linphone::Participant> & participant);
void onParticipantAdded(const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantAdded(const std::shared_ptr<const linphone::Address>& address);
void onParticipantRemoved(const std::shared_ptr<const linphone::Participant> & participant);
void onParticipantRemoved(const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantRemoved(const std::shared_ptr<const linphone::Address>& address);
void onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::Participant> & participant);
void onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantAdminStatusChanged(const std::shared_ptr<const linphone::Address>& address );
void onParticipantDeviceAdded(const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantDeviceRemoved(const std::shared_ptr<const linphone::EventLog> & eventLog);
void onParticipantRegistrationSubscriptionRequested(const std::shared_ptr<const linphone::Address> & participantAddress);
void onParticipantRegistrationUnsubscriptionRequested(const std::shared_ptr<const linphone::Address> & participantAddress);
signals:
void securityLevelChanged();
@ -76,7 +89,8 @@ signals:
void participantsChanged();
private:
ChatRoomModel* mChatRoomModel;
ChatRoomModel* mChatRoomModel = nullptr;
ConferenceModel *mConferenceModel = nullptr;
};
Q_DECLARE_METATYPE(QSharedPointer<ParticipantListModel>);
#endif // PARTICIPANT_LIST_MODEL_H_

View file

@ -65,7 +65,8 @@ bool ParticipantModel::getInviting() const{
}
bool ParticipantModel::isMe() const{
return CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->weakEqual(Utils::interpretUrl(getSipAddress()));
QString sipAddress = getSipAddress();
return !sipAddress.isEmpty() ? CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->weakEqual(Utils::interpretUrl(sipAddress)) : false;
}
QString ParticipantModel::getSipAddress() const{

View file

@ -23,6 +23,7 @@
#include "components/core/CoreManager.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "components/sip-addresses/SipAddressesModel.hpp"
#include "components/conference/ConferenceModel.hpp"
#include "utils/Utils.hpp"
#include "ParticipantListModel.hpp"
@ -36,7 +37,6 @@
// -----------------------------------------------------------------------------
ParticipantProxyModel::ParticipantProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
mChatRoomModel = nullptr;
}
// -----------------------------------------------------------------------------
@ -45,6 +45,10 @@ ChatRoomModel *ParticipantProxyModel::getChatRoomModel() const{
return mChatRoomModel;
}
ConferenceModel *ParticipantProxyModel::getConferenceModel() const{
return mConferenceModel;
}
ParticipantListModel * ParticipantProxyModel::getParticipantListModel() const{
return qobject_cast<ParticipantListModel*>(sourceModel());
}
@ -61,7 +65,7 @@ QVariantList ParticipantProxyModel::getParticipants() const{
QVariantList participants;
ParticipantListModel * list = qobject_cast<ParticipantListModel*>(sourceModel());
for(int i = 0 ; i < list->rowCount() ; ++i)
participants << QVariant::fromValue(list->getAt<ParticipantModel>(i));
participants << QVariant::fromValue(list->getAt<ParticipantModel>(i).get());
return participants;
}
@ -84,8 +88,8 @@ void ParticipantProxyModel::setChatRoomModel(ChatRoomModel * chatRoomModel){
emit participantListModelChanged();
for(int i = 0 ; i < participants->getCount() ; ++i)
emit addressAdded(participants->getAt<ParticipantModel>(i)->getSipAddress());
}else {
setSourceModel(new ParticipantListModel(nullptr, this));
}else if(!sourceModel()){
setSourceModel(new ParticipantListModel((ChatRoomModel*)nullptr, this));
emit participantListModelChanged();
}
sort(0);
@ -93,6 +97,24 @@ void ParticipantProxyModel::setChatRoomModel(ChatRoomModel * chatRoomModel){
}
}
void ParticipantProxyModel::setConferenceModel(ConferenceModel * conferenceModel){
if(!mConferenceModel || mConferenceModel != conferenceModel){
mConferenceModel = conferenceModel;
if(mConferenceModel) {
auto participants = mConferenceModel->getParticipants();
setSourceModel(participants);
emit participantListModelChanged();
for(int i = 0 ; i < participants->getCount() ; ++i)
emit addressAdded(participants->getAt<ParticipantModel>(i)->getSipAddress());
}else if(!sourceModel()){
setSourceModel(new ParticipantListModel((ConferenceModel*)nullptr, this));
emit participantListModelChanged();
}
sort(0);
emit conferenceModelChanged();
}
}
void ParticipantProxyModel::setShowMe(const bool& show){
if(mShowMe != show){
mShowMe = show;
@ -120,8 +142,11 @@ void ParticipantProxyModel::addAddress(const QString& address){
void ParticipantProxyModel::removeModel(ParticipantModel * participant){
if(participant) {
QString sipAddress = participant->getSipAddress();
if(mChatRoomModel && mChatRoomModel->getChatRoom() && participant->getParticipant() )
mChatRoomModel->getChatRoom()->removeParticipant(participant->getParticipant()); // Remove already added
auto dbParticipant = participant->getParticipant();
if(mChatRoomModel && dbParticipant && mChatRoomModel->getChatRoom())
mChatRoomModel->getChatRoom()->removeParticipant(dbParticipant); // Remove already added
if( mConferenceModel && dbParticipant && mConferenceModel->getConference())
mConferenceModel->getConference()->removeParticipant(dbParticipant );
ParticipantListModel * participantsModel = qobject_cast<ParticipantListModel*>(sourceModel());
participantsModel->remove(participant);
emit countChanged();

View file

@ -27,6 +27,7 @@
class ParticipantModel;
class ChatRoomModel;
class ParticipantListModel;
class ConferenceModel;
// =============================================================================
class QWindow;
@ -40,6 +41,7 @@ public:
ParticipantProxyModel ( QObject *parent = Q_NULLPTR);
Q_PROPERTY(ChatRoomModel* chatRoomModel READ getChatRoomModel WRITE setChatRoomModel NOTIFY chatRoomModelChanged)
Q_PROPERTY(ConferenceModel* conferenceModel READ getConferenceModel WRITE setConferenceModel NOTIFY conferenceModelChanged)
Q_PROPERTY(ParticipantListModel * participantListModel READ getParticipantListModel NOTIFY participantListModelChanged)
Q_PROPERTY(int count READ getCount NOTIFY countChanged)
Q_PROPERTY(bool showMe READ getShowMe WRITE setShowMe NOTIFY showMeChanged)
@ -48,6 +50,7 @@ public:
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override;
ChatRoomModel *getChatRoomModel() const;
ConferenceModel *getConferenceModel() const;
ParticipantListModel * getParticipantListModel() const;
Q_INVOKABLE QStringList getSipAddresses() const;
Q_INVOKABLE QVariantList getParticipants() const;
@ -55,6 +58,7 @@ public:
bool getShowMe() const;
void setChatRoomModel(ChatRoomModel * chatRoomModel);
void setConferenceModel(ConferenceModel * conferenceModel);
void setShowMe(const bool& show);
Q_INVOKABLE void addAddress(const QString& address);
@ -64,6 +68,7 @@ public:
signals:
void chatRoomModelChanged();
void conferenceModelChanged();
void participantListModelChanged();
void countChanged();
void showMeChanged();
@ -71,7 +76,8 @@ signals:
void addressRemoved(QString sipAddress);
private:
ChatRoomModel *mChatRoomModel;
ChatRoomModel *mChatRoomModel = nullptr;
ConferenceModel *mConferenceModel = nullptr;
bool mShowMe = true;
};

View file

@ -52,20 +52,24 @@ void SearchSipAddressesProxyModel::setFilter (const QString &pattern){
void SearchSipAddressesProxyModel::addAddressToIgnore(const QString& address){
std::shared_ptr<linphone::Address> a = Utils::interpretUrl(address);
mResultsToIgnore[Utils::coreStringToAppString(a->asStringUriOnly())] = true;
invalidate();
if(a) {
mResultsToIgnore[Utils::coreStringToAppString(a->asStringUriOnly())] = true;
invalidate();
}
}
void SearchSipAddressesProxyModel::removeAddressToIgnore(const QString& address){
std::shared_ptr<linphone::Address> a = Utils::interpretUrl(address);
mResultsToIgnore.remove(Utils::coreStringToAppString(a->asStringUriOnly()));
invalidate();
if( a){
mResultsToIgnore.remove(Utils::coreStringToAppString(a->asStringUriOnly()));
invalidate();
}
}
bool SearchSipAddressesProxyModel::isIgnored(const QString& address) const{
if(address != ""){
std::shared_ptr<linphone::Address> a = Utils::interpretUrl(address);
return mResultsToIgnore.contains(Utils::coreStringToAppString(a->asStringUriOnly()));
return a ? mResultsToIgnore.contains(Utils::coreStringToAppString(a->asStringUriOnly())) : false;
}
return false;
}

View file

@ -0,0 +1,88 @@
pragma Singleton
import QtQml 2.2
import QtQuick 2.7
import Units 1.0
import ColorsList 1.0
// =============================================================================
QtObject {
property string sectionName: 'ParticipantsListView'
property int height: 500
property int width: 450
property QtObject mainLayout: QtObject {
property int topMargin: 15
property int leftMargin: 25
property int rightMargin: 25
property int spacing: 7
}
property QtObject searchBar : QtObject{
property int topMargin : 10
}
property QtObject results : QtObject{
property int topMargin : 10
property color color : ColorsList.add(sectionName+'_results', 'g').color
property QtObject title : QtObject{
property int topMargin: 10
property int leftMargin: 20
property color color: ColorsList.add(sectionName+'_results_title', 'j').color
property int pointSize : Units.dp * 11
property int weight : Font.DemiBold
}
property QtObject header: QtObject{
property int rightMargin: 55
property color color: Colors.t.color
property int weight : Font.Light
property int pointSize : Units.dp * 10
}
}
property QtObject leaveButton :
QtObject {
property QtObject backgroundColor: QtObject {
property color disabled: ColorsList.add(sectionName+'_leave_bg_d', 'o').color
property color hovered: ColorsList.add(sectionName+'_leave_bg_h', 'j').color
property color normal: ColorsList.add(sectionName+'_leave_bg_n', 'k').color
property color pressed: ColorsList.add(sectionName+'_leave_bg_p', 'i').color
}
property QtObject textColor: QtObject {
property color disabled: ColorsList.add(sectionName+'_leave_text_d', 'q').color
property color hovered: ColorsList.add(sectionName+'_leave_text_h', 'q').color
property color normal: ColorsList.add(sectionName+'_leave_text_n', 'i').color
property color pressed: ColorsList.add(sectionName+'_leave_text_p', 'q').color
}
property QtObject borderColor : QtObject{
property color disabled: ColorsList.add(sectionName+'_leave_border_d', 'q').color
property color hovered: ColorsList.add(sectionName+'_leave_border_h', 'q').color
property color normal: ColorsList.add(sectionName+'_leave_border_n', 'i').color
property color pressed: ColorsList.add(sectionName+'_leave_border_p', 'q').color
}
}
property QtObject addParticipant: QtObject {
property int iconSize: 30
property string name : 'addParticipant'
property string icon : 'add_participant_custom'
property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'l_n_b_bg').color
property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'l_h_b_bg').color
property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'l_p_b_bg').color
property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'l_n_b_fg').color
property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'l_h_b_fg').color
property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'l_p_b_fg').color
}
property QtObject removeParticipant: QtObject {
property int iconSize: 30
property string name : 'removeParticipant'
property string icon : 'remove_participant_custom'
property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'l_n_b_bg').color
property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'l_h_b_bg').color
property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'l_p_b_bg').color
property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'l_n_b_fg').color
property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'l_h_b_fg').color
property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'l_p_b_fg').color
}
}

View file

@ -51,5 +51,7 @@ singleton TelKeypadStyle 1.0 TelKeypad/TelKeypadStyle.qml
singleton TimelineStyle 1.0 Timeline/TimelineStyle.qml
singleton SipAddressesViewStyle 1.0 View/SipAddressesViewStyle.qml
singleton ParticipantsListViewStyle 1.0 View/ParticipantsListViewStyle.qml
singleton ParticipantsViewStyle 1.0 View/ParticipantsViewStyle.qml
singleton SipAddressesViewStyle 1.0 View/SipAddressesViewStyle.qml

View file

@ -0,0 +1,147 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
//import LinphoneUtils 1.0
import LinphoneEnums 1.0
import App.Styles 1.0
import Common.Styles 1.0
import Linphone.Styles 1.0
import Units 1.0
import UtilsCpp 1.0
// =============================================================================
ColumnLayout {
id:mainLayout
property ChatRoomModel chatRoomModel
property ConferenceModel conferenceModel
property ParticipantModel me: conferenceModel && conferenceModel.localParticipant
property bool isAdmin : (chatRoomModel && chatRoomModel.isMeAdmin && !chatRoomModel.isReadOnly) || (me && me.adminStatus)
property bool canHandleParticipants : isAdmin && ( (chatRoomModel && chatRoomModel.canHandleParticipants) || conferenceModel)
property bool haveEncryption: chatRoomModel && chatRoomModel.haveEncryption
onIsAdminChanged: console.log("participantsListView is admin : "+isAdmin)
onCanHandleParticipantsChanged: console.log("CanHandleParticipants:"+canHandleParticipants)
spacing: ParticipantsListViewStyle.mainLayout.spacing
Component.onCompleted: console.log("participantsListView : " +isAdmin +", "+canHandleParticipants +", " +chatRoomModel+", "+conferenceModel + ", "+conferenceModel.localParticipant +", " +conferenceModel.localParticipant.adminStatus)
SmartSearchBar {
id: smartSearchBar
Layout.fillWidth: true
Layout.topMargin: ParticipantsListViewStyle.searchBar.topMargin
showHeader:false
visible: mainLayout.isAdmin && mainLayout.canHandleParticipants
maxMenuHeight: MainWindowStyle.searchBox.maxHeight
//: 'Add Participants' : Placeholder in a search bar for adding participant to the chat room
placeholderText: 'addParticipantPlaceholder'
//: 'Search participants in your contact list in order to invite them into the chat room.'
//~ Tooltip Explanation for inviting the selected participants into chat room
tooltipText: 'addParticipantTooltip'
actions:[{
colorSet: ParticipantsListViewStyle.addParticipant,
secure: mainLayout.haveEncryption,
visible: true,
secureIconVisibleHandler : function(entry) {
return entry.sipAddress && mainLayout.haveEncryption && UtilsCpp.hasCapability(entry.sipAddress, LinphoneEnums.FriendCapabilityLimeX3Dh);
},
handler: function (entry) {
selectedParticipants.addAddress(entry.sipAddress)
},
}]
onEntryClicked: {
selectedParticipants.addAddress(entry.sipAddress)
}
}
ScrollableListViewField {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.bottomMargin: 5
//readOnly: toAddView.count >= conferenceManager.maxParticipants
textFieldStyle: TextFieldStyle.normal
ColumnLayout{
anchors.fill:parent
spacing:0
Text{
Layout.topMargin: ParticipantsListViewStyle.results.title.topMargin
Layout.leftMargin: ParticipantsListViewStyle.results.title.leftMargin
//: 'Participant list'
text:qsTr('participantList')
color: ParticipantsListViewStyle.results.title.color
font.pointSize:ParticipantsListViewStyle.results.title.pointSize
font.weight: ParticipantsListViewStyle.results.title.weight
}
Text{
Layout.preferredHeight: implicitHeight
Layout.rightMargin: ParticipantsListViewStyle.results.header.rightMargin
Layout.alignment: Qt.AlignRight | Qt.AlignBottom
//Layout.topMargin: ParticipantsListViewStyle.results.topMargin
//: 'Admin' : Admin(istrator)
//~ one word for admin status
text : qsTr('adminStatus')
color: ParticipantsListViewStyle.results.header.color
font.pointSize: ParticipantsListViewStyle.results.header.pointSize
font.weight: ParticipantsListViewStyle.results.header.weight
visible: mainLayout.isAdmin && participantView.count > 0
}
ParticipantsView {
id: participantView
Layout.fillHeight: true
Layout.fillWidth: true
//anchors.fill: parent
showContactAddress:false
showSwitch : mainLayout.isAdmin
showSeparator: false
showAdminStatus:!mainLayout.isAdmin
isSelectable: false
hoveredCursor:Qt.WhatsThisCursor
actions: mainLayout.isAdmin ? [{
colorSet: ParticipantsListViewStyle.removeParticipant,
secure:0,
visible:true,
tooltipText: 'Remove this participant from the selection',
handler: function (entry) {
selectedParticipants.removeModel(entry)
// ++lastContacts.reloadCount
}
}]
: []
genSipAddress: ''
model: ParticipantProxyModel {
id:selectedParticipants
chatRoomModel: mainLayout.chatRoomModel
conferenceModel: mainLayout.conferenceModel
onAddressAdded: smartSearchBar.addAddressToIgnore(sipAddress)
onAddressRemoved: smartSearchBar.removeAddressToIgnore(sipAddress)
showMe: mainLayout.isAdmin
}
onEntryClicked: {
contactItem.showContactAddress = !contactItem.showContactAddress
}
}
}
}
}

View file

@ -52,6 +52,7 @@ TelKeypad 1.0 TelKeypad/TelKeypad.qml
Timeline 1.0 Timeline/Timeline.qml
ParticipantsListView 1.0 View/ParticipantsListView.qml
ParticipantsView 1.0 View/ParticipantsView.qml
SipAddressesView 1.0 View/SipAddressesView.qml
ParticipantsView 1.0 View/ParticipantsView.qml

View file

@ -24,7 +24,7 @@ Rectangle {
id: conference
property CallModel callModel
property ConferenceModel conferenceModel: callModel && callModel.getConferenceModel()
property ConferenceModel conferenceModel: callModel && callModel.conferenceModel
property bool cameraIsReady : false
property bool previewIsReady : false
property bool isFullScreen: false // Use this variable to test if we are in fullscreen. Do not test _fullscreen : we need to clean memory before having the window (see .js file)
@ -249,6 +249,7 @@ Rectangle {
Layout.preferredWidth: 400
Layout.rightMargin: 30
callModel: conference.callModel
conferenceModel: conference.conferenceModel
visible: false
onClose: rightMenu.visible = !rightMenu.visible
}

View file

@ -66,7 +66,7 @@ Window {
id: conference
property CallModel callModel
property ConferenceModel conferenceModel: callModel && callModel.getConferenceModel()
property ConferenceModel conferenceModel: callModel && callModel.conferenceModel
property var _fullscreen: null
property bool listCallsOpened: false
@ -287,6 +287,7 @@ Window {
Layout.preferredWidth: 400
Layout.rightMargin: 30
callModel: conference.callModel
conferenceModel: conference.conferenceModel
visible: false
onClose: rightMenu.visible = !rightMenu.visible
}

View file

@ -24,6 +24,10 @@ import 'qrc:/ui/scripts/Utils/utils.js' as Utils
Rectangle{
id: mainItem
property CallModel callModel
property ConferenceModel conferenceModel: callModel.conferenceModel
property ParticipantModel me: conferenceModel.localParticipant
property bool isMeAdmin: me && me.adminStatus
onIsMeAdminChanged: console.log("Is admin : " +isMeAdmin)
signal close()
height: 500
@ -95,8 +99,12 @@ Rectangle{
, icon: (mainItem.callModel.videoEnabled ?
(mainItem.callModel.conferenceVideoLayout == LinphoneEnums.ConferenceLayoutGrid ? VideoConferenceMenuStyle.settingsIcons.gridIcon : VideoConferenceMenuStyle.settingsIcons.activeSpeakerIcon)
: VideoConferenceMenuStyle.settingsIcons.audioOnlyIcon)
, nextPage:layoutMenu}
]
, nextPage:layoutMenu},
{text: mainItem.isMeAdmin ? 'Inviter des participants' : 'Participants'
, icon: VideoConferenceMenuStyle.settingsIcons.participantsIcon
, nextPage:participantsMenu}
]
delegate:
Borders{
bottomColor: VideoConferenceMenuStyle.list.border.color
@ -150,6 +158,7 @@ Rectangle{
}
}
}
//-----------------------------------------------------------------------------------------------------------------------------
Component{
id: mediaMenu
ColumnLayout{
@ -172,6 +181,7 @@ Rectangle{
}
}
}
//-----------------------------------------------------------------------------------------------------------------------------
Component{
id: layoutMenu
ColumnLayout{
@ -224,5 +234,23 @@ Rectangle{
}
}
}
//-----------------------------------------------------------------------------------------------------------------------------
Component{
id: participantsMenu
ColumnLayout{
Layout.fillHeight: true
Layout.fillWidth: true
ParticipantsListView{
Layout.fillHeight: true
Layout.fillWidth: true
//Layout.minimumHeight: fitHeight
conferenceModel: mainItem.conferenceModel
}
Item{// Spacer
Layout.fillWidth: true
Layout.fillHeight: true
}
}
}
}
}

View file

@ -44,6 +44,7 @@ QtObject {
property string activeSpeakerIcon: 'conference_layout_active_speaker_custom'
property string audioOnlyIcon: 'conference_audio_only_custom'
property string mediaIcon: 'micro_on_custom'
property string participantsIcon: 'participants_custom'
property int width: 40
property int height: 40
}

@ -1 +1 @@
Subproject commit c8d936196b84855415e90d41346e7b3a25374077
Subproject commit 074802f6c0bcc7f095e94faad804ce083de3bcc3