mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-07-31 04:45:39 +02:00
feature: improve advanced call information overlay
GitLab: #925 Change-Id: Id75b14bf431ac421b135beb75918dbf37a81d53c
This commit is contained in:
parent
a28d5c5c55
commit
c977c732f2
24 changed files with 853 additions and 252 deletions
0
build.py
Normal file → Executable file
0
build.py
Normal file → Executable file
2
daemon
2
daemon
|
@ -1 +1 @@
|
||||||
Subproject commit 9d76cf5cc767e33ab06054bfa40ee45f671002bd
|
Subproject commit eb9c52cee45660f68334adb32a23d6f743d6bcf4
|
|
@ -37,19 +37,27 @@
|
||||||
|
|
||||||
AvAdapter::AvAdapter(LRCInstance* instance, QObject* parent)
|
AvAdapter::AvAdapter(LRCInstance* instance, QObject* parent)
|
||||||
: QmlAdapterBase(instance, parent)
|
: QmlAdapterBase(instance, parent)
|
||||||
|
, rendererInformationListModel_(std::make_unique<RendererInformationListModel>())
|
||||||
{
|
{
|
||||||
|
set_renderersInfoList(QVariant::fromValue(rendererInformationListModel_.get()));
|
||||||
connect(&lrcInstance_->avModel(),
|
connect(&lrcInstance_->avModel(),
|
||||||
&lrc::api::AVModel::audioDeviceEvent,
|
&lrc::api::AVModel::audioDeviceEvent,
|
||||||
this,
|
this,
|
||||||
&AvAdapter::onAudioDeviceEvent);
|
&AvAdapter::onAudioDeviceEvent);
|
||||||
|
// QueuedConnection mandatory to avoid deadlock
|
||||||
connect(&lrcInstance_->avModel(),
|
connect(&lrcInstance_->avModel(),
|
||||||
&lrc::api::AVModel::rendererStarted,
|
&lrc::api::AVModel::rendererStarted,
|
||||||
this,
|
this,
|
||||||
&AvAdapter::onRendererStarted);
|
&AvAdapter::onRendererStarted,
|
||||||
|
Qt::QueuedConnection);
|
||||||
connect(&lrcInstance_->avModel(),
|
connect(&lrcInstance_->avModel(),
|
||||||
&lrc::api::AVModel::onRendererInfosUpdated,
|
&lrc::api::AVModel::rendererStopped,
|
||||||
this,
|
this,
|
||||||
&AvAdapter::setRenderersInfoList);
|
&AvAdapter::onRendererStopped);
|
||||||
|
connect(&lrcInstance_->avModel(),
|
||||||
|
&lrc::api::AVModel::onRendererFpsChange,
|
||||||
|
this,
|
||||||
|
&AvAdapter::updateRenderersFPSInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The top left corner of primary screen is (0, 0).
|
// The top left corner of primary screen is (0, 0).
|
||||||
|
@ -323,6 +331,12 @@ AvAdapter::onRendererStarted(const QString& id, const QSize& size)
|
||||||
if (callId.isEmpty()) {
|
if (callId.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update renderer Information list
|
||||||
|
auto& avModel = lrcInstance_->avModel();
|
||||||
|
auto rendererInfo = avModel.getRenderersInfo(id)[0];
|
||||||
|
rendererInformationListModel_->addElement(qMakePair(id, rendererInfo));
|
||||||
|
|
||||||
auto callModel = lrcInstance_->getCurrentCallModel();
|
auto callModel = lrcInstance_->getCurrentCallModel();
|
||||||
auto renderDevice = callModel->getCurrentRenderedDevice(callId);
|
auto renderDevice = callModel->getCurrentRenderedDevice(callId);
|
||||||
if (!id.contains("://"))
|
if (!id.contains("://"))
|
||||||
|
@ -331,6 +345,12 @@ AvAdapter::onRendererStarted(const QString& id, const QSize& size)
|
||||||
set_currentRenderingDeviceType(renderDevice.type);
|
set_currentRenderingDeviceType(renderDevice.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AvAdapter::onRendererStopped(const QString& id)
|
||||||
|
{
|
||||||
|
rendererInformationListModel_->removeElement(id);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AvAdapter::isSharing() const
|
AvAdapter::isSharing() const
|
||||||
{
|
{
|
||||||
|
@ -448,7 +468,23 @@ AvAdapter::setHardwareAcceleration(bool accelerate)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AvAdapter::setRenderersInfoList(QVariantList renderersInfo)
|
AvAdapter::resetRendererInfo()
|
||||||
{
|
{
|
||||||
set_renderersInfoList(renderersInfo);
|
rendererInformationListModel_->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AvAdapter::setRendererInfo()
|
||||||
|
{
|
||||||
|
auto& avModel = lrcInstance_->avModel();
|
||||||
|
for (auto rendererInfo : avModel.getRenderersInfo()) {
|
||||||
|
rendererInformationListModel_->addElement(
|
||||||
|
qMakePair(rendererInfo["RENDERER_ID"], rendererInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AvAdapter::updateRenderersFPSInfo(QPair<QString, QString> fpsInfo)
|
||||||
|
{
|
||||||
|
rendererInformationListModel_->updateFps(fpsInfo.first, fpsInfo.second);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <qtutils.h>
|
#include <qtutils.h>
|
||||||
|
|
||||||
|
#include "rendererinformationlistmodel.h"
|
||||||
|
|
||||||
class AvAdapter final : public QmlAdapterBase
|
class AvAdapter final : public QmlAdapterBase
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -36,7 +38,7 @@ class AvAdapter final : public QmlAdapterBase
|
||||||
QML_PROPERTY(bool, muteCamera)
|
QML_PROPERTY(bool, muteCamera)
|
||||||
QML_RO_PROPERTY(QStringList, windowsNames)
|
QML_RO_PROPERTY(QStringList, windowsNames)
|
||||||
QML_RO_PROPERTY(QList<QVariant>, windowsIds)
|
QML_RO_PROPERTY(QList<QVariant>, windowsIds)
|
||||||
QML_RO_PROPERTY(QVariantList, renderersInfoList)
|
QML_RO_PROPERTY(QVariant, renderersInfoList)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AvAdapter(LRCInstance* instance, QObject* parent = nullptr);
|
explicit AvAdapter(LRCInstance* instance, QObject* parent = nullptr);
|
||||||
|
@ -103,14 +105,18 @@ protected:
|
||||||
Q_INVOKABLE void increaseCodecPriority(unsigned int id, bool isVideo);
|
Q_INVOKABLE void increaseCodecPriority(unsigned int id, bool isVideo);
|
||||||
Q_INVOKABLE void decreaseCodecPriority(unsigned int id, bool isVideo);
|
Q_INVOKABLE void decreaseCodecPriority(unsigned int id, bool isVideo);
|
||||||
|
|
||||||
|
Q_INVOKABLE void resetRendererInfo();
|
||||||
|
Q_INVOKABLE void setRendererInfo();
|
||||||
|
|
||||||
// TODO: to be removed
|
// TODO: to be removed
|
||||||
Q_INVOKABLE bool getHardwareAcceleration();
|
Q_INVOKABLE bool getHardwareAcceleration();
|
||||||
Q_INVOKABLE void setHardwareAcceleration(bool accelerate);
|
Q_INVOKABLE void setHardwareAcceleration(bool accelerate);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void setRenderersInfoList(QVariantList renderersInfo);
|
void updateRenderersFPSInfo(QPair<QString, QString> fpsInfo);
|
||||||
void onAudioDeviceEvent();
|
void onAudioDeviceEvent();
|
||||||
void onRendererStarted(const QString& id, const QSize& size);
|
void onRendererStarted(const QString& id, const QSize& size);
|
||||||
|
void onRendererStopped(const QString& id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Get screens arrangement rect relative to primary screen.
|
// Get screens arrangement rect relative to primary screen.
|
||||||
|
@ -118,4 +124,6 @@ private:
|
||||||
|
|
||||||
// Get the screen number
|
// Get the screen number
|
||||||
int getScreenNumber(int screenId = 0) const;
|
int getScreenNumber(int screenId = 0) const;
|
||||||
|
|
||||||
|
std::unique_ptr<RendererInformationListModel> rendererInformationListModel_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,7 +40,10 @@
|
||||||
CallAdapter::CallAdapter(SystemTray* systemTray, LRCInstance* instance, QObject* parent)
|
CallAdapter::CallAdapter(SystemTray* systemTray, LRCInstance* instance, QObject* parent)
|
||||||
: QmlAdapterBase(instance, parent)
|
: QmlAdapterBase(instance, parent)
|
||||||
, systemTray_(systemTray)
|
, systemTray_(systemTray)
|
||||||
|
, callInformationListModel_(std::make_unique<CallInformationListModel>())
|
||||||
{
|
{
|
||||||
|
set_callInformationList(QVariant::fromValue(callInformationListModel_.get()));
|
||||||
|
|
||||||
timer = new QTimer(this);
|
timer = new QTimer(this);
|
||||||
connect(timer, &QTimer::timeout, this, &CallAdapter::updateAdvancedInformation);
|
connect(timer, &QTimer::timeout, this, &CallAdapter::updateAdvancedInformation);
|
||||||
|
|
||||||
|
@ -127,7 +130,6 @@ CallAdapter::onCallStatusChanged(const QString& accountId, const QString& callId
|
||||||
auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
|
auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
|
||||||
auto& callModel = accInfo.callModel;
|
auto& callModel = accInfo.callModel;
|
||||||
const auto call = callModel->getCall(callId);
|
const auto call = callModel->getCall(callId);
|
||||||
auto to = lrcInstance_->accountModel().bestNameForAccount(accountId);
|
|
||||||
|
|
||||||
const auto& convInfo = lrcInstance_->getConversationFromCallId(callId, accountId);
|
const auto& convInfo = lrcInstance_->getConversationFromCallId(callId, accountId);
|
||||||
if (convInfo.uid.isEmpty() || call.isOutgoing)
|
if (convInfo.uid.isEmpty() || call.isOutgoing)
|
||||||
|
@ -150,7 +152,7 @@ CallAdapter::onCallStatusChanged(const QString& accountId, const QString& callId
|
||||||
auto from = accInfo.conversationModel->title(convInfo.uid);
|
auto from = accInfo.conversationModel->title(convInfo.uid);
|
||||||
auto notifId = QString("%1;%2").arg(accountId).arg(convInfo.uid);
|
auto notifId = QString("%1;%2").arg(accountId).arg(convInfo.uid);
|
||||||
systemTray_->showNotification(notifId,
|
systemTray_->showNotification(notifId,
|
||||||
tr("%1 missed call").arg(to),
|
tr("Missed call"),
|
||||||
tr("Missed call with %1").arg(from),
|
tr("Missed call with %1").arg(from),
|
||||||
NotificationType::CHAT,
|
NotificationType::CHAT,
|
||||||
Utils::QImageToByteArray(convAvatar));
|
Utils::QImageToByteArray(convAvatar));
|
||||||
|
@ -170,6 +172,7 @@ CallAdapter::onParticipantAdded(const QString& callId, int index)
|
||||||
try {
|
try {
|
||||||
if (lrcInstance_->get_selectedConvUid().isEmpty())
|
if (lrcInstance_->get_selectedConvUid().isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto& currentConvInfo = accInfo.conversationModel.get()->getConversationForUid(
|
const auto& currentConvInfo = accInfo.conversationModel.get()->getConversationForUid(
|
||||||
lrcInstance_->get_selectedConvUid());
|
lrcInstance_->get_selectedConvUid());
|
||||||
if (callId != currentConvInfo->get().callId && callId != currentConvInfo->get().confId) {
|
if (callId != currentConvInfo->get().callId && callId != currentConvInfo->get().confId) {
|
||||||
|
@ -191,6 +194,7 @@ CallAdapter::onParticipantRemoved(const QString& callId, int index)
|
||||||
try {
|
try {
|
||||||
if (lrcInstance_->get_selectedConvUid().isEmpty())
|
if (lrcInstance_->get_selectedConvUid().isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto& currentConvInfo = accInfo.conversationModel.get()->getConversationForUid(
|
const auto& currentConvInfo = accInfo.conversationModel.get()->getConversationForUid(
|
||||||
lrcInstance_->get_selectedConvUid());
|
lrcInstance_->get_selectedConvUid());
|
||||||
if (callId != currentConvInfo->get().callId && callId != currentConvInfo->get().confId) {
|
if (callId != currentConvInfo->get().callId && callId != currentConvInfo->get().confId) {
|
||||||
|
@ -223,6 +227,27 @@ CallAdapter::onParticipantUpdated(const QString& callId, int index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CallAdapter::onCallStarted(const QString& callId)
|
||||||
|
{
|
||||||
|
if (lrcInstance_->get_selectedConvUid().isEmpty())
|
||||||
|
return;
|
||||||
|
auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId_);
|
||||||
|
auto& callModel = accInfo.callModel;
|
||||||
|
// update call Information list by adding the new information related to the callId
|
||||||
|
callInformationListModel_->addElement(
|
||||||
|
qMakePair(callId, callModel->advancedInformationForCallId(callId)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CallAdapter::onCallEnded(const QString& callId)
|
||||||
|
{
|
||||||
|
if (lrcInstance_->get_selectedConvUid().isEmpty())
|
||||||
|
return;
|
||||||
|
// update call Information list by removing information related to the callId
|
||||||
|
callInformationListModel_->removeElement(callId);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CallAdapter::onCallStatusChanged(const QString& callId, int code)
|
CallAdapter::onCallStatusChanged(const QString& callId, int code)
|
||||||
{
|
{
|
||||||
|
@ -570,7 +595,6 @@ CallAdapter::showNotification(const QString& accountId, const QString& convUid)
|
||||||
{
|
{
|
||||||
auto& accInfo = lrcInstance_->getAccountInfo(accountId);
|
auto& accInfo = lrcInstance_->getAccountInfo(accountId);
|
||||||
auto title = accInfo.conversationModel->title(convUid);
|
auto title = accInfo.conversationModel->title(convUid);
|
||||||
auto to = lrcInstance_->accountModel().bestNameForAccount(accountId);
|
|
||||||
|
|
||||||
auto preferences = accInfo.conversationModel->getConversationPreferences(convUid);
|
auto preferences = accInfo.conversationModel->getConversationPreferences(convUid);
|
||||||
// Ignore notifications for this conversation
|
// Ignore notifications for this conversation
|
||||||
|
@ -581,7 +605,7 @@ CallAdapter::showNotification(const QString& accountId, const QString& convUid)
|
||||||
auto convAvatar = Utils::conversationAvatar(lrcInstance_, convUid, QSize(50, 50), accountId);
|
auto convAvatar = Utils::conversationAvatar(lrcInstance_, convUid, QSize(50, 50), accountId);
|
||||||
auto notifId = QString("%1;%2").arg(accountId).arg(convUid);
|
auto notifId = QString("%1;%2").arg(accountId).arg(convUid);
|
||||||
systemTray_->showNotification(notifId,
|
systemTray_->showNotification(notifId,
|
||||||
tr("%1 incoming call").arg(to),
|
tr("Incoming call"),
|
||||||
tr("%1 is calling you").arg(title),
|
tr("%1 is calling you").arg(title),
|
||||||
NotificationType::CALL,
|
NotificationType::CALL,
|
||||||
Utils::QImageToByteArray(convAvatar));
|
Utils::QImageToByteArray(convAvatar));
|
||||||
|
@ -620,6 +644,18 @@ CallAdapter::connectCallModel(const QString& accountId)
|
||||||
&CallAdapter::onParticipantUpdated,
|
&CallAdapter::onParticipantUpdated,
|
||||||
Qt::UniqueConnection);
|
Qt::UniqueConnection);
|
||||||
|
|
||||||
|
connect(accInfo.callModel.get(),
|
||||||
|
&CallModel::callStarted,
|
||||||
|
this,
|
||||||
|
&CallAdapter::onCallStarted,
|
||||||
|
Qt::UniqueConnection);
|
||||||
|
|
||||||
|
connect(accInfo.callModel.get(),
|
||||||
|
&CallModel::callEnded,
|
||||||
|
this,
|
||||||
|
&CallAdapter::onCallEnded,
|
||||||
|
Qt::UniqueConnection);
|
||||||
|
|
||||||
connect(accInfo.callModel.get(),
|
connect(accInfo.callModel.get(),
|
||||||
&CallModel::callStatusChanged,
|
&CallModel::callStatusChanged,
|
||||||
this,
|
this,
|
||||||
|
@ -1071,13 +1107,39 @@ CallAdapter::getCallDurationTime(const QString& accountId, const QString& convUi
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CallAdapter::resetCallInfo()
|
||||||
|
{
|
||||||
|
callInformationListModel_->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CallAdapter::setCallInfo()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
auto& callModel = lrcInstance_->accountModel().getAccountInfo(accountId_).callModel;
|
||||||
|
for (auto callId : callModel->getCallIds()) {
|
||||||
|
callInformationListModel_->addElement(
|
||||||
|
qMakePair(callId, callModel->advancedInformationForCallId(callId)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
qWarning() << e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CallAdapter::updateAdvancedInformation()
|
CallAdapter::updateAdvancedInformation()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
auto& callModel = lrcInstance_->accountModel().getAccountInfo(accountId_).callModel;
|
auto& callModel = lrcInstance_->accountModel().getAccountInfo(accountId_).callModel;
|
||||||
if (callModel)
|
for (auto callId : callModel->getCallIds()) {
|
||||||
set_callInformation(QVariantList::fromList(callModel->getAdvancedInformation()));
|
if (!callInformationListModel_->addElement(
|
||||||
|
qMakePair(callId, callModel->advancedInformationForCallId(callId)))) {
|
||||||
|
callInformationListModel_->editElement(
|
||||||
|
qMakePair(callId, callModel->advancedInformationForCallId(callId)));
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
qWarning() << e.what();
|
qWarning() << e.what();
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,13 +31,15 @@
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QSystemTrayIcon>
|
#include <QSystemTrayIcon>
|
||||||
|
|
||||||
|
#include "callInformationListModel.h"
|
||||||
|
|
||||||
class SystemTray;
|
class SystemTray;
|
||||||
|
|
||||||
class CallAdapter final : public QmlAdapterBase
|
class CallAdapter final : public QmlAdapterBase
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
QML_PROPERTY(bool, hasCall)
|
QML_PROPERTY(bool, hasCall)
|
||||||
QML_RO_PROPERTY(QVariantList, callInformation)
|
QML_RO_PROPERTY(QVariant, callInformationList)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QTimer* timer;
|
QTimer* timer;
|
||||||
|
@ -92,6 +94,8 @@ public:
|
||||||
const QString& accountId = {},
|
const QString& accountId = {},
|
||||||
bool forceCallOnly = false);
|
bool forceCallOnly = false);
|
||||||
Q_INVOKABLE QString getCallDurationTime(const QString& accountId, const QString& convUid);
|
Q_INVOKABLE QString getCallDurationTime(const QString& accountId, const QString& convUid);
|
||||||
|
Q_INVOKABLE void resetCallInfo();
|
||||||
|
Q_INVOKABLE void setCallInfo();
|
||||||
Q_INVOKABLE void updateAdvancedInformation();
|
Q_INVOKABLE void updateAdvancedInformation();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
@ -112,6 +116,8 @@ public Q_SLOTS:
|
||||||
void onParticipantAdded(const QString& callId, int index);
|
void onParticipantAdded(const QString& callId, int index);
|
||||||
void onParticipantRemoved(const QString& callId, int index);
|
void onParticipantRemoved(const QString& callId, int index);
|
||||||
void onParticipantUpdated(const QString& callId, int index);
|
void onParticipantUpdated(const QString& callId, int index);
|
||||||
|
void onCallStarted(const QString& callId);
|
||||||
|
void onCallEnded(const QString& callId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void showNotification(const QString& accountId, const QString& convUid);
|
void showNotification(const QString& accountId, const QString& convUid);
|
||||||
|
@ -126,4 +132,6 @@ private:
|
||||||
QScopedPointer<CallOverlayModel> overlayModel_;
|
QScopedPointer<CallOverlayModel> overlayModel_;
|
||||||
QScopedPointer<CallParticipantsModel> participantsModel_;
|
QScopedPointer<CallParticipantsModel> participantsModel_;
|
||||||
VectorString currentConfSubcalls_;
|
VectorString currentConfSubcalls_;
|
||||||
|
|
||||||
|
std::unique_ptr<CallInformationListModel> callInformationListModel_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -299,6 +299,19 @@ Item {
|
||||||
property string raiseHand: qsTr("Raise hand")
|
property string raiseHand: qsTr("Raise hand")
|
||||||
property string layoutSettings: qsTr("Layout settings")
|
property string layoutSettings: qsTr("Layout settings")
|
||||||
|
|
||||||
|
//advanced information
|
||||||
|
property string renderersInformation: qsTr("Renderers information")
|
||||||
|
property string callInformation: qsTr("Call information")
|
||||||
|
property string peerNumber: qsTr("Peer number")
|
||||||
|
property string callId: qsTr("Call id")
|
||||||
|
property string sockets: qsTr("Sockets")
|
||||||
|
property string videoCodec: qsTr("Video codec")
|
||||||
|
property string hardwareAcceleration: qsTr("Hardware acceleration")
|
||||||
|
property string videoBitrate: qsTr("Video bitrate")
|
||||||
|
property string audioCodec: qsTr("Audio codec")
|
||||||
|
property string rendererId: qsTr("Renderer id")
|
||||||
|
property string fps_short: qsTr("Fps")
|
||||||
|
|
||||||
// Share location/position
|
// Share location/position
|
||||||
property string shareLocation: qsTr("Share location")
|
property string shareLocation: qsTr("Share location")
|
||||||
property string stopSharingLocation: qsTr("Stop sharing")
|
property string stopSharingLocation: qsTr("Stop sharing")
|
||||||
|
|
|
@ -376,9 +376,11 @@ Item {
|
||||||
//Call information
|
//Call information
|
||||||
property real textFontPointSize: calcSize(10)
|
property real textFontPointSize: calcSize(10)
|
||||||
property real titleFontPointSize: calcSize(13)
|
property real titleFontPointSize: calcSize(13)
|
||||||
property color callInfoColor: chatviewTextColor
|
property color callInfoColor: whiteColor
|
||||||
property int callInformationElementsSpacing: 5
|
property int callInformationElementsSpacing: 5
|
||||||
property int callInformationBlockSpacing: 25
|
property int callInformationBlockSpacing: 25
|
||||||
|
property int callInformationlayoutMargins: 10
|
||||||
|
|
||||||
|
|
||||||
// Jami switch
|
// Jami switch
|
||||||
property real switchIndicatorRadius: 30
|
property real switchIndicatorRadius: 30
|
||||||
|
|
255
src/app/mainview/components/CallInformationOverlay.qml
Normal file
255
src/app/mainview/components/CallInformationOverlay.qml
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Savoir-faire Linux Inc.
|
||||||
|
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
import net.jami.Models 1.1
|
||||||
|
import net.jami.Adapters 1.1
|
||||||
|
import net.jami.Constants 1.1
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
|
|
||||||
|
import "../../commoncomponents"
|
||||||
|
|
||||||
|
Popup {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property real maxHeight: parent.height * 40 / 100
|
||||||
|
property real maxTextWidth: parent.width * 30 / 100
|
||||||
|
|
||||||
|
property var advancedList
|
||||||
|
property var fps
|
||||||
|
|
||||||
|
width: container.width
|
||||||
|
height: container.height
|
||||||
|
closePolicy: Popup.NoAutoClosed
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
CallAdapter.stopTimerInformation()
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpened: {
|
||||||
|
AvAdapter.resetRendererInfo()
|
||||||
|
CallAdapter.resetCallInfo()
|
||||||
|
CallAdapter.setCallInfo()
|
||||||
|
AvAdapter.setRendererInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: JamiTheme.transparentColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: container
|
||||||
|
|
||||||
|
color: JamiTheme.blackColor
|
||||||
|
opacity: 0.85
|
||||||
|
radius: 10
|
||||||
|
width: windowContent.width
|
||||||
|
height: windowContent.height
|
||||||
|
|
||||||
|
PushButton {
|
||||||
|
id: closeButton
|
||||||
|
|
||||||
|
anchors.top: container.top
|
||||||
|
anchors.topMargin: 5
|
||||||
|
anchors.right: container.right
|
||||||
|
anchors.rightMargin: 5
|
||||||
|
normalColor: JamiTheme.transparentColor
|
||||||
|
imageColor: JamiTheme.callInfoColor
|
||||||
|
source: JamiResources.round_close_24dp_svg
|
||||||
|
circled: false
|
||||||
|
toolTipText: JamiStrings.close
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: windowContent
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: JamiTheme.callInformationBlockSpacing
|
||||||
|
Layout.margins: JamiTheme.callInformationlayoutMargins
|
||||||
|
Layout.preferredWidth: callInfoListview.width
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
|
||||||
|
Text{
|
||||||
|
id: textTest
|
||||||
|
color: JamiTheme.callInfoColor
|
||||||
|
text: JamiStrings.callInformation
|
||||||
|
font.pointSize: JamiTheme.titleFontPointSize
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: callInfoListview
|
||||||
|
|
||||||
|
model: advancedList
|
||||||
|
Layout.preferredWidth: root.maxTextWidth
|
||||||
|
Layout.preferredHeight: contentItem.childrenRect.height < root.maxHeight ? contentItem.childrenRect.height : root.maxHeight
|
||||||
|
spacing: JamiTheme.callInformationBlockSpacing
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
delegate: Column {
|
||||||
|
spacing: JamiTheme.callInformationElementsSpacing
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: JamiTheme.callInfoColor
|
||||||
|
text: JamiStrings.callId + ": " + CALL_ID
|
||||||
|
font.pointSize: JamiTheme.textFontPointSize
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
width: callInfoListview.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
function stringWithoutRing(peerNumber){
|
||||||
|
return peerNumber.replace("@ring.dht","") ;
|
||||||
|
}
|
||||||
|
color: JamiTheme.callInfoColor
|
||||||
|
text: JamiStrings.peerNumber + ": " + stringWithoutRing(PEER_NUMBER)
|
||||||
|
font.pointSize: JamiTheme.textFontPointSize
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
width: callInfoListview.width
|
||||||
|
}
|
||||||
|
Column {
|
||||||
|
id: socketLayout
|
||||||
|
|
||||||
|
property bool showAll: false
|
||||||
|
width: callInfoListview.width
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Text {
|
||||||
|
color: JamiTheme.callInfoColor
|
||||||
|
text: JamiStrings.sockets
|
||||||
|
font.pointSize: JamiTheme.textFontPointSize
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
width: socketLayout.width
|
||||||
|
}
|
||||||
|
|
||||||
|
PushButton {
|
||||||
|
source: socketLayout.showAll ? JamiResources.expand_less_24dp_svg : JamiResources.expand_more_24dp_svg
|
||||||
|
normalColor: JamiTheme.transparentColor
|
||||||
|
Layout.preferredWidth: 20
|
||||||
|
Layout.preferredHeight: 20
|
||||||
|
imageColor: JamiTheme.callInfoColor
|
||||||
|
onClicked: {
|
||||||
|
socketLayout.showAll = !socketLayout.showAll
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: JamiTheme.callInfoColor
|
||||||
|
text: SOCKETS
|
||||||
|
font.pointSize: JamiTheme.textFontPointSize
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
visible: socketLayout.showAll
|
||||||
|
width: socketLayout.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: JamiTheme.callInfoColor
|
||||||
|
text: JamiStrings.videoCodec + ": " + VIDEO_CODEC
|
||||||
|
font.pointSize: JamiTheme.textFontPointSize
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
width: callInfoListview.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: JamiTheme.callInfoColor
|
||||||
|
text: JamiStrings.audioCodec + ": " + AUDIO_CODEC + " " + AUDIO_SAMPLE_RATE + " Hz"
|
||||||
|
font.pointSize: JamiTheme.textFontPointSize
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
width: callInfoListview.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: JamiTheme.callInfoColor
|
||||||
|
text: JamiStrings.hardwareAcceleration + ": " + HARDWARE_ACCELERATION
|
||||||
|
font.pointSize: JamiTheme.textFontPointSize
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
width: callInfoListview.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: JamiTheme.callInfoColor
|
||||||
|
text: JamiStrings.videoBitrate + ": " + VIDEO_BITRATE + " bps"
|
||||||
|
font.pointSize: JamiTheme.textFontPointSize
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
width: callInfoListview.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: JamiTheme.callInformationBlockSpacing
|
||||||
|
Layout.margins: JamiTheme.callInformationlayoutMargins
|
||||||
|
Layout.preferredWidth: renderersInfoListview.width
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: JamiTheme.callInfoColor
|
||||||
|
text: JamiStrings.renderersInformation
|
||||||
|
font.pointSize: JamiTheme.titleFontPointSize
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: renderersInfoListview
|
||||||
|
|
||||||
|
Layout.preferredWidth: root.maxTextWidth
|
||||||
|
Layout.preferredHeight: contentItem.childrenRect.height < root.maxHeight ? contentItem.childrenRect.height : root.maxHeight
|
||||||
|
spacing: JamiTheme.callInformationBlockSpacing
|
||||||
|
model: fps
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
delegate: Column {
|
||||||
|
spacing: JamiTheme.callInformationElementsSpacing
|
||||||
|
|
||||||
|
Text{
|
||||||
|
color: JamiTheme.callInfoColor
|
||||||
|
text: JamiStrings.rendererId + ": " + RENDERER_ID
|
||||||
|
font.pointSize: JamiTheme.textFontPointSize
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
width: renderersInfoListview.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: testText
|
||||||
|
color: JamiTheme.callInfoColor
|
||||||
|
text: JamiStrings.fps_short + ": " + FPS
|
||||||
|
font.pointSize: JamiTheme.textFontPointSize
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
width: renderersInfoListview.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: JamiTheme.callInfoColor
|
||||||
|
text: JamiStrings.resolution + ": " + RES
|
||||||
|
font.pointSize: JamiTheme.textFontPointSize
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
width: renderersInfoListview.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,213 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2022 Savoir-faire Linux Inc.
|
|
||||||
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
import net.jami.Models 1.1
|
|
||||||
import net.jami.Adapters 1.1
|
|
||||||
import net.jami.Constants 1.1
|
|
||||||
import Qt5Compat.GraphicalEffects
|
|
||||||
|
|
||||||
import "../../commoncomponents"
|
|
||||||
|
|
||||||
Window {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
width: parent.width * 2 / 3
|
|
||||||
height: parent.height * 2 / 3
|
|
||||||
property var advancedList
|
|
||||||
property var fps
|
|
||||||
|
|
||||||
onClosing: {
|
|
||||||
CallAdapter.stopTimerInformation()
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: container
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
color: JamiTheme.secondaryBackgroundColor
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: windowContent
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: JamiTheme.callInformationBlockSpacing
|
|
||||||
|
|
||||||
Text{
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "Call information"
|
|
||||||
font.pointSize: JamiTheme.titleFontPointSize
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: itemCallInformation
|
|
||||||
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
model: advancedList
|
|
||||||
width: parent.width
|
|
||||||
height: root.height
|
|
||||||
spacing: JamiTheme.callInformationBlockSpacing
|
|
||||||
|
|
||||||
delegate: Column {
|
|
||||||
spacing: JamiTheme.callInformationElementsSpacing
|
|
||||||
|
|
||||||
Text {
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "Call id: " + modelData.CALL_ID
|
|
||||||
font.pointSize: JamiTheme.textFontPointSize
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
width: itemCallInformation.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "Video codec: " + modelData.VIDEO_CODEC
|
|
||||||
font.pointSize: JamiTheme.textFontPointSize
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
width: itemCallInformation.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "Audio codec: " + modelData.AUDIO_CODEC
|
|
||||||
font.pointSize: JamiTheme.textFontPointSize
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
width: itemCallInformation.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
function stringWithoutRing(peerNumber){
|
|
||||||
return peerNumber.replace("@ring.dht","") ;
|
|
||||||
}
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "PEER_NUMBER: " + stringWithoutRing(modelData.PEER_NUMBER)
|
|
||||||
font.pointSize: JamiTheme.textFontPointSize
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
width: itemCallInformation.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "Hardware acceleration: " + modelData.HARDWARE_ACCELERATION
|
|
||||||
font.pointSize: JamiTheme.textFontPointSize
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
width: itemCallInformation.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "Video min bitrate: " + modelData.VIDEO_MIN_BITRATE
|
|
||||||
font.pointSize: JamiTheme.textFontPointSize
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
width: itemCallInformation.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "Video max bitrate: " + modelData.VIDEO_MAX_BITRATE
|
|
||||||
font.pointSize: JamiTheme.textFontPointSize
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
width: itemCallInformation.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "Video bitrate: " + modelData.VIDEO_BITRATE
|
|
||||||
font.pointSize: JamiTheme.textFontPointSize
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
width: itemCallInformation.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "Sockets: " + modelData.SOCKETS
|
|
||||||
font.pointSize: JamiTheme.textFontPointSize
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
width: itemCallInformation.width
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: JamiTheme.callInformationBlockSpacing
|
|
||||||
|
|
||||||
Text {
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "Renderers information"
|
|
||||||
font.pointSize: JamiTheme.titleFontPointSize
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: itemParticipantInformation
|
|
||||||
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
width: parent.width
|
|
||||||
height: root.height
|
|
||||||
spacing: JamiTheme.callInformationBlockSpacing
|
|
||||||
model: fps
|
|
||||||
|
|
||||||
delegate: Column {
|
|
||||||
spacing: JamiTheme.callInformationElementsSpacing
|
|
||||||
|
|
||||||
Text{
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "Renderer id: " + modelData.ID
|
|
||||||
font.pointSize: JamiTheme.textFontPointSize
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
width: itemParticipantInformation.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "Fps: " + modelData.FPS
|
|
||||||
font.pointSize: JamiTheme.textFontPointSize
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
width: itemParticipantInformation.width
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
color: JamiTheme.callInfoColor
|
|
||||||
text: "Resolution: " + modelData.RES
|
|
||||||
font.pointSize: JamiTheme.textFontPointSize
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
width: itemParticipantInformation.width
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -46,7 +46,7 @@ Item {
|
||||||
SelectScreenWindowCreation.destroySelectScreenWindow()
|
SelectScreenWindowCreation.destroySelectScreenWindow()
|
||||||
ScreenRubberBandCreation.destroyScreenRubberBandWindow()
|
ScreenRubberBandCreation.destroyScreenRubberBandWindow()
|
||||||
PluginHandlerPickerCreation.closePluginHandlerPicker()
|
PluginHandlerPickerCreation.closePluginHandlerPicker()
|
||||||
callInformationWindow.close()
|
callInformationOverlay.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// x, y position does not need to be translated
|
// x, y position does not need to be translated
|
||||||
|
@ -71,12 +71,16 @@ Item {
|
||||||
y: root.height / 2 - sipInputPanel.height / 2
|
y: root.height / 2 - sipInputPanel.height / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
CallInformationWindow {
|
CallInformationOverlay {
|
||||||
id: callInformationWindow
|
id: callInformationOverlay
|
||||||
|
|
||||||
visible: false
|
visible: false
|
||||||
advancedList: CallAdapter.callInformation
|
advancedList: CallAdapter.callInformationList
|
||||||
fps: AvAdapter.renderersInfoList
|
fps: AvAdapter.renderersInfoList
|
||||||
|
|
||||||
|
Component.onDestruction: {
|
||||||
|
CallAdapter.stopTimerInformation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JamiFileDialog {
|
JamiFileDialog {
|
||||||
|
|
|
@ -192,7 +192,7 @@ ContextMenuAutoLoader {
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
CallAdapter.startTimerInformation();
|
CallAdapter.startTimerInformation();
|
||||||
callInformationWindow.show()
|
callInformationOverlay.open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
#include "smartlistmodel.h"
|
#include "smartlistmodel.h"
|
||||||
#include "conversationlistmodelbase.h"
|
#include "conversationlistmodelbase.h"
|
||||||
#include "filestosendlistmodel.h"
|
#include "filestosendlistmodel.h"
|
||||||
|
#include "callInformationListModel.h"
|
||||||
|
#include "rendererinformationlistmodel.h"
|
||||||
|
|
||||||
#include "qrimageprovider.h"
|
#include "qrimageprovider.h"
|
||||||
#include "avatarimageprovider.h"
|
#include "avatarimageprovider.h"
|
||||||
|
@ -170,6 +172,9 @@ registerTypes(QQmlEngine* engine,
|
||||||
QML_REGISTERTYPE(NS_MODELS, FilesToSendListModel);
|
QML_REGISTERTYPE(NS_MODELS, FilesToSendListModel);
|
||||||
QML_REGISTERTYPE(NS_MODELS, SmartListModel);
|
QML_REGISTERTYPE(NS_MODELS, SmartListModel);
|
||||||
QML_REGISTERTYPE(NS_MODELS, MessageListModel);
|
QML_REGISTERTYPE(NS_MODELS, MessageListModel);
|
||||||
|
QML_REGISTERTYPE(NS_MODELS, CallInformationListModel);
|
||||||
|
QML_REGISTERTYPE(NS_MODELS, RendererInformationListModel);
|
||||||
|
|
||||||
|
|
||||||
// Roles & type enums for models
|
// Roles & type enums for models
|
||||||
QML_REGISTERNAMESPACE(NS_MODELS, AccountList::staticMetaObject, "AccountList");
|
QML_REGISTERNAMESPACE(NS_MODELS, AccountList::staticMetaObject, "AccountList");
|
||||||
|
|
|
@ -261,6 +261,8 @@ set(LIBCLIENT_SOURCES
|
||||||
behaviorcontroller.cpp
|
behaviorcontroller.cpp
|
||||||
datatransfermodel.cpp
|
datatransfermodel.cpp
|
||||||
messagelistmodel.cpp
|
messagelistmodel.cpp
|
||||||
|
callInformationListModel.cpp
|
||||||
|
rendererinformationlistmodel.cpp
|
||||||
|
|
||||||
# communication
|
# communication
|
||||||
dbus/configurationmanager.cpp
|
dbus/configurationmanager.cpp
|
||||||
|
@ -289,6 +291,8 @@ set(LIBCLIENT_HEADERS
|
||||||
vcard.h
|
vcard.h
|
||||||
namedirectory.h
|
namedirectory.h
|
||||||
messagelistmodel.h
|
messagelistmodel.h
|
||||||
|
callInformationListModel.h
|
||||||
|
rendererinformationlistmodel.h
|
||||||
|
|
||||||
# interfaces
|
# interfaces
|
||||||
interfaces/pixmapmanipulatori.h
|
interfaces/pixmapmanipulatori.h
|
||||||
|
|
|
@ -276,17 +276,22 @@ public:
|
||||||
QSize getRendererSize(const QString& id);
|
QSize getRendererSize(const QString& id);
|
||||||
video::Frame getRendererFrame(const QString& id);
|
video::Frame getRendererFrame(const QString& id);
|
||||||
bool useDirectRenderer() const;
|
bool useDirectRenderer() const;
|
||||||
|
/**
|
||||||
|
* Get Renderers information
|
||||||
|
* @param id (optional) : for a specific renderer or for all renderers
|
||||||
|
*/
|
||||||
|
QList<MapStringString> getRenderersInfo(QString id = {});
|
||||||
/**
|
/**
|
||||||
* Update renderers information list
|
* Update renderers information list
|
||||||
*/
|
*/
|
||||||
Q_SLOT void updateRenderersInfo();
|
Q_SLOT void updateRenderersFPSInfo(QString rendererId);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
/**
|
/**
|
||||||
* Emitted after an update of renderers information
|
* Emitted after an update of renderer's fps
|
||||||
* @param renderersInfoList Information on all renderers (RES, ID, FPS)
|
* @param pair of renderer id and its fps value
|
||||||
*/
|
*/
|
||||||
void onRendererInfosUpdated(QVariantList renderersInfoList);
|
void onRendererFpsChange(QPair<QString, QString> fpsInfo);
|
||||||
/**
|
/**
|
||||||
* Emitted when a renderer is started
|
* Emitted when a renderer is started
|
||||||
* @param id of the renderer
|
* @param id of the renderer
|
||||||
|
|
|
@ -397,6 +397,10 @@ public:
|
||||||
*/
|
*/
|
||||||
QList<QVariant> getAdvancedInformation() const;
|
QList<QVariant> getAdvancedInformation() const;
|
||||||
|
|
||||||
|
MapStringString advancedInformationForCallId(QString callId) const;
|
||||||
|
|
||||||
|
QStringList getCallIds() const;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -173,21 +173,36 @@ AVModel::~AVModel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
QList<MapStringString>
|
||||||
AVModel::updateRenderersInfo()
|
AVModel::getRenderersInfo(QString id)
|
||||||
{
|
{
|
||||||
QVariantList renderersInfoList;
|
QList<MapStringString> infoList;
|
||||||
|
std::lock_guard<std::mutex> lk(pimpl_->renderers_mtx_);
|
||||||
for (auto r = pimpl_->renderers_.begin(); r != pimpl_->renderers_.end(); r++) {
|
for (auto r = pimpl_->renderers_.begin(); r != pimpl_->renderers_.end(); r++) {
|
||||||
QVariantMap qmap;
|
MapStringString qmap;
|
||||||
auto& rend = r->second;
|
auto& rend = r->second;
|
||||||
MapStringString mapInfo = rend->getInfos();
|
MapStringString mapInfo = rend->getInfos();
|
||||||
qmap.insert(rend->RES, mapInfo["RES"]);
|
if (id.isEmpty() || mapInfo["RENDERER_ID"] == id) {
|
||||||
qmap.insert(rend->ID, mapInfo["ID"]);
|
qmap.insert(rend->RES, mapInfo["RES"]);
|
||||||
qmap.insert(rend->FPS, mapInfo["FPS"]);
|
qmap.insert(rend->RENDERER_ID, mapInfo["RENDERER_ID"]);
|
||||||
renderersInfoList.append(qmap);
|
qmap.insert(rend->FPS, mapInfo["FPS"]);
|
||||||
|
infoList.append(qmap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Q_EMIT onRendererInfosUpdated(renderersInfoList);
|
return infoList;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AVModel::updateRenderersFPSInfo(QString rendererId)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(pimpl_->renderers_.begin(),
|
||||||
|
pimpl_->renderers_.end(),
|
||||||
|
[&rendererId](const auto& c) {
|
||||||
|
return rendererId == c.second->getInfos()["RENDERER_ID"];
|
||||||
|
});
|
||||||
|
if (it != pimpl_->renderers_.end())
|
||||||
|
Q_EMIT onRendererFpsChange(qMakePair(rendererId, it->second->getInfos()["FPS"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -925,7 +940,7 @@ AVModelPimpl::addRenderer(const QString& id, const QSize& res, const QString& sh
|
||||||
renderer,
|
renderer,
|
||||||
&Renderer::fpsChanged,
|
&Renderer::fpsChanged,
|
||||||
this,
|
this,
|
||||||
[this, id](void) { Q_EMIT linked_.updateRenderersInfo(); },
|
[this, id](void) { Q_EMIT linked_.updateRenderersFPSInfo(id); },
|
||||||
Qt::DirectConnection);
|
Qt::DirectConnection);
|
||||||
connect(
|
connect(
|
||||||
renderer,
|
renderer,
|
||||||
|
|
114
src/libclient/callInformationListModel.cpp
Normal file
114
src/libclient/callInformationListModel.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||||
|
*
|
||||||
|
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "callInformationListModel.h"
|
||||||
|
|
||||||
|
CallInformationListModel::CallInformationListModel(QObject* parent)
|
||||||
|
: QAbstractListModel(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int
|
||||||
|
CallInformationListModel::rowCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
return callsInfolist_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant
|
||||||
|
CallInformationListModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
using namespace InfoList;
|
||||||
|
if (role == Role::CALL_ID)
|
||||||
|
return callsInfolist_[index.row()].first;
|
||||||
|
switch (role) {
|
||||||
|
#define X(var) \
|
||||||
|
case Role::var: \
|
||||||
|
return callsInfolist_[index.row()].second[#var];
|
||||||
|
CALLINFO_ROLES
|
||||||
|
#undef X
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CallInformationListModel::addElement(QPair<QString, MapStringString> callInfo)
|
||||||
|
{
|
||||||
|
// check element existence
|
||||||
|
auto callId = callInfo.first;
|
||||||
|
auto it = std::find_if(callsInfolist_.begin(), callsInfolist_.end(), [&callId](const auto& c) {
|
||||||
|
return callId == c.first;
|
||||||
|
});
|
||||||
|
// if element doesn't exist
|
||||||
|
if (it == callsInfolist_.end()) {
|
||||||
|
beginInsertRows(QModelIndex(), rowCount(), rowCount());
|
||||||
|
callsInfolist_.append(callInfo);
|
||||||
|
endInsertRows();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CallInformationListModel::editElement(QPair<QString, MapStringString> callInfo)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(callsInfolist_.begin(),
|
||||||
|
callsInfolist_.end(),
|
||||||
|
[&callInfo](const auto& c) { return callInfo.first == c.first; });
|
||||||
|
if (it != callsInfolist_.end()) {
|
||||||
|
// update infos
|
||||||
|
auto index = std::distance(callsInfolist_.begin(), it);
|
||||||
|
QModelIndex modelIndex = QAbstractListModel::index(index, 0);
|
||||||
|
it->second = callInfo.second;
|
||||||
|
Q_EMIT dataChanged(modelIndex, modelIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray>
|
||||||
|
CallInformationListModel::roleNames() const
|
||||||
|
{
|
||||||
|
using namespace InfoList;
|
||||||
|
QHash<int, QByteArray> roles;
|
||||||
|
#define X(var) roles[var] = #var;
|
||||||
|
CALLINFO_ROLES
|
||||||
|
#undef X
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CallInformationListModel::reset()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
callsInfolist_.clear();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CallInformationListModel::removeElement(QString callId)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(callsInfolist_.begin(), callsInfolist_.end(), [&callId](const auto& c) {
|
||||||
|
return callId == c.first;
|
||||||
|
});
|
||||||
|
if (it != callsInfolist_.end()) {
|
||||||
|
auto elementIndex = std::distance(callsInfolist_.begin(), it);
|
||||||
|
beginRemoveRows(QModelIndex(), elementIndex, elementIndex);
|
||||||
|
callsInfolist_.remove(elementIndex);
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
}
|
68
src/libclient/callInformationListModel.h
Normal file
68
src/libclient/callInformationListModel.h
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||||
|
*
|
||||||
|
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "api/interaction.h"
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
#define CALLINFO_ROLES \
|
||||||
|
X(CALL_ID) \
|
||||||
|
X(PEER_NUMBER) \
|
||||||
|
X(SOCKETS) \
|
||||||
|
X(VIDEO_CODEC) \
|
||||||
|
X(AUDIO_CODEC) \
|
||||||
|
X(AUDIO_SAMPLE_RATE) \
|
||||||
|
X(HARDWARE_ACCELERATION) \
|
||||||
|
X(VIDEO_BITRATE)
|
||||||
|
|
||||||
|
namespace InfoList {
|
||||||
|
|
||||||
|
Q_NAMESPACE
|
||||||
|
enum Role {
|
||||||
|
DummyRole = Qt::UserRole + 1,
|
||||||
|
#define X(role) role,
|
||||||
|
CALLINFO_ROLES
|
||||||
|
#undef X
|
||||||
|
};
|
||||||
|
Q_ENUM_NS(Role)
|
||||||
|
} // namespace InfoList
|
||||||
|
|
||||||
|
class CallInformationListModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
CallInformationListModel(QObject* parent = 0);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
Q_INVOKABLE QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
|
bool addElement(QPair<QString, MapStringString> callInfo);
|
||||||
|
void editElement(QPair<QString, MapStringString> callInfo);
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
void reset();
|
||||||
|
void removeElement(QString callId);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using Role = InfoList::Role;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<QPair<QString, MapStringString>> callsInfolist_;
|
||||||
|
};
|
|
@ -24,6 +24,8 @@
|
||||||
#include "api/avmodel.h"
|
#include "api/avmodel.h"
|
||||||
#include "api/behaviorcontroller.h"
|
#include "api/behaviorcontroller.h"
|
||||||
#include "api/conversationmodel.h"
|
#include "api/conversationmodel.h"
|
||||||
|
#include "api/codecmodel.h"
|
||||||
|
|
||||||
#include "api/contact.h"
|
#include "api/contact.h"
|
||||||
#include "api/contactmodel.h"
|
#include "api/contactmodel.h"
|
||||||
#include "api/pluginmodel.h"
|
#include "api/pluginmodel.h"
|
||||||
|
@ -56,6 +58,7 @@
|
||||||
using namespace libjami::Media;
|
using namespace libjami::Media;
|
||||||
|
|
||||||
constexpr static const char HARDWARE_ACCELERATION[] = "HARDWARE_ACCELERATION";
|
constexpr static const char HARDWARE_ACCELERATION[] = "HARDWARE_ACCELERATION";
|
||||||
|
constexpr static const char AUDIO_CODEC[] = "AUDIO_CODEC";
|
||||||
constexpr static const char CALL_ID[] = "CALL_ID";
|
constexpr static const char CALL_ID[] = "CALL_ID";
|
||||||
|
|
||||||
static std::uniform_int_distribution<int> dis {0, std::numeric_limits<int>::max()};
|
static std::uniform_int_distribution<int> dis {0, std::numeric_limits<int>::max()};
|
||||||
|
@ -133,6 +136,9 @@ public:
|
||||||
~CallModelPimpl();
|
~CallModelPimpl();
|
||||||
|
|
||||||
QVariantList callAdvancedInformation();
|
QVariantList callAdvancedInformation();
|
||||||
|
MapStringString advancedInformationForCallId(QString callId);
|
||||||
|
|
||||||
|
QStringList getCallIds();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send the profile VCard into a call
|
* Send the profile VCard into a call
|
||||||
|
@ -389,7 +395,7 @@ CallModel::createCall(const QString& uri, bool isAudioOnly, VectorMapStringStrin
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_LIBWRAP
|
#ifdef ENABLE_LIBWRAP
|
||||||
auto callId = CallManager::instance().placeCallWithMedia(owner.id, uri, mediaList);
|
auto callId = CallManager::instance().placeCallWithMedia(owner.id, uri, mediaList);
|
||||||
#else // dbus
|
#else // dbus
|
||||||
// do not use auto here (QDBusPendingReply<QString>)
|
// do not use auto here (QDBusPendingReply<QString>)
|
||||||
QString callId = CallManager::instance().placeCallWithMedia(owner.id, uri, mediaList);
|
QString callId = CallManager::instance().placeCallWithMedia(owner.id, uri, mediaList);
|
||||||
#endif // ENABLE_LIBWRAP
|
#endif // ENABLE_LIBWRAP
|
||||||
|
@ -419,6 +425,18 @@ CallModel::getAdvancedInformation() const
|
||||||
return pimpl_->callAdvancedInformation();
|
return pimpl_->callAdvancedInformation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MapStringString
|
||||||
|
CallModel::advancedInformationForCallId(QString callId) const
|
||||||
|
{
|
||||||
|
return pimpl_->advancedInformationForCallId(callId);
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList
|
||||||
|
CallModel::getCallIds() const
|
||||||
|
{
|
||||||
|
return pimpl_->getCallIds();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CallModel::emplaceConversationConference(const QString& confId)
|
CallModel::emplaceConversationConference(const QString& confId)
|
||||||
{
|
{
|
||||||
|
@ -1026,6 +1044,23 @@ CallModelPimpl::callAdvancedInformation()
|
||||||
return advancedInformationList;
|
return advancedInformationList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MapStringString
|
||||||
|
CallModelPimpl::advancedInformationForCallId(QString callId)
|
||||||
|
{
|
||||||
|
MapStringString infoMap = CallManager::instance().getCallDetails(linked.owner.id, callId);
|
||||||
|
if (lrc.getAVModel().getHardwareAcceleration())
|
||||||
|
infoMap[HARDWARE_ACCELERATION] = "True";
|
||||||
|
else
|
||||||
|
infoMap[HARDWARE_ACCELERATION] = "False";
|
||||||
|
return infoMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList
|
||||||
|
CallModelPimpl::getCallIds()
|
||||||
|
{
|
||||||
|
return CallManager::instance().getCallList(linked.owner.id);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CallModelPimpl::initCallFromDaemon()
|
CallModelPimpl::initCallFromDaemon()
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,7 +62,7 @@ MapStringString
|
||||||
Renderer::getInfos() const
|
Renderer::getInfos() const
|
||||||
{
|
{
|
||||||
MapStringString map;
|
MapStringString map;
|
||||||
map[ID] = id();
|
map[RENDERER_ID] = id();
|
||||||
map[FPS] = QString::number(fps());
|
map[FPS] = QString::number(fps());
|
||||||
map[RES] = QString::number(size().width()) + " * " + QString::number(size().height());
|
map[RES] = QString::number(size().width()) + " * " + QString::number(size().height());
|
||||||
return map;
|
return map;
|
||||||
|
|
|
@ -36,7 +36,7 @@ class Renderer : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
constexpr static const char ID[] = "ID";
|
constexpr static const char RENDERER_ID[] = "RENDERER_ID";
|
||||||
constexpr static const char FPS[] = "FPS";
|
constexpr static const char FPS[] = "FPS";
|
||||||
constexpr static const char RES[] = "RES";
|
constexpr static const char RES[] = "RES";
|
||||||
constexpr static const int FPS_RATE_SEC = 1;
|
constexpr static const int FPS_RATE_SEC = 1;
|
||||||
|
|
114
src/libclient/rendererinformationlistmodel.cpp
Normal file
114
src/libclient/rendererinformationlistmodel.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||||
|
*
|
||||||
|
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rendererinformationlistmodel.h"
|
||||||
|
|
||||||
|
RendererInformationListModel::RendererInformationListModel(QObject* parent)
|
||||||
|
: QAbstractListModel(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int
|
||||||
|
RendererInformationListModel::rowCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
return renderersInfoList_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant
|
||||||
|
RendererInformationListModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
using namespace RendererInfoList;
|
||||||
|
|
||||||
|
if (role == Role::RENDERER_ID)
|
||||||
|
return renderersInfoList_[index.row()].first;
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
#define X(var) \
|
||||||
|
case Role::var: \
|
||||||
|
return renderersInfoList_[index.row()].second[#var];
|
||||||
|
RENDERERINFO_ROLES
|
||||||
|
#undef X
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RendererInformationListModel::updateFps(QString rendererId, QString fps)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(renderersInfoList_.begin(),
|
||||||
|
renderersInfoList_.end(),
|
||||||
|
[&rendererId](const auto& c) { return rendererId == c.first; });
|
||||||
|
if (it != renderersInfoList_.end()) {
|
||||||
|
// update fps
|
||||||
|
auto index = std::distance(renderersInfoList_.begin(), it);
|
||||||
|
QModelIndex modelIndex = QAbstractListModel::index(index, 0);
|
||||||
|
it->second["FPS"] = fps;
|
||||||
|
Q_EMIT dataChanged(modelIndex, modelIndex, {Role::FPS});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RendererInformationListModel::addElement(QPair<QString, MapStringString> rendererInfo)
|
||||||
|
{
|
||||||
|
// check element existence
|
||||||
|
auto rendererId = rendererInfo.first;
|
||||||
|
auto it = std::find_if(renderersInfoList_.begin(),
|
||||||
|
renderersInfoList_.end(),
|
||||||
|
[&rendererId](const auto& c) { return rendererId == c.first; });
|
||||||
|
// if element doesn't exist
|
||||||
|
if (it == renderersInfoList_.end()) {
|
||||||
|
beginInsertRows(QModelIndex(), rowCount(), rowCount());
|
||||||
|
renderersInfoList_.append(rendererInfo);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RendererInformationListModel::removeElement(QString rendererId)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(renderersInfoList_.begin(),
|
||||||
|
renderersInfoList_.end(),
|
||||||
|
[&rendererId](const auto& c) { return rendererId == c.first; });
|
||||||
|
if (it != renderersInfoList_.end()) {
|
||||||
|
auto elementIndex = std::distance(renderersInfoList_.begin(), it);
|
||||||
|
beginRemoveRows(QModelIndex(), elementIndex, elementIndex);
|
||||||
|
renderersInfoList_.remove(elementIndex);
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray>
|
||||||
|
RendererInformationListModel::roleNames() const
|
||||||
|
{
|
||||||
|
using namespace RendererInfoList;
|
||||||
|
QHash<int, QByteArray> roles;
|
||||||
|
#define X(var) roles[var] = #var;
|
||||||
|
RENDERERINFO_ROLES
|
||||||
|
#undef X
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RendererInformationListModel::reset()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
renderersInfoList_.clear();
|
||||||
|
endResetModel();
|
||||||
|
}
|
62
src/libclient/rendererinformationlistmodel.h
Normal file
62
src/libclient/rendererinformationlistmodel.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||||
|
*
|
||||||
|
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "api/interaction.h"
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
#define RENDERERINFO_ROLES \
|
||||||
|
X(RENDERER_ID) \
|
||||||
|
X(RES) \
|
||||||
|
X(FPS)
|
||||||
|
|
||||||
|
namespace RendererInfoList {
|
||||||
|
Q_NAMESPACE
|
||||||
|
enum Role {
|
||||||
|
DummyRole = Qt::UserRole + 1,
|
||||||
|
#define X(role) role,
|
||||||
|
RENDERERINFO_ROLES
|
||||||
|
#undef X
|
||||||
|
};
|
||||||
|
Q_ENUM_NS(Role)
|
||||||
|
} // namespace RendererInfoList
|
||||||
|
|
||||||
|
class RendererInformationListModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
RendererInformationListModel(QObject* parent = 0);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
Q_INVOKABLE QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
|
void updateFps(QString rendererId, QString fps);
|
||||||
|
void addElement(QPair<QString, MapStringString> rendererInfo);
|
||||||
|
void removeElement(QString rendererId);
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using Role = RendererInfoList::Role;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<QPair<QString, MapStringString>> renderersInfoList_;
|
||||||
|
};
|
Loading…
Add table
Reference in a new issue