##// END OF EJS Templates
Merge branch 'feature/VariableDeletion' into develop
Alexandre Leroux -
r337:c155354de1ae merge
parent child
Show More
@@ -0,0 +1,41
1 #ifndef SCIQLOP_REMOVEVARIABLEOPERATION_H
2 #define SCIQLOP_REMOVEVARIABLEOPERATION_H
3
4 #include "Visualization/IVisualizationWidgetVisitor.h"
5
6 #include <Common/spimpl.h>
7
8 #include <QLoggingCategory>
9
10 #include <memory>
11
12 class Variable;
13
14 Q_DECLARE_LOGGING_CATEGORY(LOG_RemoveVariableOperation)
15
16 /**
17 * @brief The RemoveVariableOperation class defines an operation that traverses all of visualization
18 * widgets to remove a variable if they contain it
19 */
20 class RemoveVariableOperation : public IVisualizationWidgetVisitor {
21 public:
22 /**
23 * Ctor
24 * @param variable the variable to remove from widgets
25 */
26 explicit RemoveVariableOperation(std::shared_ptr<Variable> variable);
27
28 void visitEnter(VisualizationWidget *widget) override final;
29 void visitLeave(VisualizationWidget *widget) override final;
30 void visitEnter(VisualizationTabWidget *tabWidget) override final;
31 void visitLeave(VisualizationTabWidget *tabWidget) override final;
32 void visitEnter(VisualizationZoneWidget *zoneWidget) override final;
33 void visitLeave(VisualizationZoneWidget *zoneWidget) override final;
34 void visit(VisualizationGraphWidget *graphWidget) override final;
35
36 private:
37 class RemoveVariableOperationPrivate;
38 spimpl::unique_impl_ptr<RemoveVariableOperationPrivate> impl;
39 };
40
41 #endif // SCIQLOP_REMOVEVARIABLEOPERATION_H
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -0,0 +1,70
1 #include "Visualization/operations/RemoveVariableOperation.h"
2 #include "Visualization/VisualizationGraphWidget.h"
3
4 #include <Variable/Variable.h>
5
6 Q_LOGGING_CATEGORY(LOG_RemoveVariableOperation, "RemoveVariableOperation")
7
8 struct RemoveVariableOperation::RemoveVariableOperationPrivate {
9 explicit RemoveVariableOperationPrivate(std::shared_ptr<Variable> variable)
10 : m_Variable(variable)
11 {
12 }
13
14 std::shared_ptr<Variable> m_Variable;
15 };
16
17 RemoveVariableOperation::RemoveVariableOperation(std::shared_ptr<Variable> variable)
18 : impl{spimpl::make_unique_impl<RemoveVariableOperationPrivate>(variable)}
19 {
20 }
21
22 void RemoveVariableOperation::visitEnter(VisualizationWidget *widget)
23 {
24 // VisualizationWidget is not intended to contain a variable
25 Q_UNUSED(widget)
26 }
27
28 void RemoveVariableOperation::visitLeave(VisualizationWidget *widget)
29 {
30 // VisualizationWidget is not intended to contain a variable
31 Q_UNUSED(widget)
32 }
33
34 void RemoveVariableOperation::visitEnter(VisualizationTabWidget *tabWidget)
35 {
36 // VisualizationTabWidget is not intended to contain a variable
37 Q_UNUSED(tabWidget)
38 }
39
40 void RemoveVariableOperation::visitLeave(VisualizationTabWidget *tabWidget)
41 {
42 // VisualizationTabWidget is not intended to contain a variable
43 Q_UNUSED(tabWidget)
44 }
45
46 void RemoveVariableOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
47 {
48 // VisualizationZoneWidget is not intended to contain a variable
49 Q_UNUSED(zoneWidget)
50 }
51
52 void RemoveVariableOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
53 {
54 // VisualizationZoneWidget is not intended to contain a variable
55 Q_UNUSED(zoneWidget)
56 }
57
58 void RemoveVariableOperation::visit(VisualizationGraphWidget *graphWidget)
59 {
60 if (graphWidget) {
61 // If the widget contains the variable, removes it
62 if (impl->m_Variable && graphWidget->contains(*impl->m_Variable)) {
63 graphWidget->removeVariable(impl->m_Variable);
64 }
65 }
66 else {
67 qCCritical(LOG_RemoveVariableOperation(),
68 "Can't visit VisualizationGraphWidget : the widget is null");
69 }
70 }
@@ -1,259 +1,265
1 /*------------------------------------------------------------------------------
1 /*------------------------------------------------------------------------------
2 -- This file is a part of the SciQLop Software
2 -- This file is a part of the SciQLop Software
3 -- Copyright (C) 2017, Plasma Physics Laboratory - CNRS
3 -- Copyright (C) 2017, Plasma Physics Laboratory - CNRS
4 --
4 --
5 -- This program is free software; you can redistribute it and/or modify
5 -- This program is free software; you can redistribute it and/or modify
6 -- it under the terms of the GNU General Public License as published by
6 -- it under the terms of the GNU General Public License as published by
7 -- the Free Software Foundation; either version 2 of the License, or
7 -- the Free Software Foundation; either version 2 of the License, or
8 -- (at your option) any later version.
8 -- (at your option) any later version.
9 --
9 --
10 -- This program is distributed in the hope that it will be useful,
10 -- This program is distributed in the hope that it will be useful,
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- GNU General Public License for more details.
13 -- GNU General Public License for more details.
14 --
14 --
15 -- You should have received a copy of the GNU General Public License
15 -- You should have received a copy of the GNU General Public License
16 -- along with this program; if not, write to the Free Software
16 -- along with this program; if not, write to the Free Software
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 -------------------------------------------------------------------------------*/
18 -------------------------------------------------------------------------------*/
19 /*-- Author : Alexis Jeandet
19 /*-- Author : Alexis Jeandet
20 -- Mail : alexis.jeandet@member.fsf.org
20 -- Mail : alexis.jeandet@member.fsf.org
21 ----------------------------------------------------------------------------*/
21 ----------------------------------------------------------------------------*/
22 #include "MainWindow.h"
22 #include "MainWindow.h"
23 #include "ui_MainWindow.h"
23 #include "ui_MainWindow.h"
24
24
25 #include <DataSource/DataSourceController.h>
25 #include <DataSource/DataSourceController.h>
26 #include <DataSource/DataSourceWidget.h>
26 #include <DataSource/DataSourceWidget.h>
27 #include <SidePane/SqpSidePane.h>
27 #include <SidePane/SqpSidePane.h>
28 #include <SqpApplication.h>
28 #include <SqpApplication.h>
29 #include <Time/TimeController.h>
29 #include <Time/TimeController.h>
30 #include <TimeWidget/TimeWidget.h>
30 #include <TimeWidget/TimeWidget.h>
31 #include <Variable/Variable.h>
31 #include <Variable/Variable.h>
32 #include <Variable/VariableController.h>
32 #include <Variable/VariableController.h>
33 #include <Visualization/VisualizationController.h>
33 #include <Visualization/VisualizationController.h>
34
34
35 #include <QAction>
35 #include <QAction>
36 #include <QDate>
36 #include <QDate>
37 #include <QDateTime>
37 #include <QDateTime>
38 #include <QDir>
38 #include <QDir>
39 #include <QFileDialog>
39 #include <QFileDialog>
40 #include <QToolBar>
40 #include <QToolBar>
41 #include <QToolButton>
41 #include <QToolButton>
42 #include <memory.h>
42 #include <memory.h>
43
43
44 //#include <omp.h>
44 //#include <omp.h>
45 //#include <network/filedownloader.h>
45 //#include <network/filedownloader.h>
46 //#include <qlopdatabase.h>
46 //#include <qlopdatabase.h>
47 //#include <qlopsettings.h>
47 //#include <qlopsettings.h>
48 //#include <qlopgui.h>
48 //#include <qlopgui.h>
49 //#include <spacedata.h>
49 //#include <spacedata.h>
50 //#include "qlopcore.h"
50 //#include "qlopcore.h"
51 //#include "qlopcodecmanager.h"
51 //#include "qlopcodecmanager.h"
52 //#include "cdfcodec.h"
52 //#include "cdfcodec.h"
53 //#include "amdatxtcodec.h"
53 //#include "amdatxtcodec.h"
54 //#include <qlopplotmanager.h>
54 //#include <qlopplotmanager.h>
55
55
56 #include "iostream"
56 #include "iostream"
57
57
58 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
58 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
59
59
60 namespace {
60 namespace {
61 const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0;
61 const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0;
62 const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1;
62 const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1;
63 const auto VIEWPLITTERINDEX = 2;
63 const auto VIEWPLITTERINDEX = 2;
64 const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3;
64 const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3;
65 const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4;
65 const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4;
66 }
66 }
67
67
68 class MainWindow::MainWindowPrivate {
68 class MainWindow::MainWindowPrivate {
69 public:
69 public:
70 QSize m_LastOpenLeftInspectorSize;
70 QSize m_LastOpenLeftInspectorSize;
71 QSize m_LastOpenRightInspectorSize;
71 QSize m_LastOpenRightInspectorSize;
72 };
72 };
73
73
74 MainWindow::MainWindow(QWidget *parent)
74 MainWindow::MainWindow(QWidget *parent)
75 : QMainWindow{parent},
75 : QMainWindow{parent},
76 m_Ui{new Ui::MainWindow},
76 m_Ui{new Ui::MainWindow},
77 impl{spimpl::make_unique_impl<MainWindowPrivate>()}
77 impl{spimpl::make_unique_impl<MainWindowPrivate>()}
78 {
78 {
79 m_Ui->setupUi(this);
79 m_Ui->setupUi(this);
80
80
81 m_Ui->splitter->setCollapsible(LEFTINSPECTORSIDEPANESPLITTERINDEX, false);
81 m_Ui->splitter->setCollapsible(LEFTINSPECTORSIDEPANESPLITTERINDEX, false);
82 m_Ui->splitter->setCollapsible(RIGHTINSPECTORSIDEPANESPLITTERINDEX, false);
82 m_Ui->splitter->setCollapsible(RIGHTINSPECTORSIDEPANESPLITTERINDEX, false);
83
83
84
84
85 auto leftSidePane = m_Ui->leftInspectorSidePane->sidePane();
85 auto leftSidePane = m_Ui->leftInspectorSidePane->sidePane();
86 auto openLeftInspectorAction = new QAction{QIcon{
86 auto openLeftInspectorAction = new QAction{QIcon{
87 ":/icones/previous.png",
87 ":/icones/previous.png",
88 },
88 },
89 tr("Show/hide the left inspector"), this};
89 tr("Show/hide the left inspector"), this};
90
90
91
91
92 auto spacerLeftTop = new QWidget{};
92 auto spacerLeftTop = new QWidget{};
93 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
93 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
94
94
95 auto spacerLeftBottom = new QWidget{};
95 auto spacerLeftBottom = new QWidget{};
96 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
96 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
97
97
98 leftSidePane->addWidget(spacerLeftTop);
98 leftSidePane->addWidget(spacerLeftTop);
99 leftSidePane->addAction(openLeftInspectorAction);
99 leftSidePane->addAction(openLeftInspectorAction);
100 leftSidePane->addWidget(spacerLeftBottom);
100 leftSidePane->addWidget(spacerLeftBottom);
101
101
102
102
103 auto rightSidePane = m_Ui->rightInspectorSidePane->sidePane();
103 auto rightSidePane = m_Ui->rightInspectorSidePane->sidePane();
104 auto openRightInspectorAction = new QAction{QIcon{
104 auto openRightInspectorAction = new QAction{QIcon{
105 ":/icones/next.png",
105 ":/icones/next.png",
106 },
106 },
107 tr("Show/hide the right inspector"), this};
107 tr("Show/hide the right inspector"), this};
108
108
109 auto spacerRightTop = new QWidget{};
109 auto spacerRightTop = new QWidget{};
110 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
110 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
111
111
112 auto spacerRightBottom = new QWidget{};
112 auto spacerRightBottom = new QWidget{};
113 spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
113 spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
114
114
115 rightSidePane->addWidget(spacerRightTop);
115 rightSidePane->addWidget(spacerRightTop);
116 rightSidePane->addAction(openRightInspectorAction);
116 rightSidePane->addAction(openRightInspectorAction);
117 rightSidePane->addWidget(spacerRightBottom);
117 rightSidePane->addWidget(spacerRightBottom);
118
118
119 openLeftInspectorAction->setCheckable(true);
119 openLeftInspectorAction->setCheckable(true);
120 openRightInspectorAction->setCheckable(true);
120 openRightInspectorAction->setCheckable(true);
121
121
122 auto openInspector = [this](bool checked, bool right, auto action) {
122 auto openInspector = [this](bool checked, bool right, auto action) {
123
123
124 action->setIcon(QIcon{(checked xor right) ? ":/icones/next.png" : ":/icones/previous.png"});
124 action->setIcon(QIcon{(checked xor right) ? ":/icones/next.png" : ":/icones/previous.png"});
125
125
126 auto &lastInspectorSize
126 auto &lastInspectorSize
127 = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize;
127 = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize;
128
128
129 auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size()
129 auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size()
130 : m_Ui->leftMainInspectorWidget->size();
130 : m_Ui->leftMainInspectorWidget->size();
131
131
132 // Update of the last opened geometry
132 // Update of the last opened geometry
133 if (checked) {
133 if (checked) {
134 lastInspectorSize = nextInspectorSize;
134 lastInspectorSize = nextInspectorSize;
135 }
135 }
136
136
137 auto startSize = lastInspectorSize;
137 auto startSize = lastInspectorSize;
138 auto endSize = startSize;
138 auto endSize = startSize;
139 endSize.setWidth(0);
139 endSize.setWidth(0);
140
140
141 auto splitterInspectorIndex
141 auto splitterInspectorIndex
142 = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX;
142 = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX;
143
143
144 auto currentSizes = m_Ui->splitter->sizes();
144 auto currentSizes = m_Ui->splitter->sizes();
145 if (checked) {
145 if (checked) {
146 // adjust sizes individually here, e.g.
146 // adjust sizes individually here, e.g.
147 currentSizes[splitterInspectorIndex] -= lastInspectorSize.width();
147 currentSizes[splitterInspectorIndex] -= lastInspectorSize.width();
148 currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width();
148 currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width();
149 m_Ui->splitter->setSizes(currentSizes);
149 m_Ui->splitter->setSizes(currentSizes);
150 }
150 }
151 else {
151 else {
152 // adjust sizes individually here, e.g.
152 // adjust sizes individually here, e.g.
153 currentSizes[splitterInspectorIndex] += lastInspectorSize.width();
153 currentSizes[splitterInspectorIndex] += lastInspectorSize.width();
154 currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width();
154 currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width();
155 m_Ui->splitter->setSizes(currentSizes);
155 m_Ui->splitter->setSizes(currentSizes);
156 }
156 }
157
157
158 };
158 };
159
159
160
160
161 connect(openLeftInspectorAction, &QAction::triggered,
161 connect(openLeftInspectorAction, &QAction::triggered,
162 [openInspector, openLeftInspectorAction](bool checked) {
162 [openInspector, openLeftInspectorAction](bool checked) {
163 openInspector(checked, false, openLeftInspectorAction);
163 openInspector(checked, false, openLeftInspectorAction);
164 });
164 });
165 connect(openRightInspectorAction, &QAction::triggered,
165 connect(openRightInspectorAction, &QAction::triggered,
166 [openInspector, openRightInspectorAction](bool checked) {
166 [openInspector, openRightInspectorAction](bool checked) {
167 openInspector(checked, true, openRightInspectorAction);
167 openInspector(checked, true, openRightInspectorAction);
168 });
168 });
169
169
170 this->menuBar()->addAction(tr("File"));
170 this->menuBar()->addAction(tr("File"));
171 auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar"));
171 auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar"));
172
172
173 auto timeWidget = new TimeWidget{};
173 auto timeWidget = new TimeWidget{};
174 mainToolBar->addWidget(timeWidget);
174 mainToolBar->addWidget(timeWidget);
175
175
176 // Controllers / controllers connections
177 connect(&sqpApp->timeController(), SIGNAL(timeUpdated(SqpDateTime)),
178 &sqpApp->variableController(), SLOT(onDateTimeOnSelection(SqpDateTime)));
179
176 // Widgets / controllers connections
180 // Widgets / controllers connections
177
181
178 // DataSource
182 // DataSource
179 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)),
183 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)),
180 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *)));
184 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *)));
181
185
182 // Time
186 // Time
183 connect(timeWidget, SIGNAL(timeUpdated(SqpDateTime)), &sqpApp->timeController(),
187 connect(timeWidget, SIGNAL(timeUpdated(SqpDateTime)), &sqpApp->timeController(),
184 SLOT(onTimeToUpdate(SqpDateTime)));
188 SLOT(onTimeToUpdate(SqpDateTime)));
185
189
186 connect(&sqpApp->timeController(), SIGNAL(timeUpdated(SqpDateTime)),
190 // Visualization
187 &sqpApp->variableController(), SLOT(onDateTimeOnSelection(SqpDateTime)));
191 connect(&sqpApp->visualizationController(),
192 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
193 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
188
194
189 // Widgets / widgets connections
195 // Widgets / widgets connections
190
196
191 // For the following connections, we use DirectConnection to allow each widget that can
197 // For the following connections, we use DirectConnection to allow each widget that can
192 // potentially attach a menu to the variable's menu to do so before this menu is displayed.
198 // potentially attach a menu to the variable's menu to do so before this menu is displayed.
193 // The order of connections is also important, since it determines the order in which each
199 // The order of connections is also important, since it determines the order in which each
194 // widget will attach its menu
200 // widget will attach its menu
195 connect(
201 connect(
196 m_Ui->variableInspectorWidget,
202 m_Ui->variableInspectorWidget,
197 SIGNAL(tableMenuAboutToBeDisplayed(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
203 SIGNAL(tableMenuAboutToBeDisplayed(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
198 m_Ui->view, SLOT(attachVariableMenu(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
204 m_Ui->view, SLOT(attachVariableMenu(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
199 Qt::DirectConnection);
205 Qt::DirectConnection);
200
206
201 /* QLopGUI::registerMenuBar(menuBar());
207 /* QLopGUI::registerMenuBar(menuBar());
202 this->setWindowIcon(QIcon(":/sciqlopLOGO.svg"));
208 this->setWindowIcon(QIcon(":/sciqlopLOGO.svg"));
203 this->m_progressWidget = new QWidget();
209 this->m_progressWidget = new QWidget();
204 this->m_progressLayout = new QVBoxLayout(this->m_progressWidget);
210 this->m_progressLayout = new QVBoxLayout(this->m_progressWidget);
205 this->m_progressWidget->setLayout(this->m_progressLayout);
211 this->m_progressWidget->setLayout(this->m_progressLayout);
206 this->m_progressWidget->setWindowModality(Qt::WindowModal);
212 this->m_progressWidget->setWindowModality(Qt::WindowModal);
207 m_progressThreadIds = (int*) malloc(OMP_THREADS*sizeof(int));
213 m_progressThreadIds = (int*) malloc(OMP_THREADS*sizeof(int));
208 for(int i=0;i<OMP_THREADS;i++)
214 for(int i=0;i<OMP_THREADS;i++)
209 {
215 {
210 this->m_progress.append(new QProgressBar(this->m_progressWidget));
216 this->m_progress.append(new QProgressBar(this->m_progressWidget));
211 this->m_progress.last()->setMinimum(0);
217 this->m_progress.last()->setMinimum(0);
212 this->m_progress.last()->setMaximum(100);
218 this->m_progress.last()->setMaximum(100);
213 this->m_progressLayout->addWidget(this->m_progress.last());
219 this->m_progressLayout->addWidget(this->m_progress.last());
214 this->m_progressWidget->hide();
220 this->m_progressWidget->hide();
215 this->m_progressThreadIds[i] = -1;
221 this->m_progressThreadIds[i] = -1;
216 }
222 }
217 this->m_progressWidget->setWindowTitle("Loading File");
223 this->m_progressWidget->setWindowTitle("Loading File");
218 const QList<QLopService*>ServicesToLoad=QList<QLopService*>()
224 const QList<QLopService*>ServicesToLoad=QList<QLopService*>()
219 << QLopCore::self()
225 << QLopCore::self()
220 << QLopPlotManager::self()
226 << QLopPlotManager::self()
221 << QLopCodecManager::self()
227 << QLopCodecManager::self()
222 << FileDownloader::self()
228 << FileDownloader::self()
223 << QLopDataBase::self()
229 << QLopDataBase::self()
224 << SpaceData::self();
230 << SpaceData::self();
225
231
226 CDFCodec::registerToManager();
232 CDFCodec::registerToManager();
227 AMDATXTCodec::registerToManager();
233 AMDATXTCodec::registerToManager();
228
234
229
235
230 for(int i=0;i<ServicesToLoad.count();i++)
236 for(int i=0;i<ServicesToLoad.count();i++)
231 {
237 {
232 qDebug()<<ServicesToLoad.at(i)->serviceName();
238 qDebug()<<ServicesToLoad.at(i)->serviceName();
233 ServicesToLoad.at(i)->initialize(); //must be called before getGUI
239 ServicesToLoad.at(i)->initialize(); //must be called before getGUI
234 QDockWidget* wdgt=ServicesToLoad.at(i)->getGUI();
240 QDockWidget* wdgt=ServicesToLoad.at(i)->getGUI();
235 if(wdgt)
241 if(wdgt)
236 {
242 {
237 wdgt->setAllowedAreas(Qt::AllDockWidgetAreas);
243 wdgt->setAllowedAreas(Qt::AllDockWidgetAreas);
238 this->addDockWidget(Qt::TopDockWidgetArea,wdgt);
244 this->addDockWidget(Qt::TopDockWidgetArea,wdgt);
239 }
245 }
240 PythonQt::self()->getMainModule().addObject(ServicesToLoad.at(i)->serviceName(),(QObject*)ServicesToLoad.at(i));
246 PythonQt::self()->getMainModule().addObject(ServicesToLoad.at(i)->serviceName(),(QObject*)ServicesToLoad.at(i));
241 }*/
247 }*/
242 }
248 }
243
249
244 MainWindow::~MainWindow()
250 MainWindow::~MainWindow()
245 {
251 {
246 }
252 }
247
253
248
254
249 void MainWindow::changeEvent(QEvent *e)
255 void MainWindow::changeEvent(QEvent *e)
250 {
256 {
251 QMainWindow::changeEvent(e);
257 QMainWindow::changeEvent(e);
252 switch (e->type()) {
258 switch (e->type()) {
253 case QEvent::LanguageChange:
259 case QEvent::LanguageChange:
254 m_Ui->retranslateUi(this);
260 m_Ui->retranslateUi(this);
255 break;
261 break;
256 default:
262 default:
257 break;
263 break;
258 }
264 }
259 }
265 }
@@ -1,40 +1,46
1 #ifndef SCIQLOP_VARIABLECACHECONTROLLER_H
1 #ifndef SCIQLOP_VARIABLECACHECONTROLLER_H
2 #define SCIQLOP_VARIABLECACHECONTROLLER_H
2 #define SCIQLOP_VARIABLECACHECONTROLLER_H
3
3
4 #include <QLoggingCategory>
4 #include <QObject>
5 #include <QObject>
5
6
6 #include <Data/SqpDateTime.h>
7 #include <Data/SqpDateTime.h>
7
8
8 #include <QLoggingCategory>
9 #include <QLoggingCategory>
9
10
10 #include <Common/spimpl.h>
11 #include <Common/spimpl.h>
11
12
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableCacheController)
14
12 class Variable;
15 class Variable;
13
16
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableCacheController)
17 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableCacheController)
15
18
16
19
17 /// This class aims to store in the cache all of the dateTime already requested to the variable.
20 /// This class aims to store in the cache all of the dateTime already requested to the variable.
18 class VariableCacheController : public QObject {
21 class VariableCacheController : public QObject {
19 Q_OBJECT
22 Q_OBJECT
20 public:
23 public:
21 explicit VariableCacheController(QObject *parent = 0);
24 explicit VariableCacheController(QObject *parent = 0);
22
25
23
26
24 void addDateTime(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
27 void addDateTime(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
25
28
29 /// Clears cache concerning a variable
30 void clear(std::shared_ptr<Variable> variable) noexcept;
31
26 /// Return all of the SqpDataTime part of the dateTime whose are not in the cache
32 /// Return all of the SqpDataTime part of the dateTime whose are not in the cache
27 QVector<SqpDateTime> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
33 QVector<SqpDateTime> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
28 const SqpDateTime &dateTime);
34 const SqpDateTime &dateTime);
29
35
30
36
31 QVector<SqpDateTime> dateCacheList(std::shared_ptr<Variable> variable) const noexcept;
37 QVector<SqpDateTime> dateCacheList(std::shared_ptr<Variable> variable) const noexcept;
32
38
33 void displayCache(std::shared_ptr<Variable> variable) const;
39 void displayCache(std::shared_ptr<Variable> variable) const;
34
40
35 private:
41 private:
36 class VariableCacheControllerPrivate;
42 class VariableCacheControllerPrivate;
37 spimpl::unique_impl_ptr<VariableCacheControllerPrivate> impl;
43 spimpl::unique_impl_ptr<VariableCacheControllerPrivate> impl;
38 };
44 };
39
45
40 #endif // SCIQLOP_VARIABLECACHECONTROLLER_H
46 #endif // SCIQLOP_VARIABLECACHECONTROLLER_H
@@ -1,61 +1,82
1 #ifndef SCIQLOP_VARIABLECONTROLLER_H
1 #ifndef SCIQLOP_VARIABLECONTROLLER_H
2 #define SCIQLOP_VARIABLECONTROLLER_H
2 #define SCIQLOP_VARIABLECONTROLLER_H
3
3
4 #include <Data/SqpDateTime.h>
4 #include <Data/SqpDateTime.h>
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QObject>
7 #include <QObject>
8
8
9 #include <Common/spimpl.h>
9 #include <Common/spimpl.h>
10
10
11 class IDataProvider;
11 class IDataProvider;
12 class QItemSelectionModel;
12 class QItemSelectionModel;
13 class TimeController;
13 class TimeController;
14 class Variable;
14 class Variable;
15 class VariableModel;
15 class VariableModel;
16
16
17 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
17 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
18
18
19 /**
19 /**
20 * @brief The VariableController class aims to handle the variables in SciQlop.
20 * @brief The VariableController class aims to handle the variables in SciQlop.
21 */
21 */
22 class VariableController : public QObject {
22 class VariableController : public QObject {
23 Q_OBJECT
23 Q_OBJECT
24 public:
24 public:
25 explicit VariableController(QObject *parent = 0);
25 explicit VariableController(QObject *parent = 0);
26 virtual ~VariableController();
26 virtual ~VariableController();
27
27
28 VariableModel *variableModel() noexcept;
28 VariableModel *variableModel() noexcept;
29 QItemSelectionModel *variableSelectionModel() noexcept;
29 QItemSelectionModel *variableSelectionModel() noexcept;
30
30
31 void setTimeController(TimeController *timeController) noexcept;
31 void setTimeController(TimeController *timeController) noexcept;
32
32
33 /**
34 * Deletes from the controller the variable passed in parameter.
35 *
36 * Delete a variable includes:
37 * - the deletion of the various references to the variable in SciQlop
38 * - the deletion of the model variable
39 * - the deletion of the provider associated with the variable
40 * - removing the cache associated with the variable
41 *
42 * @param variable the variable to delete from the controller.
43 */
44 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
45
46 /**
47 * Deletes from the controller the variables passed in parameter.
48 * @param variables the variables to delete from the controller.
49 * @sa deleteVariable()
50 */
51 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
33
52
34 signals:
53 signals:
54 /// Signal emitted when a variable is about to be deleted from the controller
55 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
35 /// Signal emitted when a variable has been created
56 /// Signal emitted when a variable has been created
36 void variableCreated(std::shared_ptr<Variable> variable);
57 void variableCreated(std::shared_ptr<Variable> variable);
37
58
38 public slots:
59 public slots:
39 /// Request the data loading of the variable whithin dateTime
60 /// Request the data loading of the variable whithin dateTime
40 void onRequestDataLoading(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
61 void onRequestDataLoading(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
41 /**
62 /**
42 * Creates a new variable and adds it to the model
63 * Creates a new variable and adds it to the model
43 * @param name the name of the new variable
64 * @param name the name of the new variable
44 * @param provider the data provider for the new variable
65 * @param provider the data provider for the new variable
45 */
66 */
46 void createVariable(const QString &name, std::shared_ptr<IDataProvider> provider) noexcept;
67 void createVariable(const QString &name, std::shared_ptr<IDataProvider> provider) noexcept;
47
68
48 /// Update the temporal parameters of every selected variable to dateTime
69 /// Update the temporal parameters of every selected variable to dateTime
49 void onDateTimeOnSelection(const SqpDateTime &dateTime);
70 void onDateTimeOnSelection(const SqpDateTime &dateTime);
50
71
51 void initialize();
72 void initialize();
52 void finalize();
73 void finalize();
53
74
54 private:
75 private:
55 void waitForFinish();
76 void waitForFinish();
56
77
57 class VariableControllerPrivate;
78 class VariableControllerPrivate;
58 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
79 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
59 };
80 };
60
81
61 #endif // SCIQLOP_VARIABLECONTROLLER_H
82 #endif // SCIQLOP_VARIABLECONTROLLER_H
@@ -1,49 +1,55
1 #ifndef SCIQLOP_VARIABLEMODEL_H
1 #ifndef SCIQLOP_VARIABLEMODEL_H
2 #define SCIQLOP_VARIABLEMODEL_H
2 #define SCIQLOP_VARIABLEMODEL_H
3
3
4
4
5 #include <Data/SqpDateTime.h>
5 #include <Data/SqpDateTime.h>
6
6
7 #include <QAbstractTableModel>
7 #include <QAbstractTableModel>
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9
9
10 #include <Common/spimpl.h>
10 #include <Common/spimpl.h>
11
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableModel)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableModel)
13
13
14 class IDataSeries;
14 class IDataSeries;
15 class Variable;
15 class Variable;
16
16
17 /**
17 /**
18 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
18 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
19 */
19 */
20 class VariableModel : public QAbstractTableModel {
20 class VariableModel : public QAbstractTableModel {
21 public:
21 public:
22 explicit VariableModel(QObject *parent = nullptr);
22 explicit VariableModel(QObject *parent = nullptr);
23
23
24 /**
24 /**
25 * Creates a new variable in the model
25 * Creates a new variable in the model
26 * @param name the name of the new variable
26 * @param name the name of the new variable
27 * @param dateTime the dateTime of the new variable
27 * @param dateTime the dateTime of the new variable
28 * @return the pointer to the new variable
28 * @return the pointer to the new variable
29 */
29 */
30 std::shared_ptr<Variable> createVariable(const QString &name,
30 std::shared_ptr<Variable> createVariable(const QString &name,
31 const SqpDateTime &dateTime) noexcept;
31 const SqpDateTime &dateTime) noexcept;
32
32
33 /**
34 * Deletes a variable from the model, if it exists
35 * @param variable the variable to delete
36 */
37 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
38
33 std::shared_ptr<Variable> variable(int index) const;
39 std::shared_ptr<Variable> variable(int index) const;
34
40
35 // /////////////////////////// //
41 // /////////////////////////// //
36 // QAbstractTableModel methods //
42 // QAbstractTableModel methods //
37 // /////////////////////////// //
43 // /////////////////////////// //
38 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
44 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
39 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
45 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
40 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
46 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
41 virtual QVariant headerData(int section, Qt::Orientation orientation,
47 virtual QVariant headerData(int section, Qt::Orientation orientation,
42 int role = Qt::DisplayRole) const override;
48 int role = Qt::DisplayRole) const override;
43
49
44 private:
50 private:
45 class VariableModelPrivate;
51 class VariableModelPrivate;
46 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
52 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
47 };
53 };
48
54
49 #endif // SCIQLOP_VARIABLEMODEL_H
55 #endif // SCIQLOP_VARIABLEMODEL_H
@@ -1,44 +1,46
1 #ifndef SCIQLOP_VISUALIZATIONCONTROLLER_H
1 #ifndef SCIQLOP_VISUALIZATIONCONTROLLER_H
2 #define SCIQLOP_VISUALIZATIONCONTROLLER_H
2 #define SCIQLOP_VISUALIZATIONCONTROLLER_H
3
3
4 #include <QLoggingCategory>
4 #include <QLoggingCategory>
5 #include <QObject>
5 #include <QObject>
6 #include <QUuid>
6 #include <QUuid>
7
7
8 #include <Common/spimpl.h>
8 #include <Common/spimpl.h>
9
9
10 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationController)
10 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationController)
11
11
12 class DataSourceItem;
12 class DataSourceItem;
13 class Variable;
13 class Variable;
14
14
15 /**
15 /**
16 * @brief The VisualizationController class aims to make the link between SciQlop and its plugins.
16 * @brief The VisualizationController class aims to make the link between SciQlop and its plugins.
17 * This is the intermediate class that SciQlop has to use in the way to connect a data source.
17 * This is the intermediate class that SciQlop has to use in the way to connect a data source.
18 * Please first use register method to initialize a plugin specified by its metadata name (JSON
18 * Please first use register method to initialize a plugin specified by its metadata name (JSON
19 * plugin source) then others specifics method will be able to access it. You can load a data source
19 * plugin source) then others specifics method will be able to access it. You can load a data source
20 * driver plugin then create a data source.
20 * driver plugin then create a data source.
21 */
21 */
22 class VisualizationController : public QObject {
22 class VisualizationController : public QObject {
23 Q_OBJECT
23 Q_OBJECT
24 public:
24 public:
25 explicit VisualizationController(QObject *parent = 0);
25 explicit VisualizationController(QObject *parent = 0);
26 virtual ~VisualizationController();
26 virtual ~VisualizationController();
27
27
28 signals:
28 signals:
29 /// Signal emitted when a variable is about to be deleted from SciQlop
30 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
29 /// Signal emitted when a variable has been created in SciQlop
31 /// Signal emitted when a variable has been created in SciQlop
30 void variableCreated(std::shared_ptr<Variable> variable);
32 void variableCreated(std::shared_ptr<Variable> variable);
31
33
32 public slots:
34 public slots:
33 /// Manage init/end of the controller
35 /// Manage init/end of the controller
34 void initialize();
36 void initialize();
35 void finalize();
37 void finalize();
36
38
37 private:
39 private:
38 void waitForFinish();
40 void waitForFinish();
39
41
40 class VisualizationControllerPrivate;
42 class VisualizationControllerPrivate;
41 spimpl::unique_impl_ptr<VisualizationControllerPrivate> impl;
43 spimpl::unique_impl_ptr<VisualizationControllerPrivate> impl;
42 };
44 };
43
45
44 #endif // SCIQLOP_VISUALIZATIONCONTROLLER_H
46 #endif // SCIQLOP_VISUALIZATIONCONTROLLER_H
@@ -1,204 +1,220
1 #include "Variable/VariableCacheController.h"
1 #include "Variable/VariableCacheController.h"
2
2
3 #include "Variable/Variable.h"
3 #include "Variable/Variable.h"
4 #include <unordered_map>
4 #include <unordered_map>
5
5
6 Q_LOGGING_CATEGORY(LOG_VariableCacheController, "VariableCacheController")
6 Q_LOGGING_CATEGORY(LOG_VariableCacheController, "VariableCacheController")
7
7
8 struct VariableCacheController::VariableCacheControllerPrivate {
8 struct VariableCacheController::VariableCacheControllerPrivate {
9
9
10 std::unordered_map<std::shared_ptr<Variable>, QVector<SqpDateTime> >
10 std::unordered_map<std::shared_ptr<Variable>, QVector<SqpDateTime> >
11 m_VariableToSqpDateTimeListMap;
11 m_VariableToSqpDateTimeListMap;
12
12
13 void addInCacheDataByEnd(const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
13 void addInCacheDataByEnd(const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
14 QVector<SqpDateTime> &notInCache, int cacheIndex,
14 QVector<SqpDateTime> &notInCache, int cacheIndex,
15 double currentTStart);
15 double currentTStart);
16
16
17 void addInCacheDataByStart(const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
17 void addInCacheDataByStart(const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
18 QVector<SqpDateTime> &notInCache, int cacheIndex,
18 QVector<SqpDateTime> &notInCache, int cacheIndex,
19 double currentTStart);
19 double currentTStart);
20
20
21
21
22 void addDateTimeRecurse(const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
22 void addDateTimeRecurse(const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
23 int cacheIndex);
23 int cacheIndex);
24 };
24 };
25
25
26
26
27 VariableCacheController::VariableCacheController(QObject *parent)
27 VariableCacheController::VariableCacheController(QObject *parent)
28 : QObject{parent}, impl{spimpl::make_unique_impl<VariableCacheControllerPrivate>()}
28 : QObject{parent}, impl{spimpl::make_unique_impl<VariableCacheControllerPrivate>()}
29 {
29 {
30 }
30 }
31
31
32 void VariableCacheController::addDateTime(std::shared_ptr<Variable> variable,
32 void VariableCacheController::addDateTime(std::shared_ptr<Variable> variable,
33 const SqpDateTime &dateTime)
33 const SqpDateTime &dateTime)
34 {
34 {
35 if (variable) {
35 if (variable) {
36 auto findVariableIte = impl->m_VariableToSqpDateTimeListMap.find(variable);
36 auto findVariableIte = impl->m_VariableToSqpDateTimeListMap.find(variable);
37 if (findVariableIte == impl->m_VariableToSqpDateTimeListMap.end()) {
37 if (findVariableIte == impl->m_VariableToSqpDateTimeListMap.end()) {
38 impl->m_VariableToSqpDateTimeListMap[variable].push_back(dateTime);
38 impl->m_VariableToSqpDateTimeListMap[variable].push_back(dateTime);
39 }
39 }
40 else {
40 else {
41
41
42 // addDateTime modify the list<SqpDateTime> of the variable in a way to ensure
42 // addDateTime modify the list<SqpDateTime> of the variable in a way to ensure
43 // that the list is ordered : l(0) < l(1). We assume also a < b
43 // that the list is ordered : l(0) < l(1). We assume also a < b
44 // (with a & b of type SqpDateTime) means ts(b) > te(a)
44 // (with a & b of type SqpDateTime) means ts(b) > te(a)
45
45
46 // The algorithm will try the merge of two interval:
46 // The algorithm will try the merge of two interval:
47 // - dateTime will be compare with the first interval of the list:
47 // - dateTime will be compare with the first interval of the list:
48 // A: if it is inferior, it will be inserted and it's finished.
48 // A: if it is inferior, it will be inserted and it's finished.
49 // B: if it is in intersection, it will be merge then the merged one
49 // B: if it is in intersection, it will be merge then the merged one
50 // will be compared to the next interval. The old one is remove from the list
50 // will be compared to the next interval. The old one is remove from the list
51 // C: if it is superior, we do the same with the next interval of the list
51 // C: if it is superior, we do the same with the next interval of the list
52
52
53 try {
53 try {
54 impl->addDateTimeRecurse(dateTime,
54 impl->addDateTimeRecurse(dateTime,
55 impl->m_VariableToSqpDateTimeListMap.at(variable), 0);
55 impl->m_VariableToSqpDateTimeListMap.at(variable), 0);
56 }
56 }
57 catch (const std::out_of_range &e) {
57 catch (const std::out_of_range &e) {
58 qCWarning(LOG_VariableCacheController()) << "addDateTime" << e.what();
58 qCWarning(LOG_VariableCacheController()) << "addDateTime" << e.what();
59 }
59 }
60 }
60 }
61 }
61 }
62 }
62 }
63
63
64 void VariableCacheController::clear(std::shared_ptr<Variable> variable) noexcept
65 {
66 if (!variable) {
67 qCCritical(LOG_VariableCacheController()) << "Can't clear variable cache: variable is null";
68 return;
69 }
70
71 auto nbEntries = impl->m_VariableToSqpDateTimeListMap.erase(variable);
72
73 auto clearCacheMessage
74 = (nbEntries != 0)
75 ? tr("Variable cache cleared for variable %1").arg(variable->name())
76 : tr("No deletion of variable cache: no cache was associated with the variable");
77 qCDebug(LOG_VariableCacheController()) << clearCacheMessage;
78 }
79
64 QVector<SqpDateTime>
80 QVector<SqpDateTime>
65 VariableCacheController::provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
81 VariableCacheController::provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
66 const SqpDateTime &dateTime)
82 const SqpDateTime &dateTime)
67 {
83 {
68 auto notInCache = QVector<SqpDateTime>{};
84 auto notInCache = QVector<SqpDateTime>{};
69
85
70 // This algorithm is recursif. The idea is to localise the start time then the end time in the
86 // This algorithm is recursif. The idea is to localise the start time then the end time in the
71 // list of date time request associated to the variable
87 // list of date time request associated to the variable
72 // We assume that the list is ordered in a way that l(0) < l(1). We assume also a < b
88 // We assume that the list is ordered in a way that l(0) < l(1). We assume also a < b
73 // (with a & b of type SqpDateTime) means ts(b) > te(a)
89 // (with a & b of type SqpDateTime) means ts(b) > te(a)
74 auto it = impl->m_VariableToSqpDateTimeListMap.find(variable);
90 auto it = impl->m_VariableToSqpDateTimeListMap.find(variable);
75 if (it != impl->m_VariableToSqpDateTimeListMap.end()) {
91 if (it != impl->m_VariableToSqpDateTimeListMap.end()) {
76 impl->addInCacheDataByStart(dateTime, it->second, notInCache, 0, dateTime.m_TStart);
92 impl->addInCacheDataByStart(dateTime, it->second, notInCache, 0, dateTime.m_TStart);
77 }
93 }
78 else {
94 else {
79 notInCache << dateTime;
95 notInCache << dateTime;
80 }
96 }
81
97
82 return notInCache;
98 return notInCache;
83 }
99 }
84
100
85 QVector<SqpDateTime>
101 QVector<SqpDateTime>
86 VariableCacheController::dateCacheList(std::shared_ptr<Variable> variable) const noexcept
102 VariableCacheController::dateCacheList(std::shared_ptr<Variable> variable) const noexcept
87 {
103 {
88 try {
104 try {
89 return impl->m_VariableToSqpDateTimeListMap.at(variable);
105 return impl->m_VariableToSqpDateTimeListMap.at(variable);
90 }
106 }
91 catch (const std::out_of_range &e) {
107 catch (const std::out_of_range &e) {
92 qCWarning(LOG_VariableCacheController()) << e.what();
108 qCWarning(LOG_VariableCacheController()) << e.what();
93 return QVector<SqpDateTime>{};
109 return QVector<SqpDateTime>{};
94 }
110 }
95 }
111 }
96
112
97 void VariableCacheController::VariableCacheControllerPrivate::addDateTimeRecurse(
113 void VariableCacheController::VariableCacheControllerPrivate::addDateTimeRecurse(
98 const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList, int cacheIndex)
114 const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList, int cacheIndex)
99 {
115 {
100 const auto dateTimeListSize = dateTimeList.count();
116 const auto dateTimeListSize = dateTimeList.count();
101 if (cacheIndex >= dateTimeListSize) {
117 if (cacheIndex >= dateTimeListSize) {
102 dateTimeList.push_back(dateTime);
118 dateTimeList.push_back(dateTime);
103 // there is no anymore interval to compore, we can just push_back it
119 // there is no anymore interval to compore, we can just push_back it
104 return;
120 return;
105 }
121 }
106
122
107 auto currentDateTime = dateTimeList[cacheIndex];
123 auto currentDateTime = dateTimeList[cacheIndex];
108
124
109 if (dateTime.m_TEnd < currentDateTime.m_TStart) {
125 if (dateTime.m_TEnd < currentDateTime.m_TStart) {
110 // The compared one is < to current one compared, we can insert it
126 // The compared one is < to current one compared, we can insert it
111 dateTimeList.insert(cacheIndex, dateTime);
127 dateTimeList.insert(cacheIndex, dateTime);
112 }
128 }
113 else if (dateTime.m_TStart > currentDateTime.m_TEnd) {
129 else if (dateTime.m_TStart > currentDateTime.m_TEnd) {
114 // The compared one is > to current one compared we can comparet if to the next one
130 // The compared one is > to current one compared we can comparet if to the next one
115 addDateTimeRecurse(dateTime, dateTimeList, ++cacheIndex);
131 addDateTimeRecurse(dateTime, dateTimeList, ++cacheIndex);
116 }
132 }
117 else {
133 else {
118 // Merge cases: we need to merge the two interval, remove the old one from the list then
134 // Merge cases: we need to merge the two interval, remove the old one from the list then
119 // rerun the algo from this index with the merged interval
135 // rerun the algo from this index with the merged interval
120 auto mTStart = std::min(dateTime.m_TStart, currentDateTime.m_TStart);
136 auto mTStart = std::min(dateTime.m_TStart, currentDateTime.m_TStart);
121 auto mTEnd = std::max(dateTime.m_TEnd, currentDateTime.m_TEnd);
137 auto mTEnd = std::max(dateTime.m_TEnd, currentDateTime.m_TEnd);
122 auto mergeDateTime = SqpDateTime{mTStart, mTEnd};
138 auto mergeDateTime = SqpDateTime{mTStart, mTEnd};
123
139
124 dateTimeList.remove(cacheIndex);
140 dateTimeList.remove(cacheIndex);
125 addDateTimeRecurse(mergeDateTime, dateTimeList, cacheIndex);
141 addDateTimeRecurse(mergeDateTime, dateTimeList, cacheIndex);
126 }
142 }
127 }
143 }
128
144
129
145
130 void VariableCacheController::VariableCacheControllerPrivate::addInCacheDataByEnd(
146 void VariableCacheController::VariableCacheControllerPrivate::addInCacheDataByEnd(
131 const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
147 const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
132 QVector<SqpDateTime> &notInCache, int cacheIndex, double currentTStart)
148 QVector<SqpDateTime> &notInCache, int cacheIndex, double currentTStart)
133 {
149 {
134 const auto dateTimeListSize = dateTimeList.count();
150 const auto dateTimeListSize = dateTimeList.count();
135 if (cacheIndex >= dateTimeListSize) {
151 if (cacheIndex >= dateTimeListSize) {
136 if (currentTStart < dateTime.m_TEnd) {
152 if (currentTStart < dateTime.m_TEnd) {
137
153
138 // te localised after all other interval: The last interval is [currentTsart, te]
154 // te localised after all other interval: The last interval is [currentTsart, te]
139 notInCache.push_back(SqpDateTime{currentTStart, dateTime.m_TEnd});
155 notInCache.push_back(SqpDateTime{currentTStart, dateTime.m_TEnd});
140 }
156 }
141 return;
157 return;
142 }
158 }
143
159
144 auto currentDateTimeJ = dateTimeList[cacheIndex];
160 auto currentDateTimeJ = dateTimeList[cacheIndex];
145 if (dateTime.m_TEnd <= currentDateTimeJ.m_TStart) {
161 if (dateTime.m_TEnd <= currentDateTimeJ.m_TStart) {
146 // te localised between to interval: The last interval is [currentTsart, te]
162 // te localised between to interval: The last interval is [currentTsart, te]
147 notInCache.push_back(SqpDateTime{currentTStart, dateTime.m_TEnd});
163 notInCache.push_back(SqpDateTime{currentTStart, dateTime.m_TEnd});
148 }
164 }
149 else {
165 else {
150 notInCache.push_back(SqpDateTime{currentTStart, currentDateTimeJ.m_TStart});
166 notInCache.push_back(SqpDateTime{currentTStart, currentDateTimeJ.m_TStart});
151 if (dateTime.m_TEnd > currentDateTimeJ.m_TEnd) {
167 if (dateTime.m_TEnd > currentDateTimeJ.m_TEnd) {
152 // te not localised before the current interval: we need to look at the next interval
168 // te not localised before the current interval: we need to look at the next interval
153 addInCacheDataByEnd(dateTime, dateTimeList, notInCache, ++cacheIndex,
169 addInCacheDataByEnd(dateTime, dateTimeList, notInCache, ++cacheIndex,
154 currentDateTimeJ.m_TEnd);
170 currentDateTimeJ.m_TEnd);
155 }
171 }
156 }
172 }
157 }
173 }
158
174
159 void VariableCacheController::VariableCacheControllerPrivate::addInCacheDataByStart(
175 void VariableCacheController::VariableCacheControllerPrivate::addInCacheDataByStart(
160 const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
176 const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
161 QVector<SqpDateTime> &notInCache, int cacheIndex, double currentTStart)
177 QVector<SqpDateTime> &notInCache, int cacheIndex, double currentTStart)
162 {
178 {
163 const auto dateTimeListSize = dateTimeList.count();
179 const auto dateTimeListSize = dateTimeList.count();
164 if (cacheIndex >= dateTimeListSize) {
180 if (cacheIndex >= dateTimeListSize) {
165 // ts localised after all other interval: The last interval is [ts, te]
181 // ts localised after all other interval: The last interval is [ts, te]
166 notInCache.push_back(SqpDateTime{currentTStart, dateTime.m_TEnd});
182 notInCache.push_back(SqpDateTime{currentTStart, dateTime.m_TEnd});
167 return;
183 return;
168 }
184 }
169
185
170 auto currentDateTimeI = dateTimeList[cacheIndex];
186 auto currentDateTimeI = dateTimeList[cacheIndex];
171 if (currentTStart < currentDateTimeI.m_TStart) {
187 if (currentTStart < currentDateTimeI.m_TStart) {
172
188
173 // ts localised between to interval: let's localized te
189 // ts localised between to interval: let's localized te
174 addInCacheDataByEnd(dateTime, dateTimeList, notInCache, cacheIndex, currentTStart);
190 addInCacheDataByEnd(dateTime, dateTimeList, notInCache, cacheIndex, currentTStart);
175 }
191 }
176 else if (currentTStart < currentDateTimeI.m_TEnd) {
192 else if (currentTStart < currentDateTimeI.m_TEnd) {
177 if (dateTime.m_TEnd > currentDateTimeI.m_TEnd) {
193 if (dateTime.m_TEnd > currentDateTimeI.m_TEnd) {
178 // ts not localised before the current interval: we need to look at the next interval
194 // ts not localised before the current interval: we need to look at the next interval
179 // We can assume now current tstart is the last interval tend, because data between them
195 // We can assume now current tstart is the last interval tend, because data between them
180 // are
196 // are
181 // in the cache
197 // in the cache
182 addInCacheDataByStart(dateTime, dateTimeList, notInCache, ++cacheIndex,
198 addInCacheDataByStart(dateTime, dateTimeList, notInCache, ++cacheIndex,
183 currentDateTimeI.m_TEnd);
199 currentDateTimeI.m_TEnd);
184 }
200 }
185 }
201 }
186 else {
202 else {
187 // ts not localised before the current interval: we need to look at the next interval
203 // ts not localised before the current interval: we need to look at the next interval
188 addInCacheDataByStart(dateTime, dateTimeList, notInCache, ++cacheIndex, currentTStart);
204 addInCacheDataByStart(dateTime, dateTimeList, notInCache, ++cacheIndex, currentTStart);
189 }
205 }
190 }
206 }
191
207
192
208
193 void VariableCacheController::displayCache(std::shared_ptr<Variable> variable) const
209 void VariableCacheController::displayCache(std::shared_ptr<Variable> variable) const
194 {
210 {
195 auto variableDateTimeList = impl->m_VariableToSqpDateTimeListMap.find(variable);
211 auto variableDateTimeList = impl->m_VariableToSqpDateTimeListMap.find(variable);
196 if (variableDateTimeList != impl->m_VariableToSqpDateTimeListMap.end()) {
212 if (variableDateTimeList != impl->m_VariableToSqpDateTimeListMap.end()) {
197 qCInfo(LOG_VariableCacheController()) << tr("VariableCacheController::displayCache")
213 qCInfo(LOG_VariableCacheController()) << tr("VariableCacheController::displayCache")
198 << variableDateTimeList->second;
214 << variableDateTimeList->second;
199 }
215 }
200 else {
216 else {
201 qCWarning(LOG_VariableCacheController())
217 qCWarning(LOG_VariableCacheController())
202 << tr("Cannot display a variable that is not in the cache");
218 << tr("Cannot display a variable that is not in the cache");
203 }
219 }
204 }
220 }
@@ -1,177 +1,209
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableCacheController.h>
2 #include <Variable/VariableCacheController.h>
3 #include <Variable/VariableController.h>
3 #include <Variable/VariableController.h>
4 #include <Variable/VariableModel.h>
4 #include <Variable/VariableModel.h>
5
5
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Data/IDataProvider.h>
7 #include <Data/IDataProvider.h>
8 #include <Data/IDataSeries.h>
8 #include <Data/IDataSeries.h>
9 #include <Time/TimeController.h>
9 #include <Time/TimeController.h>
10
10
11 #include <QDateTime>
11 #include <QDateTime>
12 #include <QMutex>
12 #include <QMutex>
13 #include <QThread>
13 #include <QThread>
14 #include <QtCore/QItemSelectionModel>
14 #include <QtCore/QItemSelectionModel>
15
15
16 #include <unordered_map>
16 #include <unordered_map>
17
17
18 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
18 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
19
19
20 namespace {
20 namespace {
21
21
22 /// @todo Generates default dataseries, according to the provider passed in parameter. This method
22 /// @todo Generates default dataseries, according to the provider passed in parameter. This method
23 /// will be deleted when the timerange is recovered from SciQlop
23 /// will be deleted when the timerange is recovered from SciQlop
24 std::shared_ptr<IDataSeries> generateDefaultDataSeries(const IDataProvider &provider,
24 std::shared_ptr<IDataSeries> generateDefaultDataSeries(const IDataProvider &provider,
25 const SqpDateTime &dateTime) noexcept
25 const SqpDateTime &dateTime) noexcept
26 {
26 {
27 auto parameters = DataProviderParameters{dateTime};
27 auto parameters = DataProviderParameters{dateTime};
28
28
29 return provider.retrieveData(parameters);
29 return provider.retrieveData(parameters);
30 }
30 }
31
31
32 } // namespace
32 } // namespace
33
33
34 struct VariableController::VariableControllerPrivate {
34 struct VariableController::VariableControllerPrivate {
35 explicit VariableControllerPrivate(VariableController *parent)
35 explicit VariableControllerPrivate(VariableController *parent)
36 : m_WorkingMutex{},
36 : m_WorkingMutex{},
37 m_VariableModel{new VariableModel{parent}},
37 m_VariableModel{new VariableModel{parent}},
38 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
38 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
39 m_VariableCacheController{std::make_unique<VariableCacheController>()}
39 m_VariableCacheController{std::make_unique<VariableCacheController>()}
40 {
40 {
41 }
41 }
42
42
43 QMutex m_WorkingMutex;
43 QMutex m_WorkingMutex;
44 /// Variable model. The VariableController has the ownership
44 /// Variable model. The VariableController has the ownership
45 VariableModel *m_VariableModel;
45 VariableModel *m_VariableModel;
46 QItemSelectionModel *m_VariableSelectionModel;
46 QItemSelectionModel *m_VariableSelectionModel;
47
47
48
48
49 TimeController *m_TimeController{nullptr};
49 TimeController *m_TimeController{nullptr};
50 std::unique_ptr<VariableCacheController> m_VariableCacheController;
50 std::unique_ptr<VariableCacheController> m_VariableCacheController;
51
51
52 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
52 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
53 m_VariableToProviderMap;
53 m_VariableToProviderMap;
54 };
54 };
55
55
56 VariableController::VariableController(QObject *parent)
56 VariableController::VariableController(QObject *parent)
57 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
57 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
58 {
58 {
59 qCDebug(LOG_VariableController()) << tr("VariableController construction")
59 qCDebug(LOG_VariableController()) << tr("VariableController construction")
60 << QThread::currentThread();
60 << QThread::currentThread();
61 }
61 }
62
62
63 VariableController::~VariableController()
63 VariableController::~VariableController()
64 {
64 {
65 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
65 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
66 << QThread::currentThread();
66 << QThread::currentThread();
67 this->waitForFinish();
67 this->waitForFinish();
68 }
68 }
69
69
70 VariableModel *VariableController::variableModel() noexcept
70 VariableModel *VariableController::variableModel() noexcept
71 {
71 {
72 return impl->m_VariableModel;
72 return impl->m_VariableModel;
73 }
73 }
74
74
75 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
75 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
76 {
76 {
77 return impl->m_VariableSelectionModel;
77 return impl->m_VariableSelectionModel;
78 }
78 }
79
79
80 void VariableController::setTimeController(TimeController *timeController) noexcept
80 void VariableController::setTimeController(TimeController *timeController) noexcept
81 {
81 {
82 impl->m_TimeController = timeController;
82 impl->m_TimeController = timeController;
83 }
83 }
84
84
85 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
86 {
87 if (!variable) {
88 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
89 return;
90 }
91
92 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
93 // make some treatments before the deletion
94 emit variableAboutToBeDeleted(variable);
95
96 // Deletes provider
97 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
98 qCDebug(LOG_VariableController())
99 << tr("Number of providers deleted for variable %1: %2")
100 .arg(variable->name(), QString::number(nbProvidersDeleted));
101
102 // Clears cache
103 impl->m_VariableCacheController->clear(variable);
104
105 // Deletes from model
106 impl->m_VariableModel->deleteVariable(variable);
107 }
108
109 void VariableController::deleteVariables(
110 const QVector<std::shared_ptr<Variable> > &variables) noexcept
111 {
112 for (auto variable : qAsConst(variables)) {
113 deleteVariable(variable);
114 }
115 }
116
85 void VariableController::createVariable(const QString &name,
117 void VariableController::createVariable(const QString &name,
86 std::shared_ptr<IDataProvider> provider) noexcept
118 std::shared_ptr<IDataProvider> provider) noexcept
87 {
119 {
88
120
89 if (!impl->m_TimeController) {
121 if (!impl->m_TimeController) {
90 qCCritical(LOG_VariableController())
122 qCCritical(LOG_VariableController())
91 << tr("Impossible to create variable: The time controller is null");
123 << tr("Impossible to create variable: The time controller is null");
92 return;
124 return;
93 }
125 }
94
126
95
127
96 /// @todo : for the moment :
128 /// @todo : for the moment :
97 /// - the provider is only used to retrieve data from the variable for its initialization, but
129 /// - the provider is only used to retrieve data from the variable for its initialization, but
98 /// it will be retained later
130 /// it will be retained later
99 /// - default data are generated for the variable, without taking into account the timerange set
131 /// - default data are generated for the variable, without taking into account the timerange set
100 /// in sciqlop
132 /// in sciqlop
101 auto dateTime = impl->m_TimeController->dateTime();
133 auto dateTime = impl->m_TimeController->dateTime();
102 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime)) {
134 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime)) {
103
135
104 // store the provider
136 // store the provider
105 impl->m_VariableToProviderMap[newVariable] = provider;
137 impl->m_VariableToProviderMap[newVariable] = provider;
106
138
107 auto addDateTimeAcquired
139 auto addDateTimeAcquired
108 = [this, newVariable](auto dataSeriesAcquired, auto dateTimeToPutInCache) {
140 = [this, newVariable](auto dataSeriesAcquired, auto dateTimeToPutInCache) {
109
141
110 impl->m_VariableCacheController->addDateTime(newVariable, dateTimeToPutInCache);
142 impl->m_VariableCacheController->addDateTime(newVariable, dateTimeToPutInCache);
111 newVariable->setDataSeries(dataSeriesAcquired);
143 newVariable->setDataSeries(dataSeriesAcquired);
112
144
113 };
145 };
114
146
115 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
147 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
116 this->onRequestDataLoading(newVariable, dateTime);
148 this->onRequestDataLoading(newVariable, dateTime);
117
149
118 // notify the creation
150 // notify the creation
119 emit variableCreated(newVariable);
151 emit variableCreated(newVariable);
120 }
152 }
121 }
153 }
122
154
123 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
155 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
124 {
156 {
125 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
157 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
126
158
127 for (const auto &selectedRow : qAsConst(selectedRows)) {
159 for (const auto &selectedRow : qAsConst(selectedRows)) {
128 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
160 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
129 selectedVariable->setDateTime(dateTime);
161 selectedVariable->setDateTime(dateTime);
130 this->onRequestDataLoading(selectedVariable, dateTime);
162 this->onRequestDataLoading(selectedVariable, dateTime);
131 }
163 }
132 }
164 }
133 }
165 }
134
166
135
167
136 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
168 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
137 const SqpDateTime &dateTime)
169 const SqpDateTime &dateTime)
138 {
170 {
139 // we want to load data of the variable for the dateTime.
171 // we want to load data of the variable for the dateTime.
140 // First we check if the cache contains some of them.
172 // First we check if the cache contains some of them.
141 // For the other, we ask the provider to give them.
173 // For the other, we ask the provider to give them.
142 if (variable) {
174 if (variable) {
143
175
144 auto dateTimeListNotInCache
176 auto dateTimeListNotInCache
145 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
177 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
146
178
147 if (!dateTimeListNotInCache.empty()) {
179 if (!dateTimeListNotInCache.empty()) {
148 // Ask the provider for each data on the dateTimeListNotInCache
180 // Ask the provider for each data on the dateTimeListNotInCache
149 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
181 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
150 std::move(dateTimeListNotInCache));
182 std::move(dateTimeListNotInCache));
151 }
183 }
152 else {
184 else {
153 emit variable->updated();
185 emit variable->updated();
154 }
186 }
155 }
187 }
156 else {
188 else {
157 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
189 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
158 }
190 }
159 }
191 }
160
192
161
193
162 void VariableController::initialize()
194 void VariableController::initialize()
163 {
195 {
164 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
196 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
165 impl->m_WorkingMutex.lock();
197 impl->m_WorkingMutex.lock();
166 qCDebug(LOG_VariableController()) << tr("VariableController init END");
198 qCDebug(LOG_VariableController()) << tr("VariableController init END");
167 }
199 }
168
200
169 void VariableController::finalize()
201 void VariableController::finalize()
170 {
202 {
171 impl->m_WorkingMutex.unlock();
203 impl->m_WorkingMutex.unlock();
172 }
204 }
173
205
174 void VariableController::waitForFinish()
206 void VariableController::waitForFinish()
175 {
207 {
176 QMutexLocker locker{&impl->m_WorkingMutex};
208 QMutexLocker locker{&impl->m_WorkingMutex};
177 }
209 }
@@ -1,153 +1,179
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableModel.h>
2 #include <Variable/VariableModel.h>
3
3
4 #include <Data/IDataSeries.h>
4 #include <Data/IDataSeries.h>
5
5
6 #include <QDateTime>
6 #include <QDateTime>
7 #include <QSize>
7 #include <QSize>
8
8
9 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
9 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
10
10
11 namespace {
11 namespace {
12
12
13 // Column indexes
13 // Column indexes
14 const auto NAME_COLUMN = 0;
14 const auto NAME_COLUMN = 0;
15 const auto TSTART_COLUMN = 1;
15 const auto TSTART_COLUMN = 1;
16 const auto TEND_COLUMN = 2;
16 const auto TEND_COLUMN = 2;
17 const auto NB_COLUMNS = 3;
17 const auto NB_COLUMNS = 3;
18
18
19 // Column properties
19 // Column properties
20 const auto DEFAULT_HEIGHT = 25;
20 const auto DEFAULT_HEIGHT = 25;
21 const auto DEFAULT_WIDTH = 100;
21 const auto DEFAULT_WIDTH = 100;
22
22
23 struct ColumnProperties {
23 struct ColumnProperties {
24 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
24 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
25 int height = DEFAULT_HEIGHT)
25 int height = DEFAULT_HEIGHT)
26 : m_Name{name}, m_Width{width}, m_Height{height}
26 : m_Name{name}, m_Width{width}, m_Height{height}
27 {
27 {
28 }
28 }
29
29
30 QString m_Name;
30 QString m_Name;
31 int m_Width;
31 int m_Width;
32 int m_Height;
32 int m_Height;
33 };
33 };
34
34
35 const auto COLUMN_PROPERTIES
35 const auto COLUMN_PROPERTIES
36 = QHash<int, ColumnProperties>{{NAME_COLUMN, {QObject::tr("Name")}},
36 = QHash<int, ColumnProperties>{{NAME_COLUMN, {QObject::tr("Name")}},
37 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
37 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
38 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}};
38 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}};
39
39
40 /// Format for datetimes
40 /// Format for datetimes
41 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
41 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
42
42
43 } // namespace
43 } // namespace
44
44
45 struct VariableModel::VariableModelPrivate {
45 struct VariableModel::VariableModelPrivate {
46 /// Variables created in SciQlop
46 /// Variables created in SciQlop
47 std::vector<std::shared_ptr<Variable> > m_Variables;
47 std::vector<std::shared_ptr<Variable> > m_Variables;
48 };
48 };
49
49
50 VariableModel::VariableModel(QObject *parent)
50 VariableModel::VariableModel(QObject *parent)
51 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
51 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
52 {
52 {
53 }
53 }
54
54
55 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
55 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
56 const SqpDateTime &dateTime) noexcept
56 const SqpDateTime &dateTime) noexcept
57 {
57 {
58 auto insertIndex = rowCount();
58 auto insertIndex = rowCount();
59 beginInsertRows({}, insertIndex, insertIndex);
59 beginInsertRows({}, insertIndex, insertIndex);
60
60
61 /// @todo For the moment, the other data of the variable is initialized with default values
61 /// @todo For the moment, the other data of the variable is initialized with default values
62 auto variable = std::make_shared<Variable>(name, QStringLiteral("unit"),
62 auto variable = std::make_shared<Variable>(name, QStringLiteral("unit"),
63 QStringLiteral("mission"), dateTime);
63 QStringLiteral("mission"), dateTime);
64
64
65 impl->m_Variables.push_back(variable);
65 impl->m_Variables.push_back(variable);
66
66
67 endInsertRows();
67 endInsertRows();
68
68
69 return variable;
69 return variable;
70 }
70 }
71
71
72 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
73 {
74 if (!variable) {
75 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
76 return;
77 }
78
79 // Finds variable in the model
80 auto begin = impl->m_Variables.cbegin();
81 auto end = impl->m_Variables.cend();
82 auto it = std::find(begin, end, variable);
83 if (it != end) {
84 auto removeIndex = std::distance(begin, it);
85
86 // Deletes variable
87 beginRemoveRows({}, removeIndex, removeIndex);
88 impl->m_Variables.erase(it);
89 endRemoveRows();
90 }
91 else {
92 qCritical(LOG_VariableModel())
93 << tr("Can't delete variable %1 from the model: the variable is not in the model")
94 .arg(variable->name());
95 }
96 }
97
72 std::shared_ptr<Variable> VariableModel::variable(int index) const
98 std::shared_ptr<Variable> VariableModel::variable(int index) const
73 {
99 {
74 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
100 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
75 }
101 }
76
102
77 int VariableModel::columnCount(const QModelIndex &parent) const
103 int VariableModel::columnCount(const QModelIndex &parent) const
78 {
104 {
79 Q_UNUSED(parent);
105 Q_UNUSED(parent);
80
106
81 return NB_COLUMNS;
107 return NB_COLUMNS;
82 }
108 }
83
109
84 int VariableModel::rowCount(const QModelIndex &parent) const
110 int VariableModel::rowCount(const QModelIndex &parent) const
85 {
111 {
86 Q_UNUSED(parent);
112 Q_UNUSED(parent);
87
113
88 return impl->m_Variables.size();
114 return impl->m_Variables.size();
89 }
115 }
90
116
91 QVariant VariableModel::data(const QModelIndex &index, int role) const
117 QVariant VariableModel::data(const QModelIndex &index, int role) const
92 {
118 {
93 if (!index.isValid()) {
119 if (!index.isValid()) {
94 return QVariant{};
120 return QVariant{};
95 }
121 }
96
122
97 if (index.row() < 0 || index.row() >= rowCount()) {
123 if (index.row() < 0 || index.row() >= rowCount()) {
98 return QVariant{};
124 return QVariant{};
99 }
125 }
100
126
101 if (role == Qt::DisplayRole) {
127 if (role == Qt::DisplayRole) {
102 if (auto variable = impl->m_Variables.at(index.row()).get()) {
128 if (auto variable = impl->m_Variables.at(index.row()).get()) {
103 /// Lambda function that builds the variant to return for a time value
129 /// Lambda function that builds the variant to return for a time value
104 auto dateTimeVariant = [](double time) {
130 auto dateTimeVariant = [](double time) {
105 auto dateTime = QDateTime::fromMSecsSinceEpoch(time * 1000.);
131 auto dateTime = QDateTime::fromMSecsSinceEpoch(time * 1000.);
106 return dateTime.toString(DATETIME_FORMAT);
132 return dateTime.toString(DATETIME_FORMAT);
107 };
133 };
108
134
109 switch (index.column()) {
135 switch (index.column()) {
110 case NAME_COLUMN:
136 case NAME_COLUMN:
111 return variable->name();
137 return variable->name();
112 case TSTART_COLUMN:
138 case TSTART_COLUMN:
113 return dateTimeVariant(variable->dateTime().m_TStart);
139 return dateTimeVariant(variable->dateTime().m_TStart);
114 case TEND_COLUMN:
140 case TEND_COLUMN:
115 return dateTimeVariant(variable->dateTime().m_TEnd);
141 return dateTimeVariant(variable->dateTime().m_TEnd);
116 default:
142 default:
117 // No action
143 // No action
118 break;
144 break;
119 }
145 }
120
146
121 qWarning(LOG_VariableModel())
147 qWarning(LOG_VariableModel())
122 << tr("Can't get data (unknown column %1)").arg(index.column());
148 << tr("Can't get data (unknown column %1)").arg(index.column());
123 }
149 }
124 else {
150 else {
125 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
151 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
126 }
152 }
127 }
153 }
128
154
129 return QVariant{};
155 return QVariant{};
130 }
156 }
131
157
132 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
158 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
133 {
159 {
134 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
160 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
135 return QVariant{};
161 return QVariant{};
136 }
162 }
137
163
138 if (orientation == Qt::Horizontal) {
164 if (orientation == Qt::Horizontal) {
139 auto propertiesIt = COLUMN_PROPERTIES.find(section);
165 auto propertiesIt = COLUMN_PROPERTIES.find(section);
140 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
166 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
141 // Role is either DisplayRole or SizeHintRole
167 // Role is either DisplayRole or SizeHintRole
142 return (role == Qt::DisplayRole)
168 return (role == Qt::DisplayRole)
143 ? QVariant{propertiesIt->m_Name}
169 ? QVariant{propertiesIt->m_Name}
144 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
170 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
145 }
171 }
146 else {
172 else {
147 qWarning(LOG_VariableModel())
173 qWarning(LOG_VariableModel())
148 << tr("Can't get header data (unknown column %1)").arg(section);
174 << tr("Can't get header data (unknown column %1)").arg(section);
149 }
175 }
150 }
176 }
151
177
152 return QVariant{};
178 return QVariant{};
153 }
179 }
@@ -1,19 +1,22
1 #ifndef SCIQLOP_IVARIABLECONTAINER_H
1 #ifndef SCIQLOP_IVARIABLECONTAINER_H
2 #define SCIQLOP_IVARIABLECONTAINER_H
2 #define SCIQLOP_IVARIABLECONTAINER_H
3
3
4 class Variable;
4 class Variable;
5
5
6 /**
6 /**
7 * @brief The IVariableContainer interface represents an UI object that can accommodate a variable
7 * @brief The IVariableContainer interface represents an UI object that can accommodate a variable
8 */
8 */
9 class IVariableContainer {
9 class IVariableContainer {
10
10
11 public:
11 public:
12 virtual ~IVariableContainer() = default;
12 virtual ~IVariableContainer() = default;
13
13
14 /// Checks if the container can handle the variable passed in parameter
14 /// Checks if the container can handle the variable passed in parameter
15 virtual bool canDrop(const Variable &variable) const = 0;
15 virtual bool canDrop(const Variable &variable) const = 0;
16
17 /// Checks if the container contains the variable passed in parameter
18 virtual bool contains(const Variable &variable) const = 0;
16 };
19 };
17
20
18
21
19 #endif // SCIQLOP_IVARIABLECONTAINER_H
22 #endif // SCIQLOP_IVARIABLECONTAINER_H
@@ -1,64 +1,65
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QWidget>
7 #include <QWidget>
8
8
9 #include <memory>
9 #include <memory>
10
10
11 #include <Common/spimpl.h>
11 #include <Common/spimpl.h>
12
12
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
14
14
15 class QCPRange;
15 class QCPRange;
16 class SqpDateTime;
16 class SqpDateTime;
17 class Variable;
17 class Variable;
18
18
19 namespace Ui {
19 namespace Ui {
20 class VisualizationGraphWidget;
20 class VisualizationGraphWidget;
21 } // namespace Ui
21 } // namespace Ui
22
22
23 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
23 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
24 Q_OBJECT
24 Q_OBJECT
25
25
26 public:
26 public:
27 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
27 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
28 virtual ~VisualizationGraphWidget();
28 virtual ~VisualizationGraphWidget();
29
29
30 void addVariable(std::shared_ptr<Variable> variable);
30 void addVariable(std::shared_ptr<Variable> variable);
31 void addVariableUsingGraph(std::shared_ptr<Variable> variable);
31 void addVariableUsingGraph(std::shared_ptr<Variable> variable);
32 /// Removes a variable from the graph
32 /// Removes a variable from the graph
33 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
33 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
34
34
35 // IVisualizationWidget interface
35 // IVisualizationWidget interface
36 void accept(IVisualizationWidgetVisitor *visitor) override;
36 void accept(IVisualizationWidgetVisitor *visitor) override;
37 bool canDrop(const Variable &variable) const override;
37 bool canDrop(const Variable &variable) const override;
38 bool contains(const Variable &variable) const override;
38 QString name() const override;
39 QString name() const override;
39
40
40 void updateDisplay(std::shared_ptr<Variable> variable);
41 void updateDisplay(std::shared_ptr<Variable> variable);
41
42
42 signals:
43 signals:
43 void requestDataLoading(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
44 void requestDataLoading(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
44
45
45
46
46 private:
47 private:
47 Ui::VisualizationGraphWidget *ui;
48 Ui::VisualizationGraphWidget *ui;
48
49
49 class VisualizationGraphWidgetPrivate;
50 class VisualizationGraphWidgetPrivate;
50 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
51 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
51
52
52 private slots:
53 private slots:
53 /// Slot called when right clicking on the graph (displays a menu)
54 /// Slot called when right clicking on the graph (displays a menu)
54 void onGraphMenuRequested(const QPoint &pos) noexcept;
55 void onGraphMenuRequested(const QPoint &pos) noexcept;
55
56
56 void onRangeChanged(const QCPRange &t1);
57 void onRangeChanged(const QCPRange &t1);
57
58
58 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
59 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
59 void onMouseWheel(QWheelEvent *event) noexcept;
60 void onMouseWheel(QWheelEvent *event) noexcept;
60
61
61 void onDataCacheVariableUpdated();
62 void onDataCacheVariableUpdated();
62 };
63 };
63
64
64 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
65 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -1,53 +1,54
1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <Common/spimpl.h>
6 #include <Common/spimpl.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QWidget>
9 #include <QWidget>
10
10
11 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
11 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
12
12
13 class Variable;
13 class Variable;
14 class VisualizationZoneWidget;
14 class VisualizationZoneWidget;
15
15
16 namespace Ui {
16 namespace Ui {
17 class VisualizationTabWidget;
17 class VisualizationTabWidget;
18 } // namespace Ui
18 } // namespace Ui
19
19
20 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
20 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
21 Q_OBJECT
21 Q_OBJECT
22
22
23 public:
23 public:
24 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
24 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
25 virtual ~VisualizationTabWidget();
25 virtual ~VisualizationTabWidget();
26
26
27 /// Add a zone widget
27 /// Add a zone widget
28 void addZone(VisualizationZoneWidget *zoneWidget);
28 void addZone(VisualizationZoneWidget *zoneWidget);
29
29
30 /**
30 /**
31 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
31 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
32 * zone.
32 * zone.
33 * @param variable the variable for which to create the zone
33 * @param variable the variable for which to create the zone
34 * @return the pointer to the created zone
34 * @return the pointer to the created zone
35 */
35 */
36 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
36 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
37
37
38 // IVisualizationWidget interface
38 // IVisualizationWidget interface
39 void accept(IVisualizationWidgetVisitor *visitor) override;
39 void accept(IVisualizationWidgetVisitor *visitor) override;
40 bool canDrop(const Variable &variable) const override;
40 bool canDrop(const Variable &variable) const override;
41 bool contains(const Variable &variable) const override;
41 QString name() const override;
42 QString name() const override;
42
43
43 private:
44 private:
44 /// @return the layout of tab in which zones are added
45 /// @return the layout of tab in which zones are added
45 QLayout &tabLayout() const noexcept;
46 QLayout &tabLayout() const noexcept;
46
47
47 Ui::VisualizationTabWidget *ui;
48 Ui::VisualizationTabWidget *ui;
48
49
49 class VisualizationTabWidgetPrivate;
50 class VisualizationTabWidgetPrivate;
50 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
51 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
51 };
52 };
52
53
53 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
54 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
@@ -1,44 +1,48
1 #ifndef SCIQLOP_VISUALIZATIONWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONWIDGET_H
2 #define SCIQLOP_VISUALIZATIONWIDGET_H
2 #define SCIQLOP_VISUALIZATIONWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QWidget>
7 #include <QWidget>
8
8
9 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
9 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
10
10
11 class QMenu;
11 class QMenu;
12 class Variable;
12 class Variable;
13 class VisualizationTabWidget;
13 class VisualizationTabWidget;
14
14
15 namespace Ui {
15 namespace Ui {
16 class VisualizationWidget;
16 class VisualizationWidget;
17 } // namespace Ui
17 } // namespace Ui
18
18
19 class VisualizationWidget : public QWidget, public IVisualizationWidget {
19 class VisualizationWidget : public QWidget, public IVisualizationWidget {
20 Q_OBJECT
20 Q_OBJECT
21
21
22 public:
22 public:
23 explicit VisualizationWidget(QWidget *parent = 0);
23 explicit VisualizationWidget(QWidget *parent = 0);
24 virtual ~VisualizationWidget();
24 virtual ~VisualizationWidget();
25
25
26 // IVisualizationWidget interface
26 // IVisualizationWidget interface
27 void accept(IVisualizationWidgetVisitor *visitor) override;
27 void accept(IVisualizationWidgetVisitor *visitor) override;
28 bool canDrop(const Variable &variable) const override;
28 bool canDrop(const Variable &variable) const override;
29 bool contains(const Variable &variable) const override;
29 QString name() const override;
30 QString name() const override;
30
31
31 public slots:
32 public slots:
32 /**
33 /**
33 * Attaches to a menu the menu relative to the visualization of variables
34 * Attaches to a menu the menu relative to the visualization of variables
34 * @param menu the parent menu of the generated menu
35 * @param menu the parent menu of the generated menu
35 * @param variables the variables for which to generate the menu
36 * @param variables the variables for which to generate the menu
36 */
37 */
37 void attachVariableMenu(QMenu *menu,
38 void attachVariableMenu(QMenu *menu,
38 const QVector<std::shared_ptr<Variable> > &variables) noexcept;
39 const QVector<std::shared_ptr<Variable> > &variables) noexcept;
39
40
41 /// Slot called when a variable is about to be deleted from SciQlop
42 void onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept;
43
40 private:
44 private:
41 Ui::VisualizationWidget *ui;
45 Ui::VisualizationWidget *ui;
42 };
46 };
43
47
44 #endif // VISUALIZATIONWIDGET_H
48 #endif // VISUALIZATIONWIDGET_H
@@ -1,44 +1,45
1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QWidget>
7 #include <QWidget>
8
8
9 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
9 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
10
10
11 namespace Ui {
11 namespace Ui {
12 class VisualizationZoneWidget;
12 class VisualizationZoneWidget;
13 } // Ui
13 } // Ui
14
14
15 class Variable;
15 class Variable;
16 class VisualizationGraphWidget;
16 class VisualizationGraphWidget;
17
17
18 class VisualizationZoneWidget : public QWidget, public IVisualizationWidget {
18 class VisualizationZoneWidget : public QWidget, public IVisualizationWidget {
19 Q_OBJECT
19 Q_OBJECT
20
20
21 public:
21 public:
22 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
22 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
23 virtual ~VisualizationZoneWidget();
23 virtual ~VisualizationZoneWidget();
24
24
25 /// Add a graph widget
25 /// Add a graph widget
26 void addGraph(VisualizationGraphWidget *graphWidget);
26 void addGraph(VisualizationGraphWidget *graphWidget);
27
27
28 /**
28 /**
29 * Creates a graph using a variable. The variable will be displayed in the new graph.
29 * Creates a graph using a variable. The variable will be displayed in the new graph.
30 * @param variable the variable for which to create the graph
30 * @param variable the variable for which to create the graph
31 * @return the pointer to the created graph
31 * @return the pointer to the created graph
32 */
32 */
33 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
33 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
34
34
35 // IVisualizationWidget interface
35 // IVisualizationWidget interface
36 void accept(IVisualizationWidgetVisitor *visitor) override;
36 void accept(IVisualizationWidgetVisitor *visitor) override;
37 bool canDrop(const Variable &variable) const override;
37 bool canDrop(const Variable &variable) const override;
38 bool contains(const Variable &variable) const override;
38 QString name() const override;
39 QString name() const override;
39
40
40 private:
41 private:
41 Ui::VisualizationZoneWidget *ui;
42 Ui::VisualizationZoneWidget *ui;
42 };
43 };
43
44
44 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
45 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -1,59 +1,60
1 #ifndef SCIQLOP_MENUBUILDER_H
1 #ifndef SCIQLOP_MENUBUILDER_H
2 #define SCIQLOP_MENUBUILDER_H
2 #define SCIQLOP_MENUBUILDER_H
3
3
4 #include <QLoggingCategory>
4 #include <QLoggingCategory>
5 #include <QMenu>
5 #include <QMenu>
6 #include <QStack>
6 #include <QStack>
7
7
8 Q_DECLARE_LOGGING_CATEGORY(LOG_MenuBuilder)
8 Q_DECLARE_LOGGING_CATEGORY(LOG_MenuBuilder)
9
9
10 /// Helper assigned to build a hierarchical menu
10 /// Helper assigned to build a hierarchical menu
11 class MenuBuilder {
11 class MenuBuilder {
12 public:
12 public:
13 /**
13 /**
14 * Ctor
14 * Ctor
15 * @param menu the parent menu
15 * @param menu the parent menu
16 */
16 */
17 explicit MenuBuilder(QMenu *menu);
17 explicit MenuBuilder(QMenu *menu);
18
18
19 /**
19 /**
20 * Adds action to the current menu
20 * Adds action to the current menu
21 * @param actionName the name of the action
21 * @param actionName the name of the action
22 * @param actionFunction the function that will be executed when the action is triggered
22 * @param actionFunction the function that will be executed when the action is triggered
23 */
23 */
24 template <typename ActionFun>
24 template <typename ActionFun>
25 void addAction(const QString &actionName, ActionFun actionFunction);
25 void addAction(const QString &actionName, ActionFun actionFunction);
26
26
27 /**
27 /**
28 * Adds a new menu to the current menu
28 * Adds a new menu to the current menu
29 * @param name the name of the menu
29 * @param name the name of the menu
30 * @param icon the icon of the menu (can be null)
30 */
31 */
31 void addMenu(const QString &name);
32 void addMenu(const QString &name, const QIcon &icon = {});
32
33
33 /// Adds a separator to the current menu. The separator is added only if the menu already
34 /// Adds a separator to the current menu. The separator is added only if the menu already
34 /// contains entries
35 /// contains entries
35 void addSeparator();
36 void addSeparator();
36
37
37 /// Closes the current menu
38 /// Closes the current menu
38 void closeMenu();
39 void closeMenu();
39
40
40 private:
41 private:
41 /// @return the current menu (i.e. the top menu of the stack), nullptr if there is no menu
42 /// @return the current menu (i.e. the top menu of the stack), nullptr if there is no menu
42 QMenu *currentMenu() const;
43 QMenu *currentMenu() const;
43
44
44 /// Stack of all menus currently opened
45 /// Stack of all menus currently opened
45 QStack<QMenu *> m_Menus{};
46 QStack<QMenu *> m_Menus{};
46 };
47 };
47
48
48 template <typename ActionFun>
49 template <typename ActionFun>
49 void MenuBuilder::addAction(const QString &actionName, ActionFun actionFunction)
50 void MenuBuilder::addAction(const QString &actionName, ActionFun actionFunction)
50 {
51 {
51 if (auto currMenu = currentMenu()) {
52 if (auto currMenu = currentMenu()) {
52 currMenu->addAction(actionName, actionFunction);
53 currMenu->addAction(actionName, actionFunction);
53 }
54 }
54 else {
55 else {
55 qCCritical(LOG_MenuBuilder()) << QObject::tr("No current menu to attach the action");
56 qCCritical(LOG_MenuBuilder()) << QObject::tr("No current menu to attach the action");
56 }
57 }
57 }
58 }
58
59
59 #endif // SCIQLOP_MENUBUILDER_H
60 #endif // SCIQLOP_MENUBUILDER_H
@@ -1,8 +1,10
1 <RCC>
1 <RCC>
2 <qresource prefix="/">
2 <qresource prefix="/">
3 <file>icones/delete.png</file>
3 <file>icones/delete.png</file>
4 <file>icones/openInspector.png</file>
4 <file>icones/openInspector.png</file>
5 <file>icones/next.png</file>
5 <file>icones/next.png</file>
6 <file>icones/plot.png</file>
6 <file>icones/previous.png</file>
7 <file>icones/previous.png</file>
8 <file>icones/unplot.png</file>
7 </qresource>
9 </qresource>
8 </RCC>
10 </RCC>
@@ -1,118 +1,122
1 #include "SqpApplication.h"
1 #include "SqpApplication.h"
2
2
3 #include <Data/IDataProvider.h>
3 #include <Data/IDataProvider.h>
4 #include <DataSource/DataSourceController.h>
4 #include <DataSource/DataSourceController.h>
5 #include <QThread>
5 #include <QThread>
6 #include <Time/TimeController.h>
6 #include <Time/TimeController.h>
7 #include <Variable/Variable.h>
7 #include <Variable/Variable.h>
8 #include <Variable/VariableController.h>
8 #include <Variable/VariableController.h>
9 #include <Visualization/VisualizationController.h>
9 #include <Visualization/VisualizationController.h>
10
10
11 Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication")
11 Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication")
12
12
13 class SqpApplication::SqpApplicationPrivate {
13 class SqpApplication::SqpApplicationPrivate {
14 public:
14 public:
15 SqpApplicationPrivate()
15 SqpApplicationPrivate()
16 : m_DataSourceController{std::make_unique<DataSourceController>()},
16 : m_DataSourceController{std::make_unique<DataSourceController>()},
17 m_TimeController{std::make_unique<TimeController>()},
17 m_TimeController{std::make_unique<TimeController>()},
18 m_VariableController{std::make_unique<VariableController>()},
18 m_VariableController{std::make_unique<VariableController>()},
19 m_VisualizationController{std::make_unique<VisualizationController>()}
19 m_VisualizationController{std::make_unique<VisualizationController>()}
20 {
20 {
21 // /////////////////////////////// //
21 // /////////////////////////////// //
22 // Connections between controllers //
22 // Connections between controllers //
23 // /////////////////////////////// //
23 // /////////////////////////////// //
24
24
25 // VariableController <-> DataSourceController
25 // VariableController <-> DataSourceController
26 connect(m_DataSourceController.get(),
26 connect(m_DataSourceController.get(),
27 SIGNAL(variableCreationRequested(const QString &, std::shared_ptr<IDataProvider>)),
27 SIGNAL(variableCreationRequested(const QString &, std::shared_ptr<IDataProvider>)),
28 m_VariableController.get(),
28 m_VariableController.get(),
29 SLOT(createVariable(const QString &, std::shared_ptr<IDataProvider>)));
29 SLOT(createVariable(const QString &, std::shared_ptr<IDataProvider>)));
30
30
31 // VariableController <-> VisualizationController
31 // VariableController <-> VisualizationController
32 connect(m_VariableController.get(), SIGNAL(variableCreated(std::shared_ptr<Variable>)),
32 connect(m_VariableController.get(), SIGNAL(variableCreated(std::shared_ptr<Variable>)),
33 m_VisualizationController.get(),
33 m_VisualizationController.get(),
34 SIGNAL(variableCreated(std::shared_ptr<Variable>)));
34 SIGNAL(variableCreated(std::shared_ptr<Variable>)));
35 connect(m_VariableController.get(),
36 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)),
37 m_VisualizationController.get(),
38 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), Qt::DirectConnection);
35
39
36 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
40 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
37 m_VariableController->moveToThread(&m_VariableControllerThread);
41 m_VariableController->moveToThread(&m_VariableControllerThread);
38 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
42 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
39
43
40 // Additionnal init
44 // Additionnal init
41 m_VariableController->setTimeController(m_TimeController.get());
45 m_VariableController->setTimeController(m_TimeController.get());
42 }
46 }
43
47
44 virtual ~SqpApplicationPrivate()
48 virtual ~SqpApplicationPrivate()
45 {
49 {
46 qCInfo(LOG_SqpApplication()) << tr("SqpApplicationPrivate destruction");
50 qCInfo(LOG_SqpApplication()) << tr("SqpApplicationPrivate destruction");
47 m_DataSourceControllerThread.quit();
51 m_DataSourceControllerThread.quit();
48 m_DataSourceControllerThread.wait();
52 m_DataSourceControllerThread.wait();
49
53
50 m_VariableControllerThread.quit();
54 m_VariableControllerThread.quit();
51 m_VariableControllerThread.wait();
55 m_VariableControllerThread.wait();
52
56
53 m_VisualizationControllerThread.quit();
57 m_VisualizationControllerThread.quit();
54 m_VisualizationControllerThread.wait();
58 m_VisualizationControllerThread.wait();
55 }
59 }
56
60
57 std::unique_ptr<DataSourceController> m_DataSourceController;
61 std::unique_ptr<DataSourceController> m_DataSourceController;
58 std::unique_ptr<VariableController> m_VariableController;
62 std::unique_ptr<VariableController> m_VariableController;
59 std::unique_ptr<TimeController> m_TimeController;
63 std::unique_ptr<TimeController> m_TimeController;
60 std::unique_ptr<VisualizationController> m_VisualizationController;
64 std::unique_ptr<VisualizationController> m_VisualizationController;
61 QThread m_DataSourceControllerThread;
65 QThread m_DataSourceControllerThread;
62 QThread m_VariableControllerThread;
66 QThread m_VariableControllerThread;
63 QThread m_VisualizationControllerThread;
67 QThread m_VisualizationControllerThread;
64 };
68 };
65
69
66
70
67 SqpApplication::SqpApplication(int &argc, char **argv)
71 SqpApplication::SqpApplication(int &argc, char **argv)
68 : QApplication{argc, argv}, impl{spimpl::make_unique_impl<SqpApplicationPrivate>()}
72 : QApplication{argc, argv}, impl{spimpl::make_unique_impl<SqpApplicationPrivate>()}
69 {
73 {
70 qCInfo(LOG_SqpApplication()) << tr("SqpApplication construction");
74 qCInfo(LOG_SqpApplication()) << tr("SqpApplication construction");
71
75
72 connect(&impl->m_DataSourceControllerThread, &QThread::started,
76 connect(&impl->m_DataSourceControllerThread, &QThread::started,
73 impl->m_DataSourceController.get(), &DataSourceController::initialize);
77 impl->m_DataSourceController.get(), &DataSourceController::initialize);
74 connect(&impl->m_DataSourceControllerThread, &QThread::finished,
78 connect(&impl->m_DataSourceControllerThread, &QThread::finished,
75 impl->m_DataSourceController.get(), &DataSourceController::finalize);
79 impl->m_DataSourceController.get(), &DataSourceController::finalize);
76
80
77 connect(&impl->m_VariableControllerThread, &QThread::started, impl->m_VariableController.get(),
81 connect(&impl->m_VariableControllerThread, &QThread::started, impl->m_VariableController.get(),
78 &VariableController::initialize);
82 &VariableController::initialize);
79 connect(&impl->m_VariableControllerThread, &QThread::finished, impl->m_VariableController.get(),
83 connect(&impl->m_VariableControllerThread, &QThread::finished, impl->m_VariableController.get(),
80 &VariableController::finalize);
84 &VariableController::finalize);
81
85
82 connect(&impl->m_VisualizationControllerThread, &QThread::started,
86 connect(&impl->m_VisualizationControllerThread, &QThread::started,
83 impl->m_VisualizationController.get(), &VisualizationController::initialize);
87 impl->m_VisualizationController.get(), &VisualizationController::initialize);
84 connect(&impl->m_VisualizationControllerThread, &QThread::finished,
88 connect(&impl->m_VisualizationControllerThread, &QThread::finished,
85 impl->m_VisualizationController.get(), &VisualizationController::finalize);
89 impl->m_VisualizationController.get(), &VisualizationController::finalize);
86
90
87 impl->m_DataSourceControllerThread.start();
91 impl->m_DataSourceControllerThread.start();
88 impl->m_VariableControllerThread.start();
92 impl->m_VariableControllerThread.start();
89 impl->m_VisualizationControllerThread.start();
93 impl->m_VisualizationControllerThread.start();
90 }
94 }
91
95
92 SqpApplication::~SqpApplication()
96 SqpApplication::~SqpApplication()
93 {
97 {
94 }
98 }
95
99
96 void SqpApplication::initialize()
100 void SqpApplication::initialize()
97 {
101 {
98 }
102 }
99
103
100 DataSourceController &SqpApplication::dataSourceController() noexcept
104 DataSourceController &SqpApplication::dataSourceController() noexcept
101 {
105 {
102 return *impl->m_DataSourceController;
106 return *impl->m_DataSourceController;
103 }
107 }
104
108
105 TimeController &SqpApplication::timeController() noexcept
109 TimeController &SqpApplication::timeController() noexcept
106 {
110 {
107 return *impl->m_TimeController;
111 return *impl->m_TimeController;
108 }
112 }
109
113
110 VariableController &SqpApplication::variableController() noexcept
114 VariableController &SqpApplication::variableController() noexcept
111 {
115 {
112 return *impl->m_VariableController;
116 return *impl->m_VariableController;
113 }
117 }
114
118
115 VisualizationController &SqpApplication::visualizationController() noexcept
119 VisualizationController &SqpApplication::visualizationController() noexcept
116 {
120 {
117 return *impl->m_VisualizationController;
121 return *impl->m_VisualizationController;
118 }
122 }
@@ -1,89 +1,89
1 #include <Variable/VariableController.h>
1 #include <Variable/VariableController.h>
2 #include <Variable/VariableInspectorWidget.h>
2 #include <Variable/VariableInspectorWidget.h>
3 #include <Variable/VariableMenuHeaderWidget.h>
3 #include <Variable/VariableMenuHeaderWidget.h>
4 #include <Variable/VariableModel.h>
4 #include <Variable/VariableModel.h>
5
5
6 #include <ui_VariableInspectorWidget.h>
6 #include <ui_VariableInspectorWidget.h>
7
7
8 #include <QSortFilterProxyModel>
8 #include <QSortFilterProxyModel>
9 #include <QWidgetAction>
9 #include <QWidgetAction>
10
10
11 #include <SqpApplication.h>
11 #include <SqpApplication.h>
12
12
13 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
13 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
14
14
15 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
15 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
16 : QWidget{parent}, ui{new Ui::VariableInspectorWidget}
16 : QWidget{parent}, ui{new Ui::VariableInspectorWidget}
17 {
17 {
18 ui->setupUi(this);
18 ui->setupUi(this);
19
19
20 // Sets model for table
20 // Sets model for table
21 // auto sortFilterModel = new QSortFilterProxyModel{this};
21 // auto sortFilterModel = new QSortFilterProxyModel{this};
22 // sortFilterModel->setSourceModel(sqpApp->variableController().variableModel());
22 // sortFilterModel->setSourceModel(sqpApp->variableController().variableModel());
23
23
24 ui->tableView->setModel(sqpApp->variableController().variableModel());
24 ui->tableView->setModel(sqpApp->variableController().variableModel());
25 ui->tableView->setSelectionModel(sqpApp->variableController().variableSelectionModel());
25 ui->tableView->setSelectionModel(sqpApp->variableController().variableSelectionModel());
26
26
27 // Fixes column sizes
27 // Fixes column sizes
28 auto model = ui->tableView->model();
28 auto model = ui->tableView->model();
29 const auto count = model->columnCount();
29 const auto count = model->columnCount();
30 for (auto i = 0; i < count; ++i) {
30 for (auto i = 0; i < count; ++i) {
31 ui->tableView->setColumnWidth(
31 ui->tableView->setColumnWidth(
32 i, model->headerData(i, Qt::Horizontal, Qt::SizeHintRole).toSize().width());
32 i, model->headerData(i, Qt::Horizontal, Qt::SizeHintRole).toSize().width());
33 }
33 }
34
34
35 // Sets selection options
35 // Sets selection options
36 ui->tableView->setSelectionBehavior(QTableView::SelectRows);
36 ui->tableView->setSelectionBehavior(QTableView::SelectRows);
37 ui->tableView->setSelectionMode(QTableView::ExtendedSelection);
37 ui->tableView->setSelectionMode(QTableView::ExtendedSelection);
38
38
39 // Connection to show a menu when right clicking on the tree
39 // Connection to show a menu when right clicking on the tree
40 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
40 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
41 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
41 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
42 &VariableInspectorWidget::onTableMenuRequested);
42 &VariableInspectorWidget::onTableMenuRequested);
43 }
43 }
44
44
45 VariableInspectorWidget::~VariableInspectorWidget()
45 VariableInspectorWidget::~VariableInspectorWidget()
46 {
46 {
47 delete ui;
47 delete ui;
48 }
48 }
49
49
50 void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept
50 void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept
51 {
51 {
52 auto selectedRows = ui->tableView->selectionModel()->selectedRows();
52 auto selectedRows = ui->tableView->selectionModel()->selectedRows();
53
53
54 // Gets the model to retrieve the underlying selected variables
54 // Gets the model to retrieve the underlying selected variables
55 auto model = sqpApp->variableController().variableModel();
55 auto model = sqpApp->variableController().variableModel();
56 auto selectedVariables = QVector<std::shared_ptr<Variable> >{};
56 auto selectedVariables = QVector<std::shared_ptr<Variable> >{};
57 for (const auto &selectedRow : qAsConst(selectedRows)) {
57 for (const auto &selectedRow : qAsConst(selectedRows)) {
58 if (auto selectedVariable = model->variable(selectedRow.row())) {
58 if (auto selectedVariable = model->variable(selectedRow.row())) {
59 selectedVariables.push_back(selectedVariable);
59 selectedVariables.push_back(selectedVariable);
60 }
60 }
61 }
61 }
62
62
63 QMenu tableMenu{};
63 QMenu tableMenu{};
64
64
65 // Emits a signal so that potential receivers can populate the menu before displaying it
65 // Emits a signal so that potential receivers can populate the menu before displaying it
66 emit tableMenuAboutToBeDisplayed(&tableMenu, selectedVariables);
66 emit tableMenuAboutToBeDisplayed(&tableMenu, selectedVariables);
67
67
68 // Adds menu-specific actions
68 // Adds menu-specific actions
69 if (!selectedVariables.isEmpty()) {
69 if (!selectedVariables.isEmpty()) {
70 // 'Delete' action
70 // 'Delete' action
71 auto deleteFun = []() {
71 auto deleteFun = [&selectedVariables]() {
72 /// @todo ALX : call variable deletion
72 sqpApp->variableController().deleteVariables(selectedVariables);
73 };
73 };
74
74
75 tableMenu.addSeparator();
75 tableMenu.addSeparator();
76 tableMenu.addAction(QIcon{":/icones/delete.png"}, tr("Delete"), deleteFun);
76 tableMenu.addAction(QIcon{":/icones/delete.png"}, tr("Delete"), deleteFun);
77 }
77 }
78
78
79 if (!tableMenu.isEmpty()) {
79 if (!tableMenu.isEmpty()) {
80 // Generates menu header (inserted before first action)
80 // Generates menu header (inserted before first action)
81 auto firstAction = tableMenu.actions().first();
81 auto firstAction = tableMenu.actions().first();
82 auto headerAction = new QWidgetAction{&tableMenu};
82 auto headerAction = new QWidgetAction{&tableMenu};
83 headerAction->setDefaultWidget(new VariableMenuHeaderWidget{selectedVariables, &tableMenu});
83 headerAction->setDefaultWidget(new VariableMenuHeaderWidget{selectedVariables, &tableMenu});
84 tableMenu.insertAction(firstAction, headerAction);
84 tableMenu.insertAction(firstAction, headerAction);
85
85
86 // Displays menu
86 // Displays menu
87 tableMenu.exec(mapToGlobal(pos));
87 tableMenu.exec(mapToGlobal(pos));
88 }
88 }
89 }
89 }
@@ -1,273 +1,285
1 #include "Visualization/VisualizationGraphWidget.h"
1 #include "Visualization/VisualizationGraphWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationGraphHelper.h"
3 #include "Visualization/VisualizationGraphHelper.h"
4 #include "ui_VisualizationGraphWidget.h"
4 #include "ui_VisualizationGraphWidget.h"
5
5
6 #include <Data/ArrayData.h>
6 #include <Data/ArrayData.h>
7 #include <Data/IDataSeries.h>
7 #include <Data/IDataSeries.h>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10 #include <Variable/VariableController.h>
10 #include <Variable/VariableController.h>
11
11
12 #include <unordered_map>
12 #include <unordered_map>
13
13
14 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
14 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
15
15
16 namespace {
16 namespace {
17
17
18 /// Key pressed to enable zoom on horizontal axis
18 /// Key pressed to enable zoom on horizontal axis
19 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
19 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
20
20
21 /// Key pressed to enable zoom on vertical axis
21 /// Key pressed to enable zoom on vertical axis
22 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
22 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
23
23
24 } // namespace
24 } // namespace
25
25
26 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
26 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
27
27
28 // 1 variable -> n qcpplot
28 // 1 variable -> n qcpplot
29 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
29 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
30 };
30 };
31
31
32 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
32 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
33 : QWidget{parent},
33 : QWidget{parent},
34 ui{new Ui::VisualizationGraphWidget},
34 ui{new Ui::VisualizationGraphWidget},
35 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()}
35 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()}
36 {
36 {
37 ui->setupUi(this);
37 ui->setupUi(this);
38
38
39 ui->graphNameLabel->setText(name);
39 ui->graphNameLabel->setText(name);
40
40
41 // 'Close' options : widget is deleted when closed
41 // 'Close' options : widget is deleted when closed
42 setAttribute(Qt::WA_DeleteOnClose);
42 setAttribute(Qt::WA_DeleteOnClose);
43 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationGraphWidget::close);
43 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationGraphWidget::close);
44 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
44 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
45
45
46 // Set qcpplot properties :
46 // Set qcpplot properties :
47 // - Drag (on x-axis) and zoom are enabled
47 // - Drag (on x-axis) and zoom are enabled
48 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
48 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
49 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
49 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
50 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
50 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
51 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
51 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
52 connect(ui->widget->xAxis,
52 connect(ui->widget->xAxis,
53 static_cast<void (QCPAxis::*)(const QCPRange &)>(&QCPAxis::rangeChanged), this,
53 static_cast<void (QCPAxis::*)(const QCPRange &)>(&QCPAxis::rangeChanged), this,
54 &VisualizationGraphWidget::onRangeChanged);
54 &VisualizationGraphWidget::onRangeChanged);
55
55
56 // Activates menu when right clicking on the graph
56 // Activates menu when right clicking on the graph
57 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
57 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
58 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
58 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
59 &VisualizationGraphWidget::onGraphMenuRequested);
59 &VisualizationGraphWidget::onGraphMenuRequested);
60
60
61 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
61 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
62 &VariableController::onRequestDataLoading);
62 &VariableController::onRequestDataLoading);
63 }
63 }
64
64
65
65
66 VisualizationGraphWidget::~VisualizationGraphWidget()
66 VisualizationGraphWidget::~VisualizationGraphWidget()
67 {
67 {
68 delete ui;
68 delete ui;
69 }
69 }
70
70
71 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
71 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
72 {
72 {
73 // Uses delegate to create the qcpplot components according to the variable
73 // Uses delegate to create the qcpplot components according to the variable
74 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
74 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
75
75
76 for (auto createdPlottable : qAsConst(createdPlottables)) {
76 for (auto createdPlottable : qAsConst(createdPlottables)) {
77 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
77 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
78 }
78 }
79
79
80 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
80 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
81 }
81 }
82
82
83 void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr<Variable> variable)
83 void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr<Variable> variable)
84 {
84 {
85
85
86 // when adding a variable, we need to set its time range to the current graph range
86 // when adding a variable, we need to set its time range to the current graph range
87 auto grapheRange = ui->widget->xAxis->range();
87 auto grapheRange = ui->widget->xAxis->range();
88 auto dateTime = SqpDateTime{grapheRange.lower, grapheRange.upper};
88 auto dateTime = SqpDateTime{grapheRange.lower, grapheRange.upper};
89 variable->setDateTime(dateTime);
89 variable->setDateTime(dateTime);
90
90
91 auto variableDateTimeWithTolerance = dateTime;
91 auto variableDateTimeWithTolerance = dateTime;
92
92
93 // add 10% tolerance for each side
93 // add 10% tolerance for each side
94 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
94 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
95 variableDateTimeWithTolerance.m_TStart -= tolerance;
95 variableDateTimeWithTolerance.m_TStart -= tolerance;
96 variableDateTimeWithTolerance.m_TEnd += tolerance;
96 variableDateTimeWithTolerance.m_TEnd += tolerance;
97
97
98 // Uses delegate to create the qcpplot components according to the variable
98 // Uses delegate to create the qcpplot components according to the variable
99 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
99 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
100
100
101 for (auto createdPlottable : qAsConst(createdPlottables)) {
101 for (auto createdPlottable : qAsConst(createdPlottables)) {
102 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
102 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
103 }
103 }
104
104
105 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
105 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
106
106
107 // CHangement detected, we need to ask controller to request data loading
107 // CHangement detected, we need to ask controller to request data loading
108 emit requestDataLoading(variable, variableDateTimeWithTolerance);
108 emit requestDataLoading(variable, variableDateTimeWithTolerance);
109 }
109 }
110
110
111 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
111 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
112 {
112 {
113 // Each component associated to the variable :
113 // Each component associated to the variable :
114 // - is removed from qcpplot (which deletes it)
114 // - is removed from qcpplot (which deletes it)
115 // - is no longer referenced in the map
115 // - is no longer referenced in the map
116 auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
116 auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
117 for (auto it = componentsIt.first; it != componentsIt.second;) {
117 for (auto it = componentsIt.first; it != componentsIt.second;) {
118 ui->widget->removePlottable(it->second);
118 ui->widget->removePlottable(it->second);
119 it = impl->m_VariableToPlotMultiMap.erase(it);
119 it = impl->m_VariableToPlotMultiMap.erase(it);
120 }
120 }
121
121
122 // Updates graph
122 // Updates graph
123 ui->widget->replot();
123 ui->widget->replot();
124 }
124 }
125
125
126 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
126 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
127 {
127 {
128 if (visitor) {
128 if (visitor) {
129 visitor->visit(this);
129 visitor->visit(this);
130 }
130 }
131 else {
131 else {
132 qCCritical(LOG_VisualizationGraphWidget())
132 qCCritical(LOG_VisualizationGraphWidget())
133 << tr("Can't visit widget : the visitor is null");
133 << tr("Can't visit widget : the visitor is null");
134 }
134 }
135 }
135 }
136
136
137 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
137 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
138 {
138 {
139 /// @todo : for the moment, a graph can always accomodate a variable
139 /// @todo : for the moment, a graph can always accomodate a variable
140 Q_UNUSED(variable);
140 Q_UNUSED(variable);
141 return true;
141 return true;
142 }
142 }
143
143
144 bool VisualizationGraphWidget::contains(const Variable &variable) const
145 {
146 // Finds the variable among the keys of the map
147 auto variablePtr = &variable;
148 auto findVariable
149 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
150
151 auto end = impl->m_VariableToPlotMultiMap.cend();
152 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
153 return it != end;
154 }
155
144 QString VisualizationGraphWidget::name() const
156 QString VisualizationGraphWidget::name() const
145 {
157 {
146 return ui->graphNameLabel->text();
158 return ui->graphNameLabel->text();
147 }
159 }
148
160
149 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
161 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
150 {
162 {
151 QMenu graphMenu{};
163 QMenu graphMenu{};
152
164
153 // Iterates on variables (unique keys)
165 // Iterates on variables (unique keys)
154 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
166 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
155 end = impl->m_VariableToPlotMultiMap.cend();
167 end = impl->m_VariableToPlotMultiMap.cend();
156 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
168 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
157 // 'Remove variable' action
169 // 'Remove variable' action
158 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
170 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
159 [ this, var = it->first ]() { removeVariable(var); });
171 [ this, var = it->first ]() { removeVariable(var); });
160 }
172 }
161
173
162 if (!graphMenu.isEmpty()) {
174 if (!graphMenu.isEmpty()) {
163 graphMenu.exec(mapToGlobal(pos));
175 graphMenu.exec(mapToGlobal(pos));
164 }
176 }
165 }
177 }
166
178
167 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1)
179 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1)
168 {
180 {
169 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged");
181 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged");
170
182
171 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
183 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
172 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
184 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
173
185
174 auto variable = it->first;
186 auto variable = it->first;
175 auto dateTime = SqpDateTime{t1.lower, t1.upper};
187 auto dateTime = SqpDateTime{t1.lower, t1.upper};
176
188
177 if (!variable->contains(dateTime)) {
189 if (!variable->contains(dateTime)) {
178
190
179 auto variableDateTimeWithTolerance = dateTime;
191 auto variableDateTimeWithTolerance = dateTime;
180 if (!variable->isInside(dateTime)) {
192 if (!variable->isInside(dateTime)) {
181 auto variableDateTime = variable->dateTime();
193 auto variableDateTime = variable->dateTime();
182 if (variableDateTime.m_TStart < dateTime.m_TStart) {
194 if (variableDateTime.m_TStart < dateTime.m_TStart) {
183 qCDebug(LOG_VisualizationGraphWidget()) << tr("TDetection pan to right:");
195 qCDebug(LOG_VisualizationGraphWidget()) << tr("TDetection pan to right:");
184
196
185 auto diffEndToKeepDelta = dateTime.m_TEnd - variableDateTime.m_TEnd;
197 auto diffEndToKeepDelta = dateTime.m_TEnd - variableDateTime.m_TEnd;
186 dateTime.m_TStart = variableDateTime.m_TStart + diffEndToKeepDelta;
198 dateTime.m_TStart = variableDateTime.m_TStart + diffEndToKeepDelta;
187 // Tolerance have to be added to the right
199 // Tolerance have to be added to the right
188 // add 10% tolerance for right (end) side
200 // add 10% tolerance for right (end) side
189 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
201 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
190 variableDateTimeWithTolerance.m_TEnd += tolerance;
202 variableDateTimeWithTolerance.m_TEnd += tolerance;
191 }
203 }
192 else if (variableDateTime.m_TEnd > dateTime.m_TEnd) {
204 else if (variableDateTime.m_TEnd > dateTime.m_TEnd) {
193 qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection pan to left: ");
205 qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection pan to left: ");
194 auto diffStartToKeepDelta = variableDateTime.m_TStart - dateTime.m_TStart;
206 auto diffStartToKeepDelta = variableDateTime.m_TStart - dateTime.m_TStart;
195 dateTime.m_TEnd = variableDateTime.m_TEnd - diffStartToKeepDelta;
207 dateTime.m_TEnd = variableDateTime.m_TEnd - diffStartToKeepDelta;
196 // Tolerance have to be added to the left
208 // Tolerance have to be added to the left
197 // add 10% tolerance for left (start) side
209 // add 10% tolerance for left (start) side
198 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
210 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
199 variableDateTimeWithTolerance.m_TStart -= tolerance;
211 variableDateTimeWithTolerance.m_TStart -= tolerance;
200 }
212 }
201 else {
213 else {
202 qCWarning(LOG_VisualizationGraphWidget())
214 qCWarning(LOG_VisualizationGraphWidget())
203 << tr("Detection anormal zoom detection: ");
215 << tr("Detection anormal zoom detection: ");
204 }
216 }
205 }
217 }
206 else {
218 else {
207 qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection zoom out: ");
219 qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection zoom out: ");
208 // add 10% tolerance for each side
220 // add 10% tolerance for each side
209 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
221 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
210 variableDateTimeWithTolerance.m_TStart -= tolerance;
222 variableDateTimeWithTolerance.m_TStart -= tolerance;
211 variableDateTimeWithTolerance.m_TEnd += tolerance;
223 variableDateTimeWithTolerance.m_TEnd += tolerance;
212 }
224 }
213 variable->setDateTime(dateTime);
225 variable->setDateTime(dateTime);
214
226
215 // CHangement detected, we need to ask controller to request data loading
227 // CHangement detected, we need to ask controller to request data loading
216 emit requestDataLoading(variable, variableDateTimeWithTolerance);
228 emit requestDataLoading(variable, variableDateTimeWithTolerance);
217 }
229 }
218 else {
230 else {
219 qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection zoom in: ");
231 qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection zoom in: ");
220 }
232 }
221 }
233 }
222 }
234 }
223
235
224 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
236 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
225 {
237 {
226 auto zoomOrientations = QFlags<Qt::Orientation>{};
238 auto zoomOrientations = QFlags<Qt::Orientation>{};
227
239
228 // Lambda that enables a zoom orientation if the key modifier related to this orientation
240 // Lambda that enables a zoom orientation if the key modifier related to this orientation
229 // has
241 // has
230 // been pressed
242 // been pressed
231 auto enableOrientation
243 auto enableOrientation
232 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
244 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
233 auto orientationEnabled = event->modifiers().testFlag(modifier);
245 auto orientationEnabled = event->modifiers().testFlag(modifier);
234 zoomOrientations.setFlag(orientation, orientationEnabled);
246 zoomOrientations.setFlag(orientation, orientationEnabled);
235 };
247 };
236 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
248 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
237 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
249 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
238
250
239 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
251 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
240 }
252 }
241
253
242 void VisualizationGraphWidget::onDataCacheVariableUpdated()
254 void VisualizationGraphWidget::onDataCacheVariableUpdated()
243 {
255 {
244 // NOTE:
256 // NOTE:
245 // We don't want to call the method for each component of a variable unitarily, but for
257 // We don't want to call the method for each component of a variable unitarily, but for
246 // all
258 // all
247 // its components at once (eg its three components in the case of a vector).
259 // its components at once (eg its three components in the case of a vector).
248
260
249 // The unordered_multimap does not do this easily, so the question is whether to:
261 // The unordered_multimap does not do this easily, so the question is whether to:
250 // - use an ordered_multimap and the algos of std to group the values by key
262 // - use an ordered_multimap and the algos of std to group the values by key
251 // - use a map (unique keys) and store as values directly the list of components
263 // - use a map (unique keys) and store as values directly the list of components
252
264
253 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
265 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
254 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
266 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
255 auto variable = it->first;
267 auto variable = it->first;
256 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
268 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
257 variable->dataSeries(), variable->dateTime());
269 variable->dataSeries(), variable->dateTime());
258 }
270 }
259 }
271 }
260
272
261 void VisualizationGraphWidget::updateDisplay(std::shared_ptr<Variable> variable)
273 void VisualizationGraphWidget::updateDisplay(std::shared_ptr<Variable> variable)
262 {
274 {
263 auto abstractPlotableItPair = impl->m_VariableToPlotMultiMap.equal_range(variable);
275 auto abstractPlotableItPair = impl->m_VariableToPlotMultiMap.equal_range(variable);
264
276
265 auto abstractPlotableVect = QVector<QCPAbstractPlottable *>{};
277 auto abstractPlotableVect = QVector<QCPAbstractPlottable *>{};
266
278
267 for (auto it = abstractPlotableItPair.first; it != abstractPlotableItPair.second; ++it) {
279 for (auto it = abstractPlotableItPair.first; it != abstractPlotableItPair.second; ++it) {
268 abstractPlotableVect.push_back(it->second);
280 abstractPlotableVect.push_back(it->second);
269 }
281 }
270
282
271 VisualizationGraphHelper::updateData(abstractPlotableVect, variable->dataSeries(),
283 VisualizationGraphHelper::updateData(abstractPlotableVect, variable->dataSeries(),
272 variable->dateTime());
284 variable->dateTime());
273 }
285 }
@@ -1,104 +1,110
1 #include "Visualization/VisualizationTabWidget.h"
1 #include "Visualization/VisualizationTabWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "ui_VisualizationTabWidget.h"
3 #include "ui_VisualizationTabWidget.h"
4
4
5 #include "Visualization/VisualizationZoneWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
6
6
7 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
7 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
8
8
9 namespace {
9 namespace {
10
10
11 /// Generates a default name for a new zone, according to the number of zones already displayed in
11 /// Generates a default name for a new zone, according to the number of zones already displayed in
12 /// the tab
12 /// the tab
13 QString defaultZoneName(const QLayout &layout)
13 QString defaultZoneName(const QLayout &layout)
14 {
14 {
15 auto count = 0;
15 auto count = 0;
16 for (auto i = 0; i < layout.count(); ++i) {
16 for (auto i = 0; i < layout.count(); ++i) {
17 if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) {
17 if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) {
18 count++;
18 count++;
19 }
19 }
20 }
20 }
21
21
22 return QObject::tr("Zone %1").arg(count + 1);
22 return QObject::tr("Zone %1").arg(count + 1);
23 }
23 }
24
24
25 } // namespace
25 } // namespace
26
26
27 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
27 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
28 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
28 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
29
29
30 QString m_Name;
30 QString m_Name;
31 };
31 };
32
32
33 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
33 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
34 : QWidget{parent},
34 : QWidget{parent},
35 ui{new Ui::VisualizationTabWidget},
35 ui{new Ui::VisualizationTabWidget},
36 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
36 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
37 {
37 {
38 ui->setupUi(this);
38 ui->setupUi(this);
39
39
40 // Widget is deleted when closed
40 // Widget is deleted when closed
41 setAttribute(Qt::WA_DeleteOnClose);
41 setAttribute(Qt::WA_DeleteOnClose);
42 }
42 }
43
43
44 VisualizationTabWidget::~VisualizationTabWidget()
44 VisualizationTabWidget::~VisualizationTabWidget()
45 {
45 {
46 delete ui;
46 delete ui;
47 }
47 }
48
48
49 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
49 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
50 {
50 {
51 tabLayout().addWidget(zoneWidget);
51 tabLayout().addWidget(zoneWidget);
52 }
52 }
53
53
54 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
54 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
55 {
55 {
56 auto zoneWidget = new VisualizationZoneWidget{defaultZoneName(tabLayout()), this};
56 auto zoneWidget = new VisualizationZoneWidget{defaultZoneName(tabLayout()), this};
57 this->addZone(zoneWidget);
57 this->addZone(zoneWidget);
58
58
59 // Creates a new graph into the zone
59 // Creates a new graph into the zone
60 zoneWidget->createGraph(variable);
60 zoneWidget->createGraph(variable);
61
61
62 return zoneWidget;
62 return zoneWidget;
63 }
63 }
64
64
65 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
65 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
66 {
66 {
67 if (visitor) {
67 if (visitor) {
68 visitor->visitEnter(this);
68 visitor->visitEnter(this);
69
69
70 // Apply visitor to zone children
70 // Apply visitor to zone children
71 auto &layout = tabLayout();
71 auto &layout = tabLayout();
72 for (auto i = 0; i < layout.count(); ++i) {
72 for (auto i = 0; i < layout.count(); ++i) {
73 if (auto item = layout.itemAt(i)) {
73 if (auto item = layout.itemAt(i)) {
74 // Widgets different from zones are not visited (no action)
74 // Widgets different from zones are not visited (no action)
75 if (auto visualizationZoneWidget
75 if (auto visualizationZoneWidget
76 = dynamic_cast<VisualizationZoneWidget *>(item->widget())) {
76 = dynamic_cast<VisualizationZoneWidget *>(item->widget())) {
77 visualizationZoneWidget->accept(visitor);
77 visualizationZoneWidget->accept(visitor);
78 }
78 }
79 }
79 }
80 }
80 }
81
81
82 visitor->visitLeave(this);
82 visitor->visitLeave(this);
83 }
83 }
84 else {
84 else {
85 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
85 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
86 }
86 }
87 }
87 }
88
88
89 bool VisualizationTabWidget::canDrop(const Variable &variable) const
89 bool VisualizationTabWidget::canDrop(const Variable &variable) const
90 {
90 {
91 // A tab can always accomodate a variable
91 // A tab can always accomodate a variable
92 Q_UNUSED(variable);
92 Q_UNUSED(variable);
93 return true;
93 return true;
94 }
94 }
95
95
96 bool VisualizationTabWidget::contains(const Variable &variable) const
97 {
98 Q_UNUSED(variable);
99 return false;
100 }
101
96 QString VisualizationTabWidget::name() const
102 QString VisualizationTabWidget::name() const
97 {
103 {
98 return impl->m_Name;
104 return impl->m_Name;
99 }
105 }
100
106
101 QLayout &VisualizationTabWidget::tabLayout() const noexcept
107 QLayout &VisualizationTabWidget::tabLayout() const noexcept
102 {
108 {
103 return *ui->scrollAreaWidgetContents->layout();
109 return *ui->scrollAreaWidgetContents->layout();
104 }
110 }
@@ -1,129 +1,143
1 #include "Visualization/VisualizationWidget.h"
1 #include "Visualization/VisualizationWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationGraphWidget.h"
3 #include "Visualization/VisualizationGraphWidget.h"
4 #include "Visualization/VisualizationTabWidget.h"
4 #include "Visualization/VisualizationTabWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/operations/GenerateVariableMenuOperation.h"
6 #include "Visualization/operations/GenerateVariableMenuOperation.h"
7 #include "Visualization/operations/RemoveVariableOperation.h"
7 #include "Visualization/qcustomplot.h"
8 #include "Visualization/qcustomplot.h"
8
9
9 #include "ui_VisualizationWidget.h"
10 #include "ui_VisualizationWidget.h"
10
11
11 #include <QToolButton>
12 #include <QToolButton>
12
13
13 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
14 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
14
15
15 VisualizationWidget::VisualizationWidget(QWidget *parent)
16 VisualizationWidget::VisualizationWidget(QWidget *parent)
16 : QWidget{parent}, ui{new Ui::VisualizationWidget}
17 : QWidget{parent}, ui{new Ui::VisualizationWidget}
17 {
18 {
18 ui->setupUi(this);
19 ui->setupUi(this);
19
20
20 auto addTabViewButton = new QToolButton{ui->tabWidget};
21 auto addTabViewButton = new QToolButton{ui->tabWidget};
21 addTabViewButton->setText(tr("Add View"));
22 addTabViewButton->setText(tr("Add View"));
22 addTabViewButton->setCursor(Qt::ArrowCursor);
23 addTabViewButton->setCursor(Qt::ArrowCursor);
23 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
24 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
24
25
25 auto enableMinimumCornerWidgetSize = [this](bool enable) {
26 auto enableMinimumCornerWidgetSize = [this](bool enable) {
26
27
27 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
28 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
28 auto width = enable ? tabViewCornerWidget->width() : 0;
29 auto width = enable ? tabViewCornerWidget->width() : 0;
29 auto height = enable ? tabViewCornerWidget->height() : 0;
30 auto height = enable ? tabViewCornerWidget->height() : 0;
30 tabViewCornerWidget->setMinimumHeight(height);
31 tabViewCornerWidget->setMinimumHeight(height);
31 tabViewCornerWidget->setMinimumWidth(width);
32 tabViewCornerWidget->setMinimumWidth(width);
32 ui->tabWidget->setMinimumHeight(height);
33 ui->tabWidget->setMinimumHeight(height);
33 ui->tabWidget->setMinimumWidth(width);
34 ui->tabWidget->setMinimumWidth(width);
34 };
35 };
35
36
36 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
37 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
37 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
38 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
38 ui->tabWidget};
39 ui->tabWidget};
39 auto index = ui->tabWidget->addTab(widget, widget->name());
40 auto index = ui->tabWidget->addTab(widget, widget->name());
40 if (ui->tabWidget->count() > 0) {
41 if (ui->tabWidget->count() > 0) {
41 enableMinimumCornerWidgetSize(false);
42 enableMinimumCornerWidgetSize(false);
42 }
43 }
43 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
44 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
44 };
45 };
45
46
46 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
47 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
47 if (ui->tabWidget->count() == 1) {
48 if (ui->tabWidget->count() == 1) {
48 enableMinimumCornerWidgetSize(true);
49 enableMinimumCornerWidgetSize(true);
49 }
50 }
50
51
51 // Removes widget from tab and closes it
52 // Removes widget from tab and closes it
52 auto widget = ui->tabWidget->widget(index);
53 auto widget = ui->tabWidget->widget(index);
53 ui->tabWidget->removeTab(index);
54 ui->tabWidget->removeTab(index);
54 if (widget) {
55 if (widget) {
55 widget->close();
56 widget->close();
56 }
57 }
57
58
58 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
59 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
59
60
60 };
61 };
61
62
62 ui->tabWidget->setTabsClosable(true);
63 ui->tabWidget->setTabsClosable(true);
63
64
64 connect(addTabViewButton, &QToolButton::clicked, addTabView);
65 connect(addTabViewButton, &QToolButton::clicked, addTabView);
65 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
66 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
66
67
67 // Adds default tab
68 // Adds default tab
68 addTabView();
69 addTabView();
69 }
70 }
70
71
71 VisualizationWidget::~VisualizationWidget()
72 VisualizationWidget::~VisualizationWidget()
72 {
73 {
73 delete ui;
74 delete ui;
74 }
75 }
75
76
76 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
77 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
77 {
78 {
78 if (visitor) {
79 if (visitor) {
79 visitor->visitEnter(this);
80 visitor->visitEnter(this);
80
81
81 // Apply visitor for tab children
82 // Apply visitor for tab children
82 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
83 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
83 // Widgets different from tabs are not visited (no action)
84 // Widgets different from tabs are not visited (no action)
84 if (auto visualizationTabWidget
85 if (auto visualizationTabWidget
85 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
86 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
86 visualizationTabWidget->accept(visitor);
87 visualizationTabWidget->accept(visitor);
87 }
88 }
88 }
89 }
89
90
90 visitor->visitLeave(this);
91 visitor->visitLeave(this);
91 }
92 }
92 else {
93 else {
93 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
94 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
94 }
95 }
95 }
96 }
96
97
97 bool VisualizationWidget::canDrop(const Variable &variable) const
98 bool VisualizationWidget::canDrop(const Variable &variable) const
98 {
99 {
99 // The main widget can never accomodate a variable
100 // The main widget can never accomodate a variable
100 Q_UNUSED(variable);
101 Q_UNUSED(variable);
101 return false;
102 return false;
102 }
103 }
103
104
105 bool VisualizationWidget::contains(const Variable &variable) const
106 {
107 Q_UNUSED(variable);
108 return false;
109 }
110
104 QString VisualizationWidget::name() const
111 QString VisualizationWidget::name() const
105 {
112 {
106 return QStringLiteral("MainView");
113 return QStringLiteral("MainView");
107 }
114 }
108
115
109 void VisualizationWidget::attachVariableMenu(
116 void VisualizationWidget::attachVariableMenu(
110 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
117 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
111 {
118 {
112 // Menu is generated only if there is a single variable
119 // Menu is generated only if there is a single variable
113 if (variables.size() == 1) {
120 if (variables.size() == 1) {
114 if (auto variable = variables.first()) {
121 if (auto variable = variables.first()) {
115 // Generates the actions that make it possible to visualize the variable
122 // Generates the actions that make it possible to visualize the variable
116 auto generateVariableMenuOperation = GenerateVariableMenuOperation{menu, variable};
123 auto generateVariableMenuOperation = GenerateVariableMenuOperation{menu, variable};
117 accept(&generateVariableMenuOperation);
124 accept(&generateVariableMenuOperation);
118 }
125 }
119 else {
126 else {
120 qCCritical(LOG_VisualizationWidget()) << tr(
127 qCCritical(LOG_VisualizationWidget()) << tr(
121 "Can't generate the menu relative to the visualization: the variable is null");
128 "Can't generate the menu relative to the visualization: the variable is null");
122 }
129 }
123 }
130 }
124 else {
131 else {
125 qCDebug(LOG_VisualizationWidget())
132 qCDebug(LOG_VisualizationWidget())
126 << tr("No generation of the menu related to the visualization: several variables are "
133 << tr("No generation of the menu related to the visualization: several variables are "
127 "selected");
134 "selected");
128 }
135 }
129 }
136 }
137
138 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept
139 {
140 // Calls the operation of removing all references to the variable in the visualization
141 auto removeVariableOperation = RemoveVariableOperation{variable};
142 accept(&removeVariableOperation);
143 }
@@ -1,105 +1,111
1 #include "Visualization/VisualizationZoneWidget.h"
1 #include "Visualization/VisualizationZoneWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "ui_VisualizationZoneWidget.h"
3 #include "ui_VisualizationZoneWidget.h"
4
4
5 #include "Visualization/VisualizationGraphWidget.h"
5 #include "Visualization/VisualizationGraphWidget.h"
6
6
7 #include <SqpApplication.h>
7 #include <SqpApplication.h>
8
8
9 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
9 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
10
10
11 namespace {
11 namespace {
12
12
13 /// Minimum height for graph added in zones (in pixels)
13 /// Minimum height for graph added in zones (in pixels)
14 const auto GRAPH_MINIMUM_HEIGHT = 300;
14 const auto GRAPH_MINIMUM_HEIGHT = 300;
15
15
16 /// Generates a default name for a new graph, according to the number of graphs already displayed in
16 /// Generates a default name for a new graph, according to the number of graphs already displayed in
17 /// the zone
17 /// the zone
18 QString defaultGraphName(const QLayout &layout)
18 QString defaultGraphName(const QLayout &layout)
19 {
19 {
20 auto count = 0;
20 auto count = 0;
21 for (auto i = 0; i < layout.count(); ++i) {
21 for (auto i = 0; i < layout.count(); ++i) {
22 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
22 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
23 count++;
23 count++;
24 }
24 }
25 }
25 }
26
26
27 return QObject::tr("Graph %1").arg(count + 1);
27 return QObject::tr("Graph %1").arg(count + 1);
28 }
28 }
29
29
30 } // namespace
30 } // namespace
31
31
32 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
32 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
33 : QWidget{parent}, ui{new Ui::VisualizationZoneWidget}
33 : QWidget{parent}, ui{new Ui::VisualizationZoneWidget}
34 {
34 {
35 ui->setupUi(this);
35 ui->setupUi(this);
36
36
37 ui->zoneNameLabel->setText(name);
37 ui->zoneNameLabel->setText(name);
38
38
39 // 'Close' options : widget is deleted when closed
39 // 'Close' options : widget is deleted when closed
40 setAttribute(Qt::WA_DeleteOnClose);
40 setAttribute(Qt::WA_DeleteOnClose);
41 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
41 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
42 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
42 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
43 }
43 }
44
44
45 VisualizationZoneWidget::~VisualizationZoneWidget()
45 VisualizationZoneWidget::~VisualizationZoneWidget()
46 {
46 {
47 delete ui;
47 delete ui;
48 }
48 }
49
49
50 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
50 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
51 {
51 {
52 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
52 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
53 }
53 }
54
54
55 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
55 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
56 {
56 {
57 auto graphWidget = new VisualizationGraphWidget{
57 auto graphWidget = new VisualizationGraphWidget{
58 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
58 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
59
59
60 // Set graph properties
60 // Set graph properties
61 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
61 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
62 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
62 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
63
63
64 this->addGraph(graphWidget);
64 this->addGraph(graphWidget);
65
65
66 graphWidget->addVariable(variable);
66 graphWidget->addVariable(variable);
67
67
68 return graphWidget;
68 return graphWidget;
69 }
69 }
70
70
71 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
71 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
72 {
72 {
73 if (visitor) {
73 if (visitor) {
74 visitor->visitEnter(this);
74 visitor->visitEnter(this);
75
75
76 // Apply visitor to graph children
76 // Apply visitor to graph children
77 auto layout = ui->visualizationZoneFrame->layout();
77 auto layout = ui->visualizationZoneFrame->layout();
78 for (auto i = 0; i < layout->count(); ++i) {
78 for (auto i = 0; i < layout->count(); ++i) {
79 if (auto item = layout->itemAt(i)) {
79 if (auto item = layout->itemAt(i)) {
80 // Widgets different from graphs are not visited (no action)
80 // Widgets different from graphs are not visited (no action)
81 if (auto visualizationGraphWidget
81 if (auto visualizationGraphWidget
82 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
82 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
83 visualizationGraphWidget->accept(visitor);
83 visualizationGraphWidget->accept(visitor);
84 }
84 }
85 }
85 }
86 }
86 }
87
87
88 visitor->visitLeave(this);
88 visitor->visitLeave(this);
89 }
89 }
90 else {
90 else {
91 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
91 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
92 }
92 }
93 }
93 }
94
94
95 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
95 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
96 {
96 {
97 // A tab can always accomodate a variable
97 // A tab can always accomodate a variable
98 Q_UNUSED(variable);
98 Q_UNUSED(variable);
99 return true;
99 return true;
100 }
100 }
101
101
102 bool VisualizationZoneWidget::contains(const Variable &variable) const
103 {
104 Q_UNUSED(variable);
105 return false;
106 }
107
102 QString VisualizationZoneWidget::name() const
108 QString VisualizationZoneWidget::name() const
103 {
109 {
104 return ui->zoneNameLabel->text();
110 return ui->zoneNameLabel->text();
105 }
111 }
@@ -1,146 +1,183
1 #include "Visualization/operations/GenerateVariableMenuOperation.h"
1 #include "Visualization/operations/GenerateVariableMenuOperation.h"
2 #include "Visualization/operations/MenuBuilder.h"
2 #include "Visualization/operations/MenuBuilder.h"
3
3
4 #include "Visualization/VisualizationGraphWidget.h"
4 #include "Visualization/VisualizationGraphWidget.h"
5 #include "Visualization/VisualizationTabWidget.h"
5 #include "Visualization/VisualizationTabWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
7
7
8 #include <Variable/Variable.h>
8 #include <Variable/Variable.h>
9
9
10 #include <QMenu>
10 #include <QMenu>
11 #include <QStack>
11 #include <QStack>
12
12
13 Q_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation, "GenerateVariableMenuOperation")
13 Q_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation, "GenerateVariableMenuOperation")
14
14
15 struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate {
15 struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate {
16 explicit GenerateVariableMenuOperationPrivate(QMenu *menu, std::shared_ptr<Variable> variable)
16 explicit GenerateVariableMenuOperationPrivate(QMenu *menu, std::shared_ptr<Variable> variable)
17 : m_Variable{variable}, m_MenuBuilder{menu}
17 : m_Variable{variable}, m_PlotMenuBuilder{menu}, m_UnplotMenuBuilder{menu}
18 {
18 {
19 }
19 }
20
20
21 void visitRootEnter()
21 void visitRootEnter()
22 {
22 {
23 // Creates the root menu
23 // Creates the root menu
24 m_MenuBuilder.addMenu(QObject::tr("Plot"));
24 m_PlotMenuBuilder.addMenu(QObject::tr("Plot"), QIcon{":/icones/plot.png"});
25 m_UnplotMenuBuilder.addMenu(QObject::tr("Unplot"), QIcon{":/icones/unplot.png"});
25 }
26 }
26
27
27 void visitRootLeave()
28 void visitRootLeave()
28 {
29 {
29 // Closes the root menu
30 // Closes the root menu
30 m_MenuBuilder.closeMenu();
31 m_PlotMenuBuilder.closeMenu();
32 m_UnplotMenuBuilder.closeMenu();
31 }
33 }
32
34
33 void visitNodeEnter(const IVisualizationWidget &container)
35 void visitNodeEnter(const IVisualizationWidget &container)
34 {
36 {
35 // Opens a new menu associated to the node
37 // Opens a new menu associated to the node
36 m_MenuBuilder.addMenu(container.name());
38 m_PlotMenuBuilder.addMenu(container.name());
39 m_UnplotMenuBuilder.addMenu(container.name());
37 }
40 }
38
41
39 template <typename ActionFun>
42 template <typename ActionFun>
40 void visitNodeLeave(const IVisualizationWidget &container, const QString &actionName,
43 void visitNodeLeavePlot(const IVisualizationWidget &container, const QString &actionName,
41 ActionFun actionFunction)
44 ActionFun actionFunction)
42 {
45 {
43 if (m_Variable && container.canDrop(*m_Variable)) {
46 if (m_Variable && container.canDrop(*m_Variable)) {
44 m_MenuBuilder.addSeparator();
47 m_PlotMenuBuilder.addSeparator();
45 m_MenuBuilder.addAction(actionName, actionFunction);
48 m_PlotMenuBuilder.addAction(actionName, actionFunction);
46 }
49 }
47
50
48 // Closes the menu associated to the node
51 // Closes the menu associated to the node
49 m_MenuBuilder.closeMenu();
52 m_PlotMenuBuilder.closeMenu();
53 }
54
55 void visitNodeLeaveUnplot()
56 {
57 // Closes the menu associated to the node
58 m_UnplotMenuBuilder.closeMenu();
50 }
59 }
51
60
52 template <typename ActionFun>
61 template <typename ActionFun>
53 void visitLeaf(const IVisualizationWidget &container, const QString &actionName,
62 void visitLeafPlot(const IVisualizationWidget &container, const QString &actionName,
54 ActionFun actionFunction)
63 ActionFun actionFunction)
55 {
64 {
56 if (m_Variable && container.canDrop(*m_Variable)) {
65 if (m_Variable && container.canDrop(*m_Variable)) {
57 m_MenuBuilder.addAction(actionName, actionFunction);
66 m_PlotMenuBuilder.addAction(actionName, actionFunction);
67 }
68 }
69
70 template <typename ActionFun>
71 void visitLeafUnplot(const IVisualizationWidget &container, const QString &actionName,
72 ActionFun actionFunction)
73 {
74 if (m_Variable && container.contains(*m_Variable)) {
75 m_UnplotMenuBuilder.addAction(actionName, actionFunction);
58 }
76 }
59 }
77 }
60
78
61 std::shared_ptr<Variable> m_Variable;
79 std::shared_ptr<Variable> m_Variable;
62 MenuBuilder m_MenuBuilder;
80 MenuBuilder m_PlotMenuBuilder; ///< Builder for the 'Plot' menu
81 MenuBuilder m_UnplotMenuBuilder; ///< Builder for the 'Unplot' menu
63 };
82 };
64
83
65 GenerateVariableMenuOperation::GenerateVariableMenuOperation(QMenu *menu,
84 GenerateVariableMenuOperation::GenerateVariableMenuOperation(QMenu *menu,
66 std::shared_ptr<Variable> variable)
85 std::shared_ptr<Variable> variable)
67 : impl{spimpl::make_unique_impl<GenerateVariableMenuOperationPrivate>(menu, variable)}
86 : impl{spimpl::make_unique_impl<GenerateVariableMenuOperationPrivate>(menu, variable)}
68 {
87 {
69 }
88 }
70
89
71 void GenerateVariableMenuOperation::visitEnter(VisualizationWidget *widget)
90 void GenerateVariableMenuOperation::visitEnter(VisualizationWidget *widget)
72 {
91 {
73 // VisualizationWidget is not intended to accommodate a variable
92 // VisualizationWidget is not intended to accommodate a variable
74 Q_UNUSED(widget)
93 Q_UNUSED(widget)
75
94
95 // 'Plot' and 'Unplot' menus
76 impl->visitRootEnter();
96 impl->visitRootEnter();
77 }
97 }
78
98
79 void GenerateVariableMenuOperation::visitLeave(VisualizationWidget *widget)
99 void GenerateVariableMenuOperation::visitLeave(VisualizationWidget *widget)
80 {
100 {
81 // VisualizationWidget is not intended to accommodate a variable
101 // VisualizationWidget is not intended to accommodate a variable
82 Q_UNUSED(widget)
102 Q_UNUSED(widget)
83
103
104 // 'Plot' and 'Unplot' menus
84 impl->visitRootLeave();
105 impl->visitRootLeave();
85 }
106 }
86
107
87 void GenerateVariableMenuOperation::visitEnter(VisualizationTabWidget *tabWidget)
108 void GenerateVariableMenuOperation::visitEnter(VisualizationTabWidget *tabWidget)
88 {
109 {
89 if (tabWidget) {
110 if (tabWidget) {
111 // 'Plot' and 'Unplot' menus
90 impl->visitNodeEnter(*tabWidget);
112 impl->visitNodeEnter(*tabWidget);
91 }
113 }
92 else {
114 else {
93 qCCritical(LOG_GenerateVariableMenuOperation(),
115 qCCritical(LOG_GenerateVariableMenuOperation(),
94 "Can't visit enter VisualizationTabWidget : the widget is null");
116 "Can't visit enter VisualizationTabWidget : the widget is null");
95 }
117 }
96 }
118 }
97
119
98 void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget *tabWidget)
120 void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget *tabWidget)
99 {
121 {
100 if (tabWidget) {
122 if (tabWidget) {
101 impl->visitNodeLeave(
123 // 'Plot' menu
124 impl->visitNodeLeavePlot(
102 *tabWidget, QObject::tr("Open in a new zone"),
125 *tabWidget, QObject::tr("Open in a new zone"),
103 [ var = impl->m_Variable, tabWidget ]() { tabWidget->createZone(var); });
126 [ var = impl->m_Variable, tabWidget ]() { tabWidget->createZone(var); });
127
128 // 'Unplot' menu
129 impl->visitNodeLeaveUnplot();
104 }
130 }
105 else {
131 else {
106 qCCritical(LOG_GenerateVariableMenuOperation(),
132 qCCritical(LOG_GenerateVariableMenuOperation(),
107 "Can't visit leave VisualizationTabWidget : the widget is null");
133 "Can't visit leave VisualizationTabWidget : the widget is null");
108 }
134 }
109 }
135 }
110
136
111 void GenerateVariableMenuOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
137 void GenerateVariableMenuOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
112 {
138 {
113 if (zoneWidget) {
139 if (zoneWidget) {
140 // 'Plot' and 'Unplot' menus
114 impl->visitNodeEnter(*zoneWidget);
141 impl->visitNodeEnter(*zoneWidget);
115 }
142 }
116 else {
143 else {
117 qCCritical(LOG_GenerateVariableMenuOperation(),
144 qCCritical(LOG_GenerateVariableMenuOperation(),
118 "Can't visit enter VisualizationZoneWidget : the widget is null");
145 "Can't visit enter VisualizationZoneWidget : the widget is null");
119 }
146 }
120 }
147 }
121
148
122 void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
149 void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
123 {
150 {
124 if (zoneWidget) {
151 if (zoneWidget) {
125 impl->visitNodeLeave(
152 // 'Plot' menu
153 impl->visitNodeLeavePlot(
126 *zoneWidget, QObject::tr("Open in a new graph"),
154 *zoneWidget, QObject::tr("Open in a new graph"),
127 [ var = impl->m_Variable, zoneWidget ]() { zoneWidget->createGraph(var); });
155 [ var = impl->m_Variable, zoneWidget ]() { zoneWidget->createGraph(var); });
156
157 // 'Unplot' menu
158 impl->visitNodeLeaveUnplot();
128 }
159 }
129 else {
160 else {
130 qCCritical(LOG_GenerateVariableMenuOperation(),
161 qCCritical(LOG_GenerateVariableMenuOperation(),
131 "Can't visit leave VisualizationZoneWidget : the widget is null");
162 "Can't visit leave VisualizationZoneWidget : the widget is null");
132 }
163 }
133 }
164 }
134
165
135 void GenerateVariableMenuOperation::visit(VisualizationGraphWidget *graphWidget)
166 void GenerateVariableMenuOperation::visit(VisualizationGraphWidget *graphWidget)
136 {
167 {
137 if (graphWidget) {
168 if (graphWidget) {
138 impl->visitLeaf(
169 // 'Plot' menu
170 impl->visitLeafPlot(
139 *graphWidget, QObject::tr("Open in %1").arg(graphWidget->name()),
171 *graphWidget, QObject::tr("Open in %1").arg(graphWidget->name()),
140 [ var = impl->m_Variable, graphWidget ]() { graphWidget->addVariableUsingGraph(var); });
172 [ var = impl->m_Variable, graphWidget ]() { graphWidget->addVariableUsingGraph(var); });
173
174 // 'Unplot' menu
175 impl->visitLeafUnplot(
176 *graphWidget, QObject::tr("Remove from %1").arg(graphWidget->name()),
177 [ var = impl->m_Variable, graphWidget ]() { graphWidget->removeVariable(var); });
141 }
178 }
142 else {
179 else {
143 qCCritical(LOG_GenerateVariableMenuOperation(),
180 qCCritical(LOG_GenerateVariableMenuOperation(),
144 "Can't visit VisualizationGraphWidget : the widget is null");
181 "Can't visit VisualizationGraphWidget : the widget is null");
145 }
182 }
146 }
183 }
@@ -1,55 +1,55
1 #include "Visualization/operations/MenuBuilder.h"
1 #include "Visualization/operations/MenuBuilder.h"
2
2
3 Q_LOGGING_CATEGORY(LOG_MenuBuilder, "MenuBuilder")
3 Q_LOGGING_CATEGORY(LOG_MenuBuilder, "MenuBuilder")
4
4
5 MenuBuilder::MenuBuilder(QMenu *menu)
5 MenuBuilder::MenuBuilder(QMenu *menu)
6 {
6 {
7 if (menu) {
7 if (menu) {
8 m_Menus.push(menu);
8 m_Menus.push(menu);
9 }
9 }
10 else {
10 else {
11 qCCritical(LOG_MenuBuilder()) << QObject::tr("No parent menu has been defined");
11 qCCritical(LOG_MenuBuilder()) << QObject::tr("No parent menu has been defined");
12 }
12 }
13 }
13 }
14
14
15 void MenuBuilder::addMenu(const QString &name)
15 void MenuBuilder::addMenu(const QString &name, const QIcon &icon)
16 {
16 {
17 if (auto currMenu = currentMenu()) {
17 if (auto currMenu = currentMenu()) {
18 m_Menus.push(currMenu->addMenu(name));
18 m_Menus.push(currMenu->addMenu(icon, name));
19 }
19 }
20 else {
20 else {
21 qCCritical(LOG_MenuBuilder()) << QObject::tr("No current menu to attach the new menu");
21 qCCritical(LOG_MenuBuilder()) << QObject::tr("No current menu to attach the new menu");
22 }
22 }
23 }
23 }
24
24
25 void MenuBuilder::addSeparator()
25 void MenuBuilder::addSeparator()
26 {
26 {
27 if (auto currMenu = currentMenu()) {
27 if (auto currMenu = currentMenu()) {
28 if (!currMenu->isEmpty()) {
28 if (!currMenu->isEmpty()) {
29 currMenu->addSeparator();
29 currMenu->addSeparator();
30 }
30 }
31 }
31 }
32 else {
32 else {
33 qCCritical(LOG_MenuBuilder()) << QObject::tr("No current menu to attach the separator");
33 qCCritical(LOG_MenuBuilder()) << QObject::tr("No current menu to attach the separator");
34 }
34 }
35 }
35 }
36
36
37 void MenuBuilder::closeMenu()
37 void MenuBuilder::closeMenu()
38 {
38 {
39 if (!m_Menus.isEmpty()) {
39 if (!m_Menus.isEmpty()) {
40 if (auto closedMenu = m_Menus.pop()) {
40 if (auto closedMenu = m_Menus.pop()) {
41 // Purge menu : if the closed menu has no entries, we remove it from its parent (the
41 // Purge menu : if the closed menu has no entries, we remove it from its parent (the
42 // current menu)
42 // current menu)
43 if (auto currMenu = currentMenu()) {
43 if (auto currMenu = currentMenu()) {
44 if (closedMenu->isEmpty()) {
44 if (closedMenu->isEmpty()) {
45 currMenu->removeAction(closedMenu->menuAction());
45 currMenu->removeAction(closedMenu->menuAction());
46 }
46 }
47 }
47 }
48 }
48 }
49 }
49 }
50 }
50 }
51
51
52 QMenu *MenuBuilder::currentMenu() const
52 QMenu *MenuBuilder::currentMenu() const
53 {
53 {
54 return !m_Menus.isEmpty() ? m_Menus.top() : nullptr;
54 return !m_Menus.isEmpty() ? m_Menus.top() : nullptr;
55 }
55 }
General Comments 0
You need to be logged in to leave comments. Login now