From 0525490619b5dd7c9f68326b251662d813c8a34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Cie=C5=9Blak?= Date: Fri, 13 Jan 2023 13:42:30 +0100 Subject: [PATCH] feat: Add additional utilities for real-time app inspection - context properties names exposed as a model - checking if object is a model - exposing human-readable type name - exposing role names for models Closes: https://github.com/status-im/status-desktop/issues/8787 --- .../Monitoring/ContextPropertiesModel.h | 22 ++++++++ .../DOtherSide/Status/Monitoring/Monitor.h | 17 +++--- .../Monitoring/ContextPropertiesModel.cpp | 39 ++++++++++++++ .../lib/src/Status/Monitoring/Monitor.cpp | 53 ++++++++++++++++--- 4 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 vendor/DOtherSide/lib/include/DOtherSide/Status/Monitoring/ContextPropertiesModel.h create mode 100644 vendor/DOtherSide/lib/src/Status/Monitoring/ContextPropertiesModel.cpp diff --git a/vendor/DOtherSide/lib/include/DOtherSide/Status/Monitoring/ContextPropertiesModel.h b/vendor/DOtherSide/lib/include/DOtherSide/Status/Monitoring/ContextPropertiesModel.h new file mode 100644 index 0000000000..8564a671cd --- /dev/null +++ b/vendor/DOtherSide/lib/include/DOtherSide/Status/Monitoring/ContextPropertiesModel.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +class ContextPropertiesModel : public QAbstractListModel +{ + Q_OBJECT +public: + explicit ContextPropertiesModel(QObject* parent = nullptr); + + static constexpr int NameRole = Qt::UserRole + 1; + + int rowCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role) const override; + QHash roleNames() const override; + + void addContextProperty(const QString &property); + +private: + QStringList m_contextProperties; +}; diff --git a/vendor/DOtherSide/lib/include/DOtherSide/Status/Monitoring/Monitor.h b/vendor/DOtherSide/lib/include/DOtherSide/Status/Monitoring/Monitor.h index 1a05ed63fa..742649e7bb 100644 --- a/vendor/DOtherSide/lib/include/DOtherSide/Status/Monitoring/Monitor.h +++ b/vendor/DOtherSide/lib/include/DOtherSide/Status/Monitoring/Monitor.h @@ -1,6 +1,9 @@ #pragma once #include +#include + +#include "ContextPropertiesModel.h" class QQmlApplicationEngine; class QQmlEngine; @@ -9,21 +12,23 @@ class QJSEngine; class Monitor : public QObject { Q_OBJECT - Q_PROPERTY(QStringList contexPropertiesNames READ getContextPropertiesNames - NOTIFY contextPropertiesNamesChanged) + Q_PROPERTY(ContextPropertiesModel* contexPropertiesModel + READ contexPropertiesModel CONSTANT) Monitor() = default; public: void initialize(QQmlApplicationEngine *engine); - QStringList getContextPropertiesNames() const; + ContextPropertiesModel* contexPropertiesModel(); void addContextPropertyName(const QString &contextPropertyName); + Q_INVOKABLE bool isModel(const QVariant &obj) const; + Q_INVOKABLE QString typeName(const QVariant &obj) const; + Q_INVOKABLE QJSValue modelRoles(QAbstractItemModel *model) const; + static Monitor& instance(); static QObject* qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine); -signals: - void contextPropertiesNamesChanged(); private: - QStringList m_contexPropertiesNames; + ContextPropertiesModel m_contexPropertiesModel; }; diff --git a/vendor/DOtherSide/lib/src/Status/Monitoring/ContextPropertiesModel.cpp b/vendor/DOtherSide/lib/src/Status/Monitoring/ContextPropertiesModel.cpp new file mode 100644 index 0000000000..cd6e48b3bc --- /dev/null +++ b/vendor/DOtherSide/lib/src/Status/Monitoring/ContextPropertiesModel.cpp @@ -0,0 +1,39 @@ +#include "DOtherSide/Status/Monitoring/ContextPropertiesModel.h" + +ContextPropertiesModel::ContextPropertiesModel(QObject* parent) + : QAbstractListModel(parent) +{ +} + +int ContextPropertiesModel::rowCount(const QModelIndex &parent) const +{ + return m_contextProperties.size(); +} + +QVariant ContextPropertiesModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return {}; + + return m_contextProperties.at(index.row()); +} + +QHash ContextPropertiesModel::roleNames() const +{ + static QHash roles { + { NameRole, QByteArrayLiteral("name") } + }; + + return roles; +} + +void ContextPropertiesModel::addContextProperty(const QString &property) +{ + if (m_contextProperties.contains(property)) + return; + + const auto currentCount = m_contextProperties.size(); + beginInsertRows(QModelIndex(), currentCount, currentCount); + m_contextProperties << property; + endInsertRows(); +} diff --git a/vendor/DOtherSide/lib/src/Status/Monitoring/Monitor.cpp b/vendor/DOtherSide/lib/src/Status/Monitoring/Monitor.cpp index 3d860c0ad0..aca79e2615 100644 --- a/vendor/DOtherSide/lib/src/Status/Monitoring/Monitor.cpp +++ b/vendor/DOtherSide/lib/src/Status/Monitoring/Monitor.cpp @@ -28,18 +28,59 @@ void Monitor::initialize(QQmlApplicationEngine* engine) { }, Qt::QueuedConnection); } -QStringList Monitor::getContextPropertiesNames() const +ContextPropertiesModel* Monitor::contexPropertiesModel() { - return m_contexPropertiesNames; + return &m_contexPropertiesModel; } void Monitor::addContextPropertyName(const QString &contextPropertyName) { - if (m_contexPropertiesNames.contains(contextPropertyName)) - return; + m_contexPropertiesModel.addContextProperty(contextPropertyName); +} - m_contexPropertiesNames << contextPropertyName; - emit contextPropertiesNamesChanged(); +bool Monitor::isModel(const QVariant &obj) const +{ + if (!obj.canConvert()) + return false; + + return qobject_cast(obj.value()) != nullptr; +} + +QString Monitor::typeName(const QVariant &obj) const +{ + if (obj.canConvert()) + return obj.value()->metaObject()->className(); + + return QString::fromUtf8(obj.typeName()); +} + +QJSValue Monitor::modelRoles(QAbstractItemModel *model) const +{ + if (model == nullptr) + return {}; + + QJSEngine *engine = qjsEngine(this); + + if (engine == nullptr) + return {}; + + const auto& roleNames = model->roleNames(); + + QJSValue array = engine->newArray(roleNames.size()); + QList keys = roleNames.keys(); + + for (auto i = 0; i < keys.size(); i++) { + QJSValue item = engine->newObject(); + + auto key = keys.at(i); + item.setProperty(QStringLiteral("key"), key); + item.setProperty(QStringLiteral("name"), + QString::fromUtf8(roleNames[key])); + + array.setProperty(i, item); + } + + return array; } Monitor& Monitor::instance()