From d1f9b1a4f84214f131788cb1106698fc0aaeaa3f Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 5 Jun 2019 21:04:16 +0200 Subject: [PATCH] Make findWidget more powerful --- src/gui/socketapi.cpp | 97 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 12 deletions(-) diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi.cpp index b3010cf8f..b72688fa3 100644 --- a/src/gui/socketapi.cpp +++ b/src/gui/socketapi.cpp @@ -79,15 +79,65 @@ namespace { #if GUI_TESTING -QWidget *findWidget(const QString &objectName) + +QList allObjects(const QList &widgets) { + QList objects; + std::copy(widgets.constBegin(), widgets.constEnd(), std::back_inserter(objects)); + + objects << qApp; + + return objects; +} + +QObject *findWidget(const QString &queryString, const QList &widgets = QApplication::allWidgets()) { - auto widgets = QApplication::allWidgets(); + auto objects = allObjects(widgets); - auto foundWidget = std::find_if(widgets.constBegin(), widgets.constEnd(), [&](QWidget *widget) { - return widget->objectName() == objectName; - }); + QList::const_iterator foundWidget; - if (foundWidget == widgets.constEnd()) { + if (queryString.contains('>')) { + DEBUG << "queryString contains >"; + + auto subQueries = queryString.split('>', QString::SkipEmptyParts); + Q_ASSERT(subQueries.count() == 2); + + auto parentQueryString = subQueries[0].trimmed(); + DEBUG << "Find parent: " << parentQueryString; + auto parent = findWidget(parentQueryString); + + if(!parent) { + return nullptr; + } + + auto childQueryString = subQueries[1].trimmed(); + auto child = findWidget(childQueryString, parent->findChildren()); + DEBUG << "found child: " << !!child; + return child; + + } else if(queryString.startsWith('#')) { + auto objectName = queryString.mid(1); + DEBUG << "find objectName: " << objectName; + foundWidget = std::find_if(objects.constBegin(), objects.constEnd(), [&](QObject *widget) { + return widget->objectName() == objectName; + }); + } else { + QList matches; + std::copy_if(objects.constBegin(), objects.constEnd(), std::back_inserter(matches), [&](QObject* widget) { + return widget->inherits(queryString.toLatin1()); + }); + + std::for_each(matches.constBegin(), matches.constEnd(), [](QObject* w) { + if(!w) return; + DEBUG << "WIDGET: " << w->objectName() << w->metaObject()->className(); + }); + + if(matches.empty()) { + return nullptr; + } + return matches[0]; + } + + if (foundWidget == objects.constEnd()) { return nullptr; } @@ -1135,7 +1185,7 @@ DirectEditor* SocketApi::getDirectEditorForLocalFile(const QString &localFile) void SocketApi::command_ASYNC_LIST_WIDGETS(const QSharedPointer &job) { QString response; - for (auto &widget : QApplication::allWidgets()) { + for (auto &widget : allObjects(QApplication::allWidgets())) { auto objectName = widget->objectName(); if (!objectName.isEmpty()) { response += objectName + ":" + widget->property("text").toString() + ", "; @@ -1162,16 +1212,39 @@ void SocketApi::command_ASYNC_GET_WIDGET_PROPERTY(const QSharedPointerarguments()[QLatin1String("objectName")].toString()); if (!widget) { - job->reject(QLatin1String("widget not found")); + QString message("Widget not found: 2: "); + message.append(job->arguments()["objectName"].toString()); + job->reject(message); return; } auto propertyName = job->arguments()[QLatin1String("property")].toString(); - job->resolve(widget->property(propertyName.toUtf8().constData()) - .toString() - .toUtf8() - .constData()); + auto segments = propertyName.split('.'); + + QObject* currentObject = widget; + QString value; + for(int i = 0;iproperty(segment.toUtf8().constData()); + + if(var.canConvert()) { + var.convert(QMetaType::QString); + value = var.value(); + + DEBUG << "VALUE: " << value; + break; + } + + auto tmpObject = var.value(); + if(tmpObject) { + currentObject = tmpObject; + } else { + DEBUG << "TODO: object not found, what should happen here now?"; + } + } + + job->resolve(value.toUtf8().constData()); } void SocketApi::command_ASYNC_SET_WIDGET_PROPERTY(const QSharedPointer &job)