##// END OF EJS Templates
Ported MockPlugin to new Variable2 impl and added dummy python plugin...
jeandet -
r1423:31110df2feb2
parent child
Show More
@@ -0,0 +1,26
1 include_directories(include)
2 FILE (GLOB_RECURSE python_providers
3 include/*.h
4 src/*.cpp
5 resources/*.qrc
6 )
7
8 add_definitions(-DQT_PLUGIN)
9 add_definitions(-DSCIQLOP_PLUGIN_JSON_FILE_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/python_providers.json")
10 if(NOT BUILD_SHARED_LIBS)
11 add_definitions(-DQT_STATICPLUGIN)
12 endif()
13
14 add_library(python_providers ${python_providers})
15 SET_TARGET_PROPERTIES(python_providers PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
16
17 target_link_libraries(python_providers PUBLIC sciqlopgui)
18 target_link_libraries(python_providers PRIVATE pybind11::embed)
19 ADD_DEFINITIONS(-DQT_NO_KEYWORDS)
20 install(TARGETS python_providers
21 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/SciQlop
22 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/SciQlop
23 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
24
25 include(sciqlop_tests)
26
@@ -0,0 +1,25
1 #ifndef PYTHON_PROVIDERS_H
2 #define PYTHON_PROVIDERS_H
3
4 #include <Plugin/IPlugin.h>
5
6
7 #include <memory>
8
9 #ifndef SCIQLOP_PLUGIN_JSON_FILE_PATH
10 #define SCIQLOP_PLUGIN_JSON_FILE_PATH "python_providers.json"
11 #endif
12
13 class DataSourceItem;
14
15 class PythonProviders : public QObject, public IPlugin
16 {
17 Q_OBJECT
18 Q_INTERFACES(IPlugin)
19 Q_PLUGIN_METADATA(IID "sciqlop.plugin.IPlugin" FILE SCIQLOP_PLUGIN_JSON_FILE_PATH)
20 public:
21 /// @sa IPlugin::initialize()
22 void initialize() override;
23 };
24
25 #endif // PYTHON_PROVIDERS_H
@@ -0,0 +1,3
1 {
2 "name" : "python_providers"
3 }
@@ -0,0 +1,9
1 #include "python_providers.h"
2 #include <pybind11/embed.h>
3 namespace py = pybind11;
4
5 void PythonProviders::initialize()
6 {
7 py::scoped_interpreter guard {};
8 py::print("Hello, World!");
9 }
@@ -1,41 +1,42
1 include_directories(include)
1 include_directories(include)
2
2
3 FILE (GLOB_RECURSE app_SRCS
3 FILE (GLOB_RECURSE app_SRCS
4 include/*.h
4 include/*.h
5 src/*.cpp
5 src/*.cpp
6 resources/*.qrc
6 resources/*.qrc
7 )
7 )
8
8
9 QT5_WRAP_UI(UiGenerated_SRCS
9 QT5_WRAP_UI(UiGenerated_SRCS
10 ui/MainWindow.ui
10 ui/MainWindow.ui
11 )
11 )
12
12
13 add_executable(sciqlopapp WIN32 ${app_SRCS} ${UiGenerated_SRCS})
13 add_executable(sciqlopapp WIN32 ${app_SRCS} ${UiGenerated_SRCS})
14 if(NOT BUILD_SHARED_LIBS)
14 if(NOT BUILD_SHARED_LIBS)
15 add_definitions(-DQT_STATICPLUGIN)
15 add_definitions(-DQT_STATICPLUGIN)
16 if(BUILD_PLUGINS)
16 if(BUILD_PLUGINS)
17 target_link_libraries(sciqlopapp mockplugin)
17 target_link_libraries(sciqlopapp mockplugin)
18 target_link_libraries(sciqlopapp amdaplugin)
18 #target_link_libraries(sciqlopapp amdaplugin)
19 target_link_libraries(sciqlopapp python_providers)
19 endif()
20 endif()
20 endif()
21 endif()
21
22
22 if(NOT BUILD_PLUGINS)
23 if(NOT BUILD_PLUGINS)
23 add_definitions(-DSQP_NO_PLUGINS)
24 add_definitions(-DSQP_NO_PLUGINS)
24 endif()
25 endif()
25
26
26 target_link_libraries(sciqlopapp
27 target_link_libraries(sciqlopapp
27 Qt5::Core
28 Qt5::Core
28 Qt5::Widgets
29 Qt5::Widgets
29 Qt5::Network
30 Qt5::Network
30 Qt5::PrintSupport
31 Qt5::PrintSupport
31 Qt5::Svg
32 Qt5::Svg
32 sciqlopgui
33 sciqlopgui
33 sciqlopcore
34 sciqlopcore
34 )
35 )
35
36
36 install(TARGETS sciqlopapp DESTINATION ${CMAKE_INSTALL_BINDIR})
37 install(TARGETS sciqlopapp DESTINATION ${CMAKE_INSTALL_BINDIR})
37 install(FILES resources/SciQLOP.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications/)
38 install(FILES resources/SciQLOP.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications/)
38 install(FILES resources/SciQLOP.appdata.xml DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo/)
39 install(FILES resources/SciQLOP.appdata.xml DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo/)
39 install(FILES resources/sciqlopLOGO.svg DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/SciQLOP/icons/)
40 install(FILES resources/sciqlopLOGO.svg DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/SciQLOP/icons/)
40
41
41
42
@@ -1,99 +1,100
1 /*------------------------------------------------------------------------------
1 /*------------------------------------------------------------------------------
2 -- This file is a part of the QLop Software
2 -- This file is a part of the QLop Software
3 -- Copyright (C) 2015, Plasma Physics Laboratory - CNRS
3 -- Copyright (C) 2015, 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 <QProcessEnvironment>
23 #include <QProcessEnvironment>
24 #include <QThread>
24 #include <QThread>
25 #include <SqpApplication.h>
25 #include <SqpApplication.h>
26 #include <qglobal.h>
26 #include <qglobal.h>
27
27
28 #include <PluginManager/PluginManager.h>
28 #include <PluginManager/PluginManager.h>
29 #include <QDir>
29 #include <QDir>
30 #include <QtPlugin>
30 #include <QtPlugin>
31
31
32 #include <QLoggingCategory>
32 #include <QLoggingCategory>
33
33
34 Q_LOGGING_CATEGORY(LOG_Main, "Main")
34 Q_LOGGING_CATEGORY(LOG_Main, "Main")
35
35
36 namespace
36 namespace
37 {
37 {
38
38
39 const auto PLUGIN_DIRECTORY_NAME = QStringLiteral("plugins");
39 const auto PLUGIN_DIRECTORY_NAME = QStringLiteral("plugins");
40
40
41
41
42 } // namespace
42 } // namespace
43
43
44 int main(int argc, char* argv[])
44 int main(int argc, char* argv[])
45 {
45 {
46 #ifdef QT_STATICPLUGIN
46 #ifdef QT_STATICPLUGIN
47 #ifndef SQP_NO_PLUGINS
47 #ifndef SQP_NO_PLUGINS
48 Q_IMPORT_PLUGIN(MockPlugin)
48 Q_IMPORT_PLUGIN(MockPlugin)
49 Q_IMPORT_PLUGIN(AmdaPlugin)
49 Q_IMPORT_PLUGIN(PythonProviders)
50 Q_INIT_RESOURCE(amdaresources);
50 // Q_IMPORT_PLUGIN(AmdaPlugin)
51 // Q_INIT_RESOURCE(amdaresources);
51 #endif
52 #endif
52 #endif
53 #endif
53 Q_INIT_RESOURCE(sqpguiresources);
54 Q_INIT_RESOURCE(sqpguiresources);
54
55
55 SqpApplication::setOrganizationName("LPP");
56 SqpApplication::setOrganizationName("LPP");
56 SqpApplication::setOrganizationDomain("lpp.fr");
57 SqpApplication::setOrganizationDomain("lpp.fr");
57 SqpApplication::setApplicationName("SciQLop");
58 SqpApplication::setApplicationName("SciQLop");
58
59
59 QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
60 QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
60
61
61 SqpApplication a { argc, argv };
62 SqpApplication a { argc, argv };
62
63
63 MainWindow w;
64 MainWindow w;
64 w.show();
65 w.show();
65
66
66 // Loads plugins
67 // Loads plugins
67 auto pluginDir = QDir { a.applicationDirPath() };
68 auto pluginDir = QDir { a.applicationDirPath() };
68 auto pluginLookupPath = {
69 auto pluginLookupPath = {
69 #if _WIN32 || _WIN64
70 #if _WIN32 || _WIN64
70 a.applicationDirPath() + "/SciQLop"
71 a.applicationDirPath() + "/SciQLop"
71 #else
72 #else
72 a.applicationDirPath() + "/../lib64/SciQLop",
73 a.applicationDirPath() + "/../lib64/SciQLop",
73 a.applicationDirPath() + "/../lib64/sciqlop",
74 a.applicationDirPath() + "/../lib64/sciqlop",
74 a.applicationDirPath() + "/../lib/SciQLop",
75 a.applicationDirPath() + "/../lib/SciQLop",
75 a.applicationDirPath() + "/../lib/sciqlop",
76 a.applicationDirPath() + "/../lib/sciqlop",
76 #endif
77 #endif
77 };
78 };
78
79
79 #if _WIN32 || _WIN64
80 #if _WIN32 || _WIN64
80 pluginDir.mkdir(PLUGIN_DIRECTORY_NAME);
81 pluginDir.mkdir(PLUGIN_DIRECTORY_NAME);
81 pluginDir.cd(PLUGIN_DIRECTORY_NAME);
82 pluginDir.cd(PLUGIN_DIRECTORY_NAME);
82 #endif
83 #endif
83
84
84 PluginManager pluginManager {};
85 PluginManager pluginManager {};
85
86
86 for (auto&& path : pluginLookupPath)
87 for (auto&& path : pluginLookupPath)
87 {
88 {
88 QDir directory { path };
89 QDir directory { path };
89 if (directory.exists())
90 if (directory.exists())
90 {
91 {
91 qCDebug(LOG_Main())
92 qCDebug(LOG_Main())
92 << QObject::tr("Plugin directory: %1").arg(directory.absolutePath());
93 << QObject::tr("Plugin directory: %1").arg(directory.absolutePath());
93 pluginManager.loadPlugins(directory);
94 pluginManager.loadPlugins(directory);
94 }
95 }
95 }
96 }
96 pluginManager.loadStaticPlugins();
97 pluginManager.loadStaticPlugins();
97
98
98 return a.exec();
99 return a.exec();
99 }
100 }
@@ -1,395 +1,395
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 <Visualization/VisualizationController.h>
35 #include <Visualization/VisualizationController.h>
36
36
37 #include <QAction>
37 #include <QAction>
38 #include <QCloseEvent>
38 #include <QCloseEvent>
39 #include <QDate>
39 #include <QDate>
40 #include <QDir>
40 #include <QDir>
41 #include <QFileDialog>
41 #include <QFileDialog>
42 #include <QMessageBox>
42 #include <QMessageBox>
43 #include <QToolBar>
43 #include <QToolBar>
44 #include <QToolButton>
44 #include <QToolButton>
45 #include <memory.h>
45 #include <memory.h>
46
46
47 #include "iostream"
47 #include "iostream"
48
48
49 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
49 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
50
50
51 namespace
51 namespace
52 {
52 {
53 const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0;
53 const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0;
54 const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1;
54 const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1;
55 const auto VIEWPLITTERINDEX = 2;
55 const auto VIEWPLITTERINDEX = 2;
56 const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3;
56 const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3;
57 const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4;
57 const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4;
58 }
58 }
59
59
60 class MainWindow::MainWindowPrivate
60 class MainWindow::MainWindowPrivate
61 {
61 {
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 spacerLeftTop = new QWidget {};
97 auto spacerLeftTop = new QWidget {};
98 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
98 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
99
99
100 auto spacerLeftBottom = new QWidget {};
100 auto spacerLeftBottom = new QWidget {};
101 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
101 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
102
102
103
103
104 auto spacerRightTop = new QWidget {};
104 auto spacerRightTop = new QWidget {};
105 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
105 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
106
106
107 auto spacerRightBottom = new QWidget {};
107 auto spacerRightBottom = new QWidget {};
108 spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
108 spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
109
109
110
110
111 auto openInspector = [this](bool checked, bool right, auto action) {
111 auto openInspector = [this](bool checked, bool right, auto action) {
112 action->setIcon(
112 action->setIcon(
113 QIcon { (checked ^ right) ? ":/icones/next.png" : ":/icones/previous.png" });
113 QIcon { (checked ^ right) ? ":/icones/next.png" : ":/icones/previous.png" });
114
114
115 auto& lastInspectorSize
115 auto& lastInspectorSize
116 = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize;
116 = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize;
117
117
118 auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size()
118 auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size()
119 : m_Ui->leftMainInspectorWidget->size();
119 : m_Ui->leftMainInspectorWidget->size();
120
120
121 // Update of the last opened geometry
121 // Update of the last opened geometry
122 if (checked)
122 if (checked)
123 {
123 {
124 lastInspectorSize = nextInspectorSize;
124 lastInspectorSize = nextInspectorSize;
125 }
125 }
126
126
127 auto startSize = lastInspectorSize;
127 auto startSize = lastInspectorSize;
128 auto endSize = startSize;
128 auto endSize = startSize;
129 endSize.setWidth(0);
129 endSize.setWidth(0);
130
130
131 auto splitterInspectorIndex
131 auto splitterInspectorIndex
132 = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX;
132 = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX;
133
133
134 auto currentSizes = m_Ui->splitter->sizes();
134 auto currentSizes = m_Ui->splitter->sizes();
135 if (checked)
135 if (checked)
136 {
136 {
137 // adjust sizes individually here, e.g.
137 // adjust sizes individually here, e.g.
138 currentSizes[splitterInspectorIndex] -= lastInspectorSize.width();
138 currentSizes[splitterInspectorIndex] -= lastInspectorSize.width();
139 currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width();
139 currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width();
140 m_Ui->splitter->setSizes(currentSizes);
140 m_Ui->splitter->setSizes(currentSizes);
141 }
141 }
142 else
142 else
143 {
143 {
144 // adjust sizes individually here, e.g.
144 // adjust sizes individually here, e.g.
145 currentSizes[splitterInspectorIndex] += lastInspectorSize.width();
145 currentSizes[splitterInspectorIndex] += lastInspectorSize.width();
146 currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width();
146 currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width();
147 m_Ui->splitter->setSizes(currentSizes);
147 m_Ui->splitter->setSizes(currentSizes);
148 }
148 }
149 };
149 };
150
150
151
151
152 // //////////////// //
152 // //////////////// //
153 // Menu and Toolbar //
153 // Menu and Toolbar //
154 // //////////////// //
154 // //////////////// //
155 this->menuBar()->addAction(tr("File"));
155 this->menuBar()->addAction(tr("File"));
156 auto toolsMenu = this->menuBar()->addMenu(tr("Tools"));
156 auto toolsMenu = this->menuBar()->addMenu(tr("Tools"));
157 toolsMenu->addAction(tr("Settings..."), [this]() {
157 toolsMenu->addAction(tr("Settings..."), [this]() {
158 // Loads settings
158 // Loads settings
159 impl->m_SettingsDialog->loadSettings();
159 impl->m_SettingsDialog->loadSettings();
160
160
161 // Open settings dialog and save settings if the dialog is accepted
161 // Open settings dialog and save settings if the dialog is accepted
162 if (impl->m_SettingsDialog->exec() == QDialog::Accepted)
162 if (impl->m_SettingsDialog->exec() == QDialog::Accepted)
163 {
163 {
164 impl->m_SettingsDialog->saveSettings();
164 impl->m_SettingsDialog->saveSettings();
165 }
165 }
166 });
166 });
167
167
168 auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar"));
168 auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar"));
169
169
170 auto timeWidget = new TimeWidget {};
170 auto timeWidget = new TimeWidget {};
171 mainToolBar->addWidget(timeWidget);
171 mainToolBar->addWidget(timeWidget);
172
172
173 // Interaction modes
173 // Interaction modes
174 auto actionPointerMode = new QAction { QIcon(":/icones/pointer.png"), "Move", this };
174 auto actionPointerMode = new QAction { QIcon(":/icones/pointer.png"), "Move", this };
175 actionPointerMode->setCheckable(true);
175 actionPointerMode->setCheckable(true);
176 actionPointerMode->setChecked(
176 actionPointerMode->setChecked(
177 sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::None);
177 sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::None);
178 connect(actionPointerMode, &QAction::triggered,
178 connect(actionPointerMode, &QAction::triggered,
179 []() { sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::None); });
179 []() { sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::None); });
180
180
181 auto actionZoomMode = new QAction { QIcon(":/icones/zoom.png"), "Zoom", this };
181 auto actionZoomMode = new QAction { QIcon(":/icones/zoom.png"), "Zoom", this };
182 actionZoomMode->setCheckable(true);
182 actionZoomMode->setCheckable(true);
183 actionZoomMode->setChecked(
183 actionZoomMode->setChecked(
184 sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::ZoomBox);
184 sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::ZoomBox);
185 connect(actionZoomMode, &QAction::triggered,
185 connect(actionZoomMode, &QAction::triggered,
186 []() { sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::ZoomBox); });
186 []() { sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::ZoomBox); });
187
187
188 auto actionOrganisationMode = new QAction { QIcon(":/icones/drag.png"), "Organize", this };
188 auto actionOrganisationMode = new QAction { QIcon(":/icones/drag.png"), "Organize", this };
189 actionOrganisationMode->setCheckable(true);
189 actionOrganisationMode->setCheckable(true);
190 actionOrganisationMode->setChecked(
190 actionOrganisationMode->setChecked(
191 sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::DragAndDrop);
191 sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::DragAndDrop);
192 connect(actionOrganisationMode, &QAction::triggered, []() {
192 connect(actionOrganisationMode, &QAction::triggered, []() {
193 sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::DragAndDrop);
193 sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::DragAndDrop);
194 });
194 });
195
195
196 auto actionZonesMode = new QAction { QIcon(":/icones/rectangle.png"), "Zones", this };
196 auto actionZonesMode = new QAction { QIcon(":/icones/rectangle.png"), "Zones", this };
197 actionZonesMode->setCheckable(true);
197 actionZonesMode->setCheckable(true);
198 actionZonesMode->setChecked(
198 actionZonesMode->setChecked(
199 sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones);
199 sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones);
200 connect(actionZonesMode, &QAction::triggered, []() {
200 connect(actionZonesMode, &QAction::triggered, []() {
201 sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::SelectionZones);
201 sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::SelectionZones);
202 });
202 });
203
203
204 auto modeActionGroup = new QActionGroup { this };
204 auto modeActionGroup = new QActionGroup { this };
205 modeActionGroup->addAction(actionZoomMode);
205 modeActionGroup->addAction(actionZoomMode);
206 modeActionGroup->addAction(actionZonesMode);
206 modeActionGroup->addAction(actionZonesMode);
207 modeActionGroup->addAction(actionOrganisationMode);
207 modeActionGroup->addAction(actionOrganisationMode);
208 modeActionGroup->addAction(actionPointerMode);
208 modeActionGroup->addAction(actionPointerMode);
209 modeActionGroup->setExclusive(true);
209 modeActionGroup->setExclusive(true);
210
210
211 mainToolBar->addSeparator();
211 mainToolBar->addSeparator();
212 mainToolBar->addAction(actionPointerMode);
212 mainToolBar->addAction(actionPointerMode);
213 mainToolBar->addAction(actionZoomMode);
213 mainToolBar->addAction(actionZoomMode);
214 mainToolBar->addAction(actionOrganisationMode);
214 mainToolBar->addAction(actionOrganisationMode);
215 mainToolBar->addAction(actionZonesMode);
215 mainToolBar->addAction(actionZonesMode);
216 mainToolBar->addSeparator();
216 mainToolBar->addSeparator();
217
217
218 // Cursors
218 // Cursors
219 auto btnCursor = new QToolButton { this };
219 auto btnCursor = new QToolButton { this };
220 btnCursor->setIcon(QIcon(":/icones/cursor.png"));
220 btnCursor->setIcon(QIcon(":/icones/cursor.png"));
221 btnCursor->setText("Cursor");
221 btnCursor->setText("Cursor");
222 btnCursor->setToolTip("Cursor");
222 btnCursor->setToolTip("Cursor");
223 btnCursor->setPopupMode(QToolButton::InstantPopup);
223 btnCursor->setPopupMode(QToolButton::InstantPopup);
224 auto cursorMenu = new QMenu("CursorMenu", this);
224 auto cursorMenu = new QMenu("CursorMenu", this);
225 btnCursor->setMenu(cursorMenu);
225 btnCursor->setMenu(cursorMenu);
226
226
227 auto noCursorAction = cursorMenu->addAction("No Cursor");
227 auto noCursorAction = cursorMenu->addAction("No Cursor");
228 noCursorAction->setCheckable(true);
228 noCursorAction->setCheckable(true);
229 noCursorAction->setChecked(
229 noCursorAction->setChecked(
230 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::NoCursor);
230 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::NoCursor);
231 connect(noCursorAction, &QAction::triggered,
231 connect(noCursorAction, &QAction::triggered,
232 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::NoCursor); });
232 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::NoCursor); });
233
233
234 cursorMenu->addSeparator();
234 cursorMenu->addSeparator();
235 auto verticalCursorAction = cursorMenu->addAction("Vertical Cursor");
235 auto verticalCursorAction = cursorMenu->addAction("Vertical Cursor");
236 verticalCursorAction->setCheckable(true);
236 verticalCursorAction->setCheckable(true);
237 verticalCursorAction->setChecked(
237 verticalCursorAction->setChecked(
238 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Vertical);
238 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Vertical);
239 connect(verticalCursorAction, &QAction::triggered,
239 connect(verticalCursorAction, &QAction::triggered,
240 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Vertical); });
240 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Vertical); });
241
241
242 auto temporalCursorAction = cursorMenu->addAction("Temporal Cursor");
242 auto temporalCursorAction = cursorMenu->addAction("Temporal Cursor");
243 temporalCursorAction->setCheckable(true);
243 temporalCursorAction->setCheckable(true);
244 temporalCursorAction->setChecked(
244 temporalCursorAction->setChecked(
245 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Temporal);
245 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Temporal);
246 connect(temporalCursorAction, &QAction::triggered,
246 connect(temporalCursorAction, &QAction::triggered,
247 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Temporal); });
247 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Temporal); });
248
248
249 auto horizontalCursorAction = cursorMenu->addAction("Horizontal Cursor");
249 auto horizontalCursorAction = cursorMenu->addAction("Horizontal Cursor");
250 horizontalCursorAction->setCheckable(true);
250 horizontalCursorAction->setCheckable(true);
251 horizontalCursorAction->setChecked(
251 horizontalCursorAction->setChecked(
252 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Horizontal);
252 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Horizontal);
253 connect(horizontalCursorAction, &QAction::triggered,
253 connect(horizontalCursorAction, &QAction::triggered,
254 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Horizontal); });
254 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Horizontal); });
255
255
256 auto crossCursorAction = cursorMenu->addAction("Cross Cursor");
256 auto crossCursorAction = cursorMenu->addAction("Cross Cursor");
257 crossCursorAction->setCheckable(true);
257 crossCursorAction->setCheckable(true);
258 crossCursorAction->setChecked(
258 crossCursorAction->setChecked(
259 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Cross);
259 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Cross);
260 connect(crossCursorAction, &QAction::triggered,
260 connect(crossCursorAction, &QAction::triggered,
261 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Cross); });
261 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Cross); });
262
262
263 mainToolBar->addWidget(btnCursor);
263 mainToolBar->addWidget(btnCursor);
264
264
265 auto cursorModeActionGroup = new QActionGroup { this };
265 auto cursorModeActionGroup = new QActionGroup { this };
266 cursorModeActionGroup->setExclusive(true);
266 cursorModeActionGroup->setExclusive(true);
267 cursorModeActionGroup->addAction(noCursorAction);
267 cursorModeActionGroup->addAction(noCursorAction);
268 cursorModeActionGroup->addAction(verticalCursorAction);
268 cursorModeActionGroup->addAction(verticalCursorAction);
269 cursorModeActionGroup->addAction(temporalCursorAction);
269 cursorModeActionGroup->addAction(temporalCursorAction);
270 cursorModeActionGroup->addAction(horizontalCursorAction);
270 cursorModeActionGroup->addAction(horizontalCursorAction);
271 cursorModeActionGroup->addAction(crossCursorAction);
271 cursorModeActionGroup->addAction(crossCursorAction);
272
272
273 // Catalog
273 // Catalog
274 mainToolBar->addSeparator();
274 mainToolBar->addSeparator();
275 // mainToolBar->addAction(QIcon(":/icones/catalogue.png"), "Catalogues",
275 // mainToolBar->addAction(QIcon(":/icones/catalogue.png"), "Catalogues",
276 // [this]() { impl->m_CatalogExplorer->show(); });
276 // [this]() { impl->m_CatalogExplorer->show(); });
277
277
278 // //////// //
278 // //////// //
279 // Settings //
279 // Settings //
280 // //////// //
280 // //////// //
281
281
282 // Registers "general settings" widget to the settings dialog
282 // Registers "general settings" widget to the settings dialog
283 impl->m_SettingsDialog->registerWidget(
283 impl->m_SettingsDialog->registerWidget(
284 QStringLiteral("General"), impl->m_GeneralSettingsWidget);
284 QStringLiteral("General"), impl->m_GeneralSettingsWidget);
285
285
286 // /////////// //
286 // /////////// //
287 // Connections //
287 // Connections //
288 // /////////// //
288 // /////////// //
289
289
290 // Controllers / controllers connections
290 // Controllers / controllers connections
291 // connect(&sqpApp->timeController(), SIGNAL(timeUpdated(DateTimeRange)),
291 // connect(&sqpApp->timeController(), SIGNAL(timeUpdated(DateTimeRange)),
292 // &sqpApp->variableController(),
292 // &sqpApp->variableController(),
293 // SLOT(onDateTimeOnSelection(DateTimeRange)));
293 // SLOT(onDateTimeOnSelection(DateTimeRange)));
294
294
295 // Widgets / controllers connections
295 // Widgets / controllers connections
296
296
297 // DataSource
297 // DataSource
298 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem*)),
298 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem*)),
299 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem*)));
299 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem*)));
300
300
301 // Time
301 // Time
302 connect(timeWidget, SIGNAL(timeUpdated(DateTimeRange)), &sqpApp->timeController(),
302 connect(timeWidget, SIGNAL(timeUpdated(DateTimeRange)), &sqpApp->timeController(),
303 SLOT(onTimeToUpdate(DateTimeRange)));
303 SLOT(onTimeToUpdate(DateTimeRange)));
304
304
305 // Visualization
305 // Visualization
306 connect(&sqpApp->visualizationController(),
306 connect(&sqpApp->visualizationController(),
307 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
307 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable2>)), m_Ui->view,
308 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
308 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable2>)));
309
309
310 connect(&sqpApp->visualizationController(),
310 connect(&sqpApp->visualizationController(),
311 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const DateTimeRange&)), m_Ui->view,
311 SIGNAL(rangeChanged(std::shared_ptr<Variable2>, const DateTimeRange&)), m_Ui->view,
312 SLOT(onRangeChanged(std::shared_ptr<Variable>, const DateTimeRange&)));
312 SLOT(onRangeChanged(std::shared_ptr<Variable2>, const DateTimeRange&)));
313
313
314 // Widgets / widgets connections
314 // Widgets / widgets connections
315
315
316 // For the following connections, we use DirectConnection to allow each widget that can
316 // For the following connections, we use DirectConnection to allow each widget that can
317 // potentially attach a menu to the variable's menu to do so before this menu is displayed.
317 // potentially attach a menu to the variable's menu to do so before this menu is displayed.
318 // The order of connections is also important, since it determines the order in which each
318 // The order of connections is also important, since it determines the order in which each
319 // widget will attach its menu
319 // widget will attach its menu
320 connect(m_Ui->variableInspectorWidget,
320 connect(m_Ui->variableInspectorWidget,
321 SIGNAL(tableMenuAboutToBeDisplayed(QMenu*, const QVector<std::shared_ptr<Variable>>&)),
321 SIGNAL(tableMenuAboutToBeDisplayed(QMenu*, const QVector<std::shared_ptr<Variable>>&)),
322 m_Ui->view, SLOT(attachVariableMenu(QMenu*, const QVector<std::shared_ptr<Variable>>&)),
322 m_Ui->view, SLOT(attachVariableMenu(QMenu*, const QVector<std::shared_ptr<Variable>>&)),
323 Qt::DirectConnection);
323 Qt::DirectConnection);
324 }
324 }
325
325
326 MainWindow::~MainWindow() {}
326 MainWindow::~MainWindow() {}
327
327
328 void MainWindow::changeEvent(QEvent* e)
328 void MainWindow::changeEvent(QEvent* e)
329 {
329 {
330 QMainWindow::changeEvent(e);
330 QMainWindow::changeEvent(e);
331 switch (e->type())
331 switch (e->type())
332 {
332 {
333 case QEvent::LanguageChange:
333 case QEvent::LanguageChange:
334 m_Ui->retranslateUi(this);
334 m_Ui->retranslateUi(this);
335 break;
335 break;
336 default:
336 default:
337 break;
337 break;
338 }
338 }
339 }
339 }
340
340
341 void MainWindow::closeEvent(QCloseEvent* event)
341 void MainWindow::closeEvent(QCloseEvent* event)
342 {
342 {
343 if (!impl->checkDataToSave(this))
343 if (!impl->checkDataToSave(this))
344 {
344 {
345 event->ignore();
345 event->ignore();
346 }
346 }
347 else
347 else
348 {
348 {
349 event->accept();
349 event->accept();
350 }
350 }
351 }
351 }
352
352
353 void MainWindow::keyPressEvent(QKeyEvent* event)
353 void MainWindow::keyPressEvent(QKeyEvent* event)
354 {
354 {
355 switch (event->key())
355 switch (event->key())
356 {
356 {
357 case Qt::Key_F11:
357 case Qt::Key_F11:
358 if (this->isFullScreen())
358 if (this->isFullScreen())
359 {
359 {
360 this->showNormal();
360 this->showNormal();
361 }
361 }
362 else
362 else
363 {
363 {
364 this->showFullScreen();
364 this->showFullScreen();
365 }
365 }
366 break;
366 break;
367 default:
367 default:
368 break;
368 break;
369 }
369 }
370 }
370 }
371
371
372 bool MainWindow::MainWindowPrivate::checkDataToSave(QWidget* parentWidget)
372 bool MainWindow::MainWindowPrivate::checkDataToSave(QWidget* parentWidget)
373 {
373 {
374 // auto hasChanges = sqpApp->catalogueController().hasChanges();
374 // auto hasChanges = sqpApp->catalogueController().hasChanges();
375 // if (hasChanges)
375 // if (hasChanges)
376 // {
376 // {
377 // // There are some unsaved changes
377 // // There are some unsaved changes
378 // switch (QMessageBox::question(parentWidget, tr("Save changes"),
378 // switch (QMessageBox::question(parentWidget, tr("Save changes"),
379 // tr("The catalogue controller has unsaved changes.\nDo you want to save them ?"),
379 // tr("The catalogue controller has unsaved changes.\nDo you want to save them ?"),
380 // QMessageBox::SaveAll | QMessageBox::Discard | QMessageBox::Cancel,
380 // QMessageBox::SaveAll | QMessageBox::Discard | QMessageBox::Cancel,
381 // QMessageBox::SaveAll))
381 // QMessageBox::SaveAll))
382 // {
382 // {
383 // case QMessageBox::SaveAll:
383 // case QMessageBox::SaveAll:
384 // sqpApp->catalogueController().saveAll();
384 // sqpApp->catalogueController().saveAll();
385 // break;
385 // break;
386 // case QMessageBox::Discard:
386 // case QMessageBox::Discard:
387 // break;
387 // break;
388 // case QMessageBox::Cancel:
388 // case QMessageBox::Cancel:
389 // default:
389 // default:
390 // return false;
390 // return false;
391 // }
391 // }
392 // }
392 // }
393
393
394 return true;
394 return true;
395 }
395 }
@@ -1,1 +1,1
1 Subproject commit cc26524fb5d10feca3820e6921c9cd3cfb1a3591
1 Subproject commit 00ce7df31d3e11df8a418988c601247f6dc64d13
@@ -1,90 +1,90
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 <QMimeData>
9 #include <QMimeData>
10 #include <QWidget>
10 #include <QWidget>
11
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
13
13
14 class Variable;
14 class Variable2;
15 class VisualizationZoneWidget;
15 class VisualizationZoneWidget;
16
16
17 namespace Ui
17 namespace Ui
18 {
18 {
19 class VisualizationTabWidget;
19 class VisualizationTabWidget;
20 } // namespace Ui
20 } // namespace Ui
21
21
22 class VisualizationTabWidget : public QWidget, public IVisualizationWidget
22 class VisualizationTabWidget : public QWidget, public IVisualizationWidget
23 {
23 {
24 Q_OBJECT
24 Q_OBJECT
25
25
26 public:
26 public:
27 explicit VisualizationTabWidget(const QString& name = {}, QWidget* parent = 0);
27 explicit VisualizationTabWidget(const QString& name = {}, QWidget* parent = 0);
28 virtual ~VisualizationTabWidget();
28 virtual ~VisualizationTabWidget();
29
29
30 /// Adds a zone widget
30 /// Adds a zone widget
31 void addZone(VisualizationZoneWidget* zoneWidget);
31 void addZone(VisualizationZoneWidget* zoneWidget);
32
32
33 /// Inserts a zone widget at the specified position
33 /// Inserts a zone widget at the specified position
34 void insertZone(int index, VisualizationZoneWidget* zoneWidget);
34 void insertZone(int index, VisualizationZoneWidget* zoneWidget);
35
35
36 /// Returns the list of zone widget names in the order they are displayed
36 /// Returns the list of zone widget names in the order they are displayed
37 QStringList availableZoneWidgets() const;
37 QStringList availableZoneWidgets() const;
38
38
39 /// Returns the zone with the specified name.
39 /// Returns the zone with the specified name.
40 /// If multiple zone with the same name exist, the first one is returned.
40 /// If multiple zone with the same name exist, the first one is returned.
41 VisualizationZoneWidget* getZoneWithName(const QString& zoneName);
41 VisualizationZoneWidget* getZoneWithName(const QString& zoneName);
42
42
43 /**
43 /**
44 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
44 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
45 * zone. The zone is added at the end.
45 * zone. The zone is added at the end.
46 * @param variable the variable for which to create the zone
46 * @param variable the variable for which to create the zone
47 * @return the pointer to the created zone
47 * @return the pointer to the created zone
48 */
48 */
49 VisualizationZoneWidget* createZone(std::shared_ptr<Variable2> variable);
49 VisualizationZoneWidget* createZone(std::shared_ptr<Variable2> variable);
50
50
51 /**
51 /**
52 * Creates a zone using a list of variables. The variables will be displayed in a new graph of
52 * Creates a zone using a list of variables. The variables will be displayed in a new graph of
53 * the new zone. The zone is inserted at the specified index.
53 * the new zone. The zone is inserted at the specified index.
54 * @param variables the variables for which to create the zone
54 * @param variables the variables for which to create the zone
55 * @param index The index where the zone should be inserted in the layout
55 * @param index The index where the zone should be inserted in the layout
56 * @return the pointer to the created zone
56 * @return the pointer to the created zone
57 */
57 */
58 VisualizationZoneWidget* createZone(
58 VisualizationZoneWidget* createZone(
59 const std::vector<std::shared_ptr<Variable2>>& variables, int index);
59 const std::vector<std::shared_ptr<Variable2>>& variables, int index);
60
60
61 /**
61 /**
62 * Creates a zone which is empty (no variables). The zone is inserted at the specified index.
62 * Creates a zone which is empty (no variables). The zone is inserted at the specified index.
63 * @param index The index where the zone should be inserted in the layout
63 * @param index The index where the zone should be inserted in the layout
64 * @return the pointer to the created zone
64 * @return the pointer to the created zone
65 */
65 */
66 VisualizationZoneWidget* createEmptyZone(int index);
66 VisualizationZoneWidget* createEmptyZone(int index);
67
67
68 // IVisualizationWidget interface
68 // IVisualizationWidget interface
69 void accept(IVisualizationWidgetVisitor* visitor) override;
69 void accept(IVisualizationWidgetVisitor* visitor) override;
70 bool canDrop(Variable2& variable) const override;
70 bool canDrop(Variable2& variable) const override;
71 bool contains(Variable2& variable) const override;
71 bool contains(Variable2& variable) const override;
72 QString name() const override;
72 QString name() const override;
73
73
74 protected:
74 protected:
75 void closeEvent(QCloseEvent* event) override;
75 void closeEvent(QCloseEvent* event) override;
76
76
77 private:
77 private:
78 /// @return the layout of tab in which zones are added
78 /// @return the layout of tab in which zones are added
79 QLayout& tabLayout() const noexcept;
79 QLayout& tabLayout() const noexcept;
80
80
81 Ui::VisualizationTabWidget* ui;
81 Ui::VisualizationTabWidget* ui;
82
82
83 class VisualizationTabWidgetPrivate;
83 class VisualizationTabWidgetPrivate;
84 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
84 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
85
85
86 private slots:
86 private slots:
87 void dropMimeData(int index, const QMimeData* mimeData);
87 void dropMimeData(int index, const QMimeData* mimeData);
88 };
88 };
89
89
90 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
90 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
@@ -1,442 +1,445
1 #include "Visualization/VisualizationGraphHelper.h"
1 #include "Visualization/VisualizationGraphHelper.h"
2 #include "Visualization/qcustomplot.h"
2 #include "Visualization/qcustomplot.h"
3
3
4 #include <Data/ScalarTimeSerie.h>
4 #include <Data/ScalarTimeSerie.h>
5 #include <Data/SpectrogramTimeSerie.h>
5 #include <Data/SpectrogramTimeSerie.h>
6 #include <Data/VectorTimeSerie.h>
6 #include <Data/VectorTimeSerie.h>
7
7
8 #include <Variable/Variable2.h>
8 #include <Variable/Variable2.h>
9
9
10 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
10 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
11
11
12 namespace
12 namespace
13 {
13 {
14
14
15 class SqpDataContainer : public QCPGraphDataContainer
15 class SqpDataContainer : public QCPGraphDataContainer
16 {
16 {
17 public:
17 public:
18 void appendGraphData(const QCPGraphData& data) { mData.append(data); }
18 void appendGraphData(const QCPGraphData& data) { mData.append(data); }
19 };
19 };
20
20
21 /**
21 /**
22 * Struct used to create plottables, depending on the type of the data series from which to create
22 * Struct used to create plottables, depending on the type of the data series from which to create
23 * them
23 * them
24 * @tparam T the data series' type
24 * @tparam T the data series' type
25 * @remarks Default implementation can't create plottables
25 * @remarks Default implementation can't create plottables
26 */
26 */
27 template <typename T, typename Enabled = void>
27 template <typename T, typename Enabled = void>
28 struct PlottablesCreator
28 struct PlottablesCreator
29 {
29 {
30 static PlottablesMap createPlottables(QCustomPlot&) { return {}; }
30 static PlottablesMap createPlottables(QCustomPlot&) { return {}; }
31 };
31 };
32
32
33 PlottablesMap createGraphs(QCustomPlot& plot, int nbGraphs)
33 PlottablesMap createGraphs(QCustomPlot& plot, int nbGraphs)
34 {
34 {
35 PlottablesMap result {};
35 PlottablesMap result {};
36
36
37 // Creates {nbGraphs} QCPGraph to add to the plot
37 // Creates {nbGraphs} QCPGraph to add to the plot
38 for (auto i = 0; i < nbGraphs; ++i)
38 for (auto i = 0; i < nbGraphs; ++i)
39 {
39 {
40 auto graph = plot.addGraph();
40 auto graph = plot.addGraph();
41 result.insert({ i, graph });
41 result.insert({ i, graph });
42 }
42 }
43
43
44 plot.replot();
44 plot.replot();
45
45
46 return result;
46 return result;
47 }
47 }
48
48
49 /**
49 /**
50 * Specialization of PlottablesCreator for scalars
50 * Specialization of PlottablesCreator for scalars
51 * @sa ScalarSeries
51 * @sa ScalarSeries
52 */
52 */
53 template <typename T>
53 template <typename T>
54 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value>>
54 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value>>
55 {
55 {
56 static PlottablesMap createPlottables(QCustomPlot& plot) { return createGraphs(plot, 1); }
56 static PlottablesMap createPlottables(QCustomPlot& plot) { return createGraphs(plot, 1); }
57 };
57 };
58
58
59 /**
59 /**
60 * Specialization of PlottablesCreator for vectors
60 * Specialization of PlottablesCreator for vectors
61 * @sa VectorSeries
61 * @sa VectorSeries
62 */
62 */
63 template <typename T>
63 template <typename T>
64 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>>
64 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>>
65 {
65 {
66 static PlottablesMap createPlottables(QCustomPlot& plot) { return createGraphs(plot, 3); }
66 static PlottablesMap createPlottables(QCustomPlot& plot) { return createGraphs(plot, 3); }
67 };
67 };
68
68
69 /**
69 /**
70 * Specialization of PlottablesCreator for spectrograms
70 * Specialization of PlottablesCreator for spectrograms
71 * @sa SpectrogramSeries
71 * @sa SpectrogramSeries
72 */
72 */
73 template <typename T>
73 template <typename T>
74 struct PlottablesCreator<T,
74 struct PlottablesCreator<T,
75 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
75 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
76 {
76 {
77 static PlottablesMap createPlottables(QCustomPlot& plot)
77 static PlottablesMap createPlottables(QCustomPlot& plot)
78 {
78 {
79 PlottablesMap result {};
79 PlottablesMap result {};
80 result.insert({ 0, new QCPColorMap { plot.xAxis, plot.yAxis } });
80 result.insert({ 0, new QCPColorMap { plot.xAxis, plot.yAxis } });
81
81
82 plot.replot();
82 plot.replot();
83
83
84 return result;
84 return result;
85 }
85 }
86 };
86 };
87
87
88 /**
88 /**
89 * Struct used to update plottables, depending on the type of the data series from which to update
89 * Struct used to update plottables, depending on the type of the data series from which to update
90 * them
90 * them
91 * @tparam T the data series' type
91 * @tparam T the data series' type
92 * @remarks Default implementation can't update plottables
92 * @remarks Default implementation can't update plottables
93 */
93 */
94 template <typename T, typename Enabled = void>
94 template <typename T, typename Enabled = void>
95 struct PlottablesUpdater
95 struct PlottablesUpdater
96 {
96 {
97 static void setPlotYAxisRange(T&, const DateTimeRange&, QCustomPlot&)
97 static void setPlotYAxisRange(T&, const DateTimeRange&, QCustomPlot&)
98 {
98 {
99 qCCritical(LOG_VisualizationGraphHelper())
99 qCCritical(LOG_VisualizationGraphHelper())
100 << QObject::tr("Can't set plot y-axis range: unmanaged data series type");
100 << QObject::tr("Can't set plot y-axis range: unmanaged data series type");
101 }
101 }
102
102
103 static void updatePlottables(T&, PlottablesMap&, const DateTimeRange&, bool)
103 static void updatePlottables(T&, PlottablesMap&, const DateTimeRange&, bool)
104 {
104 {
105 qCCritical(LOG_VisualizationGraphHelper())
105 qCCritical(LOG_VisualizationGraphHelper())
106 << QObject::tr("Can't update plottables: unmanaged data series type");
106 << QObject::tr("Can't update plottables: unmanaged data series type");
107 }
107 }
108 };
108 };
109
109
110 /**
110 /**
111 * Specialization of PlottablesUpdater for scalars and vectors
111 * Specialization of PlottablesUpdater for scalars and vectors
112 * @sa ScalarSeries
112 * @sa ScalarSeries
113 * @sa VectorSeries
113 * @sa VectorSeries
114 */
114 */
115 template <typename T>
115 template <typename T>
116 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value>>
116 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<ScalarTimeSerie, T>::value>>
117 {
117 {
118 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
118 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
119 {
119 {
120 auto minValue = 0., maxValue = 0.;
120 auto minValue = 0., maxValue = 0.;
121 if (auto serie = dynamic_cast<ScalarTimeSerie*>(&dataSeries))
121 if (auto serie = dynamic_cast<ScalarTimeSerie*>(&dataSeries))
122 {
122 {
123 maxValue = (*std::max_element(std::begin(*serie), std::end(*serie))).v();
123 if (serie->size())
124 minValue = (*std::min_element(std::begin(*serie), std::end(*serie))).v();
124 {
125 maxValue = (*std::max_element(std::begin(*serie), std::end(*serie))).v();
126 minValue = (*std::min_element(std::begin(*serie), std::end(*serie))).v();
127 }
125 }
128 }
126 plot.yAxis->setRange(QCPRange { minValue, maxValue });
129 plot.yAxis->setRange(QCPRange { minValue, maxValue });
127 }
130 }
128
131
129 static void updatePlottables(
132 static void updatePlottables(
130 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
133 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
131 {
134 {
132
135
133 // For each plottable to update, resets its data
136 // For each plottable to update, resets its data
134 for (const auto& plottable : plottables)
137 for (const auto& plottable : plottables)
135 {
138 {
136 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
139 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
137 {
140 {
138 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
141 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
139 if (auto serie = dynamic_cast<ScalarTimeSerie*>(&dataSeries))
142 if (auto serie = dynamic_cast<ScalarTimeSerie*>(&dataSeries))
140 {
143 {
141 std::for_each(
144 std::for_each(
142 std::begin(*serie), std::end(*serie), [&dataContainer](const auto& value) {
145 std::begin(*serie), std::end(*serie), [&dataContainer](const auto& value) {
143 dataContainer->appendGraphData(QCPGraphData(value.t(), value.v()));
146 dataContainer->appendGraphData(QCPGraphData(value.t(), value.v()));
144 });
147 });
145 }
148 }
146 graph->setData(dataContainer);
149 graph->setData(dataContainer);
147 }
150 }
148 }
151 }
149
152
150 if (!plottables.empty())
153 if (!plottables.empty())
151 {
154 {
152 auto plot = plottables.begin()->second->parentPlot();
155 auto plot = plottables.begin()->second->parentPlot();
153
156
154 if (rescaleAxes)
157 if (rescaleAxes)
155 {
158 {
156 plot->rescaleAxes();
159 plot->rescaleAxes();
157 }
160 }
158 }
161 }
159 }
162 }
160 };
163 };
161
164
162
165
163 template <typename T>
166 template <typename T>
164 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>>
167 struct PlottablesUpdater<T, typename std::enable_if_t<std::is_base_of<VectorTimeSerie, T>::value>>
165 {
168 {
166 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
169 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
167 {
170 {
168 double minValue = 0., maxValue = 0.;
171 double minValue = 0., maxValue = 0.;
169 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
172 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
170 {
173 {
171 std::for_each(
174 std::for_each(
172 std::begin(*serie), std::end(*serie), [&minValue, &maxValue](const auto& v) {
175 std::begin(*serie), std::end(*serie), [&minValue, &maxValue](const auto& v) {
173 minValue = std::min({ minValue, v.v().x, v.v().y, v.v().z });
176 minValue = std::min({ minValue, v.v().x, v.v().y, v.v().z });
174 maxValue = std::max({ maxValue, v.v().x, v.v().y, v.v().z });
177 maxValue = std::max({ maxValue, v.v().x, v.v().y, v.v().z });
175 });
178 });
176 }
179 }
177
180
178 plot.yAxis->setRange(QCPRange { minValue, maxValue });
181 plot.yAxis->setRange(QCPRange { minValue, maxValue });
179 }
182 }
180
183
181 static void updatePlottables(
184 static void updatePlottables(
182 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
185 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
183 {
186 {
184
187
185 // For each plottable to update, resets its data
188 // For each plottable to update, resets its data
186 for (const auto& plottable : plottables)
189 for (const auto& plottable : plottables)
187 {
190 {
188 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
191 if (auto graph = dynamic_cast<QCPGraph*>(plottable.second))
189 {
192 {
190 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
193 auto dataContainer = QSharedPointer<SqpDataContainer>::create();
191 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
194 if (auto serie = dynamic_cast<VectorTimeSerie*>(&dataSeries))
192 {
195 {
193 switch (plottable.first)
196 switch (plottable.first)
194 {
197 {
195 case 0:
198 case 0:
196 std::for_each(std::begin(*serie), std::end(*serie),
199 std::for_each(std::begin(*serie), std::end(*serie),
197 [&dataContainer](const auto& value) {
200 [&dataContainer](const auto& value) {
198 dataContainer->appendGraphData(
201 dataContainer->appendGraphData(
199 QCPGraphData(value.t(), value.v().x));
202 QCPGraphData(value.t(), value.v().x));
200 });
203 });
201 break;
204 break;
202 case 1:
205 case 1:
203 std::for_each(std::begin(*serie), std::end(*serie),
206 std::for_each(std::begin(*serie), std::end(*serie),
204 [&dataContainer](const auto& value) {
207 [&dataContainer](const auto& value) {
205 dataContainer->appendGraphData(
208 dataContainer->appendGraphData(
206 QCPGraphData(value.t(), value.v().y));
209 QCPGraphData(value.t(), value.v().y));
207 });
210 });
208 break;
211 break;
209 case 2:
212 case 2:
210 std::for_each(std::begin(*serie), std::end(*serie),
213 std::for_each(std::begin(*serie), std::end(*serie),
211 [&dataContainer](const auto& value) {
214 [&dataContainer](const auto& value) {
212 dataContainer->appendGraphData(
215 dataContainer->appendGraphData(
213 QCPGraphData(value.t(), value.v().z));
216 QCPGraphData(value.t(), value.v().z));
214 });
217 });
215 break;
218 break;
216 default:
219 default:
217 break;
220 break;
218 }
221 }
219 }
222 }
220 graph->setData(dataContainer);
223 graph->setData(dataContainer);
221 }
224 }
222 }
225 }
223
226
224 if (!plottables.empty())
227 if (!plottables.empty())
225 {
228 {
226 auto plot = plottables.begin()->second->parentPlot();
229 auto plot = plottables.begin()->second->parentPlot();
227
230
228 if (rescaleAxes)
231 if (rescaleAxes)
229 {
232 {
230 plot->rescaleAxes();
233 plot->rescaleAxes();
231 }
234 }
232 }
235 }
233 }
236 }
234 };
237 };
235
238
236 /**
239 /**
237 * Specialization of PlottablesUpdater for spectrograms
240 * Specialization of PlottablesUpdater for spectrograms
238 * @sa SpectrogramSeries
241 * @sa SpectrogramSeries
239 */
242 */
240 template <typename T>
243 template <typename T>
241 struct PlottablesUpdater<T,
244 struct PlottablesUpdater<T,
242 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
245 typename std::enable_if_t<std::is_base_of<SpectrogramTimeSerie, T>::value>>
243 {
246 {
244 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
247 static void setPlotYAxisRange(T& dataSeries, const DateTimeRange& xAxisRange, QCustomPlot& plot)
245 {
248 {
246 // TODO
249 // TODO
247 // double min, max;
250 // double min, max;
248 // std::tie(min, max) = dataSeries.yBounds();
251 // std::tie(min, max) = dataSeries.yBounds();
249
252
250 // if (!std::isnan(min) && !std::isnan(max))
253 // if (!std::isnan(min) && !std::isnan(max))
251 // {
254 // {
252 // plot.yAxis->setRange(QCPRange { min, max });
255 // plot.yAxis->setRange(QCPRange { min, max });
253 // }
256 // }
254 }
257 }
255
258
256 static void updatePlottables(
259 static void updatePlottables(
257 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
260 T& dataSeries, PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes)
258 {
261 {
259 // TODO
262 // TODO
260 // if (plottables.empty())
263 // if (plottables.empty())
261 // {
264 // {
262 // qCDebug(LOG_VisualizationGraphHelper())
265 // qCDebug(LOG_VisualizationGraphHelper())
263 // << QObject::tr("Can't update spectrogram: no colormap has been
266 // << QObject::tr("Can't update spectrogram: no colormap has been
264 // associated");
267 // associated");
265 // return;
268 // return;
266 // }
269 // }
267
270
268 // // Gets the colormap to update (normally there is only one colormap)
271 // // Gets the colormap to update (normally there is only one colormap)
269 // Q_ASSERT(plottables.size() == 1);
272 // Q_ASSERT(plottables.size() == 1);
270 // auto colormap = dynamic_cast<QCPColorMap*>(plottables.at(0));
273 // auto colormap = dynamic_cast<QCPColorMap*>(plottables.at(0));
271 // Q_ASSERT(colormap != nullptr);
274 // Q_ASSERT(colormap != nullptr);
272
275
273 // dataSeries.lockRead();
276 // dataSeries.lockRead();
274
277
275 // // Processing spectrogram data for display in QCustomPlot
278 // // Processing spectrogram data for display in QCustomPlot
276 // auto its = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
279 // auto its = dataSeries.xAxisRange(range.m_TStart, range.m_TEnd);
277
280
278 // // Computes logarithmic y-axis resolution for the spectrogram
281 // // Computes logarithmic y-axis resolution for the spectrogram
279 // auto yData = its.first->y();
282 // auto yData = its.first->y();
280 // auto yResolution = DataSeriesUtils::resolution(yData.begin(), yData.end(), true);
283 // auto yResolution = DataSeriesUtils::resolution(yData.begin(), yData.end(), true);
281
284
282 // // Generates mesh for colormap
285 // // Generates mesh for colormap
283 // auto mesh = DataSeriesUtils::regularMesh(its.first, its.second,
286 // auto mesh = DataSeriesUtils::regularMesh(its.first, its.second,
284 // DataSeriesUtils::Resolution { dataSeries.xResolution() }, yResolution);
287 // DataSeriesUtils::Resolution { dataSeries.xResolution() }, yResolution);
285
288
286 // dataSeries.unlock();
289 // dataSeries.unlock();
287
290
288 // colormap->data()->setSize(mesh.m_NbX, mesh.m_NbY);
291 // colormap->data()->setSize(mesh.m_NbX, mesh.m_NbY);
289 // if (!mesh.isEmpty())
292 // if (!mesh.isEmpty())
290 // {
293 // {
291 // colormap->data()->setRange(QCPRange { mesh.m_XMin, mesh.xMax() },
294 // colormap->data()->setRange(QCPRange { mesh.m_XMin, mesh.xMax() },
292 // // y-axis range is converted to linear values
295 // // y-axis range is converted to linear values
293 // QCPRange { std::pow(10, mesh.m_YMin), std::pow(10, mesh.yMax()) });
296 // QCPRange { std::pow(10, mesh.m_YMin), std::pow(10, mesh.yMax()) });
294
297
295 // // Sets values
298 // // Sets values
296 // auto index = 0;
299 // auto index = 0;
297 // for (auto it = mesh.m_Data.begin(), end = mesh.m_Data.end(); it != end; ++it,
300 // for (auto it = mesh.m_Data.begin(), end = mesh.m_Data.end(); it != end; ++it,
298 // ++index)
301 // ++index)
299 // {
302 // {
300 // auto xIndex = index % mesh.m_NbX;
303 // auto xIndex = index % mesh.m_NbX;
301 // auto yIndex = index / mesh.m_NbX;
304 // auto yIndex = index / mesh.m_NbX;
302
305
303 // colormap->data()->setCell(xIndex, yIndex, *it);
306 // colormap->data()->setCell(xIndex, yIndex, *it);
304
307
305 // // Makes the NaN values to be transparent in the colormap
308 // // Makes the NaN values to be transparent in the colormap
306 // if (std::isnan(*it))
309 // if (std::isnan(*it))
307 // {
310 // {
308 // colormap->data()->setAlpha(xIndex, yIndex, 0);
311 // colormap->data()->setAlpha(xIndex, yIndex, 0);
309 // }
312 // }
310 // }
313 // }
311 // }
314 // }
312
315
313 // // Rescales axes
316 // // Rescales axes
314 // auto plot = colormap->parentPlot();
317 // auto plot = colormap->parentPlot();
315
318
316 // if (rescaleAxes)
319 // if (rescaleAxes)
317 // {
320 // {
318 // plot->rescaleAxes();
321 // plot->rescaleAxes();
319 // }
322 // }
320 }
323 }
321 };
324 };
322
325
323 /**
326 /**
324 * Helper used to create/update plottables
327 * Helper used to create/update plottables
325 */
328 */
326 struct IPlottablesHelper
329 struct IPlottablesHelper
327 {
330 {
328 virtual ~IPlottablesHelper() noexcept = default;
331 virtual ~IPlottablesHelper() noexcept = default;
329 virtual PlottablesMap create(QCustomPlot& plot) const = 0;
332 virtual PlottablesMap create(QCustomPlot& plot) const = 0;
330 virtual void setYAxisRange(const DateTimeRange& xAxisRange, QCustomPlot& plot) const = 0;
333 virtual void setYAxisRange(const DateTimeRange& xAxisRange, QCustomPlot& plot) const = 0;
331 virtual void update(
334 virtual void update(
332 PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes = false) const = 0;
335 PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes = false) const = 0;
333 };
336 };
334
337
335 /**
338 /**
336 * Default implementation of IPlottablesHelper, which takes data series to create/update plottables
339 * Default implementation of IPlottablesHelper, which takes data series to create/update plottables
337 * @tparam T the data series' type
340 * @tparam T the data series' type
338 */
341 */
339 template <typename T>
342 template <typename T>
340 struct PlottablesHelper : public IPlottablesHelper
343 struct PlottablesHelper : public IPlottablesHelper
341 {
344 {
342 explicit PlottablesHelper(std::shared_ptr<T> dataSeries) : m_DataSeries { dataSeries } {}
345 explicit PlottablesHelper(std::shared_ptr<T> dataSeries) : m_DataSeries { dataSeries } {}
343
346
344 PlottablesMap create(QCustomPlot& plot) const override
347 PlottablesMap create(QCustomPlot& plot) const override
345 {
348 {
346 return PlottablesCreator<T>::createPlottables(plot);
349 return PlottablesCreator<T>::createPlottables(plot);
347 }
350 }
348
351
349 void update(
352 void update(
350 PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes) const override
353 PlottablesMap& plottables, const DateTimeRange& range, bool rescaleAxes) const override
351 {
354 {
352 if (m_DataSeries)
355 if (m_DataSeries)
353 {
356 {
354 PlottablesUpdater<T>::updatePlottables(*m_DataSeries, plottables, range, rescaleAxes);
357 PlottablesUpdater<T>::updatePlottables(*m_DataSeries, plottables, range, rescaleAxes);
355 }
358 }
356 else
359 else
357 {
360 {
358 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
361 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
359 "between the type of data series and the "
362 "between the type of data series and the "
360 "type supposed";
363 "type supposed";
361 }
364 }
362 }
365 }
363
366
364 void setYAxisRange(const DateTimeRange& xAxisRange, QCustomPlot& plot) const override
367 void setYAxisRange(const DateTimeRange& xAxisRange, QCustomPlot& plot) const override
365 {
368 {
366 if (m_DataSeries)
369 if (m_DataSeries)
367 {
370 {
368 PlottablesUpdater<T>::setPlotYAxisRange(*m_DataSeries, xAxisRange, plot);
371 PlottablesUpdater<T>::setPlotYAxisRange(*m_DataSeries, xAxisRange, plot);
369 }
372 }
370 else
373 else
371 {
374 {
372 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
375 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
373 "between the type of data series and the "
376 "between the type of data series and the "
374 "type supposed";
377 "type supposed";
375 }
378 }
376 }
379 }
377
380
378 std::shared_ptr<T> m_DataSeries;
381 std::shared_ptr<T> m_DataSeries;
379 };
382 };
380
383
381 /// Creates IPlottablesHelper according to the type of data series a variable holds
384 /// Creates IPlottablesHelper according to the type of data series a variable holds
382 std::unique_ptr<IPlottablesHelper> createHelper(std::shared_ptr<Variable2> variable) noexcept
385 std::unique_ptr<IPlottablesHelper> createHelper(std::shared_ptr<Variable2> variable) noexcept
383 {
386 {
384 switch (variable->type())
387 switch (variable->type())
385 {
388 {
386 case DataSeriesType::SCALAR:
389 case DataSeriesType::SCALAR:
387 return std::make_unique<PlottablesHelper<ScalarTimeSerie>>(
390 return std::make_unique<PlottablesHelper<ScalarTimeSerie>>(
388 std::dynamic_pointer_cast<ScalarTimeSerie>(variable->data()));
391 std::dynamic_pointer_cast<ScalarTimeSerie>(variable->data()));
389 case DataSeriesType::SPECTROGRAM:
392 case DataSeriesType::SPECTROGRAM:
390 return std::make_unique<PlottablesHelper<SpectrogramTimeSerie>>(
393 return std::make_unique<PlottablesHelper<SpectrogramTimeSerie>>(
391 std::dynamic_pointer_cast<SpectrogramTimeSerie>(variable->data()));
394 std::dynamic_pointer_cast<SpectrogramTimeSerie>(variable->data()));
392 case DataSeriesType::VECTOR:
395 case DataSeriesType::VECTOR:
393 return std::make_unique<PlottablesHelper<VectorTimeSerie>>(
396 return std::make_unique<PlottablesHelper<VectorTimeSerie>>(
394 std::dynamic_pointer_cast<VectorTimeSerie>(variable->data()));
397 std::dynamic_pointer_cast<VectorTimeSerie>(variable->data()));
395 default:
398 default:
396 // Creates default helper
399 // Creates default helper
397 break;
400 break;
398 }
401 }
399
402
400 return std::make_unique<PlottablesHelper<TimeSeries::ITimeSerie>>(nullptr);
403 return std::make_unique<PlottablesHelper<TimeSeries::ITimeSerie>>(nullptr);
401 }
404 }
402
405
403 } // namespace
406 } // namespace
404
407
405 PlottablesMap VisualizationGraphHelper::create(
408 PlottablesMap VisualizationGraphHelper::create(
406 std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept
409 std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept
407 {
410 {
408 if (variable)
411 if (variable)
409 {
412 {
410 auto helper = createHelper(variable);
413 auto helper = createHelper(variable);
411 auto plottables = helper->create(plot);
414 auto plottables = helper->create(plot);
412 return plottables;
415 return plottables;
413 }
416 }
414 else
417 else
415 {
418 {
416 qCDebug(LOG_VisualizationGraphHelper())
419 qCDebug(LOG_VisualizationGraphHelper())
417 << QObject::tr("Can't create graph plottables : the variable is null");
420 << QObject::tr("Can't create graph plottables : the variable is null");
418 return PlottablesMap {};
421 return PlottablesMap {};
419 }
422 }
420 }
423 }
421
424
422 void VisualizationGraphHelper::setYAxisRange(
425 void VisualizationGraphHelper::setYAxisRange(
423 std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept
426 std::shared_ptr<Variable2> variable, QCustomPlot& plot) noexcept
424 {
427 {
425 if (variable)
428 if (variable)
426 {
429 {
427 auto helper = createHelper(variable);
430 auto helper = createHelper(variable);
428 helper->setYAxisRange(variable->range(), plot);
431 helper->setYAxisRange(variable->range(), plot);
429 }
432 }
430 else
433 else
431 {
434 {
432 qCDebug(LOG_VisualizationGraphHelper())
435 qCDebug(LOG_VisualizationGraphHelper())
433 << QObject::tr("Can't set y-axis range of plot: the variable is null");
436 << QObject::tr("Can't set y-axis range of plot: the variable is null");
434 }
437 }
435 }
438 }
436
439
437 void VisualizationGraphHelper::updateData(
440 void VisualizationGraphHelper::updateData(
438 PlottablesMap& plottables, std::shared_ptr<Variable2> variable, const DateTimeRange& dateTime)
441 PlottablesMap& plottables, std::shared_ptr<Variable2> variable, const DateTimeRange& dateTime)
439 {
442 {
440 auto helper = createHelper(variable);
443 auto helper = createHelper(variable);
441 helper->update(plottables, dateTime);
444 helper->update(plottables, dateTime);
442 }
445 }
@@ -1,3 +1,4
1 add_subdirectory(mockplugin)
1 add_subdirectory(mockplugin)
2 add_subdirectory(amda)
2 add_subdirectory(python_providers)
3 add_subdirectory(generic_ws)
3 #add_subdirectory(amda)
4 #add_subdirectory(generic_ws)
@@ -1,30 +1,30
1 #ifndef SCIQLOP_AMDAPROVIDER_H
1 #ifndef SCIQLOP_AMDAPROVIDER_H
2 #define SCIQLOP_AMDAPROVIDER_H
2 #define SCIQLOP_AMDAPROVIDER_H
3
3
4 #include "AmdaGlobal.h"
4 #include "AmdaGlobal.h"
5
5
6 #include <Data/IDataProvider.h>
6 #include <Data/IDataProvider.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9
9
10 #include <map>
10 #include <map>
11
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_AmdaProvider)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_AmdaProvider)
13
13
14 class QNetworkReply;
14 class QNetworkReply;
15 class QNetworkRequest;
15 class QNetworkRequest;
16
16
17 /**
17 /**
18 * @brief The AmdaProvider class is an example of how a data provider can generate data
18 * @brief The AmdaProvider class is an example of how a data provider can generate data
19 */
19 */
20 class SCIQLOP_AMDA_EXPORT AmdaProvider : public IDataProvider {
20 class SCIQLOP_AMDA_EXPORT AmdaProvider : public IDataProvider
21 {
21 Q_OBJECT
22 Q_OBJECT
22 public:
23 public:
23 explicit AmdaProvider();
24 explicit AmdaProvider();
24 std::shared_ptr<IDataProvider> clone() const override;
25 std::shared_ptr<IDataProvider> clone() const override;
25
26
26 virtual IDataSeries *getData(const DataProviderParameters &parameters)override;
27 virtual TimeSeries::ITimeSerie* getData(const DataProviderParameters& parameters) override;
27
28 };
28 };
29
29
30 #endif // SCIQLOP_AMDAPROVIDER_H
30 #endif // SCIQLOP_AMDAPROVIDER_H
@@ -1,88 +1,85
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaDefs.h"
2 #include "AmdaDefs.h"
3 #include "AmdaResultParser.h"
3 #include "AmdaResultParser.h"
4 #include "AmdaServer.h"
4 #include "AmdaServer.h"
5
5
6 #include <Common/DateUtils.h>
6 #include <Common/DateUtils.h>
7 #include <Data/DataProviderParameters.h>
7 #include <Data/DataProviderParameters.h>
8 #include <Network/NetworkController.h>
8 #include <Network/NetworkController.h>
9 #include <SqpApplication.h>
9 #include <SqpApplication.h>
10 #include <Variable/Variable.h>
11
10
11 #include <Network/Downloader.h>
12 #include <QJsonDocument>
12 #include <QNetworkAccessManager>
13 #include <QNetworkAccessManager>
13 #include <QNetworkReply>
14 #include <QNetworkReply>
14 #include <QTemporaryFile>
15 #include <QTemporaryFile>
15 #include <QThread>
16 #include <QThread>
16 #include <QJsonDocument>
17 #include <Network/Downloader.h>
18
17
19 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
18 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
20
19
21 namespace {
20 namespace
21 {
22
22
23 /// URL format for a request on AMDA server. The parameters are as follows:
23 /// URL format for a request on AMDA server. The parameters are as follows:
24 /// - %1: server URL
24 /// - %1: server URL
25 /// - %2: start date
25 /// - %2: start date
26 /// - %3: end date
26 /// - %3: end date
27 /// - %4: parameter id
27 /// - %4: parameter id
28 /// AMDA V2: http://amdatest.irap.omp.eu/php/rest/
28 /// AMDA V2: http://amdatest.irap.omp.eu/php/rest/
29 const auto AMDA_URL_FORMAT = QStringLiteral(
29 const auto AMDA_URL_FORMAT = QStringLiteral(
30 "http://%1/php/rest/"
30 "http://%1/php/rest/"
31 "getParameter.php?startTime=%2&stopTime=%3&parameterID=%4&outputFormat=ASCII&"
31 "getParameter.php?startTime=%2&stopTime=%3&parameterID=%4&outputFormat=ASCII&"
32 "timeFormat=ISO8601&gzip=0");
32 "timeFormat=ISO8601&gzip=0");
33
33
34 const auto AMDA_URL_FORMAT_WITH_TOKEN = QStringLiteral(
34 const auto AMDA_URL_FORMAT_WITH_TOKEN = QStringLiteral(
35 "http://%1/php/rest/"
35 "http://%1/php/rest/"
36 "getParameter.php?startTime=%2&stopTime=%3&parameterID=%4&outputFormat=ASCII&"
36 "getParameter.php?startTime=%2&stopTime=%3&parameterID=%4&outputFormat=ASCII&"
37 "timeFormat=ISO8601&gzip=0&"
37 "timeFormat=ISO8601&gzip=0&"
38 "token=%5");
38 "token=%5");
39
39
40 const auto AMDA_TOKEN_URL_FORMAT = QStringLiteral(
40 const auto AMDA_TOKEN_URL_FORMAT = QStringLiteral(
41 "http://%1/php/rest/"
41 "http://%1/php/rest/"
42 "auth.php");
42 "auth.php");
43
43
44 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
44 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
45 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
45 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
46
46
47 /// Formats a time to a date that can be passed in URL
47 /// Formats a time to a date that can be passed in URL
48 QString dateFormat(double sqpRange) noexcept
48 QString dateFormat(double sqpRange) noexcept
49 {
49 {
50 auto dateTime = DateUtils::dateTime(sqpRange);
50 auto dateTime = DateUtils::dateTime(sqpRange);
51 return dateTime.toString(AMDA_TIME_FORMAT);
51 return dateTime.toString(AMDA_TIME_FORMAT);
52 }
52 }
53
53
54
54
55 } // namespace
55 } // namespace
56
56
57 AmdaProvider::AmdaProvider()
57 AmdaProvider::AmdaProvider() {}
58 {
59
60 }
61
58
62 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
59 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
63 {
60 {
64 // No copy is made in the clone
61 // No copy is made in the clone
65 return std::make_shared<AmdaProvider>();
62 return std::make_shared<AmdaProvider>();
66 }
63 }
67
64
68 IDataSeries* AmdaProvider::getData(const DataProviderParameters &parameters)
65 TimeSeries::ITimeSerie* AmdaProvider::getData(const DataProviderParameters& parameters)
69 {
66 {
70 auto range = parameters.m_Range;
67 auto range = parameters.m_Range;
71 auto metaData = parameters.m_Data;
68 auto metaData = parameters.m_Data;
72 auto productId = metaData.value(AMDA_XML_ID_KEY).toString();
69 auto productId = metaData.value(AMDA_XML_ID_KEY).toString();
73 auto productValueType
70 auto productValueType
74 = DataSeriesTypeUtils::fromString(metaData.value(AMDA_DATA_TYPE_KEY).toString());
71 = DataSeriesTypeUtils::fromString(metaData.value(AMDA_DATA_TYPE_KEY).toString());
75 auto startDate = dateFormat(range.m_TStart);
72 auto startDate = dateFormat(range.m_TStart);
76 auto endDate = dateFormat(range.m_TEnd);
73 auto endDate = dateFormat(range.m_TEnd);
77 QVariantHash urlProperties{{AMDA_SERVER_KEY, metaData.value(AMDA_SERVER_KEY)}};
74 QVariantHash urlProperties { { AMDA_SERVER_KEY, metaData.value(AMDA_SERVER_KEY) } };
78 auto token_url = QString{AMDA_TOKEN_URL_FORMAT}.arg(AmdaServer::instance().url(urlProperties));
75 auto token_url
76 = QString { AMDA_TOKEN_URL_FORMAT }.arg(AmdaServer::instance().url(urlProperties));
79 auto response = Downloader::get(token_url);
77 auto response = Downloader::get(token_url);
80 auto url = QString{AMDA_URL_FORMAT_WITH_TOKEN}.arg(AmdaServer::instance().url(urlProperties),
78 auto url = QString { AMDA_URL_FORMAT_WITH_TOKEN }.arg(AmdaServer::instance().url(urlProperties),
81 startDate, endDate, productId, QString(response.data()));
79 startDate, endDate, productId, QString(response.data()));
82 response = Downloader::get(url);
80 response = Downloader::get(url);
83 auto test = QJsonDocument::fromJson(response.data());
81 auto test = QJsonDocument::fromJson(response.data());
84 url = test["dataFileURLs"].toString();
82 url = test["dataFileURLs"].toString();
85 response = Downloader::get(url);
83 response = Downloader::get(url);
86 return AmdaResultParser::readTxt(QTextStream{response.data()},productValueType);
84 return nullptr; // AmdaResultParser::readTxt(QTextStream { response.data() }, productValueType);
87 }
85 }
88
@@ -1,150 +1,149
1 #include "AmdaResultParser.h"
1 #include "AmdaResultParser.h"
2
2
3 #include "AmdaResultParserHelper.h"
3 #include "AmdaResultParserHelper.h"
4
4
5 #include <QFile>
5 #include <QFile>
6
6
7 #include <Data/IDataSeries.h>
8 #include <cmath>
7 #include <cmath>
9
8
10 Q_LOGGING_CATEGORY(LOG_AmdaResultParser, "AmdaResultParser")
9 Q_LOGGING_CATEGORY(LOG_AmdaResultParser, "AmdaResultParser")
11
10
12 namespace
11 namespace
13 {
12 {
14
13
15 /// Message in result file when the file was not found on server
14 /// Message in result file when the file was not found on server
16 const auto FILE_NOT_FOUND_MESSAGE = QStringLiteral("Not Found");
15 const auto FILE_NOT_FOUND_MESSAGE = QStringLiteral("Not Found");
17
16
18 /// Checks if a line is a comment line
17 /// Checks if a line is a comment line
19 bool isCommentLine(const QString& line)
18 bool isCommentLine(const QString& line)
20 {
19 {
21 return line.startsWith("#");
20 return line.startsWith("#");
22 }
21 }
23
22
24 /**
23 /**
25 * Creates helper that will be used to read AMDA file, according to the type passed as parameter
24 * Creates helper that will be used to read AMDA file, according to the type passed as parameter
26 * @param valueType the type of values expected in the AMDA file (scalars, vectors, spectrograms...)
25 * @param valueType the type of values expected in the AMDA file (scalars, vectors, spectrograms...)
27 * @return the helper created
26 * @return the helper created
28 */
27 */
29 std::unique_ptr<IAmdaResultParserHelper> createHelper(DataSeriesType valueType)
28 std::unique_ptr<IAmdaResultParserHelper> createHelper(DataSeriesType valueType)
30 {
29 {
31 switch (valueType)
30 switch (valueType)
32 {
31 {
33 case DataSeriesType::SCALAR:
32 case DataSeriesType::SCALAR:
34 return std::make_unique<ScalarParserHelper>();
33 return std::make_unique<ScalarParserHelper>();
35 case DataSeriesType::SPECTROGRAM:
34 case DataSeriesType::SPECTROGRAM:
36 return std::make_unique<SpectrogramParserHelper>();
35 return std::make_unique<SpectrogramParserHelper>();
37 case DataSeriesType::VECTOR:
36 case DataSeriesType::VECTOR:
38 return std::make_unique<VectorParserHelper>();
37 return std::make_unique<VectorParserHelper>();
39 case DataSeriesType::NONE:
38 case DataSeriesType::NONE:
40 // Invalid case
39 // Invalid case
41 break;
40 break;
42 }
41 }
43
42
44 // Invalid cases
43 // Invalid cases
45 qCCritical(LOG_AmdaResultParser())
44 qCCritical(LOG_AmdaResultParser())
46 << QObject::tr("Can't create helper to read result file: unsupported type");
45 << QObject::tr("Can't create helper to read result file: unsupported type");
47 return nullptr;
46 return nullptr;
48 }
47 }
49
48
50 /**
49 /**
51 * Reads properties of the stream passed as parameter
50 * Reads properties of the stream passed as parameter
52 * @param helper the helper used to read properties line by line
51 * @param helper the helper used to read properties line by line
53 * @param stream the stream to read
52 * @param stream the stream to read
54 */
53 */
55 void readProperties(IAmdaResultParserHelper& helper, QTextStream& stream)
54 void readProperties(IAmdaResultParserHelper& helper, QTextStream& stream)
56 {
55 {
57 // Searches properties in the comment lines (as long as the reading has not reached the data)
56 // Searches properties in the comment lines (as long as the reading has not reached the data)
58 // AMDA V2: while (stream.readLineInto(&line) && !line.contains(DATA_HEADER_REGEX)) {
57 // AMDA V2: while (stream.readLineInto(&line) && !line.contains(DATA_HEADER_REGEX)) {
59 QString line {};
58 QString line {};
60 while (stream.readLineInto(&line) && isCommentLine(line))
59 while (stream.readLineInto(&line) && isCommentLine(line))
61 {
60 {
62 helper.readPropertyLine(line);
61 helper.readPropertyLine(line);
63 }
62 }
64 }
63 }
65
64
66 /**
65 /**
67 * Reads results of the stream passed as parameter
66 * Reads results of the stream passed as parameter
68 * @param helper the helper used to read results line by line
67 * @param helper the helper used to read results line by line
69 * @param stream the stream to read
68 * @param stream the stream to read
70 */
69 */
71 void readResults(IAmdaResultParserHelper& helper, QTextStream& stream)
70 void readResults(IAmdaResultParserHelper& helper, QTextStream& stream)
72 {
71 {
73 QString line {};
72 QString line {};
74
73
75 // Skip comment lines
74 // Skip comment lines
76 while (stream.readLineInto(&line) && isCommentLine(line))
75 while (stream.readLineInto(&line) && isCommentLine(line))
77 {
76 {
78 }
77 }
79
78
80 if (!stream.atEnd())
79 if (!stream.atEnd())
81 {
80 {
82 do
81 do
83 {
82 {
84 helper.readResultLine(line);
83 helper.readResultLine(line);
85 } while (stream.readLineInto(&line));
84 } while (stream.readLineInto(&line));
86 }
85 }
87 }
86 }
88
87
89 } // namespace
88 } // namespace
90
89
91 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(
90 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(
92 const QString& filePath, DataSeriesType type) noexcept
91 const QString& filePath, DataSeriesType type) noexcept
93 {
92 {
94 if (type == DataSeriesType::NONE)
93 if (type == DataSeriesType::NONE)
95 {
94 {
96 qCCritical(LOG_AmdaResultParser())
95 qCCritical(LOG_AmdaResultParser())
97 << QObject::tr("Can't retrieve AMDA data: the type of values to be read is unknown");
96 << QObject::tr("Can't retrieve AMDA data: the type of values to be read is unknown");
98 return nullptr;
97 return nullptr;
99 }
98 }
100
99
101 QFile file { filePath };
100 QFile file { filePath };
102
101
103 if (!file.open(QFile::ReadOnly | QIODevice::Text))
102 if (!file.open(QFile::ReadOnly | QIODevice::Text))
104 {
103 {
105 qCCritical(LOG_AmdaResultParser())
104 qCCritical(LOG_AmdaResultParser())
106 << QObject::tr("Can't retrieve AMDA data from file %1: %2")
105 << QObject::tr("Can't retrieve AMDA data from file %1: %2")
107 .arg(filePath, file.errorString());
106 .arg(filePath, file.errorString());
108 return nullptr;
107 return nullptr;
109 }
108 }
110
109
111 return std::shared_ptr<IDataSeries> { AmdaResultParser::readTxt(QTextStream { &file }, type) };
110 return std::shared_ptr<IDataSeries> { AmdaResultParser::readTxt(QTextStream { &file }, type) };
112 }
111 }
113
112
114 IDataSeries* AmdaResultParser::readTxt(QTextStream stream, DataSeriesType type) noexcept
113 IDataSeries* AmdaResultParser::readTxt(QTextStream stream, DataSeriesType type) noexcept
115 {
114 {
116 if (type == DataSeriesType::NONE)
115 if (type == DataSeriesType::NONE)
117 {
116 {
118 return nullptr;
117 return nullptr;
119 }
118 }
120
119
121 // Checks if the file was found on the server
120 // Checks if the file was found on the server
122 auto firstLine = stream.readLine();
121 auto firstLine = stream.readLine();
123 if (firstLine.compare(FILE_NOT_FOUND_MESSAGE) == 0)
122 if (firstLine.compare(FILE_NOT_FOUND_MESSAGE) == 0)
124 {
123 {
125 return nullptr;
124 return nullptr;
126 }
125 }
127
126
128 auto helper = createHelper(type);
127 auto helper = createHelper(type);
129 Q_ASSERT(helper != nullptr);
128 Q_ASSERT(helper != nullptr);
130
129
131 // Reads header file to retrieve properties
130 // Reads header file to retrieve properties
132 stream.seek(0); // returns to the beginning of the file
131 stream.seek(0); // returns to the beginning of the file
133 readProperties(*helper, stream);
132 readProperties(*helper, stream);
134
133
135 // Checks properties
134 // Checks properties
136 if (helper->checkProperties())
135 if (helper->checkProperties())
137 {
136 {
138 // Reads results
137 // Reads results
139 // AMDA V2: remove line
138 // AMDA V2: remove line
140 stream.seek(0); // returns to the beginning of the file
139 stream.seek(0); // returns to the beginning of the file
141 readResults(*helper, stream);
140 readResults(*helper, stream);
142
141
143 // Creates data series
142 // Creates data series
144 return helper->createSeries();
143 return helper->createSeries();
145 }
144 }
146 else
145 else
147 {
146 {
148 return nullptr;
147 return nullptr;
149 }
148 }
150 }
149 }
@@ -1,128 +1,131
1 #ifndef SCIQLOP_FUZZINGDEFS_H
1 #ifndef SCIQLOP_FUZZINGDEFS_H
2 #define SCIQLOP_FUZZINGDEFS_H
2 #define SCIQLOP_FUZZINGDEFS_H
3
3
4 #include <Data/DateTimeRange.h>
4 #include <Data/DateTimeRange.h>
5
5
6 #include <QString>
6 #include <QString>
7 #include <QUuid>
7 #include <QUuid>
8 #include <QVariantHash>
8 #include <QVariantHash>
9
9
10 #include <memory>
10 #include <memory>
11 #include <set>
11 #include <set>
12
12
13 // /////// //
13 // /////// //
14 // Aliases //
14 // Aliases //
15 // /////// //
15 // /////// //
16
16
17 using MetadataPool = std::vector<QVariantHash>;
17 using MetadataPool = std::vector<QVariantHash>;
18 Q_DECLARE_METATYPE(MetadataPool)
18 Q_DECLARE_METATYPE(MetadataPool)
19
19
20 using Properties = QVariantHash;
20 using Properties = QVariantHash;
21
21
22 // ///////// //
22 // ///////// //
23 // Constants //
23 // Constants //
24 // ///////// //
24 // ///////// //
25
25
26 /// Timeout set for data acquisition for an operation (in ms)
26 /// Timeout set for data acquisition for an operation (in ms)
27 extern const QString ACQUISITION_TIMEOUT_PROPERTY;
27 extern const QString ACQUISITION_TIMEOUT_PROPERTY;
28
28
29 /// Max number of operations to generate
29 /// Max number of operations to generate
30 extern const QString NB_MAX_OPERATIONS_PROPERTY;
30 extern const QString NB_MAX_OPERATIONS_PROPERTY;
31
31
32 /// Max number of sync groups to create through operations
32 /// Max number of sync groups to create through operations
33 extern const QString NB_MAX_SYNC_GROUPS_PROPERTY;
33 extern const QString NB_MAX_SYNC_GROUPS_PROPERTY;
34
34
35 /// Max number of variables to manipulate through operations
35 /// Max number of variables to manipulate through operations
36 extern const QString NB_MAX_VARIABLES_PROPERTY;
36 extern const QString NB_MAX_VARIABLES_PROPERTY;
37
37
38 /// Set of operations available for the test
38 /// Set of operations available for the test
39 extern const QString AVAILABLE_OPERATIONS_PROPERTY;
39 extern const QString AVAILABLE_OPERATIONS_PROPERTY;
40
40
41 /// Tolerance used for variable's cache (in ratio)
41 /// Tolerance used for variable's cache (in ratio)
42 extern const QString CACHE_TOLERANCE_PROPERTY;
42 extern const QString CACHE_TOLERANCE_PROPERTY;
43
43
44 /// Range with which the timecontroller is initialized
44 /// Range with which the timecontroller is initialized
45 extern const QString INITIAL_RANGE_PROPERTY;
45 extern const QString INITIAL_RANGE_PROPERTY;
46
46
47 /// Max range that an operation can reach
47 /// Max range that an operation can reach
48 extern const QString MAX_RANGE_PROPERTY;
48 extern const QString MAX_RANGE_PROPERTY;
49
49
50 /// Set of metadata that can be associated to a variable
50 /// Set of metadata that can be associated to a variable
51 extern const QString METADATA_POOL_PROPERTY;
51 extern const QString METADATA_POOL_PROPERTY;
52
52
53 /// Provider used to retrieve data
53 /// Provider used to retrieve data
54 extern const QString PROVIDER_PROPERTY;
54 extern const QString PROVIDER_PROPERTY;
55
55
56 /// Min/max times left for an operation to execute
56 /// Min/max times left for an operation to execute
57 extern const QString OPERATION_DELAY_BOUNDS_PROPERTY;
57 extern const QString OPERATION_DELAY_BOUNDS_PROPERTY;
58
58
59 /// Validators used to validate an operation
59 /// Validators used to validate an operation
60 extern const QString VALIDATORS_PROPERTY;
60 extern const QString VALIDATORS_PROPERTY;
61
61
62 /// Min/max number of operations to execute before calling validation of the current test's state
62 /// Min/max number of operations to execute before calling validation of the current test's state
63 extern const QString VALIDATION_FREQUENCY_BOUNDS_PROPERTY;
63 extern const QString VALIDATION_FREQUENCY_BOUNDS_PROPERTY;
64
64
65 // /////// //
65 // /////// //
66 // Structs //
66 // Structs //
67 // /////// //
67 // /////// //
68
68
69 class Variable;
69 class Variable;
70 struct VariableState {
70 struct VariableState
71 std::shared_ptr<Variable> m_Variable{nullptr};
71 {
72 DateTimeRange m_Range{INVALID_RANGE};
72 std::shared_ptr<Variable> m_Variable { nullptr };
73 DateTimeRange m_Range { INVALID_RANGE };
73 };
74 };
74
75
75 using VariableId = int;
76 using VariableId = int;
76 using VariablesPool = std::map<VariableId, VariableState>;
77 using VariablesPool = std::map<VariableId, VariableState>;
77
78
78 /**
79 /**
79 * Defines a synchronization group for a fuzzing state. A group reports the variables synchronized
80 * Defines a synchronization group for a fuzzing state. A group reports the variables synchronized
80 * with each other, and the current range of the group (i.e. range of the last synchronized variable
81 * with each other, and the current range of the group (i.e. range of the last synchronized variable
81 * that has been moved)
82 * that has been moved)
82 */
83 */
83 struct SyncGroup {
84 struct SyncGroup
84 std::set<VariableId> m_Variables{};
85 {
85 DateTimeRange m_Range{INVALID_RANGE};
86 std::set<VariableId> m_Variables {};
87 DateTimeRange m_Range { INVALID_RANGE };
86 };
88 };
87
89
88 using SyncGroupId = QUuid;
90 using SyncGroupId = QUuid;
89 using SyncGroupsPool = std::map<SyncGroupId, SyncGroup>;
91 using SyncGroupsPool = std::map<SyncGroupId, SyncGroup>;
90
92
91 /**
93 /**
92 * Defines a current state during a fuzzing state. It contains all the variables manipulated during
94 * Defines a current state during a fuzzing state. It contains all the variables manipulated during
93 * the test, as well as the synchronization status of these variables.
95 * the test, as well as the synchronization status of these variables.
94 */
96 */
95 struct FuzzingState {
97 struct FuzzingState
96 const SyncGroup &syncGroup(SyncGroupId id) const;
98 {
97 SyncGroup &syncGroup(SyncGroupId id);
99 const SyncGroup& syncGroup(SyncGroupId id) const;
100 SyncGroup& syncGroup(SyncGroupId id);
98
101
99 const VariableState &variableState(VariableId id) const;
102 const VariableState& variableState(VariableId id) const;
100 VariableState &variableState(VariableId id);
103 VariableState& variableState(VariableId id);
101
104
102 /// @return the identifier of the synchronization group in which the variable passed in
105 /// @return the identifier of the synchronization group in which the variable passed in
103 /// parameter is located. If the variable is not in any group, returns an invalid identifier
106 /// parameter is located. If the variable is not in any group, returns an invalid identifier
104 SyncGroupId syncGroupId(VariableId variableId) const;
107 SyncGroupId syncGroupId(VariableId variableId) const;
105
108
106 /// @return the set of synchronization group identifiers
109 /// @return the set of synchronization group identifiers
107 std::vector<SyncGroupId> syncGroupsIds() const;
110 std::vector<SyncGroupId> syncGroupsIds() const;
108
111
109 /// Updates fuzzing state according to a variable synchronization
112 /// Updates fuzzing state according to a variable synchronization
110 /// @param variableId the variable that is synchronized
113 /// @param variableId the variable that is synchronized
111 /// @param syncGroupId the synchronization group
114 /// @param syncGroupId the synchronization group
112 void synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
115 void synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
113
116
114 /// Updates fuzzing state according to a variable desynchronization
117 /// Updates fuzzing state according to a variable desynchronization
115 /// @param variableId the variable that is desynchronized
118 /// @param variableId the variable that is desynchronized
116 /// @param syncGroupId the synchronization group from which to remove the variable
119 /// @param syncGroupId the synchronization group from which to remove the variable
117 void desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
120 void desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
118
121
119 /// Updates the range of a variable and all variables to which it is synchronized
122 /// Updates the range of a variable and all variables to which it is synchronized
120 /// @param the variable for which to affect the range
123 /// @param the variable for which to affect the range
121 /// @param the range to affect
124 /// @param the range to affect
122 void updateRanges(VariableId variableId, const DateTimeRange &newRange);
125 void updateRanges(VariableId variableId, const DateTimeRange& newRange);
123
126
124 VariablesPool m_VariablesPool;
127 VariablesPool m_VariablesPool;
125 SyncGroupsPool m_SyncGroupsPool;
128 SyncGroupsPool m_SyncGroupsPool;
126 };
129 };
127
130
128 #endif // SCIQLOP_FUZZINGDEFS_H
131 #endif // SCIQLOP_FUZZINGDEFS_H
@@ -1,31 +1,32
1 #ifndef SCIQLOP_COSINUSPROVIDER_H
1 #ifndef SCIQLOP_COSINUSPROVIDER_H
2 #define SCIQLOP_COSINUSPROVIDER_H
2 #define SCIQLOP_COSINUSPROVIDER_H
3
3
4 #include "MockPluginGlobal.h"
4 #include "MockPluginGlobal.h"
5
5
6 #include <Data/IDataProvider.h>
6 #include <Data/IDataProvider.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QUuid>
9 #include <QUuid>
10
10
11 #include <QHash>
11 #include <QHash>
12
12
13 /**
13 /**
14 * @brief The CosinusProvider class is an example of how a data provider can generate data
14 * @brief The CosinusProvider class is an example of how a data provider can generate data
15 */
15 */
16 class SCIQLOP_MOCKPLUGIN_EXPORT CosinusProvider : public IDataProvider {
16 class SCIQLOP_MOCKPLUGIN_EXPORT CosinusProvider : public IDataProvider
17 {
17 public:
18 public:
18 std::shared_ptr<IDataProvider> clone() const override;
19 std::shared_ptr<IDataProvider> clone() const override;
19
20
20 virtual IDataSeries* getData(const DataProviderParameters &parameters) override;
21 virtual TimeSeries::ITimeSerie* getData(const DataProviderParameters& parameters) override;
21
22
22 private:
23 private:
23 std::shared_ptr<IDataSeries>
24 std::shared_ptr<IDataSeries> retrieveData(
24 retrieveData(QUuid acqIdentifier, const DateTimeRange &dataRangeRequested, const QVariantHash &data);
25 QUuid acqIdentifier, const DateTimeRange& dataRangeRequested, const QVariantHash& data);
25
26
26 IDataSeries* _generate(const DateTimeRange &range, const QVariantHash &metaData);
27 TimeSeries::ITimeSerie* _generate(const DateTimeRange& range, const QVariantHash& metaData);
27
28
28 QHash<QUuid, bool> m_VariableToEnableProvider;
29 QHash<QUuid, bool> m_VariableToEnableProvider;
29 };
30 };
30
31
31 #endif // SCIQLOP_COSINUSPROVIDER_H
32 #endif // SCIQLOP_COSINUSPROVIDER_H
@@ -1,204 +1,87
1 #include "CosinusProvider.h"
1 #include "CosinusProvider.h"
2 #include "MockDefs.h"
2 #include "MockDefs.h"
3
3
4 #include <Data/DataProviderParameters.h>
4 #include <Data/DataProviderParameters.h>
5 #include <Data/ScalarSeries.h>
5 #include <Data/ScalarTimeSerie.h>
6 #include <Data/SpectrogramSeries.h>
6 #include <Data/SpectrogramTimeSerie.h>
7 #include <Data/VectorSeries.h>
7 #include <Data/VectorTimeSerie.h>
8
8
9 #include <cmath>
9 #include <cmath>
10 #include <set>
10 #include <set>
11
11
12 #include <QFuture>
12 #include <QFuture>
13 #include <QThread>
13 #include <QThread>
14 #include <QtConcurrent/QtConcurrent>
14 #include <QtConcurrent/QtConcurrent>
15
15
16
16
17 namespace {
17 namespace
18 {
18
19
19 /// Number of bands generated for a spectrogram
20 /// Number of bands generated for a spectrogram
20 const auto SPECTROGRAM_NUMBER_BANDS = 30;
21 const auto SPECTROGRAM_NUMBER_BANDS = 30;
21
22
22 /// Bands for which to generate NaN values for a spectrogram
23 /// Bands for which to generate NaN values for a spectrogram
23 const auto SPECTROGRAM_NAN_BANDS = std::set<int>{1, 3, 10, 20};
24 const auto SPECTROGRAM_NAN_BANDS = std::set<int> { 1, 3, 10, 20 };
24
25
25 /// Bands for which to generate zeros for a spectrogram
26 /// Bands for which to generate zeros for a spectrogram
26 const auto SPECTROGRAM_ZERO_BANDS = std::set<int>{2, 15, 19, 29};
27 const auto SPECTROGRAM_ZERO_BANDS = std::set<int> { 2, 15, 19, 29 };
27
28 /// Abstract cosinus type
29 struct ICosinusType {
30 virtual ~ICosinusType() = default;
31 /// @return the number of components generated for the type
32 virtual std::size_t componentCount() const = 0;
33 /// @return the data series created for the type
34 virtual IDataSeries* createDataSeries(std::vector<double> xAxisData,
35 std::vector<double> valuesData) const = 0;
36 /// Generates values (one value per component)
37 /// @param x the x-axis data used to generate values
38 /// @param values the vector in which to insert the generated values
39 /// @param dataIndex the index of insertion of the generated values
40 ///
41 virtual void generateValues(double x, std::vector<double> &values, int dataIndex) const = 0;
42 };
43
44 struct ScalarCosinus : public ICosinusType {
45 std::size_t componentCount() const override { return 1; }
46
47 IDataSeries* createDataSeries(std::vector<double> xAxisData,
48 std::vector<double> valuesData) const override
49 {
50 return new ScalarSeries(std::move(xAxisData), std::move(valuesData),
51 Unit{QStringLiteral("t"), true}, Unit{});
52 }
53
54 void generateValues(double x, std::vector<double> &values, int dataIndex) const override
55 {
56 values[dataIndex] = std::cos(x);
57 }
58 };
59
60 struct SpectrogramCosinus : public ICosinusType {
61 /// Ctor with y-axis
62 explicit SpectrogramCosinus(std::vector<double> yAxisData, Unit yAxisUnit, Unit valuesUnit)
63 : m_YAxisData{std::move(yAxisData)},
64 m_YAxisUnit{std::move(yAxisUnit)},
65 m_ValuesUnit{std::move(valuesUnit)}
66 {
67 }
68
69 std::size_t componentCount() const override { return m_YAxisData.size(); }
70
71 IDataSeries* createDataSeries(std::vector<double> xAxisData,
72 std::vector<double> valuesData) const override
73 {
74 return new SpectrogramSeries(
75 std::move(xAxisData), m_YAxisData, std::move(valuesData),
76 Unit{QStringLiteral("t"), true}, m_YAxisUnit, m_ValuesUnit);
77 }
78
79 void generateValues(double x, std::vector<double> &values, int dataIndex) const override
80 {
81 auto componentCount = this->componentCount();
82 for (int i = 0; i < componentCount; ++i) {
83 auto y = m_YAxisData[i];
84
85 double value;
86
87 // if (SPECTROGRAM_ZERO_BANDS.find(y) != SPECTROGRAM_ZERO_BANDS.end()) {
88 // value = 0.;
89 // }
90 // else if (SPECTROGRAM_NAN_BANDS.find(y) != SPECTROGRAM_NAN_BANDS.end()) {
91 // value = std::numeric_limits<double>::quiet_NaN();
92 // }
93 // else
94 {
95 // Generates value for non NaN/zero bands
96 //auto r = 3 * std::sqrt(x * x + y * y) + 1e-2;
97 //value = 2 * x * (std::cos(r + 2) / r - std::sin(r + 2) / r);
98 value = x + 10*y;
99 }
100
101 values[componentCount * dataIndex + i] = value;
102 }
103 }
104
105 std::vector<double> m_YAxisData;
106 Unit m_YAxisUnit;
107 Unit m_ValuesUnit;
108 };
109
110 struct VectorCosinus : public ICosinusType {
111 std::size_t componentCount() const override { return 3; }
112
28
113 IDataSeries* createDataSeries(std::vector<double> xAxisData,
114 std::vector<double> valuesData) const override
115 {
116 return new VectorSeries(std::move(xAxisData), std::move(valuesData),
117 Unit{QStringLiteral("t"), true}, Unit{});
118 }
119
120 void generateValues(double x, std::vector<double> &values, int dataIndex) const override
121 {
122 // Generates value for each component: cos(x), cos(x)/2, cos(x)/3
123 auto xValue = std::cos(x);
124 auto componentCount = this->componentCount();
125 for (auto i = 0; i < componentCount; ++i) {
126 values[componentCount * dataIndex + i] = xValue / (i + 1);
127 }
128 }
129 };
130
131 /// Converts string to cosinus type
132 /// @return the cosinus type if the string could be converted, nullptr otherwise
133 std::unique_ptr<ICosinusType> cosinusType(const QString &type) noexcept
134 {
135 if (type.compare(QStringLiteral("scalar"), Qt::CaseInsensitive) == 0) {
136 return std::make_unique<ScalarCosinus>();
137 }
138 else if (type.compare(QStringLiteral("spectrogram"), Qt::CaseInsensitive) == 0) {
139 // Generates default y-axis data for spectrogram [0., 1., 2., ...]
140 std::vector<double> yAxisData(SPECTROGRAM_NUMBER_BANDS);
141 std::iota(yAxisData.begin(), yAxisData.end(), 1.);
142 for (auto & v:yAxisData)
143 {
144 v = std::pow(2,v);
145 }
146 return std::make_unique<SpectrogramCosinus>(std::move(yAxisData), Unit{"eV"},
147 Unit{"eV/(cm^2-s-sr-eV)"});
148 }
149 else if (type.compare(QStringLiteral("vector"), Qt::CaseInsensitive) == 0) {
150 return std::make_unique<VectorCosinus>();
151 }
152 else {
153 return nullptr;
154 }
155 }
156
29
157 } // namespace
30 } // namespace
158
31
159 std::shared_ptr<IDataProvider> CosinusProvider::clone() const
32 std::shared_ptr<IDataProvider> CosinusProvider::clone() const
160 {
33 {
161 // No copy is made in clone
34 // No copy is made in clone
162 return std::make_shared<CosinusProvider>();
35 return std::make_shared<CosinusProvider>();
163 }
36 }
164
37
165 IDataSeries *CosinusProvider::_generate(const DateTimeRange &range, const QVariantHash &metaData)
38 TimeSeries::ITimeSerie* CosinusProvider::_generate(
39 const DateTimeRange& range, const QVariantHash& metaData)
166 {
40 {
167 auto dataIndex = 0;
168
169 // Retrieves cosinus type
41 // Retrieves cosinus type
170 auto typeVariant = metaData.value(COSINUS_TYPE_KEY, COSINUS_TYPE_DEFAULT_VALUE);
42 auto typeVariant = metaData.value(COSINUS_TYPE_KEY, COSINUS_TYPE_DEFAULT_VALUE);
171 auto type = cosinusType(typeVariant.toString());
172 auto freqVariant = metaData.value(COSINUS_FREQUENCY_KEY, COSINUS_FREQUENCY_DEFAULT_VALUE);
43 auto freqVariant = metaData.value(COSINUS_FREQUENCY_KEY, COSINUS_FREQUENCY_DEFAULT_VALUE);
44 const auto fs = 200.;
173 double freq = freqVariant.toDouble();
45 double freq = freqVariant.toDouble();
174 double start = std::ceil(range.m_TStart * freq);
46 double start = std::ceil(range.m_TStart * freq);
175 double end = std::floor(range.m_TEnd * freq);
47 double end = std::floor(range.m_TEnd * freq);
176 if (end < start) {
48 if (end < start)
49 {
177 std::swap(start, end);
50 std::swap(start, end);
178 }
51 }
179 std::size_t dataCount = static_cast<std::size_t>(end - start + 1);
52 std::size_t dataCount = static_cast<std::size_t>(end - start + 1);
180 std::size_t componentCount = type->componentCount();
53 if (typeVariant.toString() == QStringLiteral("scalar"))
181
182 auto xAxisData = std::vector<double>{};
183 xAxisData.resize(dataCount);
184
185 auto valuesData = std::vector<double>{};
186 valuesData.resize(dataCount * componentCount);
187
188 int progress = 0;
189 auto progressEnd = dataCount;
190 for (auto time = start; time <= end; ++time, ++dataIndex)
191 {
54 {
192 const auto x = time / freq;
55 auto ts = new ScalarTimeSerie(dataCount);
193 xAxisData[dataIndex] = x;
56 std::generate(
194 // Generates values (depending on the type)
57 std::begin(*ts), std::end(*ts), [range, freq, fs, dt = 1. / freq, i = 0.]() mutable {
195 type->generateValues(x, valuesData, dataIndex);
58 auto t = range.m_TStart + i * dt;
59 i++;
60 return std::pair<double, double> { t, std::cos(2 * 3.14 * freq / fs * t) };
61 });
62 return ts;
196 }
63 }
197 return type->createDataSeries(std::move(xAxisData), std::move(valuesData));
64 if (typeVariant.toString() == QStringLiteral("vector"))
65 {
66 auto ts = new VectorTimeSerie(dataCount);
67 std::generate(
68 std::begin(*ts), std::end(*ts), [range, freq, fs, dt = 1. / freq, i = 0.]() mutable {
69 auto t = range.m_TStart + i * dt;
70 i++;
71 return std::pair<double, VectorTimeSerie::raw_value_type> { t,
72 { std::cos(2 * 3.14 * freq / fs * t), std::sin(2 * 3.14 * freq / fs * t),
73 std::cos(2 * 3.14 * freq / fs * t) * std::sin(2 * 3.14 * freq / fs * t) } };
74 });
75 return ts;
76 }
77 if (typeVariant.toString() == QStringLiteral("spectrogram"))
78 {
79 return nullptr;
80 }
81 return nullptr;
198 }
82 }
199
83
200 IDataSeries* CosinusProvider::getData(const DataProviderParameters &parameters)
84 TimeSeries::ITimeSerie* CosinusProvider::getData(const DataProviderParameters& parameters)
201 {
85 {
202 return _generate(parameters.m_Range, parameters.m_Data);
86 return _generate(parameters.m_Range, parameters.m_Data);
203 }
87 }
204
@@ -1,85 +1,86
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) 2018, Plasma Physics Laboratory - CNRS
3 -- Copyright (C) 2018, 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 <string>
23 #include <sstream>
24 #include <memory>
22 #include <memory>
23 #include <sstream>
24 #include <string>
25
25
26 #include <pybind11/pybind11.h>
26 #include <pybind11/chrono.h>
27 #include <pybind11/operators.h>
28 #include <pybind11/embed.h>
27 #include <pybind11/embed.h>
29 #include <pybind11/numpy.h>
28 #include <pybind11/numpy.h>
30 #include <pybind11/chrono.h>
29 #include <pybind11/operators.h>
30 #include <pybind11/pybind11.h>
31
31
32 #include <Common/DateUtils.h>
33 #include <Data/DataSeriesType.h>
34 #include <Data/DateTimeRange.h>
32 #include <SqpApplication.h>
35 #include <SqpApplication.h>
33 #include <Variable/VariableController2.h>
34 #include <Time/TimeController.h>
36 #include <Time/TimeController.h>
35 #include <Data/DateTimeRange.h>
37 #include <Variable/VariableController2.h>
36 #include <Data/DataSeriesType.h>
37 #include <Common/DateUtils.h>
38 #include <Variable/Variable.h>
39 #include <Data/ScalarSeries.h>
40 #include <Data/VectorSeries.h>
41
38
42 #include <MockPlugin.h>
43 #include <CosinusProvider.h>
39 #include <CosinusProvider.h>
40 #include <MockPlugin.h>
44
41
45 #include <QFile>
42 #include <QFile>
46
43
47 #include <pywrappers_common.h>
48 #include <CoreWrappers.h>
44 #include <CoreWrappers.h>
49
45 #include <pywrappers_common.h>
50
46
51
47
52 using namespace std::chrono;
48 using namespace std::chrono;
53 namespace py = pybind11;
49 namespace py = pybind11;
54
50
55
51
56
52 PYBIND11_MODULE(pytestmockplugin, m)
57 PYBIND11_MODULE(pytestmockplugin, m){
53 {
58
54
59 int argc = 0;
55 int argc = 0;
60 char ** argv=nullptr;
56 char** argv = nullptr;
61 SqpApplication::setOrganizationName("LPP");
57 SqpApplication::setOrganizationName("LPP");
62 SqpApplication::setOrganizationDomain("lpp.fr");
58 SqpApplication::setOrganizationDomain("lpp.fr");
63 SqpApplication::setApplicationName("SciQLop");
59 SqpApplication::setApplicationName("SciQLop");
64 static SqpApplication app(argc, argv);
60 static SqpApplication app(argc, argv);
65
61
66 auto qtmod = py::module::import("sciqlopqt");
62 auto qtmod = py::module::import("sciqlopqt");
67 auto sciqlopmod = py::module::import("pysciqlopcore");
63 auto sciqlopmod = py::module::import("pysciqlopcore");
68
64
69 m.doc() = "";
65 m.doc() = "";
70
66
71 py::class_<VariableController2>(m, "VariableController2").def_static("createVariable",[](const QString &name,
67 py::class_<VariableController2>(m, "VariableController2")
72 std::shared_ptr<IDataProvider> provider, const DateTimeRange& range){
68 .def_static("createVariable",
73 return sqpApp->variableController().createVariable(name, {{"cosinusType", "spectrogram"}, {"cosinusFrequency", "0.1"}}, provider, range);
69 [](const QString& name, std::shared_ptr<IDataProvider> provider,
70 const DateTimeRange& range) {
71 return sqpApp->variableController().createVariable(name,
72 { { "cosinusType", "spectrogram" }, { "cosinusFrequency", "0.1" } }, provider,
73 range);
74 });
75
76 py::class_<TimeController>(m, "TimeController").def_static("setTime", [](DateTimeRange range) {
77 sqpApp->timeController().setDateTimeRange(range);
74 });
78 });
75
79
76 py::class_<TimeController>(m,"TimeController")
77 .def_static("setTime", [](DateTimeRange range){sqpApp->timeController().setDateTimeRange(range);});
78
79 auto mock_provider = std::make_shared<CosinusProvider>();
80 auto mock_provider = std::make_shared<CosinusProvider>();
80 m.def("mock_provider",[mock_provider](){return mock_provider;}, py::return_value_policy::copy);
81 m.def("mock_provider", [mock_provider]() { return mock_provider; },
81
82 py::return_value_policy::copy);
82 py::class_<CosinusProvider, std::shared_ptr<CosinusProvider>, IDataProvider>(m, "CosinusProvider");
83
83
84 py::class_<CosinusProvider, std::shared_ptr<CosinusProvider>, IDataProvider>(
85 m, "CosinusProvider");
84 }
86 }
85
General Comments 0
You need to be logged in to leave comments. Login now