GenerateVariableMenuOperation.cpp
216 lines
| 7.4 KiB
| text/x-c
|
CppLexer
Alexandre Leroux
|
r195 | #include "Visualization/operations/GenerateVariableMenuOperation.h" | ||
Alexandre Leroux
|
r207 | #include "Visualization/operations/MenuBuilder.h" | ||
Alexandre Leroux
|
r195 | |||
#include "Visualization/VisualizationGraphWidget.h" | ||||
#include "Visualization/VisualizationTabWidget.h" | ||||
#include "Visualization/VisualizationZoneWidget.h" | ||||
#include <Variable/Variable.h> | ||||
#include <QMenu> | ||||
Alexandre Leroux
|
r196 | #include <QStack> | ||
Q_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation, "GenerateVariableMenuOperation") | ||||
Alexandre Leroux
|
r195 | struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate { | ||
Alexandre Leroux
|
r675 | explicit GenerateVariableMenuOperationPrivate( | ||
QMenu *menu, std::shared_ptr<Variable> variable, | ||||
std::set<IVisualizationWidget *> variableContainers) | ||||
: m_Variable{variable}, | ||||
m_PlotMenuBuilder{menu}, | ||||
m_UnplotMenuBuilder{menu}, | ||||
m_VariableContainers{std::move(variableContainers)} | ||||
Alexandre Leroux
|
r195 | { | ||
} | ||||
Alexandre Leroux
|
r286 | void visitRootEnter() | ||
{ | ||||
// Creates the root menu | ||||
Alexandre Leroux
|
r371 | if (auto plotMenu | ||
= m_PlotMenuBuilder.addMenu(QObject::tr("Plot"), QIcon{":/icones/plot.png"})) { | ||||
plotMenu->setEnabled(m_Variable && m_Variable->dataSeries() != nullptr); | ||||
} | ||||
Alexandre Leroux
|
r298 | m_UnplotMenuBuilder.addMenu(QObject::tr("Unplot"), QIcon{":/icones/unplot.png"}); | ||
Alexandre Leroux
|
r286 | } | ||
void visitRootLeave() | ||||
{ | ||||
// Closes the root menu | ||||
Alexandre Leroux
|
r297 | m_PlotMenuBuilder.closeMenu(); | ||
Alexandre Leroux
|
r298 | m_UnplotMenuBuilder.closeMenu(); | ||
Alexandre Leroux
|
r286 | } | ||
Alexandre Leroux
|
r197 | void visitNodeEnter(const IVisualizationWidget &container) | ||
{ | ||||
// Opens a new menu associated to the node | ||||
Alexandre Leroux
|
r297 | m_PlotMenuBuilder.addMenu(container.name()); | ||
Alexandre Leroux
|
r299 | m_UnplotMenuBuilder.addMenu(container.name()); | ||
Alexandre Leroux
|
r197 | } | ||
template <typename ActionFun> | ||||
Alexandre Leroux
|
r300 | void visitNodeLeavePlot(const IVisualizationWidget &container, const QString &actionName, | ||
ActionFun actionFunction) | ||||
Alexandre Leroux
|
r197 | { | ||
Alexandre Leroux
|
r675 | if (isValidContainer(container)) { | ||
Alexandre Leroux
|
r297 | m_PlotMenuBuilder.addSeparator(); | ||
m_PlotMenuBuilder.addAction(actionName, actionFunction); | ||||
Alexandre Leroux
|
r199 | } | ||
Alexandre Leroux
|
r197 | // Closes the menu associated to the node | ||
Alexandre Leroux
|
r297 | m_PlotMenuBuilder.closeMenu(); | ||
Alexandre Leroux
|
r197 | } | ||
Alexandre Leroux
|
r300 | void visitNodeLeaveUnplot() | ||
{ | ||||
// Closes the menu associated to the node | ||||
m_UnplotMenuBuilder.closeMenu(); | ||||
} | ||||
Alexandre Leroux
|
r198 | template <typename ActionFun> | ||
Alexandre Leroux
|
r302 | void visitLeafPlot(const IVisualizationWidget &container, const QString &actionName, | ||
ActionFun actionFunction) | ||||
Alexandre Leroux
|
r198 | { | ||
Alexandre Leroux
|
r675 | if (isValidContainer(container)) { | ||
Alexandre Leroux
|
r297 | m_PlotMenuBuilder.addAction(actionName, actionFunction); | ||
Alexandre Leroux
|
r198 | } | ||
} | ||||
Alexandre Leroux
|
r302 | template <typename ActionFun> | ||
Alexandre Leroux
|
r675 | void visitLeafUnplot(IVisualizationWidget *container, const QString &actionName, | ||
Alexandre Leroux
|
r302 | ActionFun actionFunction) | ||
{ | ||||
Alexandre Leroux
|
r675 | // If the container contains the variable, we generate 'unplot' action | ||
if (m_VariableContainers.count(container) == 1) { | ||||
Alexandre Leroux
|
r302 | m_UnplotMenuBuilder.addAction(actionName, actionFunction); | ||
} | ||||
} | ||||
Alexandre Leroux
|
r675 | bool isValidContainer(const IVisualizationWidget &container) const noexcept | ||
{ | ||||
// A container is valid if it can contain the variable and if the variable is not already | ||||
// contained in another container | ||||
return m_Variable && m_VariableContainers.size() == 0 && container.canDrop(*m_Variable); | ||||
} | ||||
Alexandre Leroux
|
r195 | std::shared_ptr<Variable> m_Variable; | ||
Alexandre Leroux
|
r675 | std::set<IVisualizationWidget *> m_VariableContainers; | ||
Alexandre Leroux
|
r302 | MenuBuilder m_PlotMenuBuilder; ///< Builder for the 'Plot' menu | ||
MenuBuilder m_UnplotMenuBuilder; ///< Builder for the 'Unplot' menu | ||||
Alexandre Leroux
|
r195 | }; | ||
Alexandre Leroux
|
r675 | GenerateVariableMenuOperation::GenerateVariableMenuOperation( | ||
QMenu *menu, std::shared_ptr<Variable> variable, | ||||
std::set<IVisualizationWidget *> variableContainers) | ||||
: impl{spimpl::make_unique_impl<GenerateVariableMenuOperationPrivate>( | ||||
menu, variable, std::move(variableContainers))} | ||||
Alexandre Leroux
|
r195 | { | ||
} | ||||
void GenerateVariableMenuOperation::visitEnter(VisualizationWidget *widget) | ||||
{ | ||||
// VisualizationWidget is not intended to accommodate a variable | ||||
Q_UNUSED(widget) | ||||
Alexandre Leroux
|
r286 | |||
Alexandre Leroux
|
r298 | // 'Plot' and 'Unplot' menus | ||
Alexandre Leroux
|
r286 | impl->visitRootEnter(); | ||
Alexandre Leroux
|
r195 | } | ||
void GenerateVariableMenuOperation::visitLeave(VisualizationWidget *widget) | ||||
{ | ||||
// VisualizationWidget is not intended to accommodate a variable | ||||
Q_UNUSED(widget) | ||||
Alexandre Leroux
|
r286 | |||
Alexandre Leroux
|
r298 | // 'Plot' and 'Unplot' menus | ||
Alexandre Leroux
|
r286 | impl->visitRootLeave(); | ||
Alexandre Leroux
|
r195 | } | ||
void GenerateVariableMenuOperation::visitEnter(VisualizationTabWidget *tabWidget) | ||||
{ | ||||
Alexandre Leroux
|
r197 | if (tabWidget) { | ||
Alexandre Leroux
|
r299 | // 'Plot' and 'Unplot' menus | ||
Alexandre Leroux
|
r197 | impl->visitNodeEnter(*tabWidget); | ||
} | ||||
Alexandre Leroux
|
r206 | else { | ||
qCCritical(LOG_GenerateVariableMenuOperation(), | ||||
"Can't visit enter VisualizationTabWidget : the widget is null"); | ||||
} | ||||
Alexandre Leroux
|
r195 | } | ||
void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget *tabWidget) | ||||
{ | ||||
Alexandre Leroux
|
r197 | if (tabWidget) { | ||
Alexandre Leroux
|
r300 | // 'Plot' menu | ||
Alexandre Leroux
|
r334 | impl->visitNodeLeavePlot(*tabWidget, QObject::tr("Open in a new zone"), | ||
[ varW = std::weak_ptr<Variable>{impl->m_Variable}, tabWidget ]() { | ||||
if (auto var = varW.lock()) { | ||||
tabWidget->createZone(var); | ||||
} | ||||
}); | ||||
Alexandre Leroux
|
r300 | |||
// 'Unplot' menu | ||||
impl->visitNodeLeaveUnplot(); | ||||
Alexandre Leroux
|
r197 | } | ||
Alexandre Leroux
|
r206 | else { | ||
qCCritical(LOG_GenerateVariableMenuOperation(), | ||||
"Can't visit leave VisualizationTabWidget : the widget is null"); | ||||
} | ||||
Alexandre Leroux
|
r195 | } | ||
void GenerateVariableMenuOperation::visitEnter(VisualizationZoneWidget *zoneWidget) | ||||
{ | ||||
Alexandre Leroux
|
r197 | if (zoneWidget) { | ||
Alexandre Leroux
|
r299 | // 'Plot' and 'Unplot' menus | ||
Alexandre Leroux
|
r197 | impl->visitNodeEnter(*zoneWidget); | ||
} | ||||
Alexandre Leroux
|
r206 | else { | ||
qCCritical(LOG_GenerateVariableMenuOperation(), | ||||
"Can't visit enter VisualizationZoneWidget : the widget is null"); | ||||
} | ||||
Alexandre Leroux
|
r195 | } | ||
void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget *zoneWidget) | ||||
{ | ||||
Alexandre Leroux
|
r197 | if (zoneWidget) { | ||
Alexandre Leroux
|
r300 | // 'Plot' menu | ||
impl->visitNodeLeavePlot( | ||||
Alexandre Leroux
|
r199 | *zoneWidget, QObject::tr("Open in a new graph"), | ||
Alexandre Leroux
|
r334 | [ varW = std::weak_ptr<Variable>{impl->m_Variable}, zoneWidget ]() { | ||
if (auto var = varW.lock()) { | ||||
zoneWidget->createGraph(var); | ||||
} | ||||
}); | ||||
Alexandre Leroux
|
r300 | |||
// 'Unplot' menu | ||||
impl->visitNodeLeaveUnplot(); | ||||
Alexandre Leroux
|
r197 | } | ||
Alexandre Leroux
|
r206 | else { | ||
qCCritical(LOG_GenerateVariableMenuOperation(), | ||||
"Can't visit leave VisualizationZoneWidget : the widget is null"); | ||||
} | ||||
Alexandre Leroux
|
r195 | } | ||
void GenerateVariableMenuOperation::visit(VisualizationGraphWidget *graphWidget) | ||||
{ | ||||
Alexandre Leroux
|
r198 | if (graphWidget) { | ||
Alexandre Leroux
|
r302 | // 'Plot' menu | ||
Alexandre Leroux
|
r334 | impl->visitLeafPlot(*graphWidget, QObject::tr("Open in %1").arg(graphWidget->name()), | ||
[ varW = std::weak_ptr<Variable>{impl->m_Variable}, graphWidget ]() { | ||||
if (auto var = varW.lock()) { | ||||
r518 | graphWidget->addVariable(var, graphWidget->graphRange()); | |||
Alexandre Leroux
|
r334 | } | ||
}); | ||||
Alexandre Leroux
|
r302 | |||
// 'Unplot' menu | ||||
Alexandre Leroux
|
r675 | impl->visitLeafUnplot(graphWidget, QObject::tr("Remove from %1").arg(graphWidget->name()), | ||
Alexandre Leroux
|
r334 | [ varW = std::weak_ptr<Variable>{impl->m_Variable}, graphWidget ]() { | ||
if (auto var = varW.lock()) { | ||||
graphWidget->removeVariable(var); | ||||
} | ||||
}); | ||||
Alexandre Leroux
|
r198 | } | ||
Alexandre Leroux
|
r206 | else { | ||
qCCritical(LOG_GenerateVariableMenuOperation(), | ||||
"Can't visit VisualizationGraphWidget : the widget is null"); | ||||
} | ||||
Alexandre Leroux
|
r195 | } | ||