##// END OF EJS Templates
spelling fix
trabillard -
r1339:1a2f30e2d800
parent child
Show More
@@ -1,405 +1,405
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 <Catalogue/CatalogueController.h>
25 #include <Catalogue/CatalogueController.h>
26 #include <Catalogue/CatalogueExplorer.h>
26 #include <Catalogue/CatalogueExplorer.h>
27 #include <DataSource/DataSourceController.h>
27 #include <DataSource/DataSourceController.h>
28 #include <DataSource/DataSourceWidget.h>
28 #include <DataSource/DataSourceWidget.h>
29 #include <Settings/SqpSettingsDialog.h>
29 #include <Settings/SqpSettingsDialog.h>
30 #include <Settings/SqpSettingsGeneralWidget.h>
30 #include <Settings/SqpSettingsGeneralWidget.h>
31 #include <SidePane/SqpSidePane.h>
31 #include <SidePane/SqpSidePane.h>
32 #include <SqpApplication.h>
32 #include <SqpApplication.h>
33 #include <Time/TimeController.h>
33 #include <Time/TimeController.h>
34 #include <TimeWidget/TimeWidget.h>
34 #include <TimeWidget/TimeWidget.h>
35 #include <Variable/Variable.h>
35 #include <Variable/Variable.h>
36 #include <Variable/VariableController.h>
36 #include <Variable/VariableController.h>
37 #include <Visualization/VisualizationController.h>
37 #include <Visualization/VisualizationController.h>
38
38
39 #include <QAction>
39 #include <QAction>
40 #include <QCloseEvent>
40 #include <QCloseEvent>
41 #include <QDate>
41 #include <QDate>
42 #include <QDir>
42 #include <QDir>
43 #include <QFileDialog>
43 #include <QFileDialog>
44 #include <QMessageBox>
44 #include <QMessageBox>
45 #include <QToolBar>
45 #include <QToolBar>
46 #include <QToolButton>
46 #include <QToolButton>
47 #include <memory.h>
47 #include <memory.h>
48
48
49 #include "iostream"
49 #include "iostream"
50
50
51 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
51 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
52
52
53 namespace {
53 namespace {
54 const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0;
54 const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0;
55 const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1;
55 const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1;
56 const auto VIEWPLITTERINDEX = 2;
56 const auto VIEWPLITTERINDEX = 2;
57 const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3;
57 const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3;
58 const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4;
58 const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4;
59 }
59 }
60
60
61 class MainWindow::MainWindowPrivate {
61 class MainWindow::MainWindowPrivate {
62 public:
62 public:
63 explicit MainWindowPrivate(MainWindow *mainWindow)
63 explicit MainWindowPrivate(MainWindow *mainWindow)
64 : m_LastOpenLeftInspectorSize{},
64 : m_LastOpenLeftInspectorSize{},
65 m_LastOpenRightInspectorSize{},
65 m_LastOpenRightInspectorSize{},
66 m_GeneralSettingsWidget{new SqpSettingsGeneralWidget{mainWindow}},
66 m_GeneralSettingsWidget{new SqpSettingsGeneralWidget{mainWindow}},
67 m_SettingsDialog{new SqpSettingsDialog{mainWindow}},
67 m_SettingsDialog{new SqpSettingsDialog{mainWindow}},
68 m_CatalogExplorer{new CatalogueExplorer{mainWindow}}
68 m_CatalogExplorer{new CatalogueExplorer{mainWindow}}
69 {
69 {
70 }
70 }
71
71
72 QSize m_LastOpenLeftInspectorSize;
72 QSize m_LastOpenLeftInspectorSize;
73 QSize m_LastOpenRightInspectorSize;
73 QSize m_LastOpenRightInspectorSize;
74 /// General settings widget. MainWindow has the ownership
74 /// General settings widget. MainWindow has the ownership
75 SqpSettingsGeneralWidget *m_GeneralSettingsWidget;
75 SqpSettingsGeneralWidget *m_GeneralSettingsWidget;
76 /// Settings dialog. MainWindow has the ownership
76 /// Settings dialog. MainWindow has the ownership
77 SqpSettingsDialog *m_SettingsDialog;
77 SqpSettingsDialog *m_SettingsDialog;
78 /// Catalogue dialog. MainWindow has the ownership
78 /// Catalogue dialog. MainWindow has the ownership
79 CatalogueExplorer *m_CatalogExplorer;
79 CatalogueExplorer *m_CatalogExplorer;
80
80
81 bool checkDataToSave(QWidget *parentWidget);
81 bool checkDataToSave(QWidget *parentWidget);
82 };
82 };
83
83
84 MainWindow::MainWindow(QWidget *parent)
84 MainWindow::MainWindow(QWidget *parent)
85 : QMainWindow{parent},
85 : QMainWindow{parent},
86 m_Ui{new Ui::MainWindow},
86 m_Ui{new Ui::MainWindow},
87 impl{spimpl::make_unique_impl<MainWindowPrivate>(this)}
87 impl{spimpl::make_unique_impl<MainWindowPrivate>(this)}
88 {
88 {
89 m_Ui->setupUi(this);
89 m_Ui->setupUi(this);
90
90
91 m_Ui->splitter->setCollapsible(LEFTINSPECTORSIDEPANESPLITTERINDEX, false);
91 m_Ui->splitter->setCollapsible(LEFTINSPECTORSIDEPANESPLITTERINDEX, false);
92 m_Ui->splitter->setCollapsible(RIGHTINSPECTORSIDEPANESPLITTERINDEX, false);
92 m_Ui->splitter->setCollapsible(RIGHTINSPECTORSIDEPANESPLITTERINDEX, false);
93
93
94 impl->m_CatalogExplorer->setVisualizationWidget(m_Ui->view);
94 impl->m_CatalogExplorer->setVisualizationWidget(m_Ui->view);
95
95
96
96
97 auto leftSidePane = m_Ui->leftInspectorSidePane->sidePane();
97 auto leftSidePane = m_Ui->leftInspectorSidePane->sidePane();
98 auto openLeftInspectorAction = new QAction{QIcon{
98 auto openLeftInspectorAction = new QAction{QIcon{
99 ":/icones/previous.png",
99 ":/icones/previous.png",
100 },
100 },
101 tr("Show/hide the left inspector"), this};
101 tr("Show/hide the left inspector"), this};
102
102
103
103
104 auto spacerLeftTop = new QWidget{};
104 auto spacerLeftTop = new QWidget{};
105 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
105 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
106
106
107 auto spacerLeftBottom = new QWidget{};
107 auto spacerLeftBottom = new QWidget{};
108 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
108 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
109
109
110 leftSidePane->addWidget(spacerLeftTop);
110 leftSidePane->addWidget(spacerLeftTop);
111 leftSidePane->addAction(openLeftInspectorAction);
111 leftSidePane->addAction(openLeftInspectorAction);
112 leftSidePane->addWidget(spacerLeftBottom);
112 leftSidePane->addWidget(spacerLeftBottom);
113
113
114
114
115 auto rightSidePane = m_Ui->rightInspectorSidePane->sidePane();
115 auto rightSidePane = m_Ui->rightInspectorSidePane->sidePane();
116 auto openRightInspectorAction = new QAction{QIcon{
116 auto openRightInspectorAction = new QAction{QIcon{
117 ":/icones/next.png",
117 ":/icones/next.png",
118 },
118 },
119 tr("Show/hide the right inspector"), this};
119 tr("Show/hide the right inspector"), this};
120
120
121 auto spacerRightTop = new QWidget{};
121 auto spacerRightTop = new QWidget{};
122 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
122 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
123
123
124 auto spacerRightBottom = new QWidget{};
124 auto spacerRightBottom = new QWidget{};
125 spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
125 spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
126
126
127 rightSidePane->addWidget(spacerRightTop);
127 rightSidePane->addWidget(spacerRightTop);
128 rightSidePane->addAction(openRightInspectorAction);
128 rightSidePane->addAction(openRightInspectorAction);
129 rightSidePane->addWidget(spacerRightBottom);
129 rightSidePane->addWidget(spacerRightBottom);
130
130
131 openLeftInspectorAction->setCheckable(true);
131 openLeftInspectorAction->setCheckable(true);
132 openRightInspectorAction->setCheckable(true);
132 openRightInspectorAction->setCheckable(true);
133
133
134 auto openInspector = [this](bool checked, bool right, auto action) {
134 auto openInspector = [this](bool checked, bool right, auto action) {
135
135
136 action->setIcon(QIcon{(checked xor right) ? ":/icones/next.png" : ":/icones/previous.png"});
136 action->setIcon(QIcon{(checked xor right) ? ":/icones/next.png" : ":/icones/previous.png"});
137
137
138 auto &lastInspectorSize
138 auto &lastInspectorSize
139 = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize;
139 = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize;
140
140
141 auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size()
141 auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size()
142 : m_Ui->leftMainInspectorWidget->size();
142 : m_Ui->leftMainInspectorWidget->size();
143
143
144 // Update of the last opened geometry
144 // Update of the last opened geometry
145 if (checked) {
145 if (checked) {
146 lastInspectorSize = nextInspectorSize;
146 lastInspectorSize = nextInspectorSize;
147 }
147 }
148
148
149 auto startSize = lastInspectorSize;
149 auto startSize = lastInspectorSize;
150 auto endSize = startSize;
150 auto endSize = startSize;
151 endSize.setWidth(0);
151 endSize.setWidth(0);
152
152
153 auto splitterInspectorIndex
153 auto splitterInspectorIndex
154 = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX;
154 = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX;
155
155
156 auto currentSizes = m_Ui->splitter->sizes();
156 auto currentSizes = m_Ui->splitter->sizes();
157 if (checked) {
157 if (checked) {
158 // adjust sizes individually here, e.g.
158 // adjust sizes individually here, e.g.
159 currentSizes[splitterInspectorIndex] -= lastInspectorSize.width();
159 currentSizes[splitterInspectorIndex] -= lastInspectorSize.width();
160 currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width();
160 currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width();
161 m_Ui->splitter->setSizes(currentSizes);
161 m_Ui->splitter->setSizes(currentSizes);
162 }
162 }
163 else {
163 else {
164 // adjust sizes individually here, e.g.
164 // adjust sizes individually here, e.g.
165 currentSizes[splitterInspectorIndex] += lastInspectorSize.width();
165 currentSizes[splitterInspectorIndex] += lastInspectorSize.width();
166 currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width();
166 currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width();
167 m_Ui->splitter->setSizes(currentSizes);
167 m_Ui->splitter->setSizes(currentSizes);
168 }
168 }
169
169
170 };
170 };
171
171
172
172
173 connect(openLeftInspectorAction, &QAction::triggered,
173 connect(openLeftInspectorAction, &QAction::triggered,
174 [openInspector, openLeftInspectorAction](bool checked) {
174 [openInspector, openLeftInspectorAction](bool checked) {
175 openInspector(checked, false, openLeftInspectorAction);
175 openInspector(checked, false, openLeftInspectorAction);
176 });
176 });
177 connect(openRightInspectorAction, &QAction::triggered,
177 connect(openRightInspectorAction, &QAction::triggered,
178 [openInspector, openRightInspectorAction](bool checked) {
178 [openInspector, openRightInspectorAction](bool checked) {
179 openInspector(checked, true, openRightInspectorAction);
179 openInspector(checked, true, openRightInspectorAction);
180 });
180 });
181
181
182 // //////////////// //
182 // //////////////// //
183 // Menu and Toolbar //
183 // Menu and Toolbar //
184 // //////////////// //
184 // //////////////// //
185 this->menuBar()->addAction(tr("File"));
185 this->menuBar()->addAction(tr("File"));
186 auto toolsMenu = this->menuBar()->addMenu(tr("Tools"));
186 auto toolsMenu = this->menuBar()->addMenu(tr("Tools"));
187 toolsMenu->addAction(tr("Settings..."), [this]() {
187 toolsMenu->addAction(tr("Settings..."), [this]() {
188 // Loads settings
188 // Loads settings
189 impl->m_SettingsDialog->loadSettings();
189 impl->m_SettingsDialog->loadSettings();
190
190
191 // Open settings dialog and save settings if the dialog is accepted
191 // Open settings dialog and save settings if the dialog is accepted
192 if (impl->m_SettingsDialog->exec() == QDialog::Accepted) {
192 if (impl->m_SettingsDialog->exec() == QDialog::Accepted) {
193 impl->m_SettingsDialog->saveSettings();
193 impl->m_SettingsDialog->saveSettings();
194 }
194 }
195
195
196 });
196 });
197
197
198 auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar"));
198 auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar"));
199
199
200 auto timeWidget = new TimeWidget{};
200 auto timeWidget = new TimeWidget{};
201 mainToolBar->addWidget(timeWidget);
201 mainToolBar->addWidget(timeWidget);
202
202
203 // Interaction modes
203 // Interaction modes
204 auto actionPointerMode = new QAction{QIcon(":/icones/pointer.png"), "Move", this};
204 auto actionPointerMode = new QAction{QIcon(":/icones/pointer.png"), "Move", this};
205 actionPointerMode->setCheckable(true);
205 actionPointerMode->setCheckable(true);
206 actionPointerMode->setChecked(sqpApp->plotsInteractionMode()
206 actionPointerMode->setChecked(sqpApp->plotsInteractionMode()
207 == SqpApplication::PlotsInteractionMode::None);
207 == SqpApplication::PlotsInteractionMode::None);
208 connect(actionPointerMode, &QAction::triggered,
208 connect(actionPointerMode, &QAction::triggered,
209 []() { sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::None); });
209 []() { sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::None); });
210
210
211 auto actionZoomMode = new QAction{QIcon(":/icones/zoom.png"), "Zoom", this};
211 auto actionZoomMode = new QAction{QIcon(":/icones/zoom.png"), "Zoom", this};
212 actionZoomMode->setCheckable(true);
212 actionZoomMode->setCheckable(true);
213 actionZoomMode->setChecked(sqpApp->plotsInteractionMode()
213 actionZoomMode->setChecked(sqpApp->plotsInteractionMode()
214 == SqpApplication::PlotsInteractionMode::ZoomBox);
214 == SqpApplication::PlotsInteractionMode::ZoomBox);
215 connect(actionZoomMode, &QAction::triggered, []() {
215 connect(actionZoomMode, &QAction::triggered, []() {
216 sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::ZoomBox);
216 sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::ZoomBox);
217 });
217 });
218
218
219 auto actionOrganisationMode = new QAction{QIcon(":/icones/drag.png"), "Organize", this};
219 auto actionOrganisationMode = new QAction{QIcon(":/icones/drag.png"), "Organize", this};
220 actionOrganisationMode->setCheckable(true);
220 actionOrganisationMode->setCheckable(true);
221 actionOrganisationMode->setChecked(sqpApp->plotsInteractionMode()
221 actionOrganisationMode->setChecked(sqpApp->plotsInteractionMode()
222 == SqpApplication::PlotsInteractionMode::DragAndDrop);
222 == SqpApplication::PlotsInteractionMode::DragAndDrop);
223 connect(actionOrganisationMode, &QAction::triggered, []() {
223 connect(actionOrganisationMode, &QAction::triggered, []() {
224 sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::DragAndDrop);
224 sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::DragAndDrop);
225 });
225 });
226
226
227 auto actionZonesMode = new QAction{QIcon(":/icones/rectangle.png"), "Zones", this};
227 auto actionZonesMode = new QAction{QIcon(":/icones/rectangle.png"), "Zones", this};
228 actionZonesMode->setCheckable(true);
228 actionZonesMode->setCheckable(true);
229 actionZonesMode->setChecked(sqpApp->plotsInteractionMode()
229 actionZonesMode->setChecked(sqpApp->plotsInteractionMode()
230 == SqpApplication::PlotsInteractionMode::SelectionZones);
230 == SqpApplication::PlotsInteractionMode::SelectionZones);
231 connect(actionZonesMode, &QAction::triggered, []() {
231 connect(actionZonesMode, &QAction::triggered, []() {
232 sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::SelectionZones);
232 sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::SelectionZones);
233 });
233 });
234
234
235 auto modeActionGroup = new QActionGroup{this};
235 auto modeActionGroup = new QActionGroup{this};
236 modeActionGroup->addAction(actionZoomMode);
236 modeActionGroup->addAction(actionZoomMode);
237 modeActionGroup->addAction(actionZonesMode);
237 modeActionGroup->addAction(actionZonesMode);
238 modeActionGroup->addAction(actionOrganisationMode);
238 modeActionGroup->addAction(actionOrganisationMode);
239 modeActionGroup->addAction(actionPointerMode);
239 modeActionGroup->addAction(actionPointerMode);
240 modeActionGroup->setExclusive(true);
240 modeActionGroup->setExclusive(true);
241
241
242 mainToolBar->addSeparator();
242 mainToolBar->addSeparator();
243 mainToolBar->addAction(actionPointerMode);
243 mainToolBar->addAction(actionPointerMode);
244 mainToolBar->addAction(actionZoomMode);
244 mainToolBar->addAction(actionZoomMode);
245 mainToolBar->addAction(actionOrganisationMode);
245 mainToolBar->addAction(actionOrganisationMode);
246 mainToolBar->addAction(actionZonesMode);
246 mainToolBar->addAction(actionZonesMode);
247 mainToolBar->addSeparator();
247 mainToolBar->addSeparator();
248
248
249 // Cursors
249 // Cursors
250 auto btnCursor = new QToolButton{this};
250 auto btnCursor = new QToolButton{this};
251 btnCursor->setIcon(QIcon(":/icones/cursor.png"));
251 btnCursor->setIcon(QIcon(":/icones/cursor.png"));
252 btnCursor->setText("Cursor");
252 btnCursor->setText("Cursor");
253 btnCursor->setToolTip("Cursor");
253 btnCursor->setToolTip("Cursor");
254 btnCursor->setPopupMode(QToolButton::InstantPopup);
254 btnCursor->setPopupMode(QToolButton::InstantPopup);
255 auto cursorMenu = new QMenu("CursorMenu", this);
255 auto cursorMenu = new QMenu("CursorMenu", this);
256 btnCursor->setMenu(cursorMenu);
256 btnCursor->setMenu(cursorMenu);
257
257
258 auto noCursorAction = cursorMenu->addAction("No Cursor");
258 auto noCursorAction = cursorMenu->addAction("No Cursor");
259 noCursorAction->setCheckable(true);
259 noCursorAction->setCheckable(true);
260 noCursorAction->setChecked(sqpApp->plotsCursorMode()
260 noCursorAction->setChecked(sqpApp->plotsCursorMode()
261 == SqpApplication::PlotsCursorMode::NoCursor);
261 == SqpApplication::PlotsCursorMode::NoCursor);
262 connect(noCursorAction, &QAction::triggered,
262 connect(noCursorAction, &QAction::triggered,
263 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::NoCursor); });
263 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::NoCursor); });
264
264
265 cursorMenu->addSeparator();
265 cursorMenu->addSeparator();
266 auto verticalCursorAction = cursorMenu->addAction("Vertical Cursor");
266 auto verticalCursorAction = cursorMenu->addAction("Vertical Cursor");
267 verticalCursorAction->setCheckable(true);
267 verticalCursorAction->setCheckable(true);
268 verticalCursorAction->setChecked(sqpApp->plotsCursorMode()
268 verticalCursorAction->setChecked(sqpApp->plotsCursorMode()
269 == SqpApplication::PlotsCursorMode::Vertical);
269 == SqpApplication::PlotsCursorMode::Vertical);
270 connect(verticalCursorAction, &QAction::triggered,
270 connect(verticalCursorAction, &QAction::triggered,
271 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Vertical); });
271 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Vertical); });
272
272
273 auto temporalCursorAction = cursorMenu->addAction("Temporal Cursor");
273 auto temporalCursorAction = cursorMenu->addAction("Temporal Cursor");
274 temporalCursorAction->setCheckable(true);
274 temporalCursorAction->setCheckable(true);
275 temporalCursorAction->setChecked(sqpApp->plotsCursorMode()
275 temporalCursorAction->setChecked(sqpApp->plotsCursorMode()
276 == SqpApplication::PlotsCursorMode::Temporal);
276 == SqpApplication::PlotsCursorMode::Temporal);
277 connect(temporalCursorAction, &QAction::triggered,
277 connect(temporalCursorAction, &QAction::triggered,
278 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Temporal); });
278 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Temporal); });
279
279
280 auto horizontalCursorAction = cursorMenu->addAction("Horizontal Cursor");
280 auto horizontalCursorAction = cursorMenu->addAction("Horizontal Cursor");
281 horizontalCursorAction->setCheckable(true);
281 horizontalCursorAction->setCheckable(true);
282 horizontalCursorAction->setChecked(sqpApp->plotsCursorMode()
282 horizontalCursorAction->setChecked(sqpApp->plotsCursorMode()
283 == SqpApplication::PlotsCursorMode::Horizontal);
283 == SqpApplication::PlotsCursorMode::Horizontal);
284 connect(horizontalCursorAction, &QAction::triggered,
284 connect(horizontalCursorAction, &QAction::triggered,
285 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Horizontal); });
285 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Horizontal); });
286
286
287 auto crossCursorAction = cursorMenu->addAction("Cross Cursor");
287 auto crossCursorAction = cursorMenu->addAction("Cross Cursor");
288 crossCursorAction->setCheckable(true);
288 crossCursorAction->setCheckable(true);
289 crossCursorAction->setChecked(sqpApp->plotsCursorMode()
289 crossCursorAction->setChecked(sqpApp->plotsCursorMode()
290 == SqpApplication::PlotsCursorMode::Cross);
290 == SqpApplication::PlotsCursorMode::Cross);
291 connect(crossCursorAction, &QAction::triggered,
291 connect(crossCursorAction, &QAction::triggered,
292 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Cross); });
292 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Cross); });
293
293
294 mainToolBar->addWidget(btnCursor);
294 mainToolBar->addWidget(btnCursor);
295
295
296 auto cursorModeActionGroup = new QActionGroup{this};
296 auto cursorModeActionGroup = new QActionGroup{this};
297 cursorModeActionGroup->setExclusive(true);
297 cursorModeActionGroup->setExclusive(true);
298 cursorModeActionGroup->addAction(noCursorAction);
298 cursorModeActionGroup->addAction(noCursorAction);
299 cursorModeActionGroup->addAction(verticalCursorAction);
299 cursorModeActionGroup->addAction(verticalCursorAction);
300 cursorModeActionGroup->addAction(temporalCursorAction);
300 cursorModeActionGroup->addAction(temporalCursorAction);
301 cursorModeActionGroup->addAction(horizontalCursorAction);
301 cursorModeActionGroup->addAction(horizontalCursorAction);
302 cursorModeActionGroup->addAction(crossCursorAction);
302 cursorModeActionGroup->addAction(crossCursorAction);
303
303
304 // Catalog
304 // Catalog
305 mainToolBar->addSeparator();
305 mainToolBar->addSeparator();
306 mainToolBar->addAction(QIcon(":/icones/catalogue.png"), "Catalogues",
306 mainToolBar->addAction(QIcon(":/icones/catalogue.png"), "Catalogues",
307 [this]() { impl->m_CatalogExplorer->show(); });
307 [this]() { impl->m_CatalogExplorer->show(); });
308
308
309 // //////// //
309 // //////// //
310 // Settings //
310 // Settings //
311 // //////// //
311 // //////// //
312
312
313 // Registers "general settings" widget to the settings dialog
313 // Registers "general settings" widget to the settings dialog
314 impl->m_SettingsDialog->registerWidget(QStringLiteral("General"),
314 impl->m_SettingsDialog->registerWidget(QStringLiteral("General"),
315 impl->m_GeneralSettingsWidget);
315 impl->m_GeneralSettingsWidget);
316
316
317 // /////////// //
317 // /////////// //
318 // Connections //
318 // Connections //
319 // /////////// //
319 // /////////// //
320
320
321 // Controllers / controllers connections
321 // Controllers / controllers connections
322 connect(&sqpApp->timeController(), SIGNAL(timeUpdated(SqpRange)), &sqpApp->variableController(),
322 connect(&sqpApp->timeController(), SIGNAL(timeUpdated(SqpRange)), &sqpApp->variableController(),
323 SLOT(onDateTimeOnSelection(SqpRange)));
323 SLOT(onDateTimeOnSelection(SqpRange)));
324
324
325 // Widgets / controllers connections
325 // Widgets / controllers connections
326
326
327 // DataSource
327 // DataSource
328 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)),
328 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)),
329 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *)));
329 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *)));
330
330
331 // Time
331 // Time
332 connect(timeWidget, SIGNAL(timeUpdated(SqpRange)), &sqpApp->timeController(),
332 connect(timeWidget, SIGNAL(timeUpdated(SqpRange)), &sqpApp->timeController(),
333 SLOT(onTimeToUpdate(SqpRange)));
333 SLOT(onTimeToUpdate(SqpRange)));
334
334
335 // Visualization
335 // Visualization
336 connect(&sqpApp->visualizationController(),
336 connect(&sqpApp->visualizationController(),
337 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
337 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
338 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
338 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
339
339
340 connect(&sqpApp->visualizationController(),
340 connect(&sqpApp->visualizationController(),
341 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpRange &)), m_Ui->view,
341 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpRange &)), m_Ui->view,
342 SLOT(onRangeChanged(std::shared_ptr<Variable>, const SqpRange &)));
342 SLOT(onRangeChanged(std::shared_ptr<Variable>, const SqpRange &)));
343
343
344 // Widgets / widgets connections
344 // Widgets / widgets connections
345
345
346 // For the following connections, we use DirectConnection to allow each widget that can
346 // For the following connections, we use DirectConnection to allow each widget that can
347 // potentially attach a menu to the variable's menu to do so before this menu is displayed.
347 // potentially attach a menu to the variable's menu to do so before this menu is displayed.
348 // The order of connections is also important, since it determines the order in which each
348 // The order of connections is also important, since it determines the order in which each
349 // widget will attach its menu
349 // widget will attach its menu
350 connect(
350 connect(
351 m_Ui->variableInspectorWidget,
351 m_Ui->variableInspectorWidget,
352 SIGNAL(tableMenuAboutToBeDisplayed(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
352 SIGNAL(tableMenuAboutToBeDisplayed(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
353 m_Ui->view, SLOT(attachVariableMenu(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
353 m_Ui->view, SLOT(attachVariableMenu(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
354 Qt::DirectConnection);
354 Qt::DirectConnection);
355 }
355 }
356
356
357 MainWindow::~MainWindow()
357 MainWindow::~MainWindow()
358 {
358 {
359 }
359 }
360
360
361 void MainWindow::changeEvent(QEvent *e)
361 void MainWindow::changeEvent(QEvent *e)
362 {
362 {
363 QMainWindow::changeEvent(e);
363 QMainWindow::changeEvent(e);
364 switch (e->type()) {
364 switch (e->type()) {
365 case QEvent::LanguageChange:
365 case QEvent::LanguageChange:
366 m_Ui->retranslateUi(this);
366 m_Ui->retranslateUi(this);
367 break;
367 break;
368 default:
368 default:
369 break;
369 break;
370 }
370 }
371 }
371 }
372
372
373 void MainWindow::closeEvent(QCloseEvent *event)
373 void MainWindow::closeEvent(QCloseEvent *event)
374 {
374 {
375 if (!impl->checkDataToSave(this)) {
375 if (!impl->checkDataToSave(this)) {
376 event->ignore();
376 event->ignore();
377 }
377 }
378 else {
378 else {
379 event->accept();
379 event->accept();
380 }
380 }
381 }
381 }
382
382
383 bool MainWindow::MainWindowPrivate::checkDataToSave(QWidget *parentWidget)
383 bool MainWindow::MainWindowPrivate::checkDataToSave(QWidget *parentWidget)
384 {
384 {
385 auto hasChanges = sqpApp->catalogueController().hasChanges();
385 auto hasChanges = sqpApp->catalogueController().hasChanges();
386 if (hasChanges) {
386 if (hasChanges) {
387 // There are some unsaved changes
387 // There are some unsaved changes
388 switch (QMessageBox::question(
388 switch (QMessageBox::question(
389 parentWidget, "Save changes",
389 parentWidget, tr("Save changes"),
390 tr("The catalogue controller unsaved changes.\nDo you want to save them ?"),
390 tr("The catalogue controller has unsaved changes.\nDo you want to save them ?"),
391 QMessageBox::SaveAll | QMessageBox::Discard | QMessageBox::Cancel,
391 QMessageBox::SaveAll | QMessageBox::Discard | QMessageBox::Cancel,
392 QMessageBox::SaveAll)) {
392 QMessageBox::SaveAll)) {
393 case QMessageBox::SaveAll:
393 case QMessageBox::SaveAll:
394 sqpApp->catalogueController().saveAll();
394 sqpApp->catalogueController().saveAll();
395 break;
395 break;
396 case QMessageBox::Discard:
396 case QMessageBox::Discard:
397 break;
397 break;
398 case QMessageBox::Cancel:
398 case QMessageBox::Cancel:
399 default:
399 default:
400 return false;
400 return false;
401 }
401 }
402 }
402 }
403
403
404 return true;
404 return true;
405 }
405 }
@@ -1,470 +1,470
1 #include "Catalogue/CatalogueEventsWidget.h"
1 #include "Catalogue/CatalogueEventsWidget.h"
2 #include "ui_CatalogueEventsWidget.h"
2 #include "ui_CatalogueEventsWidget.h"
3
3
4 #include <Catalogue/CatalogueController.h>
4 #include <Catalogue/CatalogueController.h>
5 #include <Catalogue/CatalogueEventsModel.h>
5 #include <Catalogue/CatalogueEventsModel.h>
6 #include <Catalogue/CatalogueExplorerHelper.h>
6 #include <Catalogue/CatalogueExplorerHelper.h>
7 #include <CatalogueDao.h>
7 #include <CatalogueDao.h>
8 #include <DBCatalogue.h>
8 #include <DBCatalogue.h>
9 #include <SqpApplication.h>
9 #include <SqpApplication.h>
10 #include <Visualization/VisualizationTabWidget.h>
10 #include <Visualization/VisualizationTabWidget.h>
11 #include <Visualization/VisualizationWidget.h>
11 #include <Visualization/VisualizationWidget.h>
12 #include <Visualization/VisualizationZoneWidget.h>
12 #include <Visualization/VisualizationZoneWidget.h>
13
13
14 #include <QDialog>
14 #include <QDialog>
15 #include <QDialogButtonBox>
15 #include <QDialogButtonBox>
16 #include <QListWidget>
16 #include <QListWidget>
17 #include <QMessageBox>
17 #include <QMessageBox>
18
18
19 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
19 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
20
20
21 /// Fixed size of the validation column
21 /// Fixed size of the validation column
22 const auto VALIDATION_COLUMN_SIZE = 35;
22 const auto VALIDATION_COLUMN_SIZE = 35;
23
23
24 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
24 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
25
25
26 CatalogueEventsModel *m_Model = nullptr;
26 CatalogueEventsModel *m_Model = nullptr;
27 QStringList m_ZonesForTimeMode;
27 QStringList m_ZonesForTimeMode;
28 QString m_ZoneForGraphMode;
28 QString m_ZoneForGraphMode;
29 QVector<std::shared_ptr<DBCatalogue> > m_DisplayedCatalogues;
29 QVector<std::shared_ptr<DBCatalogue> > m_DisplayedCatalogues;
30 bool m_AllEventDisplayed = false;
30 bool m_AllEventDisplayed = false;
31
31
32 VisualizationWidget *m_VisualizationWidget = nullptr;
32 VisualizationWidget *m_VisualizationWidget = nullptr;
33
33
34 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events, CatalogueEventsWidget *widget)
34 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events, CatalogueEventsWidget *widget)
35 {
35 {
36 widget->ui->treeView->setSortingEnabled(false);
36 widget->ui->treeView->setSortingEnabled(false);
37 m_Model->setEvents(events);
37 m_Model->setEvents(events);
38 widget->ui->treeView->setSortingEnabled(true);
38 widget->ui->treeView->setSortingEnabled(true);
39
39
40 for (auto event : events) {
40 for (auto event : events) {
41 if (sqpApp->catalogueController().eventHasChanges(event)) {
41 if (sqpApp->catalogueController().eventHasChanges(event)) {
42 auto index = m_Model->indexOf(event);
42 auto index = m_Model->indexOf(event);
43 widget->setEventChanges(event, true);
43 widget->setEventChanges(event, true);
44 }
44 }
45 }
45 }
46 }
46 }
47
47
48 void addEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
48 void addEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
49 {
49 {
50 treeView->setSortingEnabled(false);
50 treeView->setSortingEnabled(false);
51 m_Model->addEvent(event);
51 m_Model->addEvent(event);
52 treeView->setSortingEnabled(true);
52 treeView->setSortingEnabled(true);
53 }
53 }
54
54
55 void removeEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
55 void removeEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
56 {
56 {
57 treeView->setSortingEnabled(false);
57 treeView->setSortingEnabled(false);
58 m_Model->removeEvent(event);
58 m_Model->removeEvent(event);
59 treeView->setSortingEnabled(true);
59 treeView->setSortingEnabled(true);
60 }
60 }
61
61
62 QStringList getAvailableVisualizationZoneList() const
62 QStringList getAvailableVisualizationZoneList() const
63 {
63 {
64 if (m_VisualizationWidget) {
64 if (m_VisualizationWidget) {
65 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
65 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
66 return tab->availableZoneWidgets();
66 return tab->availableZoneWidgets();
67 }
67 }
68 }
68 }
69
69
70 return QStringList{};
70 return QStringList{};
71 }
71 }
72
72
73 QStringList selectZone(QWidget *parent, const QStringList &selectedZones,
73 QStringList selectZone(QWidget *parent, const QStringList &selectedZones,
74 bool allowMultiSelection, const QPoint &location)
74 bool allowMultiSelection, const QPoint &location)
75 {
75 {
76 auto availableZones = getAvailableVisualizationZoneList();
76 auto availableZones = getAvailableVisualizationZoneList();
77 if (availableZones.isEmpty()) {
77 if (availableZones.isEmpty()) {
78 return QStringList{};
78 return QStringList{};
79 }
79 }
80
80
81 QDialog d(parent, Qt::Tool);
81 QDialog d(parent, Qt::Tool);
82 d.setWindowTitle("Choose a zone");
82 d.setWindowTitle("Choose a zone");
83 auto layout = new QVBoxLayout{&d};
83 auto layout = new QVBoxLayout{&d};
84 layout->setContentsMargins(0, 0, 0, 0);
84 layout->setContentsMargins(0, 0, 0, 0);
85 auto listWidget = new QListWidget{&d};
85 auto listWidget = new QListWidget{&d};
86 layout->addWidget(listWidget);
86 layout->addWidget(listWidget);
87
87
88 QSet<QListWidgetItem *> checkedItems;
88 QSet<QListWidgetItem *> checkedItems;
89 for (auto zone : availableZones) {
89 for (auto zone : availableZones) {
90 auto item = new QListWidgetItem{zone};
90 auto item = new QListWidgetItem{zone};
91 item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
91 item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
92 if (selectedZones.contains(zone)) {
92 if (selectedZones.contains(zone)) {
93 item->setCheckState(Qt::Checked);
93 item->setCheckState(Qt::Checked);
94 checkedItems << item;
94 checkedItems << item;
95 }
95 }
96 else {
96 else {
97 item->setCheckState(Qt::Unchecked);
97 item->setCheckState(Qt::Unchecked);
98 }
98 }
99
99
100 listWidget->addItem(item);
100 listWidget->addItem(item);
101 }
101 }
102
102
103 auto buttonBox = new QDialogButtonBox{QDialogButtonBox::Ok, &d};
103 auto buttonBox = new QDialogButtonBox{QDialogButtonBox::Ok, &d};
104 layout->addWidget(buttonBox);
104 layout->addWidget(buttonBox);
105
105
106 QObject::connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept);
106 QObject::connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept);
107 QObject::connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject);
107 QObject::connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject);
108
108
109 QObject::connect(listWidget, &QListWidget::itemChanged,
109 QObject::connect(listWidget, &QListWidget::itemChanged,
110 [&checkedItems, allowMultiSelection, listWidget](auto item) {
110 [&checkedItems, allowMultiSelection, listWidget](auto item) {
111 if (item->checkState() == Qt::Checked) {
111 if (item->checkState() == Qt::Checked) {
112 if (!allowMultiSelection) {
112 if (!allowMultiSelection) {
113 for (auto checkedItem : checkedItems) {
113 for (auto checkedItem : checkedItems) {
114 listWidget->blockSignals(true);
114 listWidget->blockSignals(true);
115 checkedItem->setCheckState(Qt::Unchecked);
115 checkedItem->setCheckState(Qt::Unchecked);
116 listWidget->blockSignals(false);
116 listWidget->blockSignals(false);
117 }
117 }
118
118
119 checkedItems.clear();
119 checkedItems.clear();
120 }
120 }
121 checkedItems << item;
121 checkedItems << item;
122 }
122 }
123 else {
123 else {
124 checkedItems.remove(item);
124 checkedItems.remove(item);
125 }
125 }
126 });
126 });
127
127
128 QStringList result;
128 QStringList result;
129
129
130 d.setMinimumWidth(120);
130 d.setMinimumWidth(120);
131 d.resize(d.minimumSizeHint());
131 d.resize(d.minimumSizeHint());
132 d.move(location);
132 d.move(location);
133 if (d.exec() == QDialog::Accepted) {
133 if (d.exec() == QDialog::Accepted) {
134 for (auto item : checkedItems) {
134 for (auto item : checkedItems) {
135 result += item->text();
135 result += item->text();
136 }
136 }
137 }
137 }
138 else {
138 else {
139 result = selectedZones;
139 result = selectedZones;
140 }
140 }
141
141
142 return result;
142 return result;
143 }
143 }
144
144
145 void updateForTimeMode(QTreeView *treeView)
145 void updateForTimeMode(QTreeView *treeView)
146 {
146 {
147 auto selectedRows = treeView->selectionModel()->selectedRows();
147 auto selectedRows = treeView->selectionModel()->selectedRows();
148
148
149 if (selectedRows.count() == 1) {
149 if (selectedRows.count() == 1) {
150 auto event = m_Model->getEvent(selectedRows.first());
150 auto event = m_Model->getEvent(selectedRows.first());
151 if (event) {
151 if (event) {
152 if (m_VisualizationWidget) {
152 if (m_VisualizationWidget) {
153 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
153 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
154
154
155 for (auto zoneName : m_ZonesForTimeMode) {
155 for (auto zoneName : m_ZonesForTimeMode) {
156 if (auto zone = tab->getZoneWithName(zoneName)) {
156 if (auto zone = tab->getZoneWithName(zoneName)) {
157 SqpRange eventRange;
157 SqpRange eventRange;
158 eventRange.m_TStart = event->getTStart();
158 eventRange.m_TStart = event->getTStart();
159 eventRange.m_TEnd = event->getTEnd();
159 eventRange.m_TEnd = event->getTEnd();
160 zone->setZoneRange(eventRange);
160 zone->setZoneRange(eventRange);
161 }
161 }
162 }
162 }
163 }
163 }
164 else {
164 else {
165 qCWarning(LOG_CatalogueEventsWidget())
165 qCWarning(LOG_CatalogueEventsWidget())
166 << "updateTimeZone: no tab found in the visualization";
166 << "updateTimeZone: no tab found in the visualization";
167 }
167 }
168 }
168 }
169 else {
169 else {
170 qCWarning(LOG_CatalogueEventsWidget())
170 qCWarning(LOG_CatalogueEventsWidget())
171 << "updateTimeZone: visualization widget not found";
171 << "updateTimeZone: visualization widget not found";
172 }
172 }
173 }
173 }
174 }
174 }
175 else {
175 else {
176 qCWarning(LOG_CatalogueEventsWidget())
176 qCWarning(LOG_CatalogueEventsWidget())
177 << "updateTimeZone: not compatible with multiple events selected";
177 << "updateTimeZone: not compatible with multiple events selected";
178 }
178 }
179 }
179 }
180
180
181 void updateForGraphMode(QTreeView *treeView)
181 void updateForGraphMode(QTreeView *treeView)
182 {
182 {
183 auto selectedRows = treeView->selectionModel()->selectedRows();
183 auto selectedRows = treeView->selectionModel()->selectedRows();
184
184
185 if (selectedRows.count() == 1) {
185 if (selectedRows.count() == 1) {
186 auto event = m_Model->getEvent(selectedRows.first());
186 auto event = m_Model->getEvent(selectedRows.first());
187 if (m_VisualizationWidget) {
187 if (m_VisualizationWidget) {
188 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
188 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
189 if (auto zone = tab->getZoneWithName(m_ZoneForGraphMode)) {
189 if (auto zone = tab->getZoneWithName(m_ZoneForGraphMode)) {
190 // TODO
190 // TODO
191 }
191 }
192 }
192 }
193 else {
193 else {
194 qCWarning(LOG_CatalogueEventsWidget())
194 qCWarning(LOG_CatalogueEventsWidget())
195 << "updateGraphMode: no tab found in the visualization";
195 << "updateGraphMode: no tab found in the visualization";
196 }
196 }
197 }
197 }
198 else {
198 else {
199 qCWarning(LOG_CatalogueEventsWidget())
199 qCWarning(LOG_CatalogueEventsWidget())
200 << "updateGraphMode: visualization widget not found";
200 << "updateGraphMode: visualization widget not found";
201 }
201 }
202 }
202 }
203 else {
203 else {
204 qCWarning(LOG_CatalogueEventsWidget())
204 qCWarning(LOG_CatalogueEventsWidget())
205 << "updateGraphMode: not compatible with multiple events selected";
205 << "updateGraphMode: not compatible with multiple events selected";
206 }
206 }
207 }
207 }
208
208
209 void getSelectedItems(
209 void getSelectedItems(
210 QTreeView *treeView, QVector<std::shared_ptr<DBEvent> > &events,
210 QTreeView *treeView, QVector<std::shared_ptr<DBEvent> > &events,
211 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > &eventProducts)
211 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > &eventProducts)
212 {
212 {
213 for (auto rowIndex : treeView->selectionModel()->selectedRows()) {
213 for (auto rowIndex : treeView->selectionModel()->selectedRows()) {
214 auto itemType = m_Model->itemTypeOf(rowIndex);
214 auto itemType = m_Model->itemTypeOf(rowIndex);
215 if (itemType == CatalogueEventsModel::ItemType::Event) {
215 if (itemType == CatalogueEventsModel::ItemType::Event) {
216 events << m_Model->getEvent(rowIndex);
216 events << m_Model->getEvent(rowIndex);
217 }
217 }
218 else if (itemType == CatalogueEventsModel::ItemType::EventProduct) {
218 else if (itemType == CatalogueEventsModel::ItemType::EventProduct) {
219 eventProducts << qMakePair(m_Model->getParentEvent(rowIndex),
219 eventProducts << qMakePair(m_Model->getParentEvent(rowIndex),
220 m_Model->getEventProduct(rowIndex));
220 m_Model->getEventProduct(rowIndex));
221 }
221 }
222 }
222 }
223 }
223 }
224 };
224 };
225
225
226 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
226 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
227 : QWidget(parent),
227 : QWidget(parent),
228 ui(new Ui::CatalogueEventsWidget),
228 ui(new Ui::CatalogueEventsWidget),
229 impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()}
229 impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()}
230 {
230 {
231 ui->setupUi(this);
231 ui->setupUi(this);
232
232
233 impl->m_Model = new CatalogueEventsModel{this};
233 impl->m_Model = new CatalogueEventsModel{this};
234 ui->treeView->setModel(impl->m_Model);
234 ui->treeView->setModel(impl->m_Model);
235
235
236 ui->treeView->setSortingEnabled(true);
236 ui->treeView->setSortingEnabled(true);
237 ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
237 ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
238 ui->treeView->setDragEnabled(true);
238 ui->treeView->setDragEnabled(true);
239
239
240 connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) {
240 connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) {
241 if (checked) {
241 if (checked) {
242 ui->btnChart->setChecked(false);
242 ui->btnChart->setChecked(false);
243 impl->m_ZonesForTimeMode
243 impl->m_ZonesForTimeMode
244 = impl->selectZone(this, impl->m_ZonesForTimeMode, true,
244 = impl->selectZone(this, impl->m_ZonesForTimeMode, true,
245 this->mapToGlobal(ui->btnTime->frameGeometry().center()));
245 this->mapToGlobal(ui->btnTime->frameGeometry().center()));
246
246
247 impl->updateForTimeMode(ui->treeView);
247 impl->updateForTimeMode(ui->treeView);
248 }
248 }
249 });
249 });
250
250
251 connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) {
251 connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) {
252 if (checked) {
252 if (checked) {
253 ui->btnTime->setChecked(false);
253 ui->btnTime->setChecked(false);
254 impl->m_ZoneForGraphMode
254 impl->m_ZoneForGraphMode
255 = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false,
255 = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false,
256 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
256 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
257 .value(0);
257 .value(0);
258
258
259 impl->updateForGraphMode(ui->treeView);
259 impl->updateForGraphMode(ui->treeView);
260 }
260 }
261 });
261 });
262
262
263 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
263 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
264 QVector<std::shared_ptr<DBEvent> > events;
264 QVector<std::shared_ptr<DBEvent> > events;
265 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
265 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
266 impl->getSelectedItems(ui->treeView, events, eventProducts);
266 impl->getSelectedItems(ui->treeView, events, eventProducts);
267
267
268 if (!events.isEmpty() && eventProducts.isEmpty()) {
268 if (!events.isEmpty() && eventProducts.isEmpty()) {
269
269
270 if (QMessageBox::warning(this, tr("Remove Event(s)"),
270 if (QMessageBox::warning(this, tr("Remove Event(s)"),
271 tr("The selected event(s) will be completly removed "
271 tr("The selected event(s) will be permanently removed "
272 "from the repository!\nAre you sure you want to continue?"),
272 "from the repository!\nAre you sure you want to continue?"),
273 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
273 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
274 == QMessageBox::Yes) {
274 == QMessageBox::Yes) {
275
275
276 for (auto event : events) {
276 for (auto event : events) {
277 sqpApp->catalogueController().removeEvent(event);
277 sqpApp->catalogueController().removeEvent(event);
278 impl->removeEvent(event, ui->treeView);
278 impl->removeEvent(event, ui->treeView);
279 }
279 }
280 }
280 }
281 }
281 }
282 });
282 });
283
283
284 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueEventsWidget::emitSelection);
284 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueEventsWidget::emitSelection);
285 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
285 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
286 &CatalogueEventsWidget::emitSelection);
286 &CatalogueEventsWidget::emitSelection);
287
287
288 ui->btnRemove->setEnabled(false); // Disabled by default when nothing is selected
288 ui->btnRemove->setEnabled(false); // Disabled by default when nothing is selected
289 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
289 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
290 auto isNotMultiSelection = ui->treeView->selectionModel()->selectedRows().count() <= 1;
290 auto isNotMultiSelection = ui->treeView->selectionModel()->selectedRows().count() <= 1;
291 ui->btnChart->setEnabled(isNotMultiSelection);
291 ui->btnChart->setEnabled(isNotMultiSelection);
292 ui->btnTime->setEnabled(isNotMultiSelection);
292 ui->btnTime->setEnabled(isNotMultiSelection);
293
293
294 if (isNotMultiSelection && ui->btnTime->isChecked()) {
294 if (isNotMultiSelection && ui->btnTime->isChecked()) {
295 impl->updateForTimeMode(ui->treeView);
295 impl->updateForTimeMode(ui->treeView);
296 }
296 }
297 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
297 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
298 impl->updateForGraphMode(ui->treeView);
298 impl->updateForGraphMode(ui->treeView);
299 }
299 }
300
300
301 QVector<std::shared_ptr<DBEvent> > events;
301 QVector<std::shared_ptr<DBEvent> > events;
302 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
302 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
303 impl->getSelectedItems(ui->treeView, events, eventProducts);
303 impl->getSelectedItems(ui->treeView, events, eventProducts);
304 ui->btnRemove->setEnabled(!events.isEmpty() && eventProducts.isEmpty());
304 ui->btnRemove->setEnabled(!events.isEmpty() && eventProducts.isEmpty());
305 });
305 });
306
306
307 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
307 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
308 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Tags,
308 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Tags,
309 QHeaderView::Stretch);
309 QHeaderView::Stretch);
310 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Validation,
310 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Validation,
311 QHeaderView::Fixed);
311 QHeaderView::Fixed);
312 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Name,
312 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Name,
313 QHeaderView::Interactive);
313 QHeaderView::Interactive);
314 ui->treeView->header()->resizeSection((int)CatalogueEventsModel::Column::Validation,
314 ui->treeView->header()->resizeSection((int)CatalogueEventsModel::Column::Validation,
315 VALIDATION_COLUMN_SIZE);
315 VALIDATION_COLUMN_SIZE);
316 ui->treeView->header()->setSortIndicatorShown(true);
316 ui->treeView->header()->setSortIndicatorShown(true);
317
317
318 connect(impl->m_Model, &CatalogueEventsModel::modelSorted, [this]() {
318 connect(impl->m_Model, &CatalogueEventsModel::modelSorted, [this]() {
319 auto allEvents = impl->m_Model->events();
319 auto allEvents = impl->m_Model->events();
320 for (auto event : allEvents) {
320 for (auto event : allEvents) {
321 setEventChanges(event, sqpApp->catalogueController().eventHasChanges(event));
321 setEventChanges(event, sqpApp->catalogueController().eventHasChanges(event));
322 }
322 }
323 });
323 });
324
324
325 populateWithAllEvents();
325 populateWithAllEvents();
326 }
326 }
327
327
328 CatalogueEventsWidget::~CatalogueEventsWidget()
328 CatalogueEventsWidget::~CatalogueEventsWidget()
329 {
329 {
330 delete ui;
330 delete ui;
331 }
331 }
332
332
333 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization)
333 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization)
334 {
334 {
335 impl->m_VisualizationWidget = visualization;
335 impl->m_VisualizationWidget = visualization;
336 }
336 }
337
337
338 void CatalogueEventsWidget::addEvent(const std::shared_ptr<DBEvent> &event)
338 void CatalogueEventsWidget::addEvent(const std::shared_ptr<DBEvent> &event)
339 {
339 {
340 impl->addEvent(event, ui->treeView);
340 impl->addEvent(event, ui->treeView);
341 }
341 }
342
342
343 void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges)
343 void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges)
344 {
344 {
345 impl->m_Model->refreshEvent(event);
345 impl->m_Model->refreshEvent(event);
346
346
347 auto eventIndex = impl->m_Model->indexOf(event);
347 auto eventIndex = impl->m_Model->indexOf(event);
348 auto validationIndex
348 auto validationIndex
349 = eventIndex.sibling(eventIndex.row(), (int)CatalogueEventsModel::Column::Validation);
349 = eventIndex.sibling(eventIndex.row(), (int)CatalogueEventsModel::Column::Validation);
350
350
351 if (validationIndex.isValid()) {
351 if (validationIndex.isValid()) {
352 if (hasChanges) {
352 if (hasChanges) {
353 if (ui->treeView->indexWidget(validationIndex) == nullptr) {
353 if (ui->treeView->indexWidget(validationIndex) == nullptr) {
354 auto widget = CatalogueExplorerHelper::buildValidationWidget(
354 auto widget = CatalogueExplorerHelper::buildValidationWidget(
355 ui->treeView,
355 ui->treeView,
356 [this, event]() {
356 [this, event]() {
357 sqpApp->catalogueController().saveEvent(event);
357 sqpApp->catalogueController().saveEvent(event);
358 setEventChanges(event, false);
358 setEventChanges(event, false);
359 },
359 },
360 [this, event]() {
360 [this, event]() {
361 bool removed = false;
361 bool removed = false;
362 sqpApp->catalogueController().discardEvent(event, removed);
362 sqpApp->catalogueController().discardEvent(event, removed);
363 if (removed) {
363 if (removed) {
364 impl->m_Model->removeEvent(event);
364 impl->m_Model->removeEvent(event);
365 }
365 }
366 else {
366 else {
367 setEventChanges(event, false);
367 setEventChanges(event, false);
368 impl->m_Model->refreshEvent(event, true);
368 impl->m_Model->refreshEvent(event, true);
369 }
369 }
370 emitSelection();
370 emitSelection();
371 });
371 });
372 ui->treeView->setIndexWidget(validationIndex, widget);
372 ui->treeView->setIndexWidget(validationIndex, widget);
373 }
373 }
374 }
374 }
375 else {
375 else {
376 // Note: the widget is destroyed
376 // Note: the widget is destroyed
377 ui->treeView->setIndexWidget(validationIndex, nullptr);
377 ui->treeView->setIndexWidget(validationIndex, nullptr);
378 }
378 }
379 }
379 }
380 else {
380 else {
381 qCWarning(LOG_CatalogueEventsWidget())
381 qCWarning(LOG_CatalogueEventsWidget())
382 << "setEventChanges: the event is not displayed in the model.";
382 << "setEventChanges: the event is not displayed in the model.";
383 }
383 }
384 }
384 }
385
385
386 QVector<std::shared_ptr<DBCatalogue> > CatalogueEventsWidget::displayedCatalogues() const
386 QVector<std::shared_ptr<DBCatalogue> > CatalogueEventsWidget::displayedCatalogues() const
387 {
387 {
388 return impl->m_DisplayedCatalogues;
388 return impl->m_DisplayedCatalogues;
389 }
389 }
390
390
391 bool CatalogueEventsWidget::isAllEventsDisplayed() const
391 bool CatalogueEventsWidget::isAllEventsDisplayed() const
392 {
392 {
393 return impl->m_AllEventDisplayed;
393 return impl->m_AllEventDisplayed;
394 }
394 }
395
395
396 bool CatalogueEventsWidget::isEventDisplayed(const std::shared_ptr<DBEvent> &event) const
396 bool CatalogueEventsWidget::isEventDisplayed(const std::shared_ptr<DBEvent> &event) const
397 {
397 {
398 return impl->m_Model->indexOf(event).isValid();
398 return impl->m_Model->indexOf(event).isValid();
399 }
399 }
400
400
401 void CatalogueEventsWidget::populateWithCatalogues(
401 void CatalogueEventsWidget::populateWithCatalogues(
402 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
402 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
403 {
403 {
404 impl->m_DisplayedCatalogues = catalogues;
404 impl->m_DisplayedCatalogues = catalogues;
405 impl->m_AllEventDisplayed = false;
405 impl->m_AllEventDisplayed = false;
406
406
407 QSet<QUuid> eventIds;
407 QSet<QUuid> eventIds;
408 QVector<std::shared_ptr<DBEvent> > events;
408 QVector<std::shared_ptr<DBEvent> > events;
409
409
410 for (auto catalogue : catalogues) {
410 for (auto catalogue : catalogues) {
411 auto catalogueEvents = sqpApp->catalogueController().retrieveEventsFromCatalogue(catalogue);
411 auto catalogueEvents = sqpApp->catalogueController().retrieveEventsFromCatalogue(catalogue);
412 for (auto event : catalogueEvents) {
412 for (auto event : catalogueEvents) {
413 if (!eventIds.contains(event->getUniqId())) {
413 if (!eventIds.contains(event->getUniqId())) {
414 events << event;
414 events << event;
415 eventIds.insert(event->getUniqId());
415 eventIds.insert(event->getUniqId());
416 }
416 }
417 }
417 }
418 }
418 }
419
419
420 impl->setEvents(events, this);
420 impl->setEvents(events, this);
421 }
421 }
422
422
423 void CatalogueEventsWidget::populateWithAllEvents()
423 void CatalogueEventsWidget::populateWithAllEvents()
424 {
424 {
425 impl->m_DisplayedCatalogues.clear();
425 impl->m_DisplayedCatalogues.clear();
426 impl->m_AllEventDisplayed = true;
426 impl->m_AllEventDisplayed = true;
427
427
428 auto allEvents = sqpApp->catalogueController().retrieveAllEvents();
428 auto allEvents = sqpApp->catalogueController().retrieveAllEvents();
429
429
430 QVector<std::shared_ptr<DBEvent> > events;
430 QVector<std::shared_ptr<DBEvent> > events;
431 for (auto event : allEvents) {
431 for (auto event : allEvents) {
432 events << event;
432 events << event;
433 }
433 }
434
434
435 impl->setEvents(events, this);
435 impl->setEvents(events, this);
436 }
436 }
437
437
438 void CatalogueEventsWidget::clear()
438 void CatalogueEventsWidget::clear()
439 {
439 {
440 impl->m_DisplayedCatalogues.clear();
440 impl->m_DisplayedCatalogues.clear();
441 impl->m_AllEventDisplayed = false;
441 impl->m_AllEventDisplayed = false;
442 impl->setEvents({}, this);
442 impl->setEvents({}, this);
443 }
443 }
444
444
445 void CatalogueEventsWidget::refresh()
445 void CatalogueEventsWidget::refresh()
446 {
446 {
447 if (isAllEventsDisplayed()) {
447 if (isAllEventsDisplayed()) {
448 populateWithAllEvents();
448 populateWithAllEvents();
449 }
449 }
450 else if (!impl->m_DisplayedCatalogues.isEmpty()) {
450 else if (!impl->m_DisplayedCatalogues.isEmpty()) {
451 populateWithCatalogues(impl->m_DisplayedCatalogues);
451 populateWithCatalogues(impl->m_DisplayedCatalogues);
452 }
452 }
453 }
453 }
454
454
455 void CatalogueEventsWidget::emitSelection()
455 void CatalogueEventsWidget::emitSelection()
456 {
456 {
457 QVector<std::shared_ptr<DBEvent> > events;
457 QVector<std::shared_ptr<DBEvent> > events;
458 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
458 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
459 impl->getSelectedItems(ui->treeView, events, eventProducts);
459 impl->getSelectedItems(ui->treeView, events, eventProducts);
460
460
461 if (!events.isEmpty() && eventProducts.isEmpty()) {
461 if (!events.isEmpty() && eventProducts.isEmpty()) {
462 emit eventsSelected(events);
462 emit eventsSelected(events);
463 }
463 }
464 else if (events.isEmpty() && !eventProducts.isEmpty()) {
464 else if (events.isEmpty() && !eventProducts.isEmpty()) {
465 emit eventProductsSelected(eventProducts);
465 emit eventProductsSelected(eventProducts);
466 }
466 }
467 else {
467 else {
468 emit selectionCleared();
468 emit selectionCleared();
469 }
469 }
470 }
470 }
General Comments 0
You need to be logged in to leave comments. Login now