feat(MonitoringTool): Search improved

Closes: #15181
This commit is contained in:
Michał Cieślak 2024-06-28 10:41:51 +02:00 committed by Michał
parent 1c38b209c1
commit c88317d7ad
4 changed files with 61 additions and 43 deletions

View File

@ -83,6 +83,8 @@ Pane {
}
Label {
visible: listView.count
text: "Hint: use right/left button click on a column " +
"header to adjust width, press cell content to " +
"see full value"

View File

@ -17,7 +17,6 @@ Component {
Settings {
property alias tabIndex: tabBar.currentIndex
property alias modelObjectName: objectNameTextFiled.text
property alias modelObjectRootName: rootTextField.text
}
TabBar {
@ -287,28 +286,10 @@ Component {
}
}
Item {
Pane {
ColumnLayout {
anchors.fill: parent
Label {
Layout.fillWidth: true
wrapMode: Text.Wrap
text: "Note: 'applicationWindow' is good root object in"
+ " most cases. 'WalletStores.RootStore' and"
+ " `SharedStores.RootStore` are also exposed for"
+ " convenience for models created within those singletons. \n\n"
+ " Hack (see #15181): If you want to inspect a model that is not"
+ " from the root object (under a repeater), add objectName to a dummy object in AppMain.qml: \n"
+ " property var modelIWantToInspect: SortFilterProxyModel { \n"
+ " objectName: \"YYY\" \n"
+ " } \n"
+ " and inside your item add something like this: \n"
+ " Component.onCompleted: appMain.modelIWantToInspect.sourceModel = this.model \n"
+ " Then you can use 'YYY' as the object name in this search."
}
RowLayout {
Layout.fillHeight: false
Layout.fillWidth: true
@ -320,38 +301,46 @@ Component {
TextField {
id: objectNameTextFiled
Layout.fillWidth: true
selectByMouse: true
}
Label {
text: "Root:"
}
TextField {
id: rootTextField
text: "applicationWindow"
selectByMouse: true
onAccepted: searchButton.clicked()
}
Button {
id: searchButton
text: "Search"
onClicked: {
let rootObj = null
const roots = [
applicationWindow,
WalletStores.RootStore,
SharedStores.RootStore
]
try {
rootObj = eval(rootTextField.text)
} catch (error) {
objLabel.objStr = "Root object not found!"
let obj = null
for (let root of roots) {
obj = Monitor.findChild(root, objectNameTextFiled.text)
if (obj)
break
}
if (!obj) {
objLabel.objStr = "Model not found"
rolesModelContent.model = null
return
}
const obj = Monitor.findChild(
rootObj, objectNameTextFiled.text)
if (!Monitor.isModel(obj)) {
objLabel.objStr = "Found object is not a model"
rolesModelContent.model = null
return
}
objLabel.objStr = obj && Monitor.isModel(obj)
? obj.toString() : "Model not found!"
objLabel.objStr = obj.toString()
rolesModelContent.model = obj
}
}

View File

@ -26,7 +26,7 @@ public:
Q_INVOKABLE QString typeName(const QVariant &obj) const;
Q_INVOKABLE QJSValue modelRoles(QAbstractItemModel *model) const;
Q_INVOKABLE QObject* findChild(QObject* obj, const QString& name) const;
Q_INVOKABLE QObject* findChild(QObject* parent, const QString& name) const;
static Monitor& instance();
static QObject* qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine);

View File

@ -4,7 +4,9 @@
#include <QDebug>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
#include <QQuickItem>
#include <QQuickWindow>
#include <QSet>
void Monitor::initialize(QQmlApplicationEngine* engine)
{
@ -47,9 +49,34 @@ bool Monitor::isModel(const QVariant &obj) const
return qobject_cast<QAbstractItemModel*>(obj.value<QObject*>()) != nullptr;
}
QObject* Monitor::findChild(QObject* obj, const QString& name) const
QObject* Monitor::findChild(QObject* parent, const QString& name) const
{
return obj == nullptr ? nullptr : obj->findChild<QObject*>(name);
if (!parent)
return nullptr;
QSet<QObject*> children(parent->children().cbegin(),
parent->children().cend());
if (auto quickItem = qobject_cast<QQuickItem*>(parent)) {
QList<QQuickItem*> visualChildren = quickItem->childItems();
for (auto c : visualChildren)
children << c;
}
for (auto c : qAsConst(children)) {
if (c->objectName() == name)
return c;
}
for (auto c : qAsConst(children)) {
auto obj = findChild(c, name);
if (obj)
return obj;
}
return nullptr;
}
QString Monitor::typeName(const QVariant &obj) const