GenerateVariableMenuOperation.cpp
232 lines
| 7.2 KiB
| text/x-c
|
CppLexer
Alexandre Leroux
|
r210 | #include "Visualization/operations/GenerateVariableMenuOperation.h" | ||
Alexandre Leroux
|
r222 | #include "Visualization/operations/MenuBuilder.h" | ||
Alexandre Leroux
|
r210 | |||
#include "Visualization/VisualizationGraphWidget.h" | ||||
#include "Visualization/VisualizationTabWidget.h" | ||||
#include "Visualization/VisualizationZoneWidget.h" | ||||
r1420 | #include <Variable/Variable2.h> | |||
Alexandre Leroux
|
r210 | |||
#include <QMenu> | ||||
Alexandre Leroux
|
r211 | #include <QStack> | ||
Q_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation, "GenerateVariableMenuOperation") | ||||
r1420 | struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate | |||
{ | ||||
explicit GenerateVariableMenuOperationPrivate(QMenu* menu, std::shared_ptr<Variable2> variable, | ||||
std::set<IVisualizationWidget*> variableContainers) | ||||
: m_Variable { variable } | ||||
, m_VariableContainers { std::move(variableContainers) } | ||||
, m_PlotMenuBuilder { menu } | ||||
, m_UnplotMenuBuilder { menu } | ||||
Alexandre Leroux
|
r210 | { | ||
} | ||||
Alexandre Leroux
|
r309 | void visitRootEnter() | ||
{ | ||||
// Creates the root menu | ||||
Alexandre Leroux
|
r404 | if (auto plotMenu | ||
r1420 | = m_PlotMenuBuilder.addMenu(QObject::tr("Plot"), QIcon { ":/icones/plot.png" })) | |||
{ | ||||
plotMenu->setEnabled(m_Variable && m_Variable->data() != nullptr); | ||||
Alexandre Leroux
|
r404 | } | ||
r1420 | m_UnplotMenuBuilder.addMenu(QObject::tr("Unplot"), QIcon { ":/icones/unplot.png" }); | |||
Alexandre Leroux
|
r309 | } | ||
void visitRootLeave() | ||||
{ | ||||
// Closes the root menu | ||||
Alexandre Leroux
|
r323 | m_PlotMenuBuilder.closeMenu(); | ||
Alexandre Leroux
|
r324 | m_UnplotMenuBuilder.closeMenu(); | ||
Alexandre Leroux
|
r309 | } | ||
r1420 | void visitNodeEnter(const IVisualizationWidget& container) | |||
Alexandre Leroux
|
r212 | { | ||
// Opens a new menu associated to the node | ||||
Alexandre Leroux
|
r323 | m_PlotMenuBuilder.addMenu(container.name()); | ||
Alexandre Leroux
|
r325 | m_UnplotMenuBuilder.addMenu(container.name()); | ||
Alexandre Leroux
|
r212 | } | ||
template <typename ActionFun> | ||||
r1420 | void visitNodeLeavePlot( | |||
const IVisualizationWidget& container, const QString& actionName, ActionFun actionFunction) | ||||
Alexandre Leroux
|
r212 | { | ||
r1420 | if (isValidContainer(container)) | |||
{ | ||||
Alexandre Leroux
|
r323 | m_PlotMenuBuilder.addSeparator(); | ||
m_PlotMenuBuilder.addAction(actionName, actionFunction); | ||||
Alexandre Leroux
|
r214 | } | ||
Alexandre Leroux
|
r212 | // Closes the menu associated to the node | ||
Alexandre Leroux
|
r323 | m_PlotMenuBuilder.closeMenu(); | ||
Alexandre Leroux
|
r212 | } | ||
Alexandre Leroux
|
r326 | void visitNodeLeaveUnplot() | ||
{ | ||||
// Closes the menu associated to the node | ||||
m_UnplotMenuBuilder.closeMenu(); | ||||
} | ||||
Alexandre Leroux
|
r213 | template <typename ActionFun> | ||
r1420 | void visitLeafPlot( | |||
const IVisualizationWidget& container, const QString& actionName, ActionFun actionFunction) | ||||
Alexandre Leroux
|
r213 | { | ||
r1420 | if (isValidContainer(container)) | |||
{ | ||||
Alexandre Leroux
|
r323 | m_PlotMenuBuilder.addAction(actionName, actionFunction); | ||
Alexandre Leroux
|
r213 | } | ||
} | ||||
Alexandre Leroux
|
r328 | template <typename ActionFun> | ||
r1420 | void visitLeafUnplot( | |||
IVisualizationWidget* container, const QString& actionName, ActionFun actionFunction) | ||||
Alexandre Leroux
|
r328 | { | ||
Alexandre Leroux
|
r736 | // If the container contains the variable, we generate 'unplot' action | ||
r1420 | if (m_VariableContainers.count(container) == 1) | |||
{ | ||||
Alexandre Leroux
|
r328 | m_UnplotMenuBuilder.addAction(actionName, actionFunction); | ||
} | ||||
} | ||||
r1420 | bool isValidContainer(const IVisualizationWidget& container) const noexcept | |||
Alexandre Leroux
|
r736 | { | ||
// 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); | ||||
} | ||||
r1420 | std::shared_ptr<Variable2> m_Variable; | |||
std::set<IVisualizationWidget*> m_VariableContainers; | ||||
MenuBuilder m_PlotMenuBuilder; ///< Builder for the 'Plot' menu | ||||
Alexandre Leroux
|
r328 | MenuBuilder m_UnplotMenuBuilder; ///< Builder for the 'Unplot' menu | ||
Alexandre Leroux
|
r210 | }; | ||
r1420 | GenerateVariableMenuOperation::GenerateVariableMenuOperation(QMenu* menu, | |||
std::shared_ptr<Variable2> variable, std::set<IVisualizationWidget*> variableContainers) | ||||
: impl { spimpl::make_unique_impl<GenerateVariableMenuOperationPrivate>( | ||||
menu, variable, std::move(variableContainers)) } | ||||
Alexandre Leroux
|
r210 | { | ||
} | ||||
r1420 | void GenerateVariableMenuOperation::visitEnter(VisualizationWidget* widget) | |||
Alexandre Leroux
|
r210 | { | ||
// VisualizationWidget is not intended to accommodate a variable | ||||
Q_UNUSED(widget) | ||||
Alexandre Leroux
|
r309 | |||
Alexandre Leroux
|
r324 | // 'Plot' and 'Unplot' menus | ||
Alexandre Leroux
|
r309 | impl->visitRootEnter(); | ||
Alexandre Leroux
|
r210 | } | ||
r1420 | void GenerateVariableMenuOperation::visitLeave(VisualizationWidget* widget) | |||
Alexandre Leroux
|
r210 | { | ||
// VisualizationWidget is not intended to accommodate a variable | ||||
Q_UNUSED(widget) | ||||
Alexandre Leroux
|
r309 | |||
Alexandre Leroux
|
r324 | // 'Plot' and 'Unplot' menus | ||
Alexandre Leroux
|
r309 | impl->visitRootLeave(); | ||
Alexandre Leroux
|
r210 | } | ||
r1420 | void GenerateVariableMenuOperation::visitEnter(VisualizationTabWidget* tabWidget) | |||
Alexandre Leroux
|
r210 | { | ||
r1420 | if (tabWidget) | |||
{ | ||||
Alexandre Leroux
|
r325 | // 'Plot' and 'Unplot' menus | ||
Alexandre Leroux
|
r212 | impl->visitNodeEnter(*tabWidget); | ||
} | ||||
r1420 | else | |||
{ | ||||
Alexandre Leroux
|
r221 | qCCritical(LOG_GenerateVariableMenuOperation(), | ||
r1420 | "Can't visit enter VisualizationTabWidget : the widget is null"); | |||
Alexandre Leroux
|
r221 | } | ||
Alexandre Leroux
|
r210 | } | ||
r1420 | void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget* tabWidget) | |||
Alexandre Leroux
|
r210 | { | ||
r1420 | if (tabWidget) | |||
{ | ||||
Alexandre Leroux
|
r326 | // 'Plot' menu | ||
Alexandre Leroux
|
r361 | impl->visitNodeLeavePlot(*tabWidget, QObject::tr("Open in a new zone"), | ||
r1420 | [varW = std::weak_ptr<Variable2> { impl->m_Variable }, tabWidget]() { | |||
if (auto var = varW.lock()) | ||||
{ | ||||
tabWidget->createZone(var); | ||||
} | ||||
}); | ||||
Alexandre Leroux
|
r326 | |||
// 'Unplot' menu | ||||
impl->visitNodeLeaveUnplot(); | ||||
Alexandre Leroux
|
r212 | } | ||
r1420 | else | |||
{ | ||||
Alexandre Leroux
|
r221 | qCCritical(LOG_GenerateVariableMenuOperation(), | ||
r1420 | "Can't visit leave VisualizationTabWidget : the widget is null"); | |||
Alexandre Leroux
|
r221 | } | ||
Alexandre Leroux
|
r210 | } | ||
r1420 | void GenerateVariableMenuOperation::visitEnter(VisualizationZoneWidget* zoneWidget) | |||
Alexandre Leroux
|
r210 | { | ||
r1420 | if (zoneWidget) | |||
{ | ||||
Alexandre Leroux
|
r325 | // 'Plot' and 'Unplot' menus | ||
Alexandre Leroux
|
r212 | impl->visitNodeEnter(*zoneWidget); | ||
} | ||||
r1420 | else | |||
{ | ||||
Alexandre Leroux
|
r221 | qCCritical(LOG_GenerateVariableMenuOperation(), | ||
r1420 | "Can't visit enter VisualizationZoneWidget : the widget is null"); | |||
Alexandre Leroux
|
r221 | } | ||
Alexandre Leroux
|
r210 | } | ||
r1420 | void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget* zoneWidget) | |||
Alexandre Leroux
|
r210 | { | ||
r1420 | if (zoneWidget) | |||
{ | ||||
Alexandre Leroux
|
r326 | // 'Plot' menu | ||
r1420 | impl->visitNodeLeavePlot(*zoneWidget, QObject::tr("Open in a new graph"), | |||
[varW = std::weak_ptr<Variable2> { impl->m_Variable }, zoneWidget]() { | ||||
if (auto var = varW.lock()) | ||||
{ | ||||
Alexandre Leroux
|
r361 | zoneWidget->createGraph(var); | ||
} | ||||
}); | ||||
Alexandre Leroux
|
r326 | |||
// 'Unplot' menu | ||||
impl->visitNodeLeaveUnplot(); | ||||
Alexandre Leroux
|
r212 | } | ||
r1420 | else | |||
{ | ||||
Alexandre Leroux
|
r221 | qCCritical(LOG_GenerateVariableMenuOperation(), | ||
r1420 | "Can't visit leave VisualizationZoneWidget : the widget is null"); | |||
Alexandre Leroux
|
r221 | } | ||
Alexandre Leroux
|
r210 | } | ||
r1420 | void GenerateVariableMenuOperation::visit(VisualizationGraphWidget* graphWidget) | |||
Alexandre Leroux
|
r210 | { | ||
r1420 | if (graphWidget) | |||
{ | ||||
Alexandre Leroux
|
r328 | // 'Plot' menu | ||
Alexandre Leroux
|
r361 | impl->visitLeafPlot(*graphWidget, QObject::tr("Open in %1").arg(graphWidget->name()), | ||
r1420 | [varW = std::weak_ptr<Variable2> { impl->m_Variable }, graphWidget]() { | |||
if (auto var = varW.lock()) | ||||
{ | ||||
graphWidget->addVariable(var, graphWidget->graphRange()); | ||||
} | ||||
}); | ||||
Alexandre Leroux
|
r328 | |||
// 'Unplot' menu | ||||
Alexandre Leroux
|
r736 | impl->visitLeafUnplot(graphWidget, QObject::tr("Remove from %1").arg(graphWidget->name()), | ||
r1420 | [varW = std::weak_ptr<Variable2> { impl->m_Variable }, graphWidget]() { | |||
if (auto var = varW.lock()) | ||||
{ | ||||
graphWidget->removeVariable(var); | ||||
} | ||||
}); | ||||
Alexandre Leroux
|
r213 | } | ||
r1420 | else | |||
{ | ||||
Alexandre Leroux
|
r221 | qCCritical(LOG_GenerateVariableMenuOperation(), | ||
r1420 | "Can't visit VisualizationGraphWidget : the widget is null"); | |||
Alexandre Leroux
|
r221 | } | ||
Alexandre Leroux
|
r210 | } | ||