VisualizationWidget.cpp
240 lines
| 7.7 KiB
| text/x-c
|
CppLexer
r95 | #include "Visualization/VisualizationWidget.h" | |||
Alexandre Leroux
|
r207 | #include "Visualization/IVisualizationWidgetVisitor.h" | ||
r1078 | #include "Visualization/VisualizationActionManager.h" | |||
Alexandre Leroux
|
r176 | #include "Visualization/VisualizationGraphWidget.h" | ||
r1082 | #include "Visualization/VisualizationSelectionZoneItem.h" | |||
r1049 | #include "Visualization/VisualizationSelectionZoneManager.h" | |||
r95 | #include "Visualization/VisualizationTabWidget.h" | |||
Alexandre Leroux
|
r176 | #include "Visualization/VisualizationZoneWidget.h" | ||
Alexandre Leroux
|
r736 | #include "Visualization/operations/FindVariableOperation.h" | ||
Alexandre Leroux
|
r248 | #include "Visualization/operations/GenerateVariableMenuOperation.h" | ||
Alexandre Leroux
|
r334 | #include "Visualization/operations/RemoveVariableOperation.h" | ||
r437 | #include "Visualization/operations/RescaleAxeOperation.h" | |||
r118 | #include "Visualization/qcustomplot.h" | |||
r58 | #include "ui_VisualizationWidget.h" | |||
r88 | ||||
r1075 | #include "DragAndDrop/DragDropGuiController.h" | |||
r886 | #include "SqpApplication.h" | |||
r88 | #include <QToolButton> | |||
r1049 | #include <memory> | |||
r88 | Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget") | |||
r58 | ||||
r1420 | struct VisualizationWidget::VisualizationWidgetPrivate | |||
{ | ||||
r1049 | std::unique_ptr<VisualizationSelectionZoneManager> m_ZoneSelectionManager = nullptr; | |||
r1078 | VisualizationActionManager m_ActionManager; | |||
r1049 | ||||
VisualizationWidgetPrivate() | ||||
: m_ZoneSelectionManager(std::make_unique<VisualizationSelectionZoneManager>()) | ||||
{ | ||||
} | ||||
}; | ||||
r1420 | VisualizationWidget::VisualizationWidget(QWidget* parent) | |||
: QWidget { parent } | ||||
, ui { new Ui::VisualizationWidget } | ||||
, impl { spimpl::make_unique_impl<VisualizationWidgetPrivate>() } | ||||
r58 | { | |||
ui->setupUi(this); | ||||
r88 | ||||
r1420 | auto addTabViewButton = new QToolButton { ui->tabWidget }; | |||
r91 | addTabViewButton->setText(tr("Add View")); | |||
r88 | addTabViewButton->setCursor(Qt::ArrowCursor); | |||
ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner); | ||||
r186 | ||||
Alexandre Leroux
|
r188 | auto enableMinimumCornerWidgetSize = [this](bool enable) { | ||
r186 | auto tabViewCornerWidget = ui->tabWidget->cornerWidget(); | |||
auto width = enable ? tabViewCornerWidget->width() : 0; | ||||
auto height = enable ? tabViewCornerWidget->height() : 0; | ||||
tabViewCornerWidget->setMinimumHeight(height); | ||||
tabViewCornerWidget->setMinimumWidth(width); | ||||
ui->tabWidget->setMinimumHeight(height); | ||||
ui->tabWidget->setMinimumWidth(width); | ||||
}; | ||||
Alexandre Leroux
|
r188 | auto addTabView = [this, enableMinimumCornerWidgetSize]() { | ||
r1420 | auto widget | |||
= new VisualizationTabWidget { QString { "View %1" }.arg(ui->tabWidget->count() + 1), | ||||
ui->tabWidget }; | ||||
Alexandre Leroux
|
r198 | auto index = ui->tabWidget->addTab(widget, widget->name()); | ||
r1420 | if (ui->tabWidget->count() > 0) | |||
{ | ||||
Alexandre Leroux
|
r188 | enableMinimumCornerWidgetSize(false); | ||
r186 | } | |||
r88 | qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index); | |||
}; | ||||
Alexandre Leroux
|
r188 | auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) { | ||
r1420 | if (ui->tabWidget->count() == 1) | |||
{ | ||||
Alexandre Leroux
|
r188 | enableMinimumCornerWidgetSize(true); | ||
r186 | } | |||
Alexandre Leroux
|
r267 | // Removes widget from tab and closes it | ||
auto widget = ui->tabWidget->widget(index); | ||||
r88 | ui->tabWidget->removeTab(index); | |||
r1420 | if (widget) | |||
{ | ||||
Alexandre Leroux
|
r267 | widget->close(); | ||
} | ||||
r88 | qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index); | |||
}; | ||||
ui->tabWidget->setTabsClosable(true); | ||||
connect(addTabViewButton, &QToolButton::clicked, addTabView); | ||||
connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView); | ||||
Alexandre Leroux
|
r199 | |||
r1075 | sqpApp->dragDropGuiController().addDragDropTabBar(ui->tabWidget->tabBar()); | |||
r886 | ||||
r1082 | // Actions | |||
r1078 | impl->m_ActionManager.installSelectionZoneActions(); | |||
r1082 | auto removeZoneAction = new QAction("Remove selected zone(s)"); | |||
removeZoneAction->setShortcut(QKeySequence::Delete); | ||||
connect(removeZoneAction, &QAction::triggered, [this]() { | ||||
auto selection = impl->m_ZoneSelectionManager->selectedItems(); | ||||
r1420 | for (auto selectionZone : selection) | |||
{ | ||||
if (auto graph = selectionZone->parentGraphWidget()) | ||||
{ | ||||
r1082 | graph->removeSelectionZone(selectionZone); | |||
} | ||||
} | ||||
}); | ||||
addAction(removeZoneAction); | ||||
Alexandre Leroux
|
r199 | // Adds default tab | ||
addTabView(); | ||||
r58 | } | |||
VisualizationWidget::~VisualizationWidget() | ||||
{ | ||||
r1075 | sqpApp->dragDropGuiController().removeDragDropTabBar(ui->tabWidget->tabBar()); | |||
r58 | delete ui; | |||
} | ||||
r118 | ||||
r1420 | VisualizationSelectionZoneManager& VisualizationWidget::selectionZoneManager() const | |||
r1049 | { | |||
return *impl->m_ZoneSelectionManager.get(); | ||||
} | ||||
r1420 | VisualizationTabWidget* VisualizationWidget::currentTabWidget() const | |||
r1136 | { | |||
r1420 | if (auto tab = qobject_cast<VisualizationTabWidget*>(ui->tabWidget->currentWidget())) | |||
{ | ||||
r1136 | return tab; | |||
} | ||||
return nullptr; | ||||
} | ||||
r1420 | void VisualizationWidget::accept(IVisualizationWidgetVisitor* visitor) | |||
r118 | { | |||
r1420 | if (visitor) | |||
{ | ||||
Alexandre Leroux
|
r208 | visitor->visitEnter(this); | ||
// Apply visitor for tab children | ||||
r1420 | for (auto i = 0; i < ui->tabWidget->count(); ++i) | |||
{ | ||||
Alexandre Leroux
|
r220 | // Widgets different from tabs are not visited (no action) | ||
Alexandre Leroux
|
r208 | if (auto visualizationTabWidget | ||
r1420 | = dynamic_cast<VisualizationTabWidget*>(ui->tabWidget->widget(i))) | |||
{ | ||||
Alexandre Leroux
|
r208 | visualizationTabWidget->accept(visitor); | ||
} | ||||
} | ||||
visitor->visitLeave(this); | ||||
} | ||||
r1420 | else | |||
{ | ||||
Alexandre Leroux
|
r219 | qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null"); | ||
} | ||||
r118 | } | |||
r1420 | bool VisualizationWidget::canDrop(Variable2& variable) const | |||
Alexandre Leroux
|
r209 | { | ||
// The main widget can never accomodate a variable | ||||
Q_UNUSED(variable); | ||||
return false; | ||||
} | ||||
r1420 | bool VisualizationWidget::contains(Variable2& variable) const | |||
Alexandre Leroux
|
r327 | { | ||
Q_UNUSED(variable); | ||||
return false; | ||||
} | ||||
r119 | QString VisualizationWidget::name() const | |||
r118 | { | |||
return QStringLiteral("MainView"); | ||||
} | ||||
Alexandre Leroux
|
r175 | |||
Alexandre Leroux
|
r288 | void VisualizationWidget::attachVariableMenu( | ||
r1420 | QMenu* menu, const QVector<std::shared_ptr<Variable2>>& variables) noexcept | |||
Alexandre Leroux
|
r175 | { | ||
Alexandre Leroux
|
r288 | // Menu is generated only if there is a single variable | ||
r1420 | if (variables.size() == 1) | |||
{ | ||||
if (auto variable = variables.first()) | ||||
{ | ||||
Alexandre Leroux
|
r736 | // Gets the containers of the variable | ||
r1420 | FindVariableOperation findVariableOperation { variable }; | |||
Alexandre Leroux
|
r736 | accept(&findVariableOperation); | ||
auto variableContainers = findVariableOperation.result(); | ||||
Alexandre Leroux
|
r288 | // Generates the actions that make it possible to visualize the variable | ||
r1420 | GenerateVariableMenuOperation generateVariableMenuOperation { menu, variable, | |||
std::move(variableContainers) }; | ||||
Alexandre Leroux
|
r288 | accept(&generateVariableMenuOperation); | ||
} | ||||
r1420 | else | |||
{ | ||||
Alexandre Leroux
|
r288 | qCCritical(LOG_VisualizationWidget()) << tr( | ||
"Can't generate the menu relative to the visualization: the variable is null"); | ||||
} | ||||
} | ||||
r1420 | else | |||
{ | ||||
Alexandre Leroux
|
r288 | qCDebug(LOG_VisualizationWidget()) | ||
<< tr("No generation of the menu related to the visualization: several variables are " | ||||
"selected"); | ||||
} | ||||
Alexandre Leroux
|
r175 | } | ||
Alexandre Leroux
|
r334 | |||
r1420 | void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable2> variable) noexcept | |||
Alexandre Leroux
|
r334 | { | ||
// Calls the operation of removing all references to the variable in the visualization | ||||
r1420 | auto removeVariableOperation = RemoveVariableOperation { variable }; | |||
Alexandre Leroux
|
r334 | accept(&removeVariableOperation); | ||
} | ||||
r437 | ||||
r1420 | void VisualizationWidget::onRangeChanged( | |||
std::shared_ptr<Variable2> variable, const DateTimeRange& range) noexcept | ||||
r437 | { | |||
r447 | // Calls the operation of rescaling all graph that contrains variable in the visualization | |||
r1420 | auto rescaleVariableOperation = RescaleAxeOperation { variable, range }; | |||
r437 | accept(&rescaleVariableOperation); | |||
} | ||||
Alexandre Leroux
|
r738 | |||
r1420 | void VisualizationWidget::closeEvent(QCloseEvent* event) | |||
Alexandre Leroux
|
r738 | { | ||
// Closes tabs in the widget | ||||
r1420 | for (auto i = 0; i < ui->tabWidget->count(); ++i) | |||
{ | ||||
Alexandre Leroux
|
r738 | if (auto visualizationTabWidget | ||
r1420 | = dynamic_cast<VisualizationTabWidget*>(ui->tabWidget->widget(i))) | |||
{ | ||||
Alexandre Leroux
|
r738 | visualizationTabWidget->close(); | ||
} | ||||
} | ||||
QWidget::closeEvent(event); | ||||
} | ||||