##// END OF EJS Templates
Reset of the drag&drop operations when a drag is started from the datasource or from the variables
trabillard -
r883:4dce99ba7a36
parent child
Show More
@@ -0,0 +1,14
1 #ifndef SCIQLOP_VARIABLEINSPECTORTABLEVIEW_H
2 #define SCIQLOP_VARIABLEINSPECTORTABLEVIEW_H
3
4 #include <QTableView>
5
6 class VariableInspectorTableView : public QTableView {
7 public:
8 VariableInspectorTableView(QWidget *parent = nullptr);
9
10 protected:
11 void startDrag(Qt::DropActions supportedActions);
12 };
13
14 #endif // SCIQLOP_VARIABLEINSPECTORTABLEVIEW_H
@@ -0,0 +1,13
1 #include "Variable/VariableInspectorTableView.h"
2
3 #include "DragDropHelper.h"
4 #include "SqpApplication.h"
5
6 VariableInspectorTableView::VariableInspectorTableView(QWidget *parent) : QTableView(parent) {}
7
8 void VariableInspectorTableView::startDrag(Qt::DropActions supportedActions)
9 {
10 // Resets the drag&drop operations before it's starting
11 sqpApp->dragDropHelper().resetDragAndDrop();
12 QTableView::startDrag(supportedActions);
13 }
@@ -1,162 +1,162
1 #include <DataSource/DataSourceItem.h>
1 #include <DataSource/DataSourceItem.h>
2 #include <DataSource/DataSourceItemAction.h>
2 #include <DataSource/DataSourceItemAction.h>
3
3
4 #include <QVector>
4 #include <QVector>
5
5
6 const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name");
6 const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name");
7
7
8 struct DataSourceItem::DataSourceItemPrivate {
8 struct DataSourceItem::DataSourceItemPrivate {
9 explicit DataSourceItemPrivate(DataSourceItemType type, QVariantHash data)
9 explicit DataSourceItemPrivate(DataSourceItemType type, QVariantHash data)
10 : m_Parent{nullptr}, m_Children{}, m_Type{type}, m_Data{std::move(data)}, m_Actions{}
10 : m_Parent{nullptr}, m_Children{}, m_Type{type}, m_Data{std::move(data)}, m_Actions{}
11 {
11 {
12 }
12 }
13
13
14 DataSourceItem *m_Parent;
14 DataSourceItem *m_Parent;
15 std::vector<std::unique_ptr<DataSourceItem> > m_Children;
15 std::vector<std::unique_ptr<DataSourceItem> > m_Children;
16 DataSourceItemType m_Type;
16 DataSourceItemType m_Type;
17 QVariantHash m_Data;
17 QVariantHash m_Data;
18 std::vector<std::unique_ptr<DataSourceItemAction> > m_Actions;
18 std::vector<std::unique_ptr<DataSourceItemAction> > m_Actions;
19 };
19 };
20
20
21 DataSourceItem::DataSourceItem(DataSourceItemType type, const QString &name)
21 DataSourceItem::DataSourceItem(DataSourceItemType type, const QString &name)
22 : DataSourceItem{type, QVariantHash{{NAME_DATA_KEY, name}}}
22 : DataSourceItem{type, QVariantHash{{NAME_DATA_KEY, name}}}
23 {
23 {
24 }
24 }
25
25
26 DataSourceItem::DataSourceItem(DataSourceItemType type, QVariantHash data)
26 DataSourceItem::DataSourceItem(DataSourceItemType type, QVariantHash data)
27 : impl{spimpl::make_unique_impl<DataSourceItemPrivate>(type, std::move(data))}
27 : impl{spimpl::make_unique_impl<DataSourceItemPrivate>(type, std::move(data))}
28 {
28 {
29 }
29 }
30
30
31 QVector<DataSourceItemAction *> DataSourceItem::actions() const noexcept
31 QVector<DataSourceItemAction *> DataSourceItem::actions() const noexcept
32 {
32 {
33 auto result = QVector<DataSourceItemAction *>{};
33 auto result = QVector<DataSourceItemAction *>{};
34
34
35 std::transform(std::cbegin(impl->m_Actions), std::cend(impl->m_Actions),
35 std::transform(std::cbegin(impl->m_Actions), std::cend(impl->m_Actions),
36 std::back_inserter(result), [](const auto &action) { return action.get(); });
36 std::back_inserter(result), [](const auto &action) { return action.get(); });
37
37
38 return result;
38 return result;
39 }
39 }
40
40
41 void DataSourceItem::addAction(std::unique_ptr<DataSourceItemAction> action) noexcept
41 void DataSourceItem::addAction(std::unique_ptr<DataSourceItemAction> action) noexcept
42 {
42 {
43 action->setDataSourceItem(this);
43 action->setDataSourceItem(this);
44 impl->m_Actions.push_back(std::move(action));
44 impl->m_Actions.push_back(std::move(action));
45 }
45 }
46
46
47 void DataSourceItem::appendChild(std::unique_ptr<DataSourceItem> child) noexcept
47 void DataSourceItem::appendChild(std::unique_ptr<DataSourceItem> child) noexcept
48 {
48 {
49 child->impl->m_Parent = this;
49 child->impl->m_Parent = this;
50 impl->m_Children.push_back(std::move(child));
50 impl->m_Children.push_back(std::move(child));
51 }
51 }
52
52
53 DataSourceItem *DataSourceItem::child(int childIndex) const noexcept
53 DataSourceItem *DataSourceItem::child(int childIndex) const noexcept
54 {
54 {
55 if (childIndex < 0 || childIndex >= childCount()) {
55 if (childIndex < 0 || childIndex >= childCount()) {
56 return nullptr;
56 return nullptr;
57 }
57 }
58 else {
58 else {
59 return impl->m_Children.at(childIndex).get();
59 return impl->m_Children.at(childIndex).get();
60 }
60 }
61 }
61 }
62
62
63 int DataSourceItem::childCount() const noexcept
63 int DataSourceItem::childCount() const noexcept
64 {
64 {
65 return impl->m_Children.size();
65 return impl->m_Children.size();
66 }
66 }
67
67
68 QVariant DataSourceItem::data(const QString &key) const noexcept
68 QVariant DataSourceItem::data(const QString &key) const noexcept
69 {
69 {
70 return impl->m_Data.value(key);
70 return impl->m_Data.value(key);
71 }
71 }
72
72
73 QVariantHash DataSourceItem::data() const noexcept
73 QVariantHash DataSourceItem::data() const noexcept
74 {
74 {
75 return impl->m_Data;
75 return impl->m_Data;
76 }
76 }
77
77
78 bool DataSourceItem::isRoot() const noexcept
78 bool DataSourceItem::isRoot() const noexcept
79 {
79 {
80 return impl->m_Parent == nullptr;
80 return impl->m_Parent == nullptr;
81 }
81 }
82
82
83 QString DataSourceItem::name() const noexcept
83 QString DataSourceItem::name() const noexcept
84 {
84 {
85 return data(NAME_DATA_KEY).toString();
85 return data(NAME_DATA_KEY).toString();
86 }
86 }
87
87
88 DataSourceItem *DataSourceItem::parentItem() const noexcept
88 DataSourceItem *DataSourceItem::parentItem() const noexcept
89 {
89 {
90 return impl->m_Parent;
90 return impl->m_Parent;
91 }
91 }
92
92
93 const DataSourceItem &DataSourceItem::rootItem() const noexcept
93 const DataSourceItem &DataSourceItem::rootItem() const noexcept
94 {
94 {
95 return isRoot() ? *this : parentItem()->rootItem();
95 return isRoot() ? *this : parentItem()->rootItem();
96 }
96 }
97
97
98 void DataSourceItem::setData(const QString &key, const QVariant &value, bool append) noexcept
98 void DataSourceItem::setData(const QString &key, const QVariant &value, bool append) noexcept
99 {
99 {
100 auto it = impl->m_Data.constFind(key);
100 auto it = impl->m_Data.constFind(key);
101 if (append && it != impl->m_Data.constEnd()) {
101 if (append && it != impl->m_Data.constEnd()) {
102 // Case of an existing value to which we want to add to the new value
102 // Case of an existing value to which we want to add to the new value
103 if (it->canConvert<QVariantList>()) {
103 if (it->canConvert<QVariantList>()) {
104 auto variantList = it->value<QVariantList>();
104 auto variantList = it->value<QVariantList>();
105 variantList.append(value);
105 variantList.append(value);
106
106
107 impl->m_Data.insert(key, variantList);
107 impl->m_Data.insert(key, variantList);
108 }
108 }
109 else {
109 else {
110 impl->m_Data.insert(key, QVariantList{*it, value});
110 impl->m_Data.insert(key, QVariantList{*it, value});
111 }
111 }
112 }
112 }
113 else {
113 else {
114 // Other cases :
114 // Other cases :
115 // - new value in map OR
115 // - new value in map OR
116 // - replacement of an existing value (not appending)
116 // - replacement of an existing value (not appending)
117 impl->m_Data.insert(key, value);
117 impl->m_Data.insert(key, value);
118 }
118 }
119 }
119 }
120
120
121 DataSourceItemType DataSourceItem::type() const noexcept
121 DataSourceItemType DataSourceItem::type() const noexcept
122 {
122 {
123 return impl->m_Type;
123 return impl->m_Type;
124 }
124 }
125
125
126 DataSourceItem *DataSourceItem::findItem(const QVariantHash &data, bool recursive)
126 DataSourceItem *DataSourceItem::findItem(const QVariantHash &data, bool recursive)
127 {
127 {
128 for (const auto &child : impl->m_Children) {
128 for (const auto &child : impl->m_Children) {
129 if (child->impl->m_Data == data) {
129 if (child->impl->m_Data == data) {
130 return child.get();
130 return child.get();
131 }
131 }
132
132
133 if (recursive) {
133 if (recursive) {
134 if (auto foundItem = child->findItem(data, true)) {
134 if (auto foundItem = child->findItem(data, true)) {
135 return foundItem;
135 return foundItem;
136 }
136 }
137 }
137 }
138 }
138 }
139
139
140 return nullptr;
140 return nullptr;
141 }
141 }
142
142
143 bool DataSourceItem::operator==(const DataSourceItem &other)
143 bool DataSourceItem::operator==(const DataSourceItem &other)
144 {
144 {
145 // Compares items' attributes
145 // Compares items' attributes
146 if (std::tie(impl->m_Type, impl->m_Data) == std::tie(other.impl->m_Type, other.impl->m_Data)) {
146 if (std::tie(impl->m_Type, impl->m_Data) == std::tie(other.impl->m_Type, other.impl->m_Data)) {
147 // Compares contents of items' children
147 // Compares contents of items' children
148 return std::equal(std::cbegin(impl->m_Children), std::cend(impl->m_Children),
148 return std::equal(std::cbegin(impl->m_Children), std::cend(impl->m_Children),
149 std::cbegin(other.impl->m_Children),
149 std::cbegin(other.impl->m_Children),
150 [](const auto &itemChild, const auto &otherChild) {
150 [](const auto &itemChild, const auto &otherChild) {
151 return *itemChild == *otherChild;
151 return *itemChild == *otherChild;
152 });
152 });
153 }
153 }
154 else {
154 else {
155 return false;
155 return false;
156 }
156 }
157 }
157 }
158
158
159 bool DataSourceItem::operator!=(const DataSourceItem &other)
159 bool DataSourceItem::operator!=(const DataSourceItem &other)
160 {
160 {
161 return !(*this == other);
161 return !(*this == other);
162 }
162 }
@@ -1,14 +1,15
1 #ifndef SCIQLOP_DATASOURCETREEWIDGET_H
1 #ifndef SCIQLOP_DATASOURCETREEWIDGET_H
2 #define SCIQLOP_DATASOURCETREEWIDGET_H
2 #define SCIQLOP_DATASOURCETREEWIDGET_H
3
3
4 #include <QTreeWidget>
4 #include <QTreeWidget>
5
5
6 class DataSourceTreeWidget : public QTreeWidget {
6 class DataSourceTreeWidget : public QTreeWidget {
7 public:
7 public:
8 DataSourceTreeWidget(QWidget *parent);
8 DataSourceTreeWidget(QWidget *parent);
9
9
10 protected:
10 protected:
11 QMimeData *mimeData(const QList<QTreeWidgetItem *> items) const override;
11 QMimeData *mimeData(const QList<QTreeWidgetItem *> items) const override;
12 void startDrag(Qt::DropActions supportedActions) override;
12 };
13 };
13
14
14 #endif // SCIQLOP_DATASOURCETREEWIDGET_H
15 #endif // SCIQLOP_DATASOURCETREEWIDGET_H
@@ -1,87 +1,89
1
1
2 gui_moc_headers = [
2 gui_moc_headers = [
3 'include/DataSource/DataSourceWidget.h',
3 'include/DataSource/DataSourceWidget.h',
4 'include/Settings/SqpSettingsDialog.h',
4 'include/Settings/SqpSettingsDialog.h',
5 'include/Settings/SqpSettingsGeneralWidget.h',
5 'include/Settings/SqpSettingsGeneralWidget.h',
6 'include/SidePane/SqpSidePane.h',
6 'include/SidePane/SqpSidePane.h',
7 'include/SqpApplication.h',
7 'include/SqpApplication.h',
8 'include/DragDropHelper.h',
8 'include/DragDropHelper.h',
9 'include/TimeWidget/TimeWidget.h',
9 'include/TimeWidget/TimeWidget.h',
10 'include/Variable/VariableInspectorWidget.h',
10 'include/Variable/VariableInspectorWidget.h',
11 'include/Variable/VariableInspectorTableView.h',
11 'include/Variable/RenameVariableDialog.h',
12 'include/Variable/RenameVariableDialog.h',
12 'include/Visualization/qcustomplot.h',
13 'include/Visualization/qcustomplot.h',
13 'include/Visualization/VisualizationGraphWidget.h',
14 'include/Visualization/VisualizationGraphWidget.h',
14 'include/Visualization/VisualizationTabWidget.h',
15 'include/Visualization/VisualizationTabWidget.h',
15 'include/Visualization/VisualizationWidget.h',
16 'include/Visualization/VisualizationWidget.h',
16 'include/Visualization/VisualizationZoneWidget.h',
17 'include/Visualization/VisualizationZoneWidget.h',
17 'include/Visualization/VisualizationDragDropContainer.h',
18 'include/Visualization/VisualizationDragDropContainer.h',
18 'include/Visualization/VisualizationDragWidget.h'
19 'include/Visualization/VisualizationDragWidget.h'
19 ]
20 ]
20
21
21 gui_ui_files = [
22 gui_ui_files = [
22 'ui/DataSource/DataSourceWidget.ui',
23 'ui/DataSource/DataSourceWidget.ui',
23 'ui/Settings/SqpSettingsDialog.ui',
24 'ui/Settings/SqpSettingsDialog.ui',
24 'ui/Settings/SqpSettingsGeneralWidget.ui',
25 'ui/Settings/SqpSettingsGeneralWidget.ui',
25 'ui/SidePane/SqpSidePane.ui',
26 'ui/SidePane/SqpSidePane.ui',
26 'ui/TimeWidget/TimeWidget.ui',
27 'ui/TimeWidget/TimeWidget.ui',
27 'ui/Variable/VariableInspectorWidget.ui',
28 'ui/Variable/VariableInspectorWidget.ui',
28 'ui/Variable/RenameVariableDialog.ui',
29 'ui/Variable/RenameVariableDialog.ui',
29 'ui/Variable/VariableMenuHeaderWidget.ui',
30 'ui/Variable/VariableMenuHeaderWidget.ui',
30 'ui/Visualization/VisualizationGraphWidget.ui',
31 'ui/Visualization/VisualizationGraphWidget.ui',
31 'ui/Visualization/VisualizationTabWidget.ui',
32 'ui/Visualization/VisualizationTabWidget.ui',
32 'ui/Visualization/VisualizationWidget.ui',
33 'ui/Visualization/VisualizationWidget.ui',
33 'ui/Visualization/VisualizationZoneWidget.ui'
34 'ui/Visualization/VisualizationZoneWidget.ui'
34 ]
35 ]
35
36
36 gui_qresources = ['resources/sqpguiresources.qrc']
37 gui_qresources = ['resources/sqpguiresources.qrc']
37
38
38 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers,
39 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers,
39 ui_files : gui_ui_files,
40 ui_files : gui_ui_files,
40 qresources : gui_qresources)
41 qresources : gui_qresources)
41
42
42 gui_sources = [
43 gui_sources = [
43 'src/SqpApplication.cpp',
44 'src/SqpApplication.cpp',
44 'src/DragDropHelper.cpp',
45 'src/DragDropHelper.cpp',
45 'src/Common/ColorUtils.cpp',
46 'src/Common/ColorUtils.cpp',
46 'src/Common/VisualizationDef.cpp',
47 'src/Common/VisualizationDef.cpp',
47 'src/DataSource/DataSourceTreeWidgetItem.cpp',
48 'src/DataSource/DataSourceTreeWidgetItem.cpp',
48 'src/DataSource/DataSourceTreeWidgetHelper.cpp',
49 'src/DataSource/DataSourceTreeWidgetHelper.cpp',
49 'src/DataSource/DataSourceWidget.cpp',
50 'src/DataSource/DataSourceWidget.cpp',
50 'src/Settings/SqpSettingsDialog.cpp',
51 'src/Settings/SqpSettingsDialog.cpp',
51 'src/Settings/SqpSettingsGeneralWidget.cpp',
52 'src/Settings/SqpSettingsGeneralWidget.cpp',
52 'src/SidePane/SqpSidePane.cpp',
53 'src/SidePane/SqpSidePane.cpp',
53 'src/TimeWidget/TimeWidget.cpp',
54 'src/TimeWidget/TimeWidget.cpp',
54 'src/Variable/VariableInspectorWidget.cpp',
55 'src/Variable/VariableInspectorWidget.cpp',
56 'src/Variable/VariableInspectorTableView.cpp',
55 'src/Variable/VariableMenuHeaderWidget.cpp',
57 'src/Variable/VariableMenuHeaderWidget.cpp',
56 'src/Variable/RenameVariableDialog.cpp',
58 'src/Variable/RenameVariableDialog.cpp',
57 'src/Visualization/VisualizationGraphHelper.cpp',
59 'src/Visualization/VisualizationGraphHelper.cpp',
58 'src/Visualization/VisualizationGraphRenderingDelegate.cpp',
60 'src/Visualization/VisualizationGraphRenderingDelegate.cpp',
59 'src/Visualization/VisualizationGraphWidget.cpp',
61 'src/Visualization/VisualizationGraphWidget.cpp',
60 'src/Visualization/VisualizationTabWidget.cpp',
62 'src/Visualization/VisualizationTabWidget.cpp',
61 'src/Visualization/VisualizationWidget.cpp',
63 'src/Visualization/VisualizationWidget.cpp',
62 'src/Visualization/VisualizationZoneWidget.cpp',
64 'src/Visualization/VisualizationZoneWidget.cpp',
63 'src/Visualization/qcustomplot.cpp',
65 'src/Visualization/qcustomplot.cpp',
64 'src/Visualization/QCustomPlotSynchronizer.cpp',
66 'src/Visualization/QCustomPlotSynchronizer.cpp',
65 'src/Visualization/operations/FindVariableOperation.cpp',
67 'src/Visualization/operations/FindVariableOperation.cpp',
66 'src/Visualization/operations/GenerateVariableMenuOperation.cpp',
68 'src/Visualization/operations/GenerateVariableMenuOperation.cpp',
67 'src/Visualization/operations/MenuBuilder.cpp',
69 'src/Visualization/operations/MenuBuilder.cpp',
68 'src/Visualization/operations/RemoveVariableOperation.cpp',
70 'src/Visualization/operations/RemoveVariableOperation.cpp',
69 'src/Visualization/operations/RescaleAxeOperation.cpp',
71 'src/Visualization/operations/RescaleAxeOperation.cpp',
70 'src/Visualization/VisualizationDragDropContainer.cpp',
72 'src/Visualization/VisualizationDragDropContainer.cpp',
71 'src/Visualization/VisualizationDragWidget.cpp'
73 'src/Visualization/VisualizationDragWidget.cpp'
72 ]
74 ]
73
75
74 gui_inc = include_directories(['include'])
76 gui_inc = include_directories(['include'])
75
77
76 sciqlop_gui_lib = library('sciqlopgui',
78 sciqlop_gui_lib = library('sciqlopgui',
77 gui_sources,
79 gui_sources,
78 gui_moc_files,
80 gui_moc_files,
79 include_directories : [gui_inc],
81 include_directories : [gui_inc],
80 dependencies : [ qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core],
82 dependencies : [ qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core],
81 install : true
83 install : true
82 )
84 )
83
85
84 sciqlop_gui = declare_dependency(link_with : sciqlop_gui_lib,
86 sciqlop_gui = declare_dependency(link_with : sciqlop_gui_lib,
85 include_directories : gui_inc,
87 include_directories : gui_inc,
86 dependencies : [qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core])
88 dependencies : [qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core])
87
89
@@ -1,37 +1,45
1 #include "DataSource/DataSourceTreeWidget.h"
1 #include "DataSource/DataSourceTreeWidget.h"
2 #include "Common/MimeTypesDef.h"
2 #include "Common/MimeTypesDef.h"
3 #include "DataSource/DataSourceController.h"
3 #include "DataSource/DataSourceController.h"
4 #include "DataSource/DataSourceItem.h"
4 #include "DataSource/DataSourceItem.h"
5 #include "DataSource/DataSourceTreeWidgetItem.h"
5 #include "DataSource/DataSourceTreeWidgetItem.h"
6
6
7 #include "DragDropHelper.h"
7 #include "SqpApplication.h"
8 #include "SqpApplication.h"
8
9
9 #include <QMimeData>
10 #include <QMimeData>
10
11
11 DataSourceTreeWidget::DataSourceTreeWidget(QWidget *parent) : QTreeWidget(parent) {}
12 DataSourceTreeWidget::DataSourceTreeWidget(QWidget *parent) : QTreeWidget(parent) {}
12
13
13 QMimeData *DataSourceTreeWidget::mimeData(const QList<QTreeWidgetItem *> items) const
14 QMimeData *DataSourceTreeWidget::mimeData(const QList<QTreeWidgetItem *> items) const
14 {
15 {
15 auto mimeData = new QMimeData;
16 auto mimeData = new QMimeData;
16
17
17 // Basic check to ensure the item are correctly typed
18 // Basic check to ensure the item are correctly typed
18 Q_ASSERT(items.isEmpty() || dynamic_cast<DataSourceTreeWidgetItem *>(items.first()) != nullptr);
19 Q_ASSERT(items.isEmpty() || dynamic_cast<DataSourceTreeWidgetItem *>(items.first()) != nullptr);
19
20
20 QVariantList productData;
21 QVariantList productData;
21
22
22 for (auto item : items) {
23 for (auto item : items) {
23 auto dataSourceTreeItem = static_cast<DataSourceTreeWidgetItem *>(item);
24 auto dataSourceTreeItem = static_cast<DataSourceTreeWidgetItem *>(item);
24 auto dataSource = dataSourceTreeItem->data();
25 auto dataSource = dataSourceTreeItem->data();
25
26
26 if (dataSource->type() == DataSourceItemType::COMPONENT
27 if (dataSource->type() == DataSourceItemType::COMPONENT
27 || dataSource->type() == DataSourceItemType::PRODUCT) {
28 || dataSource->type() == DataSourceItemType::PRODUCT) {
28 auto metaData = dataSource->data();
29 auto metaData = dataSource->data();
29 productData << metaData;
30 productData << metaData;
30 }
31 }
31 }
32 }
32
33
33 auto encodedData = sqpApp->dataSourceController().mimeDataForProductsData(productData);
34 auto encodedData = sqpApp->dataSourceController().mimeDataForProductsData(productData);
34 mimeData->setData(MIME_TYPE_PRODUCT_LIST, encodedData);
35 mimeData->setData(MIME_TYPE_PRODUCT_LIST, encodedData);
35
36
36 return mimeData;
37 return mimeData;
37 }
38 }
39
40 void DataSourceTreeWidget::startDrag(Qt::DropActions supportedActions)
41 {
42 // Resets the drag&drop operations before it's starting
43 sqpApp->dragDropHelper().resetDragAndDrop();
44 QTreeWidget::startDrag(supportedActions);
45 }
@@ -1,245 +1,240
1 #include <Variable/RenameVariableDialog.h>
1 #include <Variable/RenameVariableDialog.h>
2 #include <Variable/Variable.h>
2 #include <Variable/Variable.h>
3 #include <Variable/VariableController.h>
3 #include <Variable/VariableController.h>
4 #include <Variable/VariableInspectorWidget.h>
4 #include <Variable/VariableInspectorWidget.h>
5 #include <Variable/VariableMenuHeaderWidget.h>
5 #include <Variable/VariableMenuHeaderWidget.h>
6 #include <Variable/VariableModel.h>
6 #include <Variable/VariableModel.h>
7
7
8 #include <ui_VariableInspectorWidget.h>
8 #include <ui_VariableInspectorWidget.h>
9
9
10 #include <QMouseEvent>
10 #include <QMouseEvent>
11 #include <QSortFilterProxyModel>
11 #include <QSortFilterProxyModel>
12 #include <QStyledItemDelegate>
12 #include <QStyledItemDelegate>
13 #include <QWidgetAction>
13 #include <QWidgetAction>
14
14
15 #include <DragDropHelper.h>
15 #include <DragDropHelper.h>
16 #include <SqpApplication.h>
16 #include <SqpApplication.h>
17
17
18 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
18 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
19
19
20
20
21 class QProgressBarItemDelegate : public QStyledItemDelegate {
21 class QProgressBarItemDelegate : public QStyledItemDelegate {
22
22
23 public:
23 public:
24 QProgressBarItemDelegate(QObject *parent) : QStyledItemDelegate{parent} {}
24 QProgressBarItemDelegate(QObject *parent) : QStyledItemDelegate{parent} {}
25
25
26 void paint(QPainter *painter, const QStyleOptionViewItem &option,
26 void paint(QPainter *painter, const QStyleOptionViewItem &option,
27 const QModelIndex &index) const
27 const QModelIndex &index) const
28 {
28 {
29 auto data = index.data(Qt::DisplayRole);
29 auto data = index.data(Qt::DisplayRole);
30 auto progressData = index.data(VariableRoles::ProgressRole);
30 auto progressData = index.data(VariableRoles::ProgressRole);
31 if (data.isValid() && progressData.isValid()) {
31 if (data.isValid() && progressData.isValid()) {
32 auto name = data.value<QString>();
32 auto name = data.value<QString>();
33 auto progress = progressData.value<double>();
33 auto progress = progressData.value<double>();
34 if (progress > 0) {
34 if (progress > 0) {
35 auto cancelButtonWidth = 20;
35 auto cancelButtonWidth = 20;
36 auto progressBarOption = QStyleOptionProgressBar{};
36 auto progressBarOption = QStyleOptionProgressBar{};
37 auto progressRect = option.rect;
37 auto progressRect = option.rect;
38 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
38 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
39 progressBarOption.rect = progressRect;
39 progressBarOption.rect = progressRect;
40 progressBarOption.minimum = 0;
40 progressBarOption.minimum = 0;
41 progressBarOption.maximum = 100;
41 progressBarOption.maximum = 100;
42 progressBarOption.progress = progress;
42 progressBarOption.progress = progress;
43 progressBarOption.text
43 progressBarOption.text
44 = QString("%1 %2").arg(name).arg(QString::number(progress, 'f', 2) + "%");
44 = QString("%1 %2").arg(name).arg(QString::number(progress, 'f', 2) + "%");
45 progressBarOption.textVisible = true;
45 progressBarOption.textVisible = true;
46 progressBarOption.textAlignment = Qt::AlignCenter;
46 progressBarOption.textAlignment = Qt::AlignCenter;
47
47
48
48
49 QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption,
49 QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption,
50 painter);
50 painter);
51
51
52 // Cancel button
52 // Cancel button
53 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
53 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
54 option.rect.height());
54 option.rect.height());
55 auto buttonOption = QStyleOptionButton{};
55 auto buttonOption = QStyleOptionButton{};
56 buttonOption.rect = buttonRect;
56 buttonOption.rect = buttonRect;
57 buttonOption.text = "X";
57 buttonOption.text = "X";
58
58
59 QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
59 QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
60 }
60 }
61 else {
61 else {
62 QStyledItemDelegate::paint(painter, option, index);
62 QStyledItemDelegate::paint(painter, option, index);
63 }
63 }
64 }
64 }
65 else {
65 else {
66 QStyledItemDelegate::paint(painter, option, index);
66 QStyledItemDelegate::paint(painter, option, index);
67 }
67 }
68 }
68 }
69
69
70 bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
70 bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
71 const QModelIndex &index)
71 const QModelIndex &index)
72 {
72 {
73 if (event->type() == QEvent::MouseButtonRelease) {
73 if (event->type() == QEvent::MouseButtonRelease) {
74 auto data = index.data(Qt::DisplayRole);
74 auto data = index.data(Qt::DisplayRole);
75 auto progressData = index.data(VariableRoles::ProgressRole);
75 auto progressData = index.data(VariableRoles::ProgressRole);
76 if (data.isValid() && progressData.isValid()) {
76 if (data.isValid() && progressData.isValid()) {
77 auto cancelButtonWidth = 20;
77 auto cancelButtonWidth = 20;
78 auto progressRect = option.rect;
78 auto progressRect = option.rect;
79 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
79 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
80 // Cancel button
80 // Cancel button
81 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
81 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
82 option.rect.height());
82 option.rect.height());
83
83
84 auto e = (QMouseEvent *)event;
84 auto e = (QMouseEvent *)event;
85 auto clickX = e->x();
85 auto clickX = e->x();
86 auto clickY = e->y();
86 auto clickY = e->y();
87
87
88 auto x = buttonRect.left(); // the X coordinate
88 auto x = buttonRect.left(); // the X coordinate
89 auto y = buttonRect.top(); // the Y coordinate
89 auto y = buttonRect.top(); // the Y coordinate
90 auto w = buttonRect.width(); // button width
90 auto w = buttonRect.width(); // button width
91 auto h = buttonRect.height(); // button height
91 auto h = buttonRect.height(); // button height
92
92
93 if (clickX > x && clickX < x + w) {
93 if (clickX > x && clickX < x + w) {
94 if (clickY > y && clickY < y + h) {
94 if (clickY > y && clickY < y + h) {
95 auto variableModel = sqpApp->variableController().variableModel();
95 auto variableModel = sqpApp->variableController().variableModel();
96 variableModel->abortProgress(index);
96 variableModel->abortProgress(index);
97 }
97 }
98 return true;
98 return true;
99 }
99 }
100 else {
100 else {
101 return QStyledItemDelegate::editorEvent(event, model, option, index);
101 return QStyledItemDelegate::editorEvent(event, model, option, index);
102 }
102 }
103 }
103 }
104 else {
104 else {
105 return QStyledItemDelegate::editorEvent(event, model, option, index);
105 return QStyledItemDelegate::editorEvent(event, model, option, index);
106 }
106 }
107 }
107 }
108 else {
108 else {
109 return QStyledItemDelegate::editorEvent(event, model, option, index);
109 return QStyledItemDelegate::editorEvent(event, model, option, index);
110 }
110 }
111
111
112
112
113 return QStyledItemDelegate::editorEvent(event, model, option, index);
113 return QStyledItemDelegate::editorEvent(event, model, option, index);
114 }
114 }
115 };
115 };
116
116
117 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
117 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
118 : QWidget{parent},
118 : QWidget{parent},
119 ui{new Ui::VariableInspectorWidget},
119 ui{new Ui::VariableInspectorWidget},
120 m_ProgressBarItemDelegate{new QProgressBarItemDelegate{this}}
120 m_ProgressBarItemDelegate{new QProgressBarItemDelegate{this}}
121 {
121 {
122 ui->setupUi(this);
122 ui->setupUi(this);
123
123
124 // Sets model for table
124 // Sets model for table
125 // auto sortFilterModel = new QSortFilterProxyModel{this};
125 // auto sortFilterModel = new QSortFilterProxyModel{this};
126 // sortFilterModel->setSourceModel(sqpApp->variableController().variableModel());
126 // sortFilterModel->setSourceModel(sqpApp->variableController().variableModel());
127
127
128 auto variableModel = sqpApp->variableController().variableModel();
128 auto variableModel = sqpApp->variableController().variableModel();
129 ui->tableView->setModel(variableModel);
129 ui->tableView->setModel(variableModel);
130
130
131 // Adds extra signal/slot between view and model, so the view can be updated instantly when
131 // Adds extra signal/slot between view and model, so the view can be updated instantly when
132 // there is a change of data in the model
132 // there is a change of data in the model
133 connect(variableModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this,
133 connect(variableModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this,
134 SLOT(refresh()));
134 SLOT(refresh()));
135
135
136 ui->tableView->setSelectionModel(sqpApp->variableController().variableSelectionModel());
136 ui->tableView->setSelectionModel(sqpApp->variableController().variableSelectionModel());
137 ui->tableView->setItemDelegateForColumn(0, m_ProgressBarItemDelegate);
137 ui->tableView->setItemDelegateForColumn(0, m_ProgressBarItemDelegate);
138
138
139 // Fixes column sizes
139 // Fixes column sizes
140 auto model = ui->tableView->model();
140 auto model = ui->tableView->model();
141 const auto count = model->columnCount();
141 const auto count = model->columnCount();
142 for (auto i = 0; i < count; ++i) {
142 for (auto i = 0; i < count; ++i) {
143 ui->tableView->setColumnWidth(
143 ui->tableView->setColumnWidth(
144 i, model->headerData(i, Qt::Horizontal, Qt::SizeHintRole).toSize().width());
144 i, model->headerData(i, Qt::Horizontal, Qt::SizeHintRole).toSize().width());
145 }
145 }
146
146
147 // Sets selection options
147 // Sets selection options
148 ui->tableView->setSelectionBehavior(QTableView::SelectRows);
148 ui->tableView->setSelectionBehavior(QTableView::SelectRows);
149 ui->tableView->setSelectionMode(QTableView::ExtendedSelection);
149 ui->tableView->setSelectionMode(QTableView::ExtendedSelection);
150
150
151 // Connection to show a menu when right clicking on the tree
151 // Connection to show a menu when right clicking on the tree
152 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
152 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
153 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
153 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
154 &VariableInspectorWidget::onTableMenuRequested);
154 &VariableInspectorWidget::onTableMenuRequested);
155
156 // Resets the drag&drop operation on a left-click (the drag&drop is also started by a left
157 // click).
158 connect(ui->tableView, &QTableView::clicked,
159 [](const auto &modelIndex) { sqpApp->dragDropHelper().resetDragAndDrop(); });
160 }
155 }
161
156
162 VariableInspectorWidget::~VariableInspectorWidget()
157 VariableInspectorWidget::~VariableInspectorWidget()
163 {
158 {
164 delete ui;
159 delete ui;
165 }
160 }
166
161
167 void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept
162 void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept
168 {
163 {
169 auto selectedRows = ui->tableView->selectionModel()->selectedRows();
164 auto selectedRows = ui->tableView->selectionModel()->selectedRows();
170
165
171 // Gets the model to retrieve the underlying selected variables
166 // Gets the model to retrieve the underlying selected variables
172 auto model = sqpApp->variableController().variableModel();
167 auto model = sqpApp->variableController().variableModel();
173 auto selectedVariables = QVector<std::shared_ptr<Variable> >{};
168 auto selectedVariables = QVector<std::shared_ptr<Variable> >{};
174 for (const auto &selectedRow : qAsConst(selectedRows)) {
169 for (const auto &selectedRow : qAsConst(selectedRows)) {
175 if (auto selectedVariable = model->variable(selectedRow.row())) {
170 if (auto selectedVariable = model->variable(selectedRow.row())) {
176 selectedVariables.push_back(selectedVariable);
171 selectedVariables.push_back(selectedVariable);
177 }
172 }
178 }
173 }
179
174
180 QMenu tableMenu{};
175 QMenu tableMenu{};
181
176
182 // Emits a signal so that potential receivers can populate the menu before displaying it
177 // Emits a signal so that potential receivers can populate the menu before displaying it
183 emit tableMenuAboutToBeDisplayed(&tableMenu, selectedVariables);
178 emit tableMenuAboutToBeDisplayed(&tableMenu, selectedVariables);
184
179
185 // Adds menu-specific actions
180 // Adds menu-specific actions
186 if (!selectedVariables.isEmpty()) {
181 if (!selectedVariables.isEmpty()) {
187 tableMenu.addSeparator();
182 tableMenu.addSeparator();
188
183
189 // 'Rename' and 'Duplicate' actions (only if one variable selected)
184 // 'Rename' and 'Duplicate' actions (only if one variable selected)
190 if (selectedVariables.size() == 1) {
185 if (selectedVariables.size() == 1) {
191 auto selectedVariable = selectedVariables.front();
186 auto selectedVariable = selectedVariables.front();
192
187
193 auto duplicateFun = [varW = std::weak_ptr<Variable>(selectedVariable)]()
188 auto duplicateFun = [varW = std::weak_ptr<Variable>(selectedVariable)]()
194 {
189 {
195 if (auto var = varW.lock()) {
190 if (auto var = varW.lock()) {
196 sqpApp->variableController().cloneVariable(var);
191 sqpApp->variableController().cloneVariable(var);
197 }
192 }
198 };
193 };
199
194
200 tableMenu.addAction(tr("Duplicate"), duplicateFun);
195 tableMenu.addAction(tr("Duplicate"), duplicateFun);
201
196
202 auto renameFun = [ varW = std::weak_ptr<Variable>(selectedVariable), &model, this ]()
197 auto renameFun = [ varW = std::weak_ptr<Variable>(selectedVariable), &model, this ]()
203 {
198 {
204 if (auto var = varW.lock()) {
199 if (auto var = varW.lock()) {
205 // Generates forbidden names (names associated to existing variables)
200 // Generates forbidden names (names associated to existing variables)
206 auto allVariables = model->variables();
201 auto allVariables = model->variables();
207 auto forbiddenNames = QVector<QString>(allVariables.size());
202 auto forbiddenNames = QVector<QString>(allVariables.size());
208 std::transform(allVariables.cbegin(), allVariables.cend(),
203 std::transform(allVariables.cbegin(), allVariables.cend(),
209 forbiddenNames.begin(),
204 forbiddenNames.begin(),
210 [](const auto &variable) { return variable->name(); });
205 [](const auto &variable) { return variable->name(); });
211
206
212 RenameVariableDialog dialog{var->name(), forbiddenNames, this};
207 RenameVariableDialog dialog{var->name(), forbiddenNames, this};
213 if (dialog.exec() == QDialog::Accepted) {
208 if (dialog.exec() == QDialog::Accepted) {
214 var->setName(dialog.name());
209 var->setName(dialog.name());
215 }
210 }
216 }
211 }
217 };
212 };
218
213
219 tableMenu.addAction(tr("Rename..."), renameFun);
214 tableMenu.addAction(tr("Rename..."), renameFun);
220 }
215 }
221
216
222 // 'Delete' action
217 // 'Delete' action
223 auto deleteFun = [&selectedVariables]() {
218 auto deleteFun = [&selectedVariables]() {
224 sqpApp->variableController().deleteVariables(selectedVariables);
219 sqpApp->variableController().deleteVariables(selectedVariables);
225 };
220 };
226
221
227 tableMenu.addAction(QIcon{":/icones/delete.png"}, tr("Delete"), deleteFun);
222 tableMenu.addAction(QIcon{":/icones/delete.png"}, tr("Delete"), deleteFun);
228 }
223 }
229
224
230 if (!tableMenu.isEmpty()) {
225 if (!tableMenu.isEmpty()) {
231 // Generates menu header (inserted before first action)
226 // Generates menu header (inserted before first action)
232 auto firstAction = tableMenu.actions().first();
227 auto firstAction = tableMenu.actions().first();
233 auto headerAction = new QWidgetAction{&tableMenu};
228 auto headerAction = new QWidgetAction{&tableMenu};
234 headerAction->setDefaultWidget(new VariableMenuHeaderWidget{selectedVariables, &tableMenu});
229 headerAction->setDefaultWidget(new VariableMenuHeaderWidget{selectedVariables, &tableMenu});
235 tableMenu.insertAction(firstAction, headerAction);
230 tableMenu.insertAction(firstAction, headerAction);
236
231
237 // Displays menu
232 // Displays menu
238 tableMenu.exec(QCursor::pos());
233 tableMenu.exec(QCursor::pos());
239 }
234 }
240 }
235 }
241
236
242 void VariableInspectorWidget::refresh() noexcept
237 void VariableInspectorWidget::refresh() noexcept
243 {
238 {
244 ui->tableView->viewport()->update();
239 ui->tableView->viewport()->update();
245 }
240 }
@@ -1,40 +1,47
1 <?xml version="1.0" encoding="UTF-8"?>
1 <?xml version="1.0" encoding="UTF-8"?>
2 <ui version="4.0">
2 <ui version="4.0">
3 <class>VariableInspectorWidget</class>
3 <class>VariableInspectorWidget</class>
4 <widget class="QWidget" name="VariableInspectorWidget">
4 <widget class="QWidget" name="VariableInspectorWidget">
5 <property name="geometry">
5 <property name="geometry">
6 <rect>
6 <rect>
7 <x>0</x>
7 <x>0</x>
8 <y>0</y>
8 <y>0</y>
9 <width>400</width>
9 <width>400</width>
10 <height>300</height>
10 <height>300</height>
11 </rect>
11 </rect>
12 </property>
12 </property>
13 <property name="windowTitle">
13 <property name="windowTitle">
14 <string>Variables</string>
14 <string>Variables</string>
15 </property>
15 </property>
16 <layout class="QGridLayout" name="gridLayout">
16 <layout class="QGridLayout" name="gridLayout">
17 <item row="0" column="0">
17 <item row="0" column="0">
18 <widget class="QTableView" name="tableView">
18 <widget class="VariableInspectorTableView" name="tableView">
19 <property name="acceptDrops">
19 <property name="acceptDrops">
20 <bool>true</bool>
20 <bool>true</bool>
21 </property>
21 </property>
22 <property name="dragEnabled">
22 <property name="dragEnabled">
23 <bool>true</bool>
23 <bool>true</bool>
24 </property>
24 </property>
25 <property name="dragDropMode">
25 <property name="dragDropMode">
26 <enum>QAbstractItemView::DragDrop</enum>
26 <enum>QAbstractItemView::DragDrop</enum>
27 </property>
27 </property>
28 <property name="sortingEnabled">
28 <property name="sortingEnabled">
29 <bool>true</bool>
29 <bool>true</bool>
30 </property>
30 </property>
31 <attribute name="horizontalHeaderStretchLastSection">
31 <attribute name="horizontalHeaderStretchLastSection">
32 <bool>true</bool>
32 <bool>true</bool>
33 </attribute>
33 </attribute>
34 </widget>
34 </widget>
35 </item>
35 </item>
36 </layout>
36 </layout>
37 </widget>
37 </widget>
38 <customwidgets>
39 <customwidget>
40 <class>VariableInspectorTableView</class>
41 <extends>QTableView</extends>
42 <header>Variable/VariableInspectorTableView.h</header>
43 </customwidget>
44 </customwidgets>
38 <resources/>
45 <resources/>
39 <connections/>
46 <connections/>
40 </ui>
47 </ui>
General Comments 3
Under Review
author

Pull request updated. Auto status change to "Under Review"

Changed commits:
  * 1 added
  * 0 removed

Changed files:
  * A core/tests/meson.build
You need to be logged in to leave comments. Login now