diff --git a/core/include/DataSource/DataSourceController.h b/core/include/DataSource/DataSourceController.h index 13e89a2..a5a5cd6 100644 --- a/core/include/DataSource/DataSourceController.h +++ b/core/include/DataSource/DataSourceController.h @@ -64,6 +64,8 @@ public: */ void loadProductItem(const QUuid &dataSourceUid, const DataSourceItem &productItem) noexcept; + std::shared_ptr providerForProductData(const QVariantHash &productData); + QByteArray mimeDataForProductsData(const QVariantList &productsData) const; QVariantList productsDataForMimeData(const QByteArray &mimeData) const; diff --git a/core/src/DataSource/DataSourceController.cpp b/core/src/DataSource/DataSourceController.cpp index 1228d87..3064afe 100644 --- a/core/src/DataSource/DataSourceController.cpp +++ b/core/src/DataSource/DataSourceController.cpp @@ -139,6 +139,26 @@ void DataSourceController::loadProductItem(const QUuid &dataSourceUid, } } +std::shared_ptr +DataSourceController::providerForProductData(const QVariantHash &productData) +{ + DataSourceItem *sourceItem = impl->findDataSourceItem(productData); + + if (sourceItem && sourceItem->type() == DataSourceItemType::PRODUCT + || sourceItem->type() == DataSourceItemType::COMPONENT) { + auto sourceName = sourceItem->rootItem().name(); + auto sourceId = impl->m_DataSources.key(sourceName); + auto it = impl->m_DataProviders.find(sourceId); + auto dataProvider = (it != impl->m_DataProviders.end()) ? it->second : nullptr; + return dataProvider; + } + else { + qCWarning(LOG_DataSourceController()) << tr("requestVariable, product data not found"); + } + + return nullptr; +} + QByteArray DataSourceController::mimeDataForProductsData(const QVariantList &productsData) const { QByteArray encodedData; diff --git a/gui/src/DragDropHelper.cpp b/gui/src/DragDropHelper.cpp index 5e720e8..53aefd8 100644 --- a/gui/src/DragDropHelper.cpp +++ b/gui/src/DragDropHelper.cpp @@ -282,6 +282,14 @@ bool DragDropHelper::checkMimeDataForVisualization(const QMimeData *mimeData, result = false; } } + else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) { + QDataStream stream(mimeData->data(MIME_TYPE_PRODUCT_LIST)); + + QVariantList productList; + stream >> productList; + + result = productList.count() == 1; + } return result; } diff --git a/gui/src/Visualization/VisualizationTabWidget.cpp b/gui/src/Visualization/VisualizationTabWidget.cpp index d6b63d6..5415aa5 100644 --- a/gui/src/Visualization/VisualizationTabWidget.cpp +++ b/gui/src/Visualization/VisualizationTabWidget.cpp @@ -5,6 +5,8 @@ #include "Visualization/VisualizationGraphWidget.h" #include "Visualization/VisualizationZoneWidget.h" +#include "DataSource/DataSourceController.h" +#include "DataSource/DataSourceItem.h" #include "Variable/VariableController.h" #include "Common/MimeTypesDef.h" @@ -12,6 +14,8 @@ #include "DragDropHelper.h" #include "SqpApplication.h" +#include + Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget") namespace { @@ -59,6 +63,8 @@ struct VisualizationTabWidget::VisualizationTabWidgetPrivate { void dropZone(int index, VisualizationTabWidget *tabWidget); void dropVariables(const QList > &variables, int index, VisualizationTabWidget *tabWidget); + void dropProduct(const QVariantList &productDataList, int index, + VisualizationTabWidget *tabWidget); }; VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent) @@ -69,7 +75,7 @@ VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *par ui->setupUi(this); ui->dragDropContainer->setAcceptedMimeTypes( - {MIME_TYPE_GRAPH, MIME_TYPE_ZONE, MIME_TYPE_VARIABLE_LIST}); + {MIME_TYPE_GRAPH, MIME_TYPE_ZONE, MIME_TYPE_VARIABLE_LIST, MIME_TYPE_PRODUCT_LIST}); connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this, &VisualizationTabWidget::dropMimeData); ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) { @@ -184,6 +190,11 @@ void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData) mimeData->data(MIME_TYPE_VARIABLE_LIST)); impl->dropVariables(variables, index, this); } + else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) { + auto productList = sqpApp->dataSourceController().productsDataForMimeData( + mimeData->data(MIME_TYPE_PRODUCT_LIST)); + impl->dropProduct(productList, index, this); + } else { qCWarning(LOG_VisualizationZoneWidget()) << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received."); @@ -287,8 +298,33 @@ void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables( const QList > &variables, int index, VisualizationTabWidget *tabWidget) { - // Note: we are sure that there is a single and compatible variable here - // because the AcceptMimeDataFunction, set on the drop container, makes the check before the - // drop can occur. + // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and + // compatible variable here + if (variables.count() > 1) { + qCWarning(LOG_VisualizationZoneWidget()) + << tr("VisualizationTabWidget::dropVariables, dropping multiple variables, operation " + "aborted."); + return; + } + tabWidget->createZone(variables, index); } + +void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropProduct( + const QVariantList &productDataList, int index, VisualizationTabWidget *tabWidget) +{ + // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and + // compatible product here + if (productDataList.count() > 1) { + qCWarning(LOG_VisualizationZoneWidget()) << tr( + "VisualizationTabWidget::dropProduct, dropping multiple products, operation aborted."); + return; + } + + auto productData = productDataList.first().toHash(); + auto provider = sqpApp->dataSourceController().providerForProductData(productData); + auto name = productData.value(DataSourceItem::NAME_DATA_KEY).toString(); + auto variable = sqpApp->variableController().createVariable(name, productData, provider); + QTimer::singleShot( + 3000, [tabWidget, variable, index]() { tabWidget->createZone({variable}, index); }); +} diff --git a/gui/src/Visualization/VisualizationZoneWidget.cpp b/gui/src/Visualization/VisualizationZoneWidget.cpp index ae8f9d8..4dc8eaa 100644 --- a/gui/src/Visualization/VisualizationZoneWidget.cpp +++ b/gui/src/Visualization/VisualizationZoneWidget.cpp @@ -10,6 +10,8 @@ #include "Common/VisualizationDef.h" #include +#include +#include #include #include @@ -74,6 +76,8 @@ struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate { void dropGraph(int index, VisualizationZoneWidget *zoneWidget); void dropVariables(const QList > &variables, int index, VisualizationZoneWidget *zoneWidget); + void dropProduct(const QVariantList &productDataList, int index, + VisualizationZoneWidget *zoneWidget); }; VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent) @@ -85,7 +89,8 @@ VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p ui->zoneNameLabel->setText(name); - ui->dragDropContainer->setAcceptedMimeTypes({MIME_TYPE_GRAPH, MIME_TYPE_VARIABLE_LIST}); + ui->dragDropContainer->setAcceptedMimeTypes( + {MIME_TYPE_GRAPH, MIME_TYPE_VARIABLE_LIST, MIME_TYPE_PRODUCT_LIST}); ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) { return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData, ui->dragDropContainer); @@ -374,6 +379,11 @@ void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData) mimeData->data(MIME_TYPE_VARIABLE_LIST)); impl->dropVariables(variables, index, this); } + else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) { + auto productList = sqpApp->dataSourceController().productsDataForMimeData( + mimeData->data(MIME_TYPE_PRODUCT_LIST)); + impl->dropProduct(productList, index, this); + } else { qCWarning(LOG_VisualizationZoneWidget()) << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received."); @@ -455,30 +465,33 @@ void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropVariables( const QList > &variables, int index, VisualizationZoneWidget *zoneWidget) { - // Search for the top level VisualizationWidget - auto parent = zoneWidget->parentWidget(); - while (parent && qobject_cast(parent) == nullptr) { - parent = parent->parentWidget(); - } - - if (!parent) { + // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and + // compatible variable here + if (variables.count() > 1) { qCWarning(LOG_VisualizationZoneWidget()) - << tr("VisualizationZoneWidget::dropVariables, drop aborted, the parent " - "VisualizationWidget cannot be found."); - Q_ASSERT(false); + << tr("VisualizationZoneWidget::dropVariables, dropping multiple variables, operation " + "aborted."); return; } - auto visualizationWidget = static_cast(parent); + Q_ASSERT(variables.count() == 1); + zoneWidget->createGraph(variables, index); +} - // Search for the first variable which can be dropped - for (auto variable : variables) { - FindVariableOperation findVariableOperation{variable}; - visualizationWidget->accept(&findVariableOperation); - auto variableContainers = findVariableOperation.result(); - if (variableContainers.empty()) { - zoneWidget->createGraph(variable, index); - break; - } +void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropProduct( + const QVariantList &productDataList, int index, VisualizationZoneWidget *zoneWidget) +{ + // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and + // compatible product here + if (productDataList.count() > 1) { + qCWarning(LOG_VisualizationZoneWidget()) << tr( + "VisualizationZoneWidget::dropProduct, dropping multiple products, operation aborted."); + return; } + + auto productData = productDataList.first().toHash(); + auto provider = sqpApp->dataSourceController().providerForProductData(productData); + auto name = productData.value(DataSourceItem::NAME_DATA_KEY).toString(); + auto variable = sqpApp->variableController().createVariable(name, productData, provider); + zoneWidget->createGraph(variable, index); }