##// END OF EJS Templates
Merge branch 'feature/DataSourceItemActions' into develop
Alexandre Leroux -
r139:87e3d651fb37 merge
parent child
Show More
@@ -0,0 +1,48
1 #ifndef SCIQLOP_DATASOURCEITEMACTION_H
2 #define SCIQLOP_DATASOURCEITEMACTION_H
3
4 #include <Common/spimpl.h>
5
6 #include <QLoggingCategory>
7 #include <QObject>
8
9 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSourceItemAction)
10
11 class DataSourceItem;
12
13 /**
14 * @brief The DataSourceItemAction class represents an action on a data source item.
15 *
16 * An action is a function that will be executed when the slot execute() is called.
17 */
18 class DataSourceItemAction : public QObject {
19
20 Q_OBJECT
21
22 public:
23 /// Signature of the function associated to the action
24 using ExecuteFunction = std::function<void(DataSourceItem &dataSourceItem)>;
25
26 /**
27 * Ctor
28 * @param name the name of the action
29 * @param fun the function that will be called when the action is executed
30 * @sa execute()
31 */
32 explicit DataSourceItemAction(const QString &name, ExecuteFunction fun);
33
34 QString name() const noexcept;
35
36 /// Sets the data source item concerned by the action
37 void setDataSourceItem(DataSourceItem *dataSourceItem) noexcept;
38
39 public slots:
40 /// Executes the action
41 void execute();
42
43 private:
44 class DataSourceItemActionPrivate;
45 spimpl::unique_impl_ptr<DataSourceItemActionPrivate> impl;
46 };
47
48 #endif // SCIQLOP_DATASOURCEITEMACTION_H
@@ -0,0 +1,42
1 #include <DataSource/DataSourceItemAction.h>
2
3 Q_LOGGING_CATEGORY(LOG_DataSourceItemAction, "DataSourceItemAction")
4
5 struct DataSourceItemAction::DataSourceItemActionPrivate {
6 explicit DataSourceItemActionPrivate(const QString &name,
7 DataSourceItemAction::ExecuteFunction fun)
8 : m_Name{name}, m_Fun{std::move(fun)}, m_DataSourceItem{nullptr}
9 {
10 }
11
12 QString m_Name;
13 DataSourceItemAction::ExecuteFunction m_Fun;
14 /// Item associated to the action (can be null, in which case the action will not be executed)
15 DataSourceItem *m_DataSourceItem;
16 };
17
18 DataSourceItemAction::DataSourceItemAction(const QString &name, ExecuteFunction fun)
19 : impl{spimpl::make_unique_impl<DataSourceItemActionPrivate>(name, std::move(fun))}
20 {
21 }
22
23 QString DataSourceItemAction::name() const noexcept
24 {
25 return impl->m_Name;
26 }
27
28 void DataSourceItemAction::setDataSourceItem(DataSourceItem *dataSourceItem) noexcept
29 {
30 impl->m_DataSourceItem = dataSourceItem;
31 }
32
33 void DataSourceItemAction::execute()
34 {
35 if (impl->m_DataSourceItem) {
36 impl->m_Fun(*impl->m_DataSourceItem);
37 }
38 else {
39 qCDebug(LOG_DataSourceItemAction())
40 << tr("Can't execute action : no item has been associated");
41 }
42 }
@@ -54,6 +54,12 public:
54 void setDataProvider(const QUuid &dataSourceUid,
54 void setDataProvider(const QUuid &dataSourceUid,
55 std::unique_ptr<IDataProvider> dataProvider) noexcept;
55 std::unique_ptr<IDataProvider> dataProvider) noexcept;
56
56
57 /**
58 * Loads an item (product) as a variable in SciQlop
59 * @param productItem the item to load
60 */
61 void loadProductItem(const DataSourceItem &productItem) noexcept;
62
57 public slots:
63 public slots:
58 /// Manage init/end of the controller
64 /// Manage init/end of the controller
59 void initialize();
65 void initialize();
@@ -6,6 +6,8
6 #include <QVariant>
6 #include <QVariant>
7 #include <QVector>
7 #include <QVector>
8
8
9 class DataSourceItemAction;
10
9 /**
11 /**
10 * Possible types of an item
12 * Possible types of an item
11 */
13 */
@@ -21,6 +23,16 class DataSourceItem {
21 public:
23 public:
22 explicit DataSourceItem(DataSourceItemType type, QVector<QVariant> data = {});
24 explicit DataSourceItem(DataSourceItemType type, QVector<QVariant> data = {});
23
25
26 /// @return the actions of the item as a vector
27 QVector<DataSourceItemAction *> actions() const noexcept;
28
29 /**
30 * Adds an action to the item. The item takes ownership of the action, and the action is
31 * automatically associated to the item
32 * @param action the action to add
33 */
34 void addAction(std::unique_ptr<DataSourceItemAction> action) noexcept;
35
24 /**
36 /**
25 * Adds a child to the item. The item takes ownership of the child.
37 * Adds a child to the item. The item takes ownership of the child.
26 * @param child the child to add
38 * @param child the child to add
@@ -43,6 +55,8 public:
43 */
55 */
44 QVariant data(int dataIndex) const noexcept;
56 QVariant data(int dataIndex) const noexcept;
45
57
58 QString name() const noexcept;
59
46 /**
60 /**
47 * Get the item's parent
61 * Get the item's parent
48 * @return a pointer to the parent if it exists, nullptr if the item is a root
62 * @return a pointer to the parent if it exists, nullptr if the item is a root
@@ -76,6 +76,11 void DataSourceController::setDataProvider(const QUuid &dataSourceUid,
76 }
76 }
77 }
77 }
78
78
79 void DataSourceController::loadProductItem(const DataSourceItem &productItem) noexcept
80 {
81 /// @todo ALX
82 }
83
79 void DataSourceController::initialize()
84 void DataSourceController::initialize()
80 {
85 {
81 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init")
86 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init")
@@ -1,10 +1,18
1 #include <DataSource/DataSourceItem.h>
1 #include <DataSource/DataSourceItem.h>
2 #include <DataSource/DataSourceItemAction.h>
2
3
3 #include <QVector>
4 #include <QVector>
4
5
6 namespace {
7
8 /// Index of the 'name' value in the item
9 const auto NAME_INDEX = 0;
10
11 } // namespace
12
5 struct DataSourceItem::DataSourceItemPrivate {
13 struct DataSourceItem::DataSourceItemPrivate {
6 explicit DataSourceItemPrivate(DataSourceItemType type, QVector<QVariant> data)
14 explicit DataSourceItemPrivate(DataSourceItemType type, QVector<QVariant> data)
7 : m_Parent{nullptr}, m_Children{}, m_Type{type}, m_Data{std::move(data)}
15 : m_Parent{nullptr}, m_Children{}, m_Type{type}, m_Data{std::move(data)}, m_Actions{}
8 {
16 {
9 }
17 }
10
18
@@ -12,6 +20,7 struct DataSourceItem::DataSourceItemPrivate {
12 std::vector<std::unique_ptr<DataSourceItem> > m_Children;
20 std::vector<std::unique_ptr<DataSourceItem> > m_Children;
13 DataSourceItemType m_Type;
21 DataSourceItemType m_Type;
14 QVector<QVariant> m_Data;
22 QVector<QVariant> m_Data;
23 std::vector<std::unique_ptr<DataSourceItemAction> > m_Actions;
15 };
24 };
16
25
17 DataSourceItem::DataSourceItem(DataSourceItemType type, QVector<QVariant> data)
26 DataSourceItem::DataSourceItem(DataSourceItemType type, QVector<QVariant> data)
@@ -19,6 +28,22 DataSourceItem::DataSourceItem(DataSourceItemType type, QVector<QVariant> data)
19 {
28 {
20 }
29 }
21
30
31 QVector<DataSourceItemAction *> DataSourceItem::actions() const noexcept
32 {
33 QVector<DataSourceItemAction *> result{};
34
35 std::transform(std::cbegin(impl->m_Actions), std::cend(impl->m_Actions),
36 std::back_inserter(result), [](const auto &action) { return action.get(); });
37
38 return result;
39 }
40
41 void DataSourceItem::addAction(std::unique_ptr<DataSourceItemAction> action) noexcept
42 {
43 action->setDataSourceItem(this);
44 impl->m_Actions.push_back(std::move(action));
45 }
46
22 void DataSourceItem::appendChild(std::unique_ptr<DataSourceItem> child) noexcept
47 void DataSourceItem::appendChild(std::unique_ptr<DataSourceItem> child) noexcept
23 {
48 {
24 child->impl->m_Parent = this;
49 child->impl->m_Parent = this;
@@ -45,6 +70,11 QVariant DataSourceItem::data(int dataIndex) const noexcept
45 return impl->m_Data.value(dataIndex);
70 return impl->m_Data.value(dataIndex);
46 }
71 }
47
72
73 QString DataSourceItem::name() const noexcept
74 {
75 return data(NAME_INDEX).toString();
76 }
77
48 DataSourceItem *DataSourceItem::parentItem() const noexcept
78 DataSourceItem *DataSourceItem::parentItem() const noexcept
49 {
79 {
50 return impl->m_Parent;
80 return impl->m_Parent;
@@ -8,3 +8,6 DataSourceItem\.h:\d+:.*IPSIS_S01.*
8 ArrayData\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (D)
8 ArrayData\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (D)
9 ArrayData\.h:\d+:.*IPSIS_S06.*found: (D)
9 ArrayData\.h:\d+:.*IPSIS_S06.*found: (D)
10 ArrayData\.h:\d+:.*IPSIS_S06.*found: (Dim)
10 ArrayData\.h:\d+:.*IPSIS_S06.*found: (Dim)
11
12 # Ignore false positive relative to an alias
13 DataSourceItemAction\.h:\d+:.*IPSIS_S06.*found: (ExecuteFunction)
@@ -24,6 +24,9 public:
24 virtual QVariant data(int column, int role) const override;
24 virtual QVariant data(int column, int role) const override;
25 virtual void setData(int column, int role, const QVariant &value) override;
25 virtual void setData(int column, int role, const QVariant &value) override;
26
26
27 /// @return the actions associated to the item
28 QList<QAction *> actions() const noexcept;
29
27 private:
30 private:
28 class DataSourceTreeWidgetItemPrivate;
31 class DataSourceTreeWidgetItemPrivate;
29 spimpl::unique_impl_ptr<DataSourceTreeWidgetItemPrivate> impl;
32 spimpl::unique_impl_ptr<DataSourceTreeWidgetItemPrivate> impl;
@@ -29,6 +29,10 public slots:
29
29
30 private:
30 private:
31 Ui::DataSourceWidget *ui;
31 Ui::DataSourceWidget *ui;
32
33 private slots:
34 /// Slot called when right clicking on an item in the tree (displays a menu)
35 void onTreeMenuRequested(const QPoint &pos) noexcept;
32 };
36 };
33
37
34 #endif // SCIQLOP_DATASOURCEWIDGET_H
38 #endif // SCIQLOP_DATASOURCEWIDGET_H
@@ -1,8 +1,11
1 #include <DataSource/DataSourceItem.h>
1 #include <DataSource/DataSourceItem.h>
2 #include <DataSource/DataSourceItemAction.h>
2 #include <DataSource/DataSourceTreeWidgetItem.h>
3 #include <DataSource/DataSourceTreeWidgetItem.h>
3
4
4 #include <SqpApplication.h>
5 #include <SqpApplication.h>
5
6
7 #include <QAction>
8
6 Q_LOGGING_CATEGORY(LOG_DataSourceTreeWidgetItem, "DataSourceTreeWidgetItem")
9 Q_LOGGING_CATEGORY(LOG_DataSourceTreeWidgetItem, "DataSourceTreeWidgetItem")
7
10
8 namespace {
11 namespace {
@@ -40,6 +43,9 struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
40
43
41 /// Model used to retrieve data source information
44 /// Model used to retrieve data source information
42 const DataSourceItem *m_Data;
45 const DataSourceItem *m_Data;
46 /// Actions associated to the item. The parent of the item (QTreeWidget) takes the ownership of
47 /// the actions
48 QList<QAction *> m_Actions;
43 };
49 };
44
50
45 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(const DataSourceItem *data, int type)
51 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(const DataSourceItem *data, int type)
@@ -54,6 +60,21 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(QTreeWidget *parent, const Da
54 {
60 {
55 // Sets the icon depending on the data source
61 // Sets the icon depending on the data source
56 setIcon(0, itemIcon(impl->m_Data));
62 setIcon(0, itemIcon(impl->m_Data));
63
64 // Generates tree actions based on the item actions
65 auto createTreeAction = [this, &parent](const auto &itemAction) {
66 auto treeAction = new QAction{itemAction->name(), parent};
67
68 // Executes item action when tree action is triggered
69 QObject::connect(treeAction, &QAction::triggered, itemAction,
70 &DataSourceItemAction::execute);
71
72 return treeAction;
73 };
74
75 auto itemActions = impl->m_Data->actions();
76 std::transform(std::cbegin(itemActions), std::cend(itemActions),
77 std::back_inserter(impl->m_Actions), createTreeAction);
57 }
78 }
58
79
59 QVariant DataSourceTreeWidgetItem::data(int column, int role) const
80 QVariant DataSourceTreeWidgetItem::data(int column, int role) const
@@ -73,3 +94,8 void DataSourceTreeWidgetItem::setData(int column, int role, const QVariant &val
73 QTreeWidgetItem::setData(column, role, value);
94 QTreeWidgetItem::setData(column, role, value);
74 }
95 }
75 }
96 }
97
98 QList<QAction *> DataSourceTreeWidgetItem::actions() const noexcept
99 {
100 return impl->m_Actions;
101 }
@@ -5,6 +5,8
5 #include <DataSource/DataSourceItem.h>
5 #include <DataSource/DataSourceItem.h>
6 #include <DataSource/DataSourceTreeWidgetItem.h>
6 #include <DataSource/DataSourceTreeWidgetItem.h>
7
7
8 #include <QMenu>
9
8 namespace {
10 namespace {
9
11
10 /// Number of columns displayed in the tree
12 /// Number of columns displayed in the tree
@@ -40,6 +42,11 DataSourceWidget::DataSourceWidget(QWidget *parent) : QWidget{parent}, ui{new Ui
40 // Set tree properties
42 // Set tree properties
41 ui->treeWidget->setColumnCount(TREE_NB_COLUMNS);
43 ui->treeWidget->setColumnCount(TREE_NB_COLUMNS);
42 ui->treeWidget->setHeaderLabels(TREE_HEADER_LABELS);
44 ui->treeWidget->setHeaderLabels(TREE_HEADER_LABELS);
45 ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
46
47 // Connection to show a menu when right clicking on the tree
48 connect(ui->treeWidget, &QTreeWidget::customContextMenuRequested, this,
49 &DataSourceWidget::onTreeMenuRequested);
43 }
50 }
44
51
45 void DataSourceWidget::addDataSource(DataSourceItem *dataSource) noexcept
52 void DataSourceWidget::addDataSource(DataSourceItem *dataSource) noexcept
@@ -50,3 +57,16 void DataSourceWidget::addDataSource(DataSourceItem *dataSource) noexcept
50 ui->treeWidget->addTopLevelItem(createTreeWidgetItem(dataSource));
57 ui->treeWidget->addTopLevelItem(createTreeWidgetItem(dataSource));
51 }
58 }
52 }
59 }
60
61 void DataSourceWidget::onTreeMenuRequested(const QPoint &pos) noexcept
62 {
63 // Retrieves the selected item in the tree, and build the menu from its actions
64 if (auto selectedItem = dynamic_cast<DataSourceTreeWidgetItem *>(ui->treeWidget->itemAt(pos))) {
65 QMenu treeMenu{};
66 treeMenu.addActions(selectedItem->actions());
67
68 if (!treeMenu.isEmpty()) {
69 treeMenu.exec(mapToGlobal(pos));
70 }
71 }
72 }
@@ -3,6 +3,7
3
3
4 #include <DataSource/DataSourceController.h>
4 #include <DataSource/DataSourceController.h>
5 #include <DataSource/DataSourceItem.h>
5 #include <DataSource/DataSourceItem.h>
6 #include <DataSource/DataSourceItemAction.h>
6
7
7 #include <SqpApplication.h>
8 #include <SqpApplication.h>
8
9
@@ -19,19 +20,30 std::unique_ptr<IDataProvider> createDataProvider() noexcept
19 return std::make_unique<CosinusProvider>();
20 return std::make_unique<CosinusProvider>();
20 }
21 }
21
22
23 std::unique_ptr<DataSourceItem> createProductItem(const QString &productName)
24 {
25 auto result = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT,
26 QVector<QVariant>{productName});
27
28 // Add action to load product from DataSourceController
29 result->addAction(std::make_unique<DataSourceItemAction>(
30 QObject::tr("Load %1 product").arg(productName), [productName](DataSourceItem &item) {
31 if (auto app = sqpApp) {
32 app->dataSourceController().loadProductItem(item);
33 }
34 }));
35
36 return result;
37 }
38
22 /// Creates the data source item relative to the plugin
39 /// Creates the data source item relative to the plugin
23 std::unique_ptr<DataSourceItem> createDataSourceItem() noexcept
40 std::unique_ptr<DataSourceItem> createDataSourceItem() noexcept
24 {
41 {
25 // Magnetic field products
42 // Magnetic field products
26 auto fgmProduct = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT,
27 QVector<QVariant>{QStringLiteral("FGM")});
28 auto scProduct = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT,
29 QVector<QVariant>{QStringLiteral("SC")});
30
31 auto magneticFieldFolder = std::make_unique<DataSourceItem>(
43 auto magneticFieldFolder = std::make_unique<DataSourceItem>(
32 DataSourceItemType::NODE, QVector<QVariant>{QStringLiteral("Magnetic field")});
44 DataSourceItemType::NODE, QVector<QVariant>{QStringLiteral("Magnetic field")});
33 magneticFieldFolder->appendChild(std::move(fgmProduct));
45 magneticFieldFolder->appendChild(createProductItem(QStringLiteral("FGM")));
34 magneticFieldFolder->appendChild(std::move(scProduct));
46 magneticFieldFolder->appendChild(createProductItem(QStringLiteral("SC")));
35
47
36 // Electric field products
48 // Electric field products
37 auto electricFieldFolder = std::make_unique<DataSourceItem>(
49 auto electricFieldFolder = std::make_unique<DataSourceItem>(
General Comments 0
You need to be logged in to leave comments. Login now