##// END OF EJS Templates
PySide2 bindings + some GUI clean...
jeandet -
r1478:6e3f56cd8c8b
parent child
Show More
@@ -63,7 +63,7 include_directories(
63 ${PYSIDE_INCLUDE_DIR}/QtGui
63 ${PYSIDE_INCLUDE_DIR}/QtGui
64 ${PYSIDE_INCLUDE_DIR}/QtWidgets)
64 ${PYSIDE_INCLUDE_DIR}/QtWidgets)
65
65
66 add_library(SciQLopBindings MODULE ${BINDINGS_SOURCE} numpy_wrappers.h)
66 add_library(SciQLopBindings MODULE ${BINDINGS_SOURCE} numpy_wrappers.h PyDataProvider.h)
67 set_target_properties(
67 set_target_properties(
68 SciQLopBindings
68 SciQLopBindings
69 PROPERTIES
69 PROPERTIES
@@ -1,16 +1,89
1 #pragma once
1 #pragma once
2 #include <Data/DataProviderParameters.h>
2 #include <Data/IDataProvider.h>
3 #include <Data/IDataProvider.h>
4 #include <DataSource/DataSourceController.h>
5 #include <DataSource/DataSourceItem.h>
6 #include <DataSource/DataSourceItemAction.h>
7 #include <QPair>
8 #include <SqpApplication.h>
9 // must be included last because of Python/Qt definition of slots
10 #include "numpy_wrappers.h"
11
12 struct Product
13 {
14 QString path;
15 std::vector<std::string> components;
16 QMap<QString, QString> metadata;
17 Product() = default;
18 explicit Product(const QString& path, const std::vector<std::string>& components,
19 const QMap<QString, QString>& metadata)
20 : path { path }, components { components }, metadata { metadata }
21 {
22 }
23 virtual ~Product() = default;
24 };
3
25
4 class PyDataProvider : public IDataProvider
26 class PyDataProvider : public IDataProvider
5 {
27 {
6 public:
28 public:
7 PyDataProvider() {}
29 PyDataProvider()
30 {
31 auto& dataSourceController = sqpApp->dataSourceController();
32 dataSourceController.registerProvider(this);
33 }
34
35 virtual ~PyDataProvider() {}
8
36
9 virtual TimeSeries::ITimeSerie getData(const std::string& key, double start_time, double stop_time)
37 virtual QPair<NpArray, NpArray> getData(
10 {}
38 const std::string& key, double start_time, double stop_time)
39 {
40 (void)key, (void)start_time, (void)stop_time;
41 return {};
42 }
11
43
12 virtual TimeSeries::ITimeSerie* getData(const DataProviderParameters& parameters)
44 virtual TimeSeries::ITimeSerie* getData(const DataProviderParameters& parameters) override
13 {
45 {
46 if (parameters.m_Data.contains("name"))
47 {
48 auto data = getData(parameters.m_Data["name"].toString().toStdString(),
49 parameters.m_Range.m_TStart, parameters.m_Range.m_TEnd);
50 // TODO add shape/type switch
51 return new ScalarTimeSerie { data.first.to_std_vect(), data.second.to_std_vect() };
52 }
14 return nullptr;
53 return nullptr;
15 }
54 }
55
56
57 inline void register_products(const QVector<Product*>& products)
58 {
59 auto& dataSourceController = sqpApp->dataSourceController();
60 auto id = this->id();
61 auto data_source_name = this->name();
62 std::for_each(std::cbegin(products), std::cend(products),
63 [&id, &dataSourceController](const Product* product) {
64 dataSourceController.setDataSourceItem(id, product->path, product->metadata);
65 });
66 }
16 };
67 };
68
69
70 struct Providers
71 {
72 Providers() = default;
73 virtual ~Providers() = default;
74 inline void register_provider(PyDataProvider* provider)
75 {
76 auto& dataSourceController = sqpApp->dataSourceController();
77 dataSourceController.setDataProvider(
78 provider->id(), std::unique_ptr<IDataProvider>(provider));
79 }
80 };
81
82
83 inline ScalarTimeSerie test_PyDataProvider(PyDataProvider& prov)
84 {
85 auto v = prov.getData("", 0., 0.);
86 ScalarTimeSerie s;
87 s.set_data(v.first.to_std_vect(), v.second.to_std_vect());
88 return s;
89 }
@@ -31,18 +31,36
31 </target-to-native>
31 </target-to-native>
32 </conversion-rule>
32 </conversion-rule>
33 </container-type>
33 </container-type>
34 <object-type name="PyDataProvider" />
35 <object-type name="Product" />
34 <object-type name="MainWindow" />
36 <object-type name="MainWindow" />
35 <object-type name="SqpApplication">
37 <object-type name="SqpApplication">
36 <modify-function signature="SqpApplication(int&amp;,char**)" access="private"/>
38 <modify-function signature="SqpApplication(int&amp;,char**)" access="private"/>
37 </object-type>
39 </object-type>
38 <object-type name="PyDataProvider" />
40 <object-type name="Providers">
39 <function signature="SqpApplication_ctor()"/>
41 <modify-function signature="register_provider(PyDataProvider*)">
42 <modify-argument index="1">
43 <define-ownership owner="c++" />
44 </modify-argument>
45 </modify-function>
46 </object-type>
47 <function signature="SqpApplication_ctor()" return-type="SqpApplication*"/>
48 <add-function signature="SqpApplication_ctor(PySequence)" return-type="SqpApplication*">
49 <inject-code class="target">
50 static int argc;
51 static char **argv;
52 Shiboken::listToArgcArgv(%1, &amp;argc, &amp;argv, "PySideApp");
53 auto retval = new SqpApplication(argc,argv);
54 %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
55 </inject-code>
56 </add-function>
40 <function signature="init_resources()"/>
57 <function signature="init_resources()"/>
41 <primitive-type name="NpArray" target-lang-api-name="PyObject">
58 <primitive-type name="NpArray" target-lang-api-name="PyObject">
42 <include file-name="numpy_wrappers.h" location="local"/>
59 <include file-name="numpy_wrappers.h" location="local"/>
43 <conversion-rule>
60 <conversion-rule>
44 <native-to-target>
61 <native-to-target>
45 return %in.py_object();
62 auto result = %in.py_object();
63 return result;
46 </native-to-target>
64 </native-to-target>
47 <target-to-native>
65 <target-to-native>
48 <add-conversion type="PyObject" check="NpArray::isNpArray(%in)">
66 <add-conversion type="PyObject" check="NpArray::isNpArray(%in)">
@@ -68,5 +86,6
68 </inject-code>
86 </inject-code>
69 </add-function>
87 </add-function>
70 </object-type>
88 </object-type>
89 <function signature="test_PyDataProvider(PyDataProvider&amp;)"/>
71 <function signature="test_np_array(NpArray&amp;)"/>
90 <function signature="test_np_array(NpArray&amp;)"/>
72 </typesystem>
91 </typesystem>
@@ -4,6 +4,17
4 #define Py_DEBUG
4 #define Py_DEBUG
5 #include <Python.h>
5 #include <Python.h>
6
6
7 wchar_t** decode_argv(int argc, char** argv)
8 {
9 wchar_t** _argv = static_cast<wchar_t**>(PyMem_Malloc(sizeof(wchar_t*) * argc));
10 for (int i = 0; i < argc; i++)
11 {
12 wchar_t* arg = Py_DecodeLocale(argv[i], NULL);
13 _argv[i] = arg;
14 }
15 return _argv;
16 }
17
7 int main(int argc, char** argv)
18 int main(int argc, char** argv)
8 {
19 {
9 wchar_t* program = Py_DecodeLocale(argv[0], NULL);
20 wchar_t* program = Py_DecodeLocale(argv[0], NULL);
@@ -12,8 +23,10 int main(int argc, char** argv)
12 fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
23 fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
13 exit(1);
24 exit(1);
14 }
25 }
26
15 Py_SetProgramName(program); /* optional but recommended */
27 Py_SetProgramName(program); /* optional but recommended */
16 Py_Initialize();
28 Py_Initialize();
29 PySys_SetArgv(argc, decode_argv(argc, argv));
17 std::ifstream t(argv[1]);
30 std::ifstream t(argv[1]);
18 std::string str((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
31 std::string str((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
19 PyRun_SimpleString(str.data());
32 PyRun_SimpleString(str.data());
@@ -6,6 +6,7 from PySide2.QtWidgets import QApplication, QMainWindow, QDockWidget
6 from PySide2.QtCore import QSize, Qt
6 from PySide2.QtCore import QSize, Qt
7 from PySide2 import QtGui
7 from PySide2 import QtGui
8 import os
8 import os
9 sys.path.append(os.getcwd())
9 from SciQLopBindings import SqpApplication, MainWindow, init_resources, load_plugins, SqpApplication_ctor
10 from SciQLopBindings import SqpApplication, MainWindow, init_resources, load_plugins, SqpApplication_ctor
10 from qtconsole.rich_ipython_widget import RichJupyterWidget
11 from qtconsole.rich_ipython_widget import RichJupyterWidget
11 from qtconsole.inprocess import QtInProcessKernelManager
12 from qtconsole.inprocess import QtInProcessKernelManager
@@ -91,7 +92,7 def print_process_id():
91
92
92 if __name__ == "__main__":
93 if __name__ == "__main__":
93 init_resources()
94 init_resources()
94 app = SqpApplication_ctor()
95 app = SqpApplication_ctor(sys.argv)
95 QtGui.qApp = app
96 QtGui.qApp = app
96 load_plugins(app)
97 load_plugins(app)
97 main_window = MainWindow()
98 main_window = MainWindow()
@@ -29,6 +29,8 extern "C"
29 #endif
29 #endif
30 #include <assert.h>
30 #include <assert.h>
31
31
32 #include <map>
33
32 inline int init_numpy()
34 inline int init_numpy()
33 {
35 {
34 import_array(); // PyError if not successful
36 import_array(); // PyError if not successful
@@ -39,32 +41,31 template <typename dest_type = PyObject>
39 struct PyObjectWrapper
41 struct PyObjectWrapper
40 {
42 {
41 private:
43 private:
42 PyObject* _py_obj;
44 PyObject* _py_obj = nullptr;
43
44 void inc_refcount()
45 void inc_refcount()
45 {
46 {
46 if (_py_obj)
47 Py_XINCREF(_py_obj);
47 Py_IncRef(_py_obj);
48 }
48 }
49 void dec_refcount()
49 void dec_refcount()
50 {
50 {
51 if (_py_obj)
51 Py_XDECREF(_py_obj);
52 Py_DecRef(_py_obj);
52 _py_obj = nullptr;
53 }
53 }
54
54
55 public:
55 public:
56 PyObjectWrapper() : _py_obj { nullptr } {}
56 PyObjectWrapper() : _py_obj { nullptr } {}
57 PyObjectWrapper(const PyObjectWrapper& other) : _py_obj { other._py_obj } { inc_refcount(); };
57 PyObjectWrapper(const PyObjectWrapper& other) : _py_obj { other._py_obj } { inc_refcount(); }
58 PyObjectWrapper(PyObjectWrapper&& other) : _py_obj { other._py_obj }
58 PyObjectWrapper(PyObjectWrapper&& other) : _py_obj { other._py_obj } { inc_refcount(); }
59 explicit PyObjectWrapper(PyObject* obj) : _py_obj { obj }
59 {
60 {
60 other._py_obj = nullptr;
61 inc_refcount();
61 }
62 }
62 PyObjectWrapper(PyObject* obj) : _py_obj { obj } { inc_refcount(); }
63 ~PyObjectWrapper() { dec_refcount(); }
63 ~PyObjectWrapper() { dec_refcount(); }
64 PyObjectWrapper& operator=(PyObjectWrapper&& other)
64 PyObjectWrapper& operator=(PyObjectWrapper&& other)
65 {
65 {
66 dec_refcount();
66 this->_py_obj = other._py_obj;
67 this->_py_obj = other._py_obj;
67 other._py_obj = nullptr;
68 inc_refcount();
68 return *this;
69 return *this;
69 }
70 }
70 PyObjectWrapper& operator=(const PyObjectWrapper& other)
71 PyObjectWrapper& operator=(const PyObjectWrapper& other)
@@ -91,14 +92,14 private:
91 public:
92 public:
92 static bool isNpArray(PyObject* obj)
93 static bool isNpArray(PyObject* obj)
93 {
94 {
94 return obj && PyArray_Check(reinterpret_cast<PyArrayObject*>(obj))
95 auto arr = reinterpret_cast<PyArrayObject*>(obj);
95 && PyArray_IS_C_CONTIGUOUS(reinterpret_cast<PyArrayObject*>(obj));
96 auto is_c_aray = obj && PyArray_Check(arr) && PyArray_ISCARRAY(arr);
97 return is_c_aray;
96 }
98 }
97 NpArray() : _py_obj { nullptr } {}
99 NpArray() : _py_obj { nullptr } {}
98 NpArray(NpArray&& other) : _py_obj { std::move(other._py_obj) } {}
100 NpArray(NpArray&& other) : _py_obj { other._py_obj } {}
99 explicit NpArray(PyObject* obj) : _py_obj { obj }
101 explicit NpArray(PyObject* obj) : _py_obj { obj }
100 {
102 {
101 std::cout << "NpArray ctor" << std::endl;
102 assert(isNpArray(obj));
103 assert(isNpArray(obj));
103 assert(PyArray_ISFLOAT(_py_obj.get()));
104 assert(PyArray_ISFLOAT(_py_obj.get()));
104 }
105 }
@@ -111,7 +112,7 public:
111
112
112 NpArray& operator=(NpArray&& other)
113 NpArray& operator=(NpArray&& other)
113 {
114 {
114 this->_py_obj = std::move(other._py_obj);
115 this->_py_obj = other._py_obj;
115 return *this;
116 return *this;
116 }
117 }
117
118
@@ -9,7 +9,7
9 #include <QWidget>
9 #include <QWidget>
10 #include <TimeWidget/TimeWidget.h>
10 #include <TimeWidget/TimeWidget.h>
11
11
12 // @TODO remove this, shouldn't need to include SqpApplication to get PlotsInteractionMode
12 // TODO remove this, shouldn't need to include SqpApplication to get PlotsInteractionMode
13 #include <SqpApplication.h>
13 #include <SqpApplication.h>
14
14
15 class ToolBar : public QToolBar
15 class ToolBar : public QToolBar
@@ -25,6 +25,7
25 #include <Catalogue/CatalogueController.h>
25 #include <Catalogue/CatalogueController.h>
26 #include <Catalogue2/browser.h>
26 #include <Catalogue2/browser.h>
27 #include <DataSource/DataSourceController.h>
27 #include <DataSource/DataSourceController.h>
28 #include <DataSource/DataSourceItem.h>
28 #include <DataSource/DataSourceWidget.h>
29 #include <DataSource/DataSourceWidget.h>
29 #include <Settings/SqpSettingsDialog.h>
30 #include <Settings/SqpSettingsDialog.h>
30 #include <Settings/SqpSettingsGeneralWidget.h>
31 #include <Settings/SqpSettingsGeneralWidget.h>
@@ -48,29 +49,16
48
49
49 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
50 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
50
51
51 namespace
52 {
53 const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0;
54 const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1;
55 const auto VIEWPLITTERINDEX = 2;
56 const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3;
57 const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4;
58 }
59
60 class MainWindow::MainWindowPrivate
52 class MainWindow::MainWindowPrivate
61 {
53 {
62 public:
54 public:
63 explicit MainWindowPrivate(MainWindow* mainWindow)
55 explicit MainWindowPrivate(MainWindow* mainWindow)
64 : m_LastOpenLeftInspectorSize {}
56 : m_GeneralSettingsWidget { new SqpSettingsGeneralWidget { mainWindow } }
65 , m_LastOpenRightInspectorSize {}
66 , m_GeneralSettingsWidget { new SqpSettingsGeneralWidget { mainWindow } }
67 , m_SettingsDialog { new SqpSettingsDialog { mainWindow } }
57 , m_SettingsDialog { new SqpSettingsDialog { mainWindow } }
68 , m_CatalogExplorer { new CataloguesBrowser { mainWindow } }
58 , m_CatalogExplorer { new CataloguesBrowser { mainWindow } }
69 {
59 {
70 }
60 }
71
61
72 QSize m_LastOpenLeftInspectorSize;
73 QSize m_LastOpenRightInspectorSize;
74 /// General settings widget. MainWindow has the ownership
62 /// General settings widget. MainWindow has the ownership
75 SqpSettingsGeneralWidget* m_GeneralSettingsWidget;
63 SqpSettingsGeneralWidget* m_GeneralSettingsWidget;
76 /// Settings dialog. MainWindow has the ownership
64 /// Settings dialog. MainWindow has the ownership
@@ -89,67 +77,6 MainWindow::MainWindow(QWidget* parent)
89 m_Ui->setupUi(this);
77 m_Ui->setupUi(this);
90 setWindowTitle(QString("SciQLop v%1").arg(SCIQLOP_VERSION));
78 setWindowTitle(QString("SciQLop v%1").arg(SCIQLOP_VERSION));
91
79
92 m_Ui->splitter->setCollapsible(LEFTINSPECTORSIDEPANESPLITTERINDEX, false);
93 m_Ui->splitter->setCollapsible(RIGHTINSPECTORSIDEPANESPLITTERINDEX, false);
94
95 // impl->m_CatalogExplorer->setVisualizationWidget(m_Ui->view);
96
97
98 auto spacerLeftTop = new QWidget {};
99 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
100
101 auto spacerLeftBottom = new QWidget {};
102 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
103
104
105 auto spacerRightTop = new QWidget {};
106 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
107
108 auto spacerRightBottom = new QWidget {};
109 spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
110
111
112 auto openInspector = [this](bool checked, bool right, auto action) {
113 action->setIcon(
114 QIcon { (checked ^ right) ? ":/icones/next.png" : ":/icones/previous.png" });
115
116 auto& lastInspectorSize
117 = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize;
118
119 auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size()
120 : m_Ui->leftMainInspectorWidget->size();
121
122 // Update of the last opened geometry
123 if (checked)
124 {
125 lastInspectorSize = nextInspectorSize;
126 }
127
128 auto startSize = lastInspectorSize;
129 auto endSize = startSize;
130 endSize.setWidth(0);
131
132 auto splitterInspectorIndex
133 = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX;
134
135 auto currentSizes = m_Ui->splitter->sizes();
136 if (checked)
137 {
138 // adjust sizes individually here, e.g.
139 currentSizes[splitterInspectorIndex] -= lastInspectorSize.width();
140 currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width();
141 m_Ui->splitter->setSizes(currentSizes);
142 }
143 else
144 {
145 // adjust sizes individually here, e.g.
146 currentSizes[splitterInspectorIndex] += lastInspectorSize.width();
147 currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width();
148 m_Ui->splitter->setSizes(currentSizes);
149 }
150 };
151
152
153 // //////////////// //
80 // //////////////// //
154 // Menu and Toolbar //
81 // Menu and Toolbar //
155 // //////////////// //
82 // //////////////// //
@@ -188,8 +115,8 MainWindow::MainWindow(QWidget* parent)
188 // Widgets / controllers connections
115 // Widgets / controllers connections
189
116
190 // DataSource
117 // DataSource
191 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem*)),
118 connect(&sqpApp->dataSourceController(), &DataSourceController::dataSourceItemSet,
192 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem*)));
119 m_Ui->dataSourceWidget, &DataSourceWidget::addDataSource);
193
120
194 // Time
121 // Time
195 // connect(timeWidget, SIGNAL(timeUpdated(DateTimeRange)), &sqpApp->timeController(),
122 // connect(timeWidget, SIGNAL(timeUpdated(DateTimeRange)), &sqpApp->timeController(),
@@ -16,7 +16,7
16 <property name="dockNestingEnabled">
16 <property name="dockNestingEnabled">
17 <bool>true</bool>
17 <bool>true</bool>
18 </property>
18 </property>
19 <widget class="QWidget" name="centralWidget">
19 <widget class="VisualizationWidget" name="view">
20 <property name="enabled">
20 <property name="enabled">
21 <bool>true</bool>
21 <bool>true</bool>
22 </property>
22 </property>
@@ -32,97 +32,6
32 <height>16777215</height>
32 <height>16777215</height>
33 </size>
33 </size>
34 </property>
34 </property>
35 <layout class="QHBoxLayout" name="horizontalLayout">
36 <property name="spacing">
37 <number>0</number>
38 </property>
39 <property name="leftMargin">
40 <number>0</number>
41 </property>
42 <property name="topMargin">
43 <number>0</number>
44 </property>
45 <property name="rightMargin">
46 <number>0</number>
47 </property>
48 <property name="bottomMargin">
49 <number>0</number>
50 </property>
51 <item>
52 <widget class="QSplitter" name="splitter">
53 <property name="orientation">
54 <enum>Qt::Horizontal</enum>
55 </property>
56 <widget class="QWidget" name="leftMainInspectorWidget" native="true">
57 <layout class="QVBoxLayout" name="verticalLayout">
58 <property name="spacing">
59 <number>0</number>
60 </property>
61 <property name="leftMargin">
62 <number>0</number>
63 </property>
64 <property name="topMargin">
65 <number>0</number>
66 </property>
67 <property name="rightMargin">
68 <number>0</number>
69 </property>
70 <property name="bottomMargin">
71 <number>0</number>
72 </property>
73 <item>
74 <widget class="DataSourceWidget" name="dataSourceWidget" native="true"/>
75 </item>
76 <item>
77 <widget class="QWidget" name="dateTimeWidget" native="true"/>
78 </item>
79 <item>
80 <widget class="VariableInspectorWidget" name="variableInspectorWidget" native="true"/>
81 </item>
82 </layout>
83 </widget>
84 <widget class="VisualizationWidget" name="view" native="true">
85 <property name="sizePolicy">
86 <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
87 <horstretch>0</horstretch>
88 <verstretch>0</verstretch>
89 </sizepolicy>
90 </property>
91 </widget>
92 <widget class="QWidget" name="rightMainInspectorWidget" native="true">
93 <layout class="QVBoxLayout" name="verticalLayout_3">
94 <property name="spacing">
95 <number>0</number>
96 </property>
97 <property name="leftMargin">
98 <number>0</number>
99 </property>
100 <property name="topMargin">
101 <number>0</number>
102 </property>
103 <property name="rightMargin">
104 <number>0</number>
105 </property>
106 <property name="bottomMargin">
107 <number>0</number>
108 </property>
109 <item>
110 <widget class="QWidget" name="commonPropertyInspectorWidget" native="true"/>
111 </item>
112 <item>
113 <widget class="QTreeWidget" name="catalogWidget">
114 <column>
115 <property name="text">
116 <string notr="true">Name</string>
117 </property>
118 </column>
119 </widget>
120 </item>
121 </layout>
122 </widget>
123 </widget>
124 </item>
125 </layout>
126 </widget>
35 </widget>
127 <widget class="QMenuBar" name="menuBar">
36 <widget class="QMenuBar" name="menuBar">
128 <property name="geometry">
37 <property name="geometry">
@@ -130,7 +39,7
130 <x>0</x>
39 <x>0</x>
131 <y>0</y>
40 <y>0</y>
132 <width>800</width>
41 <width>800</width>
133 <height>27</height>
42 <height>24</height>
134 </rect>
43 </rect>
135 </property>
44 </property>
136 <property name="sizePolicy">
45 <property name="sizePolicy">
@@ -150,6 +59,30
150 </property>
59 </property>
151 </widget>
60 </widget>
152 <widget class="QStatusBar" name="statusBar"/>
61 <widget class="QStatusBar" name="statusBar"/>
62 <widget class="QDockWidget" name="dockWidget">
63 <property name="features">
64 <set>QDockWidget::DockWidgetMovable</set>
65 </property>
66 <property name="windowTitle">
67 <string>Products</string>
68 </property>
69 <attribute name="dockWidgetArea">
70 <number>1</number>
71 </attribute>
72 <widget class="DataSourceWidget" name="dataSourceWidget"/>
73 </widget>
74 <widget class="QDockWidget" name="dockWidget_2">
75 <property name="features">
76 <set>QDockWidget::DockWidgetMovable</set>
77 </property>
78 <property name="windowTitle">
79 <string>Variables</string>
80 </property>
81 <attribute name="dockWidgetArea">
82 <number>1</number>
83 </attribute>
84 <widget class="VariableInspectorWidget" name="variableInspectorWidget"/>
85 </widget>
153 </widget>
86 </widget>
154 <layoutdefault spacing="6" margin="11"/>
87 <layoutdefault spacing="6" margin="11"/>
155 <customwidgets>
88 <customwidgets>
@@ -1,1 +1,1
1 Subproject commit c4e273750e74336d1d125c02989c922f2032e489
1 Subproject commit 9ff5f48e3d71ce2d3a8b2156f778f3f9be3ea389
@@ -138,7 +138,7 struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
138 QString m_Name;
138 QString m_Name;
139 /// Actions associated to the item. The parent of the item (QTreeWidget) takes the ownership of
139 /// Actions associated to the item. The parent of the item (QTreeWidget) takes the ownership of
140 /// the actions
140 /// the actions
141 QList<QAction *> m_Actions;
141 QList<QAction *> m_Actions; //TODO check if no memory leak here
142 };
142 };
143
143
144 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(const DataSourceItem *data, int type)
144 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(const DataSourceItem *data, int type)
@@ -8,39 +8,39
8
8
9 #include <QMenu>
9 #include <QMenu>
10
10
11 namespace {
11 namespace
12 {
12
13
13 /// Number of columns displayed in the tree
14 /// Number of columns displayed in the tree
14 const auto TREE_NB_COLUMNS = 1;
15 const auto TREE_NB_COLUMNS = 1;
15
16
16 /// Header labels for the tree
17 /// Header labels for the tree
17 const auto TREE_HEADER_LABELS = QStringList{QObject::tr("Name")};
18 const auto TREE_HEADER_LABELS = QStringList { QObject::tr("Name") };
18
19
19 /**
20 /**
20 * Creates the item associated to a data source
21 * Creates the item associated to a data source
21 * @param dataSource the data source for which to create the item
22 * @param dataSource the data source for which to create the item
22 * @return the new item
23 * @return the new item
23 */
24 */
24 DataSourceTreeWidgetItem *createTreeWidgetItem(DataSourceItem *dataSource)
25 DataSourceTreeWidgetItem* createTreeWidgetItem(DataSourceItem* dataSource)
25 {
26 {
26 // Creates item for the data source
27 // Creates item for the data source
27 auto item = new DataSourceTreeWidgetItem{dataSource};
28 auto item = new DataSourceTreeWidgetItem { dataSource };
28
29 // Generates items for the children of the data source
29 // Generates items for the children of the data source
30 for (auto i = 0; i < dataSource->childCount(); ++i) {
30 std::for_each(dataSource->cbegin(), dataSource->cend(),
31 item->addChild(createTreeWidgetItem(dataSource->child(i)));
31 [&item](const std::unique_ptr<DataSourceItem>& child) {
32 }
32 item->addChild(createTreeWidgetItem(child.get()));
33
33 });
34 return item;
34 return item;
35 }
35 }
36
36
37 } // namespace
37 } // namespace
38
38
39 DataSourceWidget::DataSourceWidget(QWidget *parent)
39 DataSourceWidget::DataSourceWidget(QWidget* parent)
40 : QWidget{parent},
40 : QWidget { parent }
41 ui{new Ui::DataSourceWidget},
41 , ui { new Ui::DataSourceWidget }
42 m_Root{
42 , m_Root { std::make_unique<DataSourceItem>(
43 std::make_unique<DataSourceItem>(DataSourceItemType::NODE, QStringLiteral("Sources"))}
43 DataSourceItemType::NODE, QStringLiteral("Sources")) }
44 {
44 {
45 ui->setupUi(this);
45 ui->setupUi(this);
46
46
@@ -51,7 +51,7 DataSourceWidget::DataSourceWidget(QWidget *parent)
51
51
52 // Connection to show a menu when right clicking on the tree
52 // Connection to show a menu when right clicking on the tree
53 connect(ui->treeWidget, &QTreeWidget::customContextMenuRequested, this,
53 connect(ui->treeWidget, &QTreeWidget::customContextMenuRequested, this,
54 &DataSourceWidget::onTreeMenuRequested);
54 &DataSourceWidget::onTreeMenuRequested);
55
55
56 // Connection to filter tree
56 // Connection to filter tree
57 connect(ui->filterLineEdit, &QLineEdit::textChanged, this, &DataSourceWidget::filterChanged);
57 connect(ui->filterLineEdit, &QLineEdit::textChanged, this, &DataSourceWidget::filterChanged);
@@ -65,14 +65,13 DataSourceWidget::~DataSourceWidget() noexcept
65 delete ui;
65 delete ui;
66 }
66 }
67
67
68 void DataSourceWidget::addDataSource(DataSourceItem *dataSource) noexcept
68 void DataSourceWidget::addDataSource(DataSourceItem* dataSource) noexcept
69 {
69 {
70 // Merges the data source (without taking its root)
70 // Merges the data source (without taking its root)
71 if (dataSource) {
71 if (dataSource)
72 for (auto i = 0, count = dataSource->childCount(); i < count; ++i) {
72 {
73 m_Root->merge(*dataSource->child(i));
73 std::for_each(std::cbegin(*dataSource), std::cend(*dataSource),
74 }
74 [this](const auto& child) { this->m_Root->merge(*child.get()); });
75
76 updateTreeWidget();
75 updateTreeWidget();
77 }
76 }
78 }
77 }
@@ -90,33 +89,35 void DataSourceWidget::updateTreeWidget() noexcept
90 ui->treeWidget->sortByColumn(0, Qt::AscendingOrder);
89 ui->treeWidget->sortByColumn(0, Qt::AscendingOrder);
91 }
90 }
92
91
93 void DataSourceWidget::filterChanged(const QString &text) noexcept
92 void DataSourceWidget::filterChanged(const QString& text) noexcept
94 {
93 {
95 auto validateItem = [&text](const DataSourceTreeWidgetItem &item) {
94 auto validateItem = [&text](const DataSourceTreeWidgetItem& item) {
96 auto regExp = QRegExp{text, Qt::CaseInsensitive, QRegExp::Wildcard};
95 auto regExp = QRegExp { text, Qt::CaseInsensitive, QRegExp::Wildcard };
97
96
98 // An item is valid if any of its metadata validates the text filter
97 // An item is valid if any of its metadata validates the text filter
99 auto itemMetadata = item.data()->data();
98 auto itemMetadata = item.data()->data();
100 auto itemMetadataEnd = itemMetadata.cend();
99 auto itemMetadataEnd = itemMetadata.cend();
101 auto acceptFilter
100 auto acceptFilter
102 = [&regExp](const auto &variant) { return variant.toString().contains(regExp); };
101 = [&regExp](const auto& variant) { return variant.toString().contains(regExp); };
103
102
104 return std::find_if(itemMetadata.cbegin(), itemMetadataEnd, acceptFilter)
103 return std::find_if(itemMetadata.cbegin(), itemMetadataEnd, acceptFilter)
105 != itemMetadataEnd;
104 != itemMetadataEnd;
106 };
105 };
107
106
108 // Applies filter on tree widget
107 // Applies filter on tree widget
109 DataSourceTreeWidgetHelper::filter(*ui->treeWidget, validateItem);
108 DataSourceTreeWidgetHelper::filter(*ui->treeWidget, validateItem);
110 }
109 }
111
110
112 void DataSourceWidget::onTreeMenuRequested(const QPoint &pos) noexcept
111 void DataSourceWidget::onTreeMenuRequested(const QPoint& pos) noexcept
113 {
112 {
114 // Retrieves the selected item in the tree, and build the menu from its actions
113 // Retrieves the selected item in the tree, and build the menu from its actions
115 if (auto selectedItem = dynamic_cast<DataSourceTreeWidgetItem *>(ui->treeWidget->itemAt(pos))) {
114 if (auto selectedItem = dynamic_cast<DataSourceTreeWidgetItem*>(ui->treeWidget->itemAt(pos)))
116 QMenu treeMenu{};
115 {
116 QMenu treeMenu {};
117 treeMenu.addActions(selectedItem->actions());
117 treeMenu.addActions(selectedItem->actions());
118
118
119 if (!treeMenu.isEmpty()) {
119 if (!treeMenu.isEmpty())
120 {
120 treeMenu.exec(QCursor::pos());
121 treeMenu.exec(QCursor::pos());
121 }
122 }
122 }
123 }
@@ -219,7 +219,7 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate
219 {
219 {
220 /*
220 /*
221 * I give up on this for now
221 * I give up on this for now
222 * @TODO implement this, the difficulty is that selection zones have their own
222 * TODO implement this, the difficulty is that selection zones have their own
223 * event handling code which seems to rely on QCP GUI event handling propagation
223 * event handling code which seems to rely on QCP GUI event handling propagation
224 * which was a realy bad design choice.
224 * which was a realy bad design choice.
225 */
225 */
@@ -506,7 +506,7 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable2> variable,
506 delete context;
506 delete context;
507 });
507 });
508 }
508 }
509 //@TODO this is bad! when variable is moved to another graph it still fires
509 //TODO this is bad! when variable is moved to another graph it still fires
510 // even if this has been deleted
510 // even if this has been deleted
511 connect(variable.get(), &Variable2::updated, this, &VisualizationGraphWidget::variableUpdated);
511 connect(variable.get(), &Variable2::updated, this, &VisualizationGraphWidget::variableUpdated);
512 this->onUpdateVarDisplaying(variable, range); // My bullshit
512 this->onUpdateVarDisplaying(variable, range); // My bullshit
General Comments 0
You need to be logged in to leave comments. Login now