##// END OF EJS Templates
PySide2 bindings + some GUI clean...
jeandet -
r1478:6e3f56cd8c8b
parent child
Show More
@@ -63,7 +63,7 include_directories(
63 63 ${PYSIDE_INCLUDE_DIR}/QtGui
64 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 67 set_target_properties(
68 68 SciQLopBindings
69 69 PROPERTIES
@@ -1,16 +1,89
1 1 #pragma once
2 #include <Data/DataProviderParameters.h>
2 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 26 class PyDataProvider : public IDataProvider
5 27 {
6 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)
10 {}
37 virtual QPair<NpArray, NpArray> getData(
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 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 31 </target-to-native>
32 32 </conversion-rule>
33 33 </container-type>
34 <object-type name="PyDataProvider" />
35 <object-type name="Product" />
34 36 <object-type name="MainWindow" />
35 37 <object-type name="SqpApplication">
36 38 <modify-function signature="SqpApplication(int&amp;,char**)" access="private"/>
37 39 </object-type>
38 <object-type name="PyDataProvider" />
39 <function signature="SqpApplication_ctor()"/>
40 <object-type name="Providers">
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 57 <function signature="init_resources()"/>
41 58 <primitive-type name="NpArray" target-lang-api-name="PyObject">
42 59 <include file-name="numpy_wrappers.h" location="local"/>
43 60 <conversion-rule>
44 61 <native-to-target>
45 return %in.py_object();
62 auto result = %in.py_object();
63 return result;
46 64 </native-to-target>
47 65 <target-to-native>
48 66 <add-conversion type="PyObject" check="NpArray::isNpArray(%in)">
@@ -68,5 +86,6
68 86 </inject-code>
69 87 </add-function>
70 88 </object-type>
89 <function signature="test_PyDataProvider(PyDataProvider&amp;)"/>
71 90 <function signature="test_np_array(NpArray&amp;)"/>
72 91 </typesystem>
@@ -4,6 +4,17
4 4 #define Py_DEBUG
5 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 18 int main(int argc, char** argv)
8 19 {
9 20 wchar_t* program = Py_DecodeLocale(argv[0], NULL);
@@ -12,8 +23,10 int main(int argc, char** argv)
12 23 fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
13 24 exit(1);
14 25 }
26
15 27 Py_SetProgramName(program); /* optional but recommended */
16 28 Py_Initialize();
29 PySys_SetArgv(argc, decode_argv(argc, argv));
17 30 std::ifstream t(argv[1]);
18 31 std::string str((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
19 32 PyRun_SimpleString(str.data());
@@ -6,6 +6,7 from PySide2.QtWidgets import QApplication, QMainWindow, QDockWidget
6 6 from PySide2.QtCore import QSize, Qt
7 7 from PySide2 import QtGui
8 8 import os
9 sys.path.append(os.getcwd())
9 10 from SciQLopBindings import SqpApplication, MainWindow, init_resources, load_plugins, SqpApplication_ctor
10 11 from qtconsole.rich_ipython_widget import RichJupyterWidget
11 12 from qtconsole.inprocess import QtInProcessKernelManager
@@ -91,7 +92,7 def print_process_id():
91 92
92 93 if __name__ == "__main__":
93 94 init_resources()
94 app = SqpApplication_ctor()
95 app = SqpApplication_ctor(sys.argv)
95 96 QtGui.qApp = app
96 97 load_plugins(app)
97 98 main_window = MainWindow()
@@ -29,6 +29,8 extern "C"
29 29 #endif
30 30 #include <assert.h>
31 31
32 #include <map>
33
32 34 inline int init_numpy()
33 35 {
34 36 import_array(); // PyError if not successful
@@ -39,32 +41,31 template <typename dest_type = PyObject>
39 41 struct PyObjectWrapper
40 42 {
41 43 private:
42 PyObject* _py_obj;
43
44 PyObject* _py_obj = nullptr;
44 45 void inc_refcount()
45 46 {
46 if (_py_obj)
47 Py_IncRef(_py_obj);
47 Py_XINCREF(_py_obj);
48 48 }
49 49 void dec_refcount()
50 50 {
51 if (_py_obj)
52 Py_DecRef(_py_obj);
51 Py_XDECREF(_py_obj);
52 _py_obj = nullptr;
53 53 }
54 54
55 55 public:
56 56 PyObjectWrapper() : _py_obj { nullptr } {}
57 PyObjectWrapper(const PyObjectWrapper& other) : _py_obj { other._py_obj } { inc_refcount(); };
58 PyObjectWrapper(PyObjectWrapper&& other) : _py_obj { other._py_obj }
57 PyObjectWrapper(const PyObjectWrapper& other) : _py_obj { other._py_obj } { inc_refcount(); }
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 63 ~PyObjectWrapper() { dec_refcount(); }
64 64 PyObjectWrapper& operator=(PyObjectWrapper&& other)
65 65 {
66 dec_refcount();
66 67 this->_py_obj = other._py_obj;
67 other._py_obj = nullptr;
68 inc_refcount();
68 69 return *this;
69 70 }
70 71 PyObjectWrapper& operator=(const PyObjectWrapper& other)
@@ -91,14 +92,14 private:
91 92 public:
92 93 static bool isNpArray(PyObject* obj)
93 94 {
94 return obj && PyArray_Check(reinterpret_cast<PyArrayObject*>(obj))
95 && PyArray_IS_C_CONTIGUOUS(reinterpret_cast<PyArrayObject*>(obj));
95 auto arr = reinterpret_cast<PyArrayObject*>(obj);
96 auto is_c_aray = obj && PyArray_Check(arr) && PyArray_ISCARRAY(arr);
97 return is_c_aray;
96 98 }
97 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 101 explicit NpArray(PyObject* obj) : _py_obj { obj }
100 102 {
101 std::cout << "NpArray ctor" << std::endl;
102 103 assert(isNpArray(obj));
103 104 assert(PyArray_ISFLOAT(_py_obj.get()));
104 105 }
@@ -111,7 +112,7 public:
111 112
112 113 NpArray& operator=(NpArray&& other)
113 114 {
114 this->_py_obj = std::move(other._py_obj);
115 this->_py_obj = other._py_obj;
115 116 return *this;
116 117 }
117 118
@@ -9,7 +9,7
9 9 #include <QWidget>
10 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 13 #include <SqpApplication.h>
14 14
15 15 class ToolBar : public QToolBar
@@ -25,6 +25,7
25 25 #include <Catalogue/CatalogueController.h>
26 26 #include <Catalogue2/browser.h>
27 27 #include <DataSource/DataSourceController.h>
28 #include <DataSource/DataSourceItem.h>
28 29 #include <DataSource/DataSourceWidget.h>
29 30 #include <Settings/SqpSettingsDialog.h>
30 31 #include <Settings/SqpSettingsGeneralWidget.h>
@@ -48,29 +49,16
48 49
49 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 52 class MainWindow::MainWindowPrivate
61 53 {
62 54 public:
63 55 explicit MainWindowPrivate(MainWindow* mainWindow)
64 : m_LastOpenLeftInspectorSize {}
65 , m_LastOpenRightInspectorSize {}
66 , m_GeneralSettingsWidget { new SqpSettingsGeneralWidget { mainWindow } }
56 : m_GeneralSettingsWidget { new SqpSettingsGeneralWidget { mainWindow } }
67 57 , m_SettingsDialog { new SqpSettingsDialog { mainWindow } }
68 58 , m_CatalogExplorer { new CataloguesBrowser { mainWindow } }
69 59 {
70 60 }
71 61
72 QSize m_LastOpenLeftInspectorSize;
73 QSize m_LastOpenRightInspectorSize;
74 62 /// General settings widget. MainWindow has the ownership
75 63 SqpSettingsGeneralWidget* m_GeneralSettingsWidget;
76 64 /// Settings dialog. MainWindow has the ownership
@@ -89,67 +77,6 MainWindow::MainWindow(QWidget* parent)
89 77 m_Ui->setupUi(this);
90 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 81 // Menu and Toolbar //
155 82 // //////////////// //
@@ -188,8 +115,8 MainWindow::MainWindow(QWidget* parent)
188 115 // Widgets / controllers connections
189 116
190 117 // DataSource
191 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem*)),
192 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem*)));
118 connect(&sqpApp->dataSourceController(), &DataSourceController::dataSourceItemSet,
119 m_Ui->dataSourceWidget, &DataSourceWidget::addDataSource);
193 120
194 121 // Time
195 122 // connect(timeWidget, SIGNAL(timeUpdated(DateTimeRange)), &sqpApp->timeController(),
@@ -16,7 +16,7
16 16 <property name="dockNestingEnabled">
17 17 <bool>true</bool>
18 18 </property>
19 <widget class="QWidget" name="centralWidget">
19 <widget class="VisualizationWidget" name="view">
20 20 <property name="enabled">
21 21 <bool>true</bool>
22 22 </property>
@@ -32,97 +32,6
32 32 <height>16777215</height>
33 33 </size>
34 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 35 </widget>
127 36 <widget class="QMenuBar" name="menuBar">
128 37 <property name="geometry">
@@ -130,7 +39,7
130 39 <x>0</x>
131 40 <y>0</y>
132 41 <width>800</width>
133 <height>27</height>
42 <height>24</height>
134 43 </rect>
135 44 </property>
136 45 <property name="sizePolicy">
@@ -150,6 +59,30
150 59 </property>
151 60 </widget>
152 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 86 </widget>
154 87 <layoutdefault spacing="6" margin="11"/>
155 88 <customwidgets>
@@ -1,1 +1,1
1 Subproject commit c4e273750e74336d1d125c02989c922f2032e489
1 Subproject commit 9ff5f48e3d71ce2d3a8b2156f778f3f9be3ea389
@@ -138,7 +138,7 struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
138 138 QString m_Name;
139 139 /// Actions associated to the item. The parent of the item (QTreeWidget) takes the ownership of
140 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 144 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(const DataSourceItem *data, int type)
@@ -8,39 +8,39
8 8
9 9 #include <QMenu>
10 10
11 namespace {
11 namespace
12 {
12 13
13 14 /// Number of columns displayed in the tree
14 15 const auto TREE_NB_COLUMNS = 1;
15 16
16 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 21 * Creates the item associated to a data source
21 22 * @param dataSource the data source for which to create the item
22 23 * @return the new item
23 24 */
24 DataSourceTreeWidgetItem *createTreeWidgetItem(DataSourceItem *dataSource)
25 DataSourceTreeWidgetItem* createTreeWidgetItem(DataSourceItem* dataSource)
25 26 {
26 27 // Creates item for the data source
27 auto item = new DataSourceTreeWidgetItem{dataSource};
28
28 auto item = new DataSourceTreeWidgetItem { dataSource };
29 29 // Generates items for the children of the data source
30 for (auto i = 0; i < dataSource->childCount(); ++i) {
31 item->addChild(createTreeWidgetItem(dataSource->child(i)));
32 }
33
30 std::for_each(dataSource->cbegin(), dataSource->cend(),
31 [&item](const std::unique_ptr<DataSourceItem>& child) {
32 item->addChild(createTreeWidgetItem(child.get()));
33 });
34 34 return item;
35 35 }
36 36
37 37 } // namespace
38 38
39 DataSourceWidget::DataSourceWidget(QWidget *parent)
40 : QWidget{parent},
41 ui{new Ui::DataSourceWidget},
42 m_Root{
43 std::make_unique<DataSourceItem>(DataSourceItemType::NODE, QStringLiteral("Sources"))}
39 DataSourceWidget::DataSourceWidget(QWidget* parent)
40 : QWidget { parent }
41 , ui { new Ui::DataSourceWidget }
42 , m_Root { std::make_unique<DataSourceItem>(
43 DataSourceItemType::NODE, QStringLiteral("Sources")) }
44 44 {
45 45 ui->setupUi(this);
46 46
@@ -51,7 +51,7 DataSourceWidget::DataSourceWidget(QWidget *parent)
51 51
52 52 // Connection to show a menu when right clicking on the tree
53 53 connect(ui->treeWidget, &QTreeWidget::customContextMenuRequested, this,
54 &DataSourceWidget::onTreeMenuRequested);
54 &DataSourceWidget::onTreeMenuRequested);
55 55
56 56 // Connection to filter tree
57 57 connect(ui->filterLineEdit, &QLineEdit::textChanged, this, &DataSourceWidget::filterChanged);
@@ -65,14 +65,13 DataSourceWidget::~DataSourceWidget() noexcept
65 65 delete ui;
66 66 }
67 67
68 void DataSourceWidget::addDataSource(DataSourceItem *dataSource) noexcept
68 void DataSourceWidget::addDataSource(DataSourceItem* dataSource) noexcept
69 69 {
70 70 // Merges the data source (without taking its root)
71 if (dataSource) {
72 for (auto i = 0, count = dataSource->childCount(); i < count; ++i) {
73 m_Root->merge(*dataSource->child(i));
74 }
75
71 if (dataSource)
72 {
73 std::for_each(std::cbegin(*dataSource), std::cend(*dataSource),
74 [this](const auto& child) { this->m_Root->merge(*child.get()); });
76 75 updateTreeWidget();
77 76 }
78 77 }
@@ -90,33 +89,35 void DataSourceWidget::updateTreeWidget() noexcept
90 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) {
96 auto regExp = QRegExp{text, Qt::CaseInsensitive, QRegExp::Wildcard};
94 auto validateItem = [&text](const DataSourceTreeWidgetItem& item) {
95 auto regExp = QRegExp { text, Qt::CaseInsensitive, QRegExp::Wildcard };
97 96
98 97 // An item is valid if any of its metadata validates the text filter
99 98 auto itemMetadata = item.data()->data();
100 99 auto itemMetadataEnd = itemMetadata.cend();
101 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 103 return std::find_if(itemMetadata.cbegin(), itemMetadataEnd, acceptFilter)
105 != itemMetadataEnd;
104 != itemMetadataEnd;
106 105 };
107 106
108 107 // Applies filter on tree widget
109 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 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))) {
116 QMenu treeMenu{};
114 if (auto selectedItem = dynamic_cast<DataSourceTreeWidgetItem*>(ui->treeWidget->itemAt(pos)))
115 {
116 QMenu treeMenu {};
117 117 treeMenu.addActions(selectedItem->actions());
118 118
119 if (!treeMenu.isEmpty()) {
119 if (!treeMenu.isEmpty())
120 {
120 121 treeMenu.exec(QCursor::pos());
121 122 }
122 123 }
@@ -219,7 +219,7 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate
219 219 {
220 220 /*
221 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 223 * event handling code which seems to rely on QCP GUI event handling propagation
224 224 * which was a realy bad design choice.
225 225 */
@@ -506,7 +506,7 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable2> variable,
506 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 510 // even if this has been deleted
511 511 connect(variable.get(), &Variable2::updated, this, &VisualizationGraphWidget::variableUpdated);
512 512 this->onUpdateVarDisplaying(variable, range); // My bullshit
General Comments 0
You need to be logged in to leave comments. Login now