diff --git a/app/src/MainWindow.cpp b/app/src/MainWindow.cpp index 2e6506b..3e6f828 100644 --- a/app/src/MainWindow.cpp +++ b/app/src/MainWindow.cpp @@ -182,10 +182,16 @@ MainWindow::MainWindow(QWidget *parent) connect(timeWidget, SIGNAL(timeUpdated(SqpDateTime)), &sqpApp->timeController(), SLOT(onTimeToUpdate(SqpDateTime))); - // Variable + // Widgets / widgets connections qRegisterMetaType >(); - connect(&sqpApp->visualizationController(), SIGNAL(variableCreated(std::shared_ptr)), - m_Ui->view, SLOT(displayVariable(std::shared_ptr))); + + // For the following connections, we use DirectConnection to allow each widget that can + // potentially attach a menu to the variable's menu to do so before this menu is displayed. + // The order of connections is also important, since it determines the order in which each + // widget will attach its menu + connect(m_Ui->variableInspectorWidget, + SIGNAL(tableMenuAboutToBeDisplayed(QMenu *, std::shared_ptr)), m_Ui->view, + SLOT(attachVariableMenu(QMenu *, std::shared_ptr)), Qt::DirectConnection); /* QLopGUI::registerMenuBar(menuBar()); this->setWindowIcon(QIcon(":/sciqlopLOGO.svg")); diff --git a/core/include/Variable/VariableModel.h b/core/include/Variable/VariableModel.h index 490f43b..07f60fc 100644 --- a/core/include/Variable/VariableModel.h +++ b/core/include/Variable/VariableModel.h @@ -32,6 +32,8 @@ public: createVariable(const QString &name, const SqpDateTime &dateTime, std::unique_ptr defaultDataSeries) noexcept; + std::shared_ptr variable(int index) const; + // /////////////////////////// // // QAbstractTableModel methods // // /////////////////////////// // diff --git a/core/src/Variable/VariableModel.cpp b/core/src/Variable/VariableModel.cpp index 601f3cb..af16df1 100644 --- a/core/src/Variable/VariableModel.cpp +++ b/core/src/Variable/VariableModel.cpp @@ -44,6 +44,11 @@ VariableModel::createVariable(const QString &name, const SqpDateTime &dateTime, return variable; } +std::shared_ptr VariableModel::variable(int index) const +{ + return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables.at(index) : nullptr; +} + int VariableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); diff --git a/gui/include/Variable/VariableInspectorWidget.h b/gui/include/Variable/VariableInspectorWidget.h index c4d5f41..6adb0a0 100644 --- a/gui/include/Variable/VariableInspectorWidget.h +++ b/gui/include/Variable/VariableInspectorWidget.h @@ -1,8 +1,13 @@ #ifndef SCIQLOP_VARIABLEINSPECTORWIDGET_H #define SCIQLOP_VARIABLEINSPECTORWIDGET_H +#include #include +#include + +class Variable; + namespace Ui { class VariableInspectorWidget; } // Ui @@ -19,8 +24,23 @@ public: explicit VariableInspectorWidget(QWidget *parent = 0); virtual ~VariableInspectorWidget(); +signals: + /** + * Signal emitted before a menu concerning a variable is displayed. It is used for other widgets + * to complete the menu. + * @param tableMenu the menu to be completed + * @param variable the variable concerned by the menu + * @remarks To make the dynamic addition of menus work, the connections to this signal must be + * in Qt :: DirectConnection + */ + void tableMenuAboutToBeDisplayed(QMenu *tableMenu, std::shared_ptr variable); + private: Ui::VariableInspectorWidget *ui; + +private slots: + /// Slot called when right clicking on an variable in the table (displays a menu) + void onTableMenuRequested(const QPoint &pos) noexcept; }; #endif // SCIQLOP_VARIABLEINSPECTORWIDGET_H diff --git a/gui/include/Visualization/VisualizationWidget.h b/gui/include/Visualization/VisualizationWidget.h index 52285c2..ca74bdf 100644 --- a/gui/include/Visualization/VisualizationWidget.h +++ b/gui/include/Visualization/VisualizationWidget.h @@ -8,6 +8,7 @@ Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget) +class QMenu; class Variable; class VisualizationTabWidget; @@ -39,12 +40,11 @@ public: public slots: /** - * Displays a variable in a new graph of a new zone of the current tab - * @param variable the variable to display - * @todo this is a temporary method that will be replaced by own actions for each type of - * visualization widget + * Attaches to a menu the menu relating to the visualization of a variable + * @param menu the parent menu of the generated menu + * @param variable the variable for which to generate the menu */ - void displayVariable(std::shared_ptr variable) noexcept; + void attachVariableMenu(QMenu *menu, std::shared_ptr variable) noexcept; private: Ui::VisualizationWidget *ui; diff --git a/gui/src/Variable/VariableInspectorWidget.cpp b/gui/src/Variable/VariableInspectorWidget.cpp index 7a788b7..0c8dfaa 100644 --- a/gui/src/Variable/VariableInspectorWidget.cpp +++ b/gui/src/Variable/VariableInspectorWidget.cpp @@ -18,9 +18,33 @@ VariableInspectorWidget::VariableInspectorWidget(QWidget *parent) sortFilterModel->setSourceModel(sqpApp->variableController().variableModel()); ui->tableView->setModel(sortFilterModel); + + // Connection to show a menu when right clicking on the tree + ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->tableView, &QTableView::customContextMenuRequested, this, + &VariableInspectorWidget::onTableMenuRequested); } VariableInspectorWidget::~VariableInspectorWidget() { delete ui; } + +void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept +{ + auto selectedIndex = ui->tableView->indexAt(pos); + if (selectedIndex.isValid()) { + // Gets the model to retrieve the underlying selected variable + auto model = sqpApp->variableController().variableModel(); + if (auto selectedVariable = model->variable(selectedIndex.row())) { + QMenu tableMenu{}; + + // Emit a signal so that potential receivers can populate the menu before displaying it + emit tableMenuAboutToBeDisplayed(&tableMenu, selectedVariable); + + if (!tableMenu.isEmpty()) { + tableMenu.exec(mapToGlobal(pos)); + } + } + } +} diff --git a/gui/src/Visualization/VisualizationWidget.cpp b/gui/src/Visualization/VisualizationWidget.cpp index c0467e6..cccc592 100644 --- a/gui/src/Visualization/VisualizationWidget.cpp +++ b/gui/src/Visualization/VisualizationWidget.cpp @@ -3,6 +3,7 @@ #include "Visualization/VisualizationGraphWidget.h" #include "Visualization/VisualizationTabWidget.h" #include "Visualization/VisualizationZoneWidget.h" +#include "Visualization/operations/GenerateVariableMenuOperation.h" #include "Visualization/qcustomplot.h" #include "ui_VisualizationWidget.h" @@ -121,16 +122,10 @@ QString VisualizationWidget::name() const return QStringLiteral("MainView"); } -void VisualizationWidget::displayVariable(std::shared_ptr variable) noexcept +void VisualizationWidget::attachVariableMenu(QMenu *menu, + std::shared_ptr variable) noexcept { - if (auto currentTab = dynamic_cast(ui->tabWidget->currentWidget())) { - if (!currentTab->createZone(variable)) { - qCCritical(LOG_VisualizationWidget()) - << tr("Can't display the variable : can't create a new zone in the current tab"); - } - } - else { - qCCritical(LOG_VisualizationWidget()) - << tr("Can't display the variable : there is no current tab"); - } + // Generates the actions that make it possible to visualize the variable + auto generateVariableMenuOperation = GenerateVariableMenuOperation{menu, variable}; + accept(&generateVariableMenuOperation); }