##// END OF EJS Templates
Merge branch 'feature/DataSourceItemActions' into develop
Alexandre Leroux -
r148: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 54 void setDataProvider(const QUuid &dataSourceUid,
55 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 63 public slots:
58 64 /// Manage init/end of the controller
59 65 void initialize();
@@ -6,6 +6,8
6 6 #include <QVariant>
7 7 #include <QVector>
8 8
9 class DataSourceItemAction;
10
9 11 /**
10 12 * Possible types of an item
11 13 */
@@ -21,6 +23,16 class DataSourceItem {
21 23 public:
22 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 37 * Adds a child to the item. The item takes ownership of the child.
26 38 * @param child the child to add
@@ -43,6 +55,8 public:
43 55 */
44 56 QVariant data(int dataIndex) const noexcept;
45 57
58 QString name() const noexcept;
59
46 60 /**
47 61 * Get the item's parent
48 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 84 void DataSourceController::initialize()
80 85 {
81 86 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init")
@@ -1,10 +1,18
1 1 #include <DataSource/DataSourceItem.h>
2 #include <DataSource/DataSourceItemAction.h>
2 3
3 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 13 struct DataSourceItem::DataSourceItemPrivate {
6 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 20 std::vector<std::unique_ptr<DataSourceItem> > m_Children;
13 21 DataSourceItemType m_Type;
14 22 QVector<QVariant> m_Data;
23 std::vector<std::unique_ptr<DataSourceItemAction> > m_Actions;
15 24 };
16 25
17 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 47 void DataSourceItem::appendChild(std::unique_ptr<DataSourceItem> child) noexcept
23 48 {
24 49 child->impl->m_Parent = this;
@@ -45,6 +70,11 QVariant DataSourceItem::data(int dataIndex) const noexcept
45 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 78 DataSourceItem *DataSourceItem::parentItem() const noexcept
49 79 {
50 80 return impl->m_Parent;
@@ -8,3 +8,6 DataSourceItem\.h:\d+:.*IPSIS_S01.*
8 8 ArrayData\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (D)
9 9 ArrayData\.h:\d+:.*IPSIS_S06.*found: (D)
10 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 24 virtual QVariant data(int column, int role) const override;
25 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 30 private:
28 31 class DataSourceTreeWidgetItemPrivate;
29 32 spimpl::unique_impl_ptr<DataSourceTreeWidgetItemPrivate> impl;
@@ -29,6 +29,10 public slots:
29 29
30 30 private:
31 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 38 #endif // SCIQLOP_DATASOURCEWIDGET_H
@@ -1,8 +1,11
1 1 #include <DataSource/DataSourceItem.h>
2 #include <DataSource/DataSourceItemAction.h>
2 3 #include <DataSource/DataSourceTreeWidgetItem.h>
3 4
4 5 #include <SqpApplication.h>
5 6
7 #include <QAction>
8
6 9 Q_LOGGING_CATEGORY(LOG_DataSourceTreeWidgetItem, "DataSourceTreeWidgetItem")
7 10
8 11 namespace {
@@ -40,6 +43,9 struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
40 43
41 44 /// Model used to retrieve data source information
42 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 51 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(const DataSourceItem *data, int type)
@@ -54,6 +60,21 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(QTreeWidget *parent, const Da
54 60 {
55 61 // Sets the icon depending on the data source
56 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 80 QVariant DataSourceTreeWidgetItem::data(int column, int role) const
@@ -73,3 +94,8 void DataSourceTreeWidgetItem::setData(int column, int role, const QVariant &val
73 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 5 #include <DataSource/DataSourceItem.h>
6 6 #include <DataSource/DataSourceTreeWidgetItem.h>
7 7
8 #include <QMenu>
9
8 10 namespace {
9 11
10 12 /// Number of columns displayed in the tree
@@ -40,6 +42,11 DataSourceWidget::DataSourceWidget(QWidget *parent) : QWidget{parent}, ui{new Ui
40 42 // Set tree properties
41 43 ui->treeWidget->setColumnCount(TREE_NB_COLUMNS);
42 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 52 void DataSourceWidget::addDataSource(DataSourceItem *dataSource) noexcept
@@ -50,3 +57,16 void DataSourceWidget::addDataSource(DataSourceItem *dataSource) noexcept
50 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 4 #include <DataSource/DataSourceController.h>
5 5 #include <DataSource/DataSourceItem.h>
6 #include <DataSource/DataSourceItemAction.h>
6 7
7 8 #include <SqpApplication.h>
8 9
@@ -19,19 +20,30 std::unique_ptr<IDataProvider> createDataProvider() noexcept
19 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 39 /// Creates the data source item relative to the plugin
23 40 std::unique_ptr<DataSourceItem> createDataSourceItem() noexcept
24 41 {
25 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 43 auto magneticFieldFolder = std::make_unique<DataSourceItem>(
32 44 DataSourceItemType::NODE, QVector<QVariant>{QStringLiteral("Magnetic field")});
33 magneticFieldFolder->appendChild(std::move(fgmProduct));
34 magneticFieldFolder->appendChild(std::move(scProduct));
45 magneticFieldFolder->appendChild(createProductItem(QStringLiteral("FGM")));
46 magneticFieldFolder->appendChild(createProductItem(QStringLiteral("SC")));
35 47
36 48 // Electric field products
37 49 auto electricFieldFolder = std::make_unique<DataSourceItem>(
General Comments 0
You need to be logged in to leave comments. Login now