##// END OF EJS Templates
Removed bad dependency between VC and VariableModel, moved mime stuff...
jeandet -
r27:c08d1b8ad297
parent child
Show More
@@ -1,106 +1,106
1 #ifndef SCIQLOP_DATASOURCECONTROLLER_H
1 #ifndef SCIQLOP_DATASOURCECONTROLLER_H
2 #define SCIQLOP_DATASOURCECONTROLLER_H
2 #define SCIQLOP_DATASOURCECONTROLLER_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QObject>
7 #include <QObject>
8 #include <QUuid>
8 #include <QUuid>
9
9
10 #include <Common/spimpl.h>
10 #include <Common/spimpl.h>
11
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSourceController)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSourceController)
13
13
14 class DataSourceItem;
14 class DataSourceItem;
15 class IDataProvider;
15 class IDataProvider;
16
16
17 /**
17 /**
18 * @brief The DataSourceController class aims to make the link between SciQlop and its plugins. This
18 * @brief The DataSourceController class aims to make the link between SciQlop and its plugins. This
19 * is the intermediate class that SciQlop has to use in the way to connect a data source. Please
19 * is the intermediate class that SciQlop has to use in the way to connect a data source. Please
20 * first use register method to initialize a plugin specified by its metadata name (JSON plugin
20 * first use register method to initialize a plugin specified by its metadata name (JSON plugin
21 * source) then others specifics method will be able to access it. You can load a data source driver
21 * source) then others specifics method will be able to access it. You can load a data source driver
22 * plugin then create a data source.
22 * plugin then create a data source.
23 */
23 */
24 class SCIQLOP_CORE_EXPORT DataSourceController : public QObject {
24 class SCIQLOP_CORE_EXPORT DataSourceController : public QObject {
25 Q_OBJECT
25 Q_OBJECT
26 public:
26 public:
27 explicit DataSourceController(QObject *parent = 0);
27 explicit DataSourceController(QObject *parent = 0);
28 virtual ~DataSourceController();
28 virtual ~DataSourceController();
29
29
30 /**
30 /**
31 * Registers a data source. The method delivers a unique id that can be used afterwards to
31 * Registers a data source. The method delivers a unique id that can be used afterwards to
32 * access to the data source properties (structure, connection parameters, data provider, etc.)
32 * access to the data source properties (structure, connection parameters, data provider, etc.)
33 * @param dataSourceName the name of the data source
33 * @param dataSourceName the name of the data source
34 * @return the unique id with which the data source has been registered
34 * @return the unique id with which the data source has been registered
35 */
35 */
36 QUuid registerDataSource(const QString &dataSourceName) noexcept;
36 QUuid registerDataSource(const QString &dataSourceName) noexcept;
37
37
38 /**
38 /**
39 * Sets the structure of a data source. The controller takes ownership of the structure.
39 * Sets the structure of a data source. The controller takes ownership of the structure.
40 * @param dataSourceUid the unique id with which the data source has been registered into the
40 * @param dataSourceUid the unique id with which the data source has been registered into the
41 * controller. If it is invalid, the method has no effect.
41 * controller. If it is invalid, the method has no effect.
42 * @param dataSourceItem the structure of the data source. It must be not null to be registered
42 * @param dataSourceItem the structure of the data source. It must be not null to be registered
43 * @sa registerDataSource()
43 * @sa registerDataSource()
44 */
44 */
45 void setDataSourceItem(const QUuid &dataSourceUid,
45 void setDataSourceItem(const QUuid &dataSourceUid,
46 std::unique_ptr<DataSourceItem> dataSourceItem) noexcept;
46 std::unique_ptr<DataSourceItem> dataSourceItem) noexcept;
47
47
48 /**
48 /**
49 * Sets the data provider used to retrieve data from of a data source. The controller takes
49 * Sets the data provider used to retrieve data from of a data source. The controller takes
50 * ownership of the provider.
50 * ownership of the provider.
51 * @param dataSourceUid the unique id with which the data source has been registered into the
51 * @param dataSourceUid the unique id with which the data source has been registered into the
52 * controller. If it is invalid, the method has no effect.
52 * controller. If it is invalid, the method has no effect.
53 * @param dataProvider the provider of the data source
53 * @param dataProvider the provider of the data source
54 * @sa registerDataSource()
54 * @sa registerDataSource()
55 */
55 */
56 void setDataProvider(const QUuid &dataSourceUid,
56 void setDataProvider(const QUuid &dataSourceUid,
57 std::unique_ptr<IDataProvider> dataProvider) noexcept;
57 std::unique_ptr<IDataProvider> dataProvider) noexcept;
58
58
59 /**
59 /**
60 * Loads an item (product) as a variable in SciQlop
60 * Loads an item (product) as a variable in SciQlop
61 * @param dataSourceUid the unique id of the data source containing the item. It is used to get
61 * @param dataSourceUid the unique id of the data source containing the item. It is used to get
62 * the data provider associated to the data source, and pass it to for the variable creation
62 * the data provider associated to the data source, and pass it to for the variable creation
63 * @param productItem the item to load
63 * @param productItem the item to load
64 */
64 */
65 void loadProductItem(const QUuid &dataSourceUid, const DataSourceItem &productItem) noexcept;
65 void loadProductItem(const QUuid &dataSourceUid, const DataSourceItem &productItem) noexcept;
66
66
67 /// Returns the MIME data associated to a list of product meta data
67 /// Returns the MIME data associated to a list of product meta data
68 static QByteArray mimeDataForProductsData(const QVariantList &productsData);
68 static QByteArray mimeDataForProductsData(const QVariantList &productsData);
69
69
70 /// Returns the list of meta data contained in a MIME data
70 /// Returns the list of meta data contained in a MIME data
71 static QVariantList productsDataForMimeData(const QByteArray &mimeData);
71 static QVariantList productsDataForMimeData(const QByteArray &mimeData);
72
72
73 public slots:
73 public slots:
74 /// Manage init/end of the controller
74 /// Manage init/end of the controller
75 void initialize();
75 void initialize();
76 void finalize();
76 void finalize();
77
77
78 /// Request the creation of a variable from the ID_DATA_KEY of a product
78 /// Request the creation of a variable from the ID_DATA_KEY of a product
79 void requestVariableFromProductIdKey(const QString &datasourceIdKey);
79 void requestVariableFromProductIdKey(const QString &datasourceIdKey);
80
80
81 /// Request the creation of a variable from metadata of a product
81 /// Request the creation of a variable from metadata of a product
82 void requestVariable(const QVariantHash &productData);
82 void requestVariable(const QVariantHash &productData);
83
83
84 signals:
84 signals:
85 /// Signal emitted when a structure has been set for a data source
85 /// Signal emitted when a structure has been set for a data source
86 void dataSourceItemSet(DataSourceItem *dataSourceItem);
86 void dataSourceItemSet(DataSourceItem *dataSourceItem);
87
87
88 /**
88 /**
89 * Signal emitted when a variable creation is asked for a product
89 * Signal emitted when a variable creation is asked for a product
90 * @param variableName the name of the variable
90 * @param variableName the name of the variable
91 * @param variableMetadata the metadata of the variable
91 * @param variableMetadata the metadata of the variable
92 * @param variableProvider the provider that will be used to retrieve the data of the variable
92 * @param variableProvider the provider that will be used to retrieve the data of the variable
93 * (can be null)
93 * (can be null)
94 */
94 */
95 void variableCreationRequested(const QString &variableName,
95 void createVariable(const QString &variableName,
96 const QVariantHash &variableMetadata,
96 const QVariantHash &variableMetadata,
97 std::shared_ptr<IDataProvider> variableProvider);
97 std::shared_ptr<IDataProvider> variableProvider);
98
98
99 private:
99 private:
100 void waitForFinish();
100 void waitForFinish();
101
101
102 class DataSourceControllerPrivate;
102 class DataSourceControllerPrivate;
103 spimpl::unique_impl_ptr<DataSourceControllerPrivate> impl;
103 spimpl::unique_impl_ptr<DataSourceControllerPrivate> impl;
104 };
104 };
105
105
106 #endif // SCIQLOP_DATASOURCECONTROLLER_H
106 #endif // SCIQLOP_DATASOURCECONTROLLER_H
@@ -1,110 +1,135
1 #ifndef SCIQLOP_VARIABLE_H
1 #ifndef SCIQLOP_VARIABLE_H
2 #define SCIQLOP_VARIABLE_H
2 #define SCIQLOP_VARIABLE_H
3
3
4 #include <optional>
4 #include <optional>
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QObject>
7 #include <QObject>
8 #include <QUuid>
8 #include <QUuid>
9 #include <QReadWriteLock>
9 #include <QReadWriteLock>
10 #include <QDataStream>
10
11
11 #include "CoreGlobal.h"
12 #include "CoreGlobal.h"
12 #include <Data/DataSeriesIterator.h>
13 #include <Data/DataSeriesIterator.h>
13 #include <Data/DataSeriesType.h>
14 #include <Data/DataSeriesType.h>
14 #include <Data/DateTimeRange.h>
15 #include <Data/DateTimeRange.h>
15
16
16
17
17 #include <Common/deprecate.h>
18 #include <Common/deprecate.h>
18 #include <Common/MetaTypes.h>
19 #include <Common/MetaTypes.h>
19 #include <Common/spimpl.h>
20 #include <Common/spimpl.h>
20
21
21 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
22 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
22
23
23 class IDataSeries;
24 class IDataSeries;
24 class QString;
25 class QString;
25
26
26 /**
27 /**
27 * @brief The Variable class represents a variable in SciQlop.
28 * @brief The Variable class represents a variable in SciQlop.
28 */
29 */
29 class SCIQLOP_CORE_EXPORT Variable : public QObject {
30 class SCIQLOP_CORE_EXPORT Variable : public QObject {
30
31
31 Q_OBJECT
32 Q_OBJECT
32
33
33 public:
34 public:
34 explicit Variable(const QString &name, const QVariantHash &metadata = {});
35 explicit Variable(const QString &name, const QVariantHash &metadata = {});
35
36
36 /// Copy ctor
37 /// Copy ctor
37 explicit Variable(const Variable &other);
38 explicit Variable(const Variable &other);
38
39
39 std::shared_ptr<Variable> clone() const;
40 std::shared_ptr<Variable> clone() const;
40
41
41 QString name() const noexcept;
42 QString name() const noexcept;
42 void setName(const QString &name) noexcept;
43 void setName(const QString &name) noexcept;
43 DateTimeRange range() const noexcept;
44 DateTimeRange range() const noexcept;
44 void setRange(const DateTimeRange &range, bool notify=false) noexcept;
45 void setRange(const DateTimeRange &range, bool notify=false) noexcept;
45 DateTimeRange cacheRange() const noexcept;
46 DateTimeRange cacheRange() const noexcept;
46 void setCacheRange(const DateTimeRange &cacheRange) noexcept;
47 void setCacheRange(const DateTimeRange &cacheRange) noexcept;
47
48
48 /// @return the number of points hold by the variable. The number of points is updated each time
49 /// @return the number of points hold by the variable. The number of points is updated each time
49 /// the data series changes
50 /// the data series changes
50 unsigned int nbPoints() const noexcept;
51 unsigned int nbPoints() const noexcept;
51
52
52 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
53 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
53 /// series between the range of the variable. The real range is updated each time the variable
54 /// series between the range of the variable. The real range is updated each time the variable
54 /// range or the data series changed
55 /// range or the data series changed
55 /// @return the real range, invalid range if the data series is null or empty
56 /// @return the real range, invalid range if the data series is null or empty
56 /// @sa setDataSeries()
57 /// @sa setDataSeries()
57 /// @sa setRange()
58 /// @sa setRange()
58 std::optional<DateTimeRange> realRange() const noexcept;
59 std::optional<DateTimeRange> realRange() const noexcept;
59
60
60 /// @return the data of the variable, nullptr if there is no data
61 /// @return the data of the variable, nullptr if there is no data
61 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
62 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
62
63
63 /// @return the type of data that the variable holds
64 /// @return the type of data that the variable holds
64 DataSeriesType type() const noexcept;
65 DataSeriesType type() const noexcept;
65
66
66 QVariantHash metadata() const noexcept;
67 QVariantHash metadata() const noexcept;
67
68
68 void updateData(const std::vector<IDataSeries*>& dataSeries,
69 void updateData(const std::vector<IDataSeries*>& dataSeries,
69 const DateTimeRange& newRange, const DateTimeRange& newCacheRange,
70 const DateTimeRange& newRange, const DateTimeRange& newCacheRange,
70 bool notify=true);
71 bool notify=true);
71
72
73 static QByteArray mimeData(const std::vector<std::shared_ptr<Variable> > &variables)
74 {
75 auto encodedData = QByteArray{};
76 QDataStream stream{&encodedData, QIODevice::WriteOnly};
77 for (auto &var : variables) {
78 stream << var->ID().toByteArray();
79 }
80 return encodedData;
81 }
82
83 static std::vector<QUuid> variablesIDs(QByteArray mimeData)
84 {
85 std::vector<QUuid> variables;
86 QDataStream stream{mimeData};
87
88 QVariantList ids;
89 stream >> ids;
90
91 for (const auto& id : ids) {
92 variables.emplace_back (id.toByteArray());
93 }
94 return variables;
95 }
96
72 DEPRECATE(
97 DEPRECATE(
73
98
74 bool contains(const DateTimeRange &range) const noexcept;
99 bool contains(const DateTimeRange &range) const noexcept;
75 bool intersect(const DateTimeRange &range) const noexcept;
100 bool intersect(const DateTimeRange &range) const noexcept;
76 bool isInside(const DateTimeRange &range) const noexcept;
101 bool isInside(const DateTimeRange &range) const noexcept;
77
102
78 bool cacheContains(const DateTimeRange &range) const noexcept;
103 bool cacheContains(const DateTimeRange &range) const noexcept;
79 bool cacheIntersect(const DateTimeRange &range) const noexcept;
104 bool cacheIntersect(const DateTimeRange &range) const noexcept;
80 bool cacheIsInside(const DateTimeRange &range) const noexcept;
105 bool cacheIsInside(const DateTimeRange &range) const noexcept;
81 QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &range) const noexcept;
106 QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &range) const noexcept;
82 QVector<DateTimeRange> provideInCacheRangeList(const DateTimeRange &range) const noexcept;
107 QVector<DateTimeRange> provideInCacheRangeList(const DateTimeRange &range) const noexcept;
83 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
108 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
84 static QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &oldRange,
109 static QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &oldRange,
85 const DateTimeRange &nextRange);
110 const DateTimeRange &nextRange);
86
111
87 static QVector<DateTimeRange> provideInCacheRangeList(const DateTimeRange &oldRange,
112 static QVector<DateTimeRange> provideInCacheRangeList(const DateTimeRange &oldRange,
88 const DateTimeRange &nextRange);
113 const DateTimeRange &nextRange);
89 )
114 )
90
115
91 operator QUuid() {return _uuid;}
116 operator QUuid() {return _uuid;}
92 QUuid ID(){return _uuid;}
117 QUuid ID(){return _uuid;}
93 signals:
118 signals:
94 void updated();
119 void updated();
95 DEPRECATE(
120 DEPRECATE(
96 /// Signal emitted when when the data series of the variable is loaded for the first time
121 /// Signal emitted when when the data series of the variable is loaded for the first time
97 void dataInitialized();
122 void dataInitialized();
98 )
123 )
99 private:
124 private:
100 class VariablePrivate;
125 class VariablePrivate;
101 spimpl::unique_impl_ptr<VariablePrivate> impl;
126 spimpl::unique_impl_ptr<VariablePrivate> impl;
102 QUuid _uuid;
127 QUuid _uuid;
103 QReadWriteLock m_lock;
128 QReadWriteLock m_lock;
104 };
129 };
105
130
106 // Required for using shared_ptr in signals/slots
131 // Required for using shared_ptr in signals/slots
107 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
132 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
108 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
133 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
109
134
110 #endif // SCIQLOP_VARIABLE_H
135 #endif // SCIQLOP_VARIABLE_H
@@ -1,54 +1,52
1 #ifndef VARIABLECONTROLLER2_H
1 #ifndef VARIABLECONTROLLER2_H
2 #define VARIABLECONTROLLER2_H
2 #define VARIABLECONTROLLER2_H
3 #include <memory>
3 #include <memory>
4 #include <vector>
4 #include <vector>
5 #include <set>
5 #include <set>
6 #include <QHash>
6 #include <QHash>
7 #include <QObject>
7 #include <QObject>
8 #include <QMutexLocker>
8 #include <QMutexLocker>
9 #include <QUuid>
9 #include <QUuid>
10 #include <QByteArray>
10 #include <QByteArray>
11 #include <QItemSelectionModel>
11 #include <QItemSelectionModel>
12 #include <Common/spimpl.h>
12 #include <Common/spimpl.h>
13 #include <Variable/Variable.h>
13 #include <Variable/Variable.h>
14 #include <Data/IDataProvider.h>
14 #include <Data/IDataProvider.h>
15 #include "Data/DateTimeRange.h"
15 #include "Data/DateTimeRange.h"
16
16
17 class VariableController2: public QObject
17 class VariableController2: public QObject
18 {
18 {
19 class VariableController2Private;
19 class VariableController2Private;
20 Q_OBJECT
20 Q_OBJECT
21
21
22 spimpl::unique_impl_ptr<VariableController2Private> impl;
22 spimpl::unique_impl_ptr<VariableController2Private> impl;
23
23
24 public:
24 public:
25 explicit VariableController2();
25 explicit VariableController2();
26 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
26 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
27 const std::shared_ptr<IDataProvider>& provider,
27 const std::shared_ptr<IDataProvider>& provider,
28 const DateTimeRange &range);
28 const DateTimeRange &range);
29
29
30 std::shared_ptr<Variable> cloneVariable(const std::shared_ptr<Variable>& variable);
30 std::shared_ptr<Variable> cloneVariable(const std::shared_ptr<Variable>& variable);
31 void deleteVariable(const std::shared_ptr<Variable>& variable);
31 void deleteVariable(const std::shared_ptr<Variable>& variable);
32 void changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
32 void changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
33 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
33 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
34 const std::vector<std::shared_ptr<Variable>> variables();
34 const std::vector<std::shared_ptr<Variable>> variables();
35
35
36 bool isReady(const std::shared_ptr<Variable>& variable);
36 bool isReady(const std::shared_ptr<Variable>& variable);
37
37
38 void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with);
38 void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with);
39
39
40 //This should be somewhere else VC has nothing to do with MIMEData
40 const std::vector<std::shared_ptr<Variable>> variables(const std::vector<QUuid>& ids);
41 QByteArray mimeData(const std::vector<std::shared_ptr<Variable>> &variables) const;
42 const std::vector<std::shared_ptr<Variable>> variables(QByteArray mimeData);
43
41
44 const std::shared_ptr<Variable>& operator[] (int index) const;
42 const std::shared_ptr<Variable>& operator[] (int index) const;
45 std::shared_ptr<Variable> operator[] (int index);
43 std::shared_ptr<Variable> operator[] (int index);
46
44
47
45
48 signals:
46 signals:
49 void variableAdded(const std::shared_ptr<Variable>&);
47 void variableAdded(const std::shared_ptr<Variable>&);
50 void variableDeleted(const std::shared_ptr<Variable>&);
48 void variableDeleted(const std::shared_ptr<Variable>&);
51
49
52 };
50 };
53
51
54 #endif //VARIABLECONTROLLER2_H
52 #endif //VARIABLECONTROLLER2_H
@@ -1,63 +1,66
1 #ifndef SCIQLOP_VARIABLEMODEL2_H
1 #ifndef SCIQLOP_VARIABLEMODEL2_H
2 #define SCIQLOP_VARIABLEMODEL2_H
2 #define SCIQLOP_VARIABLEMODEL2_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/DateTimeRange.h>
6 #include <Data/DateTimeRange.h>
7
7
8 #include <QAbstractTableModel>
8 #include <QAbstractTableModel>
9 #include <QLoggingCategory>
9 #include <QLoggingCategory>
10
10
11 #include <Common/MetaTypes.h>
11 #include <Common/MetaTypes.h>
12 #include <Common/spimpl.h>
12 #include <Common/spimpl.h>
13
13
14
14
15
15
16 class IDataSeries;
16 class IDataSeries;
17 class Variable;
17 class Variable;
18 class VariableController2;
18 class VariableController2;
19
19
20 enum VariableRoles { ProgressRole = Qt::UserRole };
20 enum VariableRoles { ProgressRole = Qt::UserRole };
21
21
22 /**
22 /**
23 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
23 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
24 */
24 */
25 class SCIQLOP_CORE_EXPORT VariableModel2 : public QAbstractTableModel {
25 class SCIQLOP_CORE_EXPORT VariableModel2 : public QAbstractTableModel {
26 Q_OBJECT
26 Q_OBJECT
27 std::shared_ptr<VariableController2> _variableController;
27 // read only mirror of VariableController2 content
28 std::vector<std::shared_ptr<Variable>> _variables;
28 public:
29 public:
29 explicit VariableModel2(const std::shared_ptr<VariableController2>& variableController, QObject *parent = nullptr);
30 explicit VariableModel2(QObject *parent = nullptr);
30
31
31 // /////////////////////////// //
32 // /////////////////////////// //
32 // QAbstractTableModel methods //
33 // QAbstractTableModel methods //
33 // /////////////////////////// //
34 // /////////////////////////// //
34
35
35 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
36 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
36 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
37 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
37 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
38 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
38 virtual QVariant headerData(int section, Qt::Orientation orientation,
39 virtual QVariant headerData(int section, Qt::Orientation orientation,
39 int role = Qt::DisplayRole) const override;
40 int role = Qt::DisplayRole) const override;
40 virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
41 virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
41
42
42 // ///////////////// //
43 // ///////////////// //
43 // Drag&Drop methods //
44 // Drag&Drop methods //
44 // ///////////////// //
45 // ///////////////// //
45
46
46 virtual Qt::DropActions supportedDropActions() const override;
47 virtual Qt::DropActions supportedDropActions() const override;
47 virtual Qt::DropActions supportedDragActions() const override;
48 virtual Qt::DropActions supportedDragActions() const override;
48 virtual QStringList mimeTypes() const override;
49 virtual QStringList mimeTypes() const override;
49 virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
50 virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
50 virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
51 virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
51 const QModelIndex &parent) const override;
52 const QModelIndex &parent) const override;
52 virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
53 virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
53 const QModelIndex &parent) override;
54 const QModelIndex &parent) override;
54
55
55
56 signals:
56 signals:
57
57 void createVariable(const QVariantHash &productData);
58 private slots:
58 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
59 public slots:
59 /// Slot called when data of a variable has been updated
60 /// Slot called when data of a variable has been updated
60 void variableUpdated() noexcept;
61 void variableUpdated() noexcept;
62 void variableAdded(const std::shared_ptr<Variable>&);
63 void variableDeleted(const std::shared_ptr<Variable>&);
61 };
64 };
62
65
63 #endif // SCIQLOP_VARIABLEMODEL2_H
66 #endif // SCIQLOP_VARIABLEMODEL2_H
@@ -1,197 +1,197
1 #include "DataSource/DataSourceController.h"
1 #include "DataSource/DataSourceController.h"
2 #include "DataSource/DataSourceItem.h"
2 #include "DataSource/DataSourceItem.h"
3
3
4 #include <Data/IDataProvider.h>
4 #include <Data/IDataProvider.h>
5
5
6 #include <QMutex>
6 #include <QMutex>
7 #include <QThread>
7 #include <QThread>
8
8
9 #include <QDataStream>
9 #include <QDataStream>
10 #include <QDir>
10 #include <QDir>
11 #include <QStandardPaths>
11 #include <QStandardPaths>
12
12
13 Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController")
13 Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController")
14
14
15 class DataSourceController::DataSourceControllerPrivate {
15 class DataSourceController::DataSourceControllerPrivate {
16 public:
16 public:
17 QMutex m_WorkingMutex;
17 QMutex m_WorkingMutex;
18 /// Data sources registered
18 /// Data sources registered
19 QHash<QUuid, QString> m_DataSources;
19 QHash<QUuid, QString> m_DataSources;
20 /// Data sources structures
20 /// Data sources structures
21 std::map<QUuid, std::unique_ptr<DataSourceItem> > m_DataSourceItems;
21 std::map<QUuid, std::unique_ptr<DataSourceItem> > m_DataSourceItems;
22 /// Data providers registered
22 /// Data providers registered
23 /// @remarks Data providers are stored as shared_ptr as they can be sent to a variable and
23 /// @remarks Data providers are stored as shared_ptr as they can be sent to a variable and
24 /// continue to live without necessarily the data source controller
24 /// continue to live without necessarily the data source controller
25 std::map<QUuid, std::shared_ptr<IDataProvider> > m_DataProviders;
25 std::map<QUuid, std::shared_ptr<IDataProvider> > m_DataProviders;
26
26
27 // Search for the first datasource item matching the specified data
27 // Search for the first datasource item matching the specified data
28 DataSourceItem *findDataSourceItem(const QVariantHash &data)
28 DataSourceItem *findDataSourceItem(const QVariantHash &data)
29 {
29 {
30 DataSourceItem *sourceItem = nullptr;
30 DataSourceItem *sourceItem = nullptr;
31 for (const auto &item : m_DataSourceItems) {
31 for (const auto &item : m_DataSourceItems) {
32 sourceItem = item.second->findItem(data, true);
32 sourceItem = item.second->findItem(data, true);
33 if (sourceItem) {
33 if (sourceItem) {
34 break;
34 break;
35 }
35 }
36 }
36 }
37
37
38 return sourceItem;
38 return sourceItem;
39 }
39 }
40
40
41 // Search for the first datasource item matching the specified ID_DATA_KEY
41 // Search for the first datasource item matching the specified ID_DATA_KEY
42 DataSourceItem *findDataSourceItem(const QString &datasourceIdKey)
42 DataSourceItem *findDataSourceItem(const QString &datasourceIdKey)
43 {
43 {
44 DataSourceItem *sourceItem = nullptr;
44 DataSourceItem *sourceItem = nullptr;
45 for (const auto &item : m_DataSourceItems) {
45 for (const auto &item : m_DataSourceItems) {
46 sourceItem = item.second->findItem(datasourceIdKey, true);
46 sourceItem = item.second->findItem(datasourceIdKey, true);
47 if (sourceItem) {
47 if (sourceItem) {
48 break;
48 break;
49 }
49 }
50 }
50 }
51
51
52 return sourceItem;
52 return sourceItem;
53 }
53 }
54 };
54 };
55
55
56 DataSourceController::DataSourceController(QObject *parent)
56 DataSourceController::DataSourceController(QObject *parent)
57 : impl{spimpl::make_unique_impl<DataSourceControllerPrivate>()}
57 : impl{spimpl::make_unique_impl<DataSourceControllerPrivate>()}
58 {
58 {
59 qCDebug(LOG_DataSourceController()) << tr("DataSourceController construction")
59 qCDebug(LOG_DataSourceController()) << tr("DataSourceController construction")
60 << QThread::currentThread();
60 << QThread::currentThread();
61 }
61 }
62
62
63 DataSourceController::~DataSourceController()
63 DataSourceController::~DataSourceController()
64 {
64 {
65 qCDebug(LOG_DataSourceController()) << tr("DataSourceController destruction")
65 qCDebug(LOG_DataSourceController()) << tr("DataSourceController destruction")
66 << QThread::currentThread();
66 << QThread::currentThread();
67 this->waitForFinish();
67 this->waitForFinish();
68 }
68 }
69
69
70 QUuid DataSourceController::registerDataSource(const QString &dataSourceName) noexcept
70 QUuid DataSourceController::registerDataSource(const QString &dataSourceName) noexcept
71 {
71 {
72 auto dataSourceUid = QUuid::createUuid();
72 auto dataSourceUid = QUuid::createUuid();
73 impl->m_DataSources.insert(dataSourceUid, dataSourceName);
73 impl->m_DataSources.insert(dataSourceUid, dataSourceName);
74
74
75 return dataSourceUid;
75 return dataSourceUid;
76 }
76 }
77
77
78 void DataSourceController::setDataSourceItem(
78 void DataSourceController::setDataSourceItem(
79 const QUuid &dataSourceUid, std::unique_ptr<DataSourceItem> dataSourceItem) noexcept
79 const QUuid &dataSourceUid, std::unique_ptr<DataSourceItem> dataSourceItem) noexcept
80 {
80 {
81 if (!dataSourceItem) {
81 if (!dataSourceItem) {
82 qCWarning(LOG_DataSourceController())
82 qCWarning(LOG_DataSourceController())
83 << tr("Data source item can't be registered (null item)");
83 << tr("Data source item can't be registered (null item)");
84 return;
84 return;
85 }
85 }
86
86
87 if (impl->m_DataSources.contains(dataSourceUid)) {
87 if (impl->m_DataSources.contains(dataSourceUid)) {
88 // The data provider is implicitly converted to a shared_ptr
88 // The data provider is implicitly converted to a shared_ptr
89 impl->m_DataSourceItems.insert(std::make_pair(dataSourceUid, std::move(dataSourceItem)));
89 impl->m_DataSourceItems.insert(std::make_pair(dataSourceUid, std::move(dataSourceItem)));
90
90
91 // Retrieves the data source item to emit the signal with it
91 // Retrieves the data source item to emit the signal with it
92 auto it = impl->m_DataSourceItems.find(dataSourceUid);
92 auto it = impl->m_DataSourceItems.find(dataSourceUid);
93 if (it != impl->m_DataSourceItems.end()) {
93 if (it != impl->m_DataSourceItems.end()) {
94 emit dataSourceItemSet(it->second.get());
94 emit dataSourceItemSet(it->second.get());
95 }
95 }
96 }
96 }
97 else {
97 else {
98 qCWarning(LOG_DataSourceController()) << tr("Can't set data source item for uid %1 : no "
98 qCWarning(LOG_DataSourceController()) << tr("Can't set data source item for uid %1 : no "
99 "data source has been registered with the uid")
99 "data source has been registered with the uid")
100 .arg(dataSourceUid.toString());
100 .arg(dataSourceUid.toString());
101 }
101 }
102 }
102 }
103
103
104 void DataSourceController::setDataProvider(const QUuid &dataSourceUid,
104 void DataSourceController::setDataProvider(const QUuid &dataSourceUid,
105 std::unique_ptr<IDataProvider> dataProvider) noexcept
105 std::unique_ptr<IDataProvider> dataProvider) noexcept
106 {
106 {
107 if (impl->m_DataSources.contains(dataSourceUid)) {
107 if (impl->m_DataSources.contains(dataSourceUid)) {
108 impl->m_DataProviders.insert(std::make_pair(dataSourceUid, std::move(dataProvider)));
108 impl->m_DataProviders.insert(std::make_pair(dataSourceUid, std::move(dataProvider)));
109 }
109 }
110 else {
110 else {
111 qCWarning(LOG_DataSourceController()) << tr("Can't set data provider for uid %1 : no data "
111 qCWarning(LOG_DataSourceController()) << tr("Can't set data provider for uid %1 : no data "
112 "source has been registered with the uid")
112 "source has been registered with the uid")
113 .arg(dataSourceUid.toString());
113 .arg(dataSourceUid.toString());
114 }
114 }
115 }
115 }
116
116
117 void DataSourceController::loadProductItem(const QUuid &dataSourceUid,
117 void DataSourceController::loadProductItem(const QUuid &dataSourceUid,
118 const DataSourceItem &productItem) noexcept
118 const DataSourceItem &productItem) noexcept
119 {
119 {
120 if (productItem.type() == DataSourceItemType::PRODUCT
120 if (productItem.type() == DataSourceItemType::PRODUCT
121 || productItem.type() == DataSourceItemType::COMPONENT) {
121 || productItem.type() == DataSourceItemType::COMPONENT) {
122 /// Retrieves the data provider of the data source (if any)
122 /// Retrieves the data provider of the data source (if any)
123 auto it = impl->m_DataProviders.find(dataSourceUid);
123 auto it = impl->m_DataProviders.find(dataSourceUid);
124 auto dataProvider = (it != impl->m_DataProviders.end()) ? it->second : nullptr;
124 auto dataProvider = (it != impl->m_DataProviders.end()) ? it->second : nullptr;
125
125
126 emit variableCreationRequested(productItem.name(), productItem.data(), dataProvider);
126 emit createVariable(productItem.name(), productItem.data(), dataProvider);
127 }
127 }
128 else {
128 else {
129 qCWarning(LOG_DataSourceController()) << tr("Can't load an item that is not a product");
129 qCWarning(LOG_DataSourceController()) << tr("Can't load an item that is not a product");
130 }
130 }
131 }
131 }
132
132
133 QByteArray DataSourceController::mimeDataForProductsData(const QVariantList &productsData)
133 QByteArray DataSourceController::mimeDataForProductsData(const QVariantList &productsData)
134 {
134 {
135 QByteArray encodedData;
135 QByteArray encodedData;
136 QDataStream stream{&encodedData, QIODevice::WriteOnly};
136 QDataStream stream{&encodedData, QIODevice::WriteOnly};
137
137
138 stream << productsData;
138 stream << productsData;
139
139
140 return encodedData;
140 return encodedData;
141 }
141 }
142
142
143 QVariantList DataSourceController::productsDataForMimeData(const QByteArray &mimeData)
143 QVariantList DataSourceController::productsDataForMimeData(const QByteArray &mimeData)
144 {
144 {
145 QDataStream stream{mimeData};
145 QDataStream stream{mimeData};
146
146
147 QVariantList productList;
147 QVariantList productList;
148 stream >> productList;
148 stream >> productList;
149
149
150 return productList;
150 return productList;
151 }
151 }
152
152
153 void DataSourceController::initialize()
153 void DataSourceController::initialize()
154 {
154 {
155 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init")
155 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init")
156 << QThread::currentThread();
156 << QThread::currentThread();
157 impl->m_WorkingMutex.lock();
157 impl->m_WorkingMutex.lock();
158 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init END");
158 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init END");
159 }
159 }
160
160
161 void DataSourceController::finalize()
161 void DataSourceController::finalize()
162 {
162 {
163 impl->m_WorkingMutex.unlock();
163 impl->m_WorkingMutex.unlock();
164 }
164 }
165
165
166 void DataSourceController::requestVariableFromProductIdKey(const QString &datasourceIdKey)
166 void DataSourceController::requestVariableFromProductIdKey(const QString &datasourceIdKey)
167 {
167 {
168 auto sourceItem = impl->findDataSourceItem(datasourceIdKey);
168 auto sourceItem = impl->findDataSourceItem(datasourceIdKey);
169
169
170 if (sourceItem) {
170 if (sourceItem) {
171 auto sourceName = sourceItem->rootItem().name();
171 auto sourceName = sourceItem->rootItem().name();
172 auto sourceId = impl->m_DataSources.key(sourceName);
172 auto sourceId = impl->m_DataSources.key(sourceName);
173 loadProductItem(sourceId, *sourceItem);
173 loadProductItem(sourceId, *sourceItem);
174 }
174 }
175 else {
175 else {
176 qCWarning(LOG_DataSourceController()) << tr("requestVariable, product data not found");
176 qCWarning(LOG_DataSourceController()) << tr("requestVariable, product data not found");
177 }
177 }
178 }
178 }
179
179
180 void DataSourceController::requestVariable(const QVariantHash &productData)
180 void DataSourceController::requestVariable(const QVariantHash &productData)
181 {
181 {
182 auto sourceItem = impl->findDataSourceItem(productData);
182 auto sourceItem = impl->findDataSourceItem(productData);
183
183
184 if (sourceItem) {
184 if (sourceItem) {
185 auto sourceName = sourceItem->rootItem().name();
185 auto sourceName = sourceItem->rootItem().name();
186 auto sourceId = impl->m_DataSources.key(sourceName);
186 auto sourceId = impl->m_DataSources.key(sourceName);
187 loadProductItem(sourceId, *sourceItem);
187 loadProductItem(sourceId, *sourceItem);
188 }
188 }
189 else {
189 else {
190 qCWarning(LOG_DataSourceController()) << tr("requestVariable, product data not found");
190 qCWarning(LOG_DataSourceController()) << tr("requestVariable, product data not found");
191 }
191 }
192 }
192 }
193
193
194 void DataSourceController::waitForFinish()
194 void DataSourceController::waitForFinish()
195 {
195 {
196 QMutexLocker locker{&impl->m_WorkingMutex};
196 QMutexLocker locker{&impl->m_WorkingMutex};
197 }
197 }
@@ -1,403 +1,392
1 #include <QQueue>
1 #include <QQueue>
2 #include <QThreadPool>
2 #include <QThreadPool>
3 #include <QRunnable>
3 #include <QRunnable>
4 #include <QObject>
4 #include <QObject>
5 #include <QDataStream>
5 #include <QDataStream>
6
6
7 #include "Variable/VariableController2.h"
7 #include "Variable/VariableController2.h"
8 #include "Variable/VariableSynchronizationGroup2.h"
8 #include "Variable/VariableSynchronizationGroup2.h"
9 #include <Common/containers.h>
9 #include <Common/containers.h>
10 #include <Common/debug.h>
10 #include <Common/debug.h>
11 #include <Data/DataProviderParameters.h>
11 #include <Data/DataProviderParameters.h>
12 #include <Data/DateTimeRangeHelper.h>
12 #include <Data/DateTimeRangeHelper.h>
13 #include <Data/DateTimeRange.h>
13 #include <Data/DateTimeRange.h>
14 #include <Variable/VariableCacheStrategyFactory.h>
14 #include <Variable/VariableCacheStrategyFactory.h>
15 #include <Variable/private/VCTransaction.h>
15 #include <Variable/private/VCTransaction.h>
16 #include <QCoreApplication>
16 #include <QCoreApplication>
17
17
18
18
19
19
20 class VariableController2::VariableController2Private
20 class VariableController2::VariableController2Private
21 {
21 {
22 struct threadSafeVaraiblesMaps
22 struct threadSafeVaraiblesMaps
23 {
23 {
24 inline void addVariable(const std::shared_ptr<Variable>& variable, const std::shared_ptr<IDataProvider>& provider, const std::shared_ptr<VariableSynchronizationGroup2>& synchronizationGroup)
24 inline void addVariable(const std::shared_ptr<Variable>& variable, const std::shared_ptr<IDataProvider>& provider, const std::shared_ptr<VariableSynchronizationGroup2>& synchronizationGroup)
25 {
25 {
26 QWriteLocker lock{&_lock};
26 QWriteLocker lock{&_lock};
27 _variables[*variable] = variable;
27 _variables[*variable] = variable;
28 _providers[*variable] = provider;
28 _providers[*variable] = provider;
29 _synchronizationGroups[*variable] = synchronizationGroup;
29 _synchronizationGroups[*variable] = synchronizationGroup;
30 }
30 }
31
31
32 inline void removeVariable(const std::shared_ptr<Variable>& variable)
32 inline void removeVariable(const std::shared_ptr<Variable>& variable)
33 {
33 {
34 QWriteLocker lock{&_lock};
34 QWriteLocker lock{&_lock};
35 _variables.remove(*variable);
35 _variables.erase(*variable);
36 _providers.remove(*variable);
36 _providers.remove(*variable);
37 _synchronizationGroups.remove(*variable);
37 _synchronizationGroups.remove(*variable);
38 }
38 }
39
39
40 inline void synchronize(const std::shared_ptr<Variable>& variable, const std::optional<std::shared_ptr<Variable>>& with)
40 inline void synchronize(const std::shared_ptr<Variable>& variable, const std::optional<std::shared_ptr<Variable>>& with)
41 {
41 {
42 QWriteLocker lock{&_lock};
42 QWriteLocker lock{&_lock};
43 if(with.has_value())
43 if(with.has_value())
44 {
44 {
45 auto newGroup = _synchronizationGroups[*with.value()];
45 auto newGroup = _synchronizationGroups[*with.value()];
46 newGroup->addVariable(*variable);
46 newGroup->addVariable(*variable);
47 _synchronizationGroups[*variable] = newGroup;
47 _synchronizationGroups[*variable] = newGroup;
48 }
48 }
49 else
49 else
50 {
50 {
51 _synchronizationGroups[*variable] = std::make_shared<VariableSynchronizationGroup2>(*variable);
51 _synchronizationGroups[*variable] = std::make_shared<VariableSynchronizationGroup2>(*variable);
52 }
52 }
53 }
53 }
54
54
55 inline std::shared_ptr<Variable> variable(QUuid variable)
55 inline std::shared_ptr<Variable> variable(QUuid variable)
56 {
56 {
57 QReadLocker lock{&_lock};
57 QReadLocker lock{&_lock};
58 auto it = _variables.find(variable);
58 [[unlikely]]
59 [[unlikely]]
59 if(!_variables.contains(variable))
60 if(it==_variables.end())
60 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
61 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
61 return _variables[variable];
62 return (*it).second;
62 }
63 }
63
64
64 inline std::shared_ptr<Variable> variable(int index)
65 inline std::shared_ptr<Variable> variable(int index)
65 {
66 {
66 QReadLocker lock{&_lock};
67 QReadLocker lock{&_lock};
67 [[unlikely]]
68 [[unlikely]]
68 if(!_variables.size() > index)
69 if(!_variables.size() > index)
69 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Index is out of bounds");
70 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Index is out of bounds");
70 return _variables.values()[index];
71 auto it = _variables.cbegin();
72 while (index!=0) {
73 index-=1;
74 it++;
75 }
76 return (*it).second;
71 }
77 }
72
78
73 inline const std::vector<std::shared_ptr<Variable>> variables()
79 inline const std::vector<std::shared_ptr<Variable>> variables()
74 {
80 {
75 std::vector<std::shared_ptr<Variable>> vars;
81 std::vector<std::shared_ptr<Variable>> vars;
76 QReadLocker lock{&_lock};
82 QReadLocker lock{&_lock};
77 for(const auto &var:_variables)
83 for(const auto&[id, var]:_variables)
78 {
84 {
79 vars.push_back(var);
85 vars.push_back(var);
80 }
86 }
81 return vars;
87 return vars;
82 }
88 }
83
89
84 inline std::shared_ptr<IDataProvider> provider(QUuid variable)
90 inline std::shared_ptr<IDataProvider> provider(QUuid variable)
85 {
91 {
86 QReadLocker lock{&_lock};
92 QReadLocker lock{&_lock};
87 [[unlikely]]
93 [[unlikely]]
88 if(!_providers.contains(variable))
94 if(!_providers.contains(variable))
89 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
95 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
90 return _providers[variable];
96 return _providers[variable];
91 }
97 }
92
98
93 inline std::shared_ptr<VariableSynchronizationGroup2> group(QUuid variable)
99 inline std::shared_ptr<VariableSynchronizationGroup2> group(QUuid variable)
94 {
100 {
95 QReadLocker lock{&_lock};
101 QReadLocker lock{&_lock};
96 [[unlikely]]
102 [[unlikely]]
97 if(!_synchronizationGroups.contains(variable))
103 if(!_synchronizationGroups.contains(variable))
98 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
104 SCIQLOP_ERROR(threadSafeVaraiblesMaps,"Unknown Variable");
99 return _synchronizationGroups[variable];
105 return _synchronizationGroups[variable];
100 }
106 }
101
107
102 inline bool has(const std::shared_ptr<Variable>& variable)
108 inline bool has(const std::shared_ptr<Variable>& variable)
103 {
109 {
104 QReadLocker lock{&_lock};
110 QReadLocker lock{&_lock};
105 return _variables.contains(*variable);
111 return _variables.find(*variable)==_variables.end();
106 }
112 }
107
113
108 private:
114 private:
109 QMap<QUuid,std::shared_ptr<Variable>> _variables;
115 std::map<QUuid,std::shared_ptr<Variable>> _variables;
110 QMap<QUuid,std::shared_ptr<IDataProvider>> _providers;
116 QMap<QUuid,std::shared_ptr<IDataProvider>> _providers;
111 QMap<QUuid,std::shared_ptr<VariableSynchronizationGroup2>> _synchronizationGroups;
117 QMap<QUuid,std::shared_ptr<VariableSynchronizationGroup2>> _synchronizationGroups;
112 QReadWriteLock _lock{QReadWriteLock::Recursive};
118 QReadWriteLock _lock{QReadWriteLock::Recursive};
113 }_maps;
119 }_maps;
114 QThreadPool _ThreadPool;
120 QThreadPool _ThreadPool;
115 VCTransactionsQueues _transactions;
121 VCTransactionsQueues _transactions;
116 std::unique_ptr<VariableCacheStrategy> _cacheStrategy;
122 std::unique_ptr<VariableCacheStrategy> _cacheStrategy;
117
123
118 void _transactionComplete(QUuid group, std::shared_ptr<VCTransaction> transaction)
124 void _transactionComplete(QUuid group, std::shared_ptr<VCTransaction> transaction)
119 {
125 {
120 if(transaction->done())
126 if(transaction->done())
121 {
127 {
122 _transactions.complete(group);
128 _transactions.complete(group);
123 }
129 }
124 this->_processTransactions();
130 this->_processTransactions();
125 }
131 }
126 void _processTransactions()
132 void _processTransactions()
127 {
133 {
128 auto nextTransactions = _transactions.nextTransactions();
134 auto nextTransactions = _transactions.nextTransactions();
129 auto pendingTransactions = _transactions.pendingTransactions();
135 auto pendingTransactions = _transactions.pendingTransactions();
130 for( auto [groupID, newTransaction] : nextTransactions)
136 for( auto [groupID, newTransaction] : nextTransactions)
131 {
137 {
132 if(newTransaction.has_value() && !pendingTransactions[groupID].has_value())
138 if(newTransaction.has_value() && !pendingTransactions[groupID].has_value())
133 {
139 {
134 _transactions.start(groupID);
140 _transactions.start(groupID);
135 auto refVar = _maps.variable(newTransaction.value()->refVar);
141 auto refVar = _maps.variable(newTransaction.value()->refVar);
136 auto ranges = _computeAllRangesInGroup(refVar,newTransaction.value()->range);
142 auto ranges = _computeAllRangesInGroup(refVar,newTransaction.value()->range);
137 for( auto const& [ID, range] : ranges)
143 for( auto const& [ID, range] : ranges)
138 {
144 {
139 auto provider = _maps.provider(ID);
145 auto provider = _maps.provider(ID);
140 auto variable = _maps.variable(ID);
146 auto variable = _maps.variable(ID);
141 auto [missingRanges, newCacheRange] = _computeMissingRanges(variable,range);
147 auto [missingRanges, newCacheRange] = _computeMissingRanges(variable,range);
142 auto exe = new TransactionExe(variable, provider, missingRanges, range, newCacheRange);
148 auto exe = new TransactionExe(variable, provider, missingRanges, range, newCacheRange);
143 QObject::connect(exe,
149 QObject::connect(exe,
144 &TransactionExe::transactionComplete,
150 &TransactionExe::transactionComplete,
145 [groupID=groupID,transaction=newTransaction.value(),this]()
151 [groupID=groupID,transaction=newTransaction.value(),this]()
146 {
152 {
147 this->_transactionComplete(groupID, transaction);
153 this->_transactionComplete(groupID, transaction);
148 }
154 }
149 );
155 );
150 _ThreadPool.start(exe);
156 _ThreadPool.start(exe);
151 }
157 }
152 }
158 }
153 }
159 }
154 }
160 }
155
161
156 std::map<QUuid,DateTimeRange> _computeAllRangesInGroup(const std::shared_ptr<Variable>& refVar, DateTimeRange r)
162 std::map<QUuid,DateTimeRange> _computeAllRangesInGroup(const std::shared_ptr<Variable>& refVar, DateTimeRange r)
157 {
163 {
158 std::map<QUuid,DateTimeRange> ranges;
164 std::map<QUuid,DateTimeRange> ranges;
159 if(!DateTimeRangeHelper::hasnan(r))
165 if(!DateTimeRangeHelper::hasnan(r))
160 {
166 {
161 auto group = _maps.group(*refVar);
167 auto group = _maps.group(*refVar);
162 if(auto transformation = DateTimeRangeHelper::computeTransformation(refVar->range(),r);
168 if(auto transformation = DateTimeRangeHelper::computeTransformation(refVar->range(),r);
163 transformation.has_value())
169 transformation.has_value())
164 {
170 {
165 for(auto varId:group->variables())
171 for(auto varId:group->variables())
166 {
172 {
167 auto var = _maps.variable(varId);
173 auto var = _maps.variable(varId);
168 auto newRange = var->range().transform(transformation.value());
174 auto newRange = var->range().transform(transformation.value());
169 ranges[varId] = newRange;
175 ranges[varId] = newRange;
170 }
176 }
171 }
177 }
172 else // force new range to all variables -> may be weird if more than one var in the group
178 else // force new range to all variables -> may be weird if more than one var in the group
173 // @TODO ensure that there is no side effects
179 // @TODO ensure that there is no side effects
174 {
180 {
175 for(auto varId:group->variables())
181 for(auto varId:group->variables())
176 {
182 {
177 auto var = _maps.variable(varId);
183 auto var = _maps.variable(varId);
178 ranges[varId] = r;
184 ranges[varId] = r;
179 }
185 }
180 }
186 }
181 }
187 }
182 else
188 else
183 {
189 {
184 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
190 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
185 }
191 }
186 return ranges;
192 return ranges;
187 }
193 }
188
194
189 std::pair<std::vector<DateTimeRange>,DateTimeRange> _computeMissingRanges(const std::shared_ptr<Variable>& var, DateTimeRange r)
195 std::pair<std::vector<DateTimeRange>,DateTimeRange> _computeMissingRanges(const std::shared_ptr<Variable>& var, DateTimeRange r)
190 {
196 {
191 DateTimeRange newCacheRange;
197 DateTimeRange newCacheRange;
192 std::vector<DateTimeRange> missingRanges;
198 std::vector<DateTimeRange> missingRanges;
193 if(DateTimeRangeHelper::hasnan(var->cacheRange()))
199 if(DateTimeRangeHelper::hasnan(var->cacheRange()))
194 {
200 {
195 newCacheRange = _cacheStrategy->computeRange(r,r);
201 newCacheRange = _cacheStrategy->computeRange(r,r);
196 missingRanges = {newCacheRange};
202 missingRanges = {newCacheRange};
197 }
203 }
198 else
204 else
199 {
205 {
200 newCacheRange = _cacheStrategy->computeRange(var->cacheRange(),r);
206 newCacheRange = _cacheStrategy->computeRange(var->cacheRange(),r);
201 missingRanges = newCacheRange - var->cacheRange();
207 missingRanges = newCacheRange - var->cacheRange();
202 }
208 }
203 return {missingRanges,newCacheRange};
209 return {missingRanges,newCacheRange};
204 }
210 }
205
211
206 void _changeRange(QUuid id, DateTimeRange r)
212 void _changeRange(QUuid id, DateTimeRange r)
207 {
213 {
208 _changeRange(_maps.variable(id) ,r);
214 _changeRange(_maps.variable(id) ,r);
209 }
215 }
210 void _changeRange(const std::shared_ptr<Variable>& var, DateTimeRange r)
216 void _changeRange(const std::shared_ptr<Variable>& var, DateTimeRange r)
211 {
217 {
212 auto provider = _maps.provider(*var);
218 auto provider = _maps.provider(*var);
213 auto [missingRanges, newCacheRange] = _computeMissingRanges(var,r);
219 auto [missingRanges, newCacheRange] = _computeMissingRanges(var,r);
214 std::vector<IDataSeries*> data;
220 std::vector<IDataSeries*> data;
215 for(auto range:missingRanges)
221 for(auto range:missingRanges)
216 {
222 {
217 data.push_back(provider->getData(DataProviderParameters{{range}, var->metadata()}));
223 data.push_back(provider->getData(DataProviderParameters{{range}, var->metadata()}));
218 }
224 }
219 var->updateData(data, r, newCacheRange, true);
225 var->updateData(data, r, newCacheRange, true);
220 }
226 }
221 public:
227 public:
222 VariableController2Private(QObject* parent=Q_NULLPTR)
228 VariableController2Private(QObject* parent=Q_NULLPTR)
223 :_cacheStrategy(VariableCacheStrategyFactory::createCacheStrategy(CacheStrategy::SingleThreshold))
229 :_cacheStrategy(VariableCacheStrategyFactory::createCacheStrategy(CacheStrategy::SingleThreshold))
224 {
230 {
225 Q_UNUSED(parent);
231 Q_UNUSED(parent);
226 this->_ThreadPool.setMaxThreadCount(32);
232 this->_ThreadPool.setMaxThreadCount(32);
227 }
233 }
228
234
229 /*
235 /*
230 * This dtor has to like this even if this is ugly, because default dtor would rely on
236 * This dtor has to like this even if this is ugly, because default dtor would rely on
231 * declaration order to destruct members and that would always lead to regressions when
237 * declaration order to destruct members and that would always lead to regressions when
232 * modifying class members
238 * modifying class members
233 */
239 */
234 ~VariableController2Private()
240 ~VariableController2Private()
235 {
241 {
236 while (this->_ThreadPool.activeThreadCount())
242 while (this->_ThreadPool.activeThreadCount())
237 {
243 {
238 this->_ThreadPool.waitForDone(100);
244 this->_ThreadPool.waitForDone(100);
239 }
245 }
240 }
246 }
241
247
242 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata, std::shared_ptr<IDataProvider> provider)
248 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata, std::shared_ptr<IDataProvider> provider)
243 {
249 {
244 auto newVar = std::make_shared<Variable>(name,metadata);
250 auto newVar = std::make_shared<Variable>(name,metadata);
245 auto group = std::make_shared<VariableSynchronizationGroup2>(newVar->ID());
251 auto group = std::make_shared<VariableSynchronizationGroup2>(newVar->ID());
246 _maps.addVariable(newVar,std::move(provider),group);
252 _maps.addVariable(newVar,std::move(provider),group);
247 this->_transactions.addEntry(*group);
253 this->_transactions.addEntry(*group);
248 return newVar;
254 return newVar;
249 }
255 }
250
256
251 std::shared_ptr<Variable> variable(QUuid ID)
257 std::shared_ptr<Variable> variable(QUuid ID)
252 {
258 {
253 return _maps.variable(ID);
259 return _maps.variable(ID);
254 }
260 }
255
261
256 std::shared_ptr<Variable> variable(int index)
262 std::shared_ptr<Variable> variable(int index)
257 {
263 {
258 return _maps.variable(index);
264 return _maps.variable(index);
259 }
265 }
260
266
261 std::shared_ptr<Variable> cloneVariable(const std::shared_ptr<Variable>& variable)
267 std::shared_ptr<Variable> cloneVariable(const std::shared_ptr<Variable>& variable)
262 {
268 {
263 auto newVar = variable->clone();
269 auto newVar = variable->clone();
264 _maps.synchronize(newVar,std::nullopt);
270 _maps.synchronize(newVar,std::nullopt);
265 _maps.addVariable(newVar,_maps.provider(*variable),_maps.group(*newVar));
271 _maps.addVariable(newVar,_maps.provider(*variable),_maps.group(*newVar));
266 this->_transactions.addEntry(*_maps.group(*newVar));
272 this->_transactions.addEntry(*_maps.group(*newVar));
267 return newVar;
273 return newVar;
268 }
274 }
269
275
270 bool hasPendingTransactions(const std::shared_ptr<Variable>& variable)
276 bool hasPendingTransactions(const std::shared_ptr<Variable>& variable)
271 {
277 {
272 return _transactions.active(*_maps.group(*variable));
278 return _transactions.active(*_maps.group(*variable));
273 }
279 }
274
280
275 void deleteVariable(const std::shared_ptr<Variable>& variable)
281 void deleteVariable(const std::shared_ptr<Variable>& variable)
276 {
282 {
277 _maps.removeVariable(variable);
283 _maps.removeVariable(variable);
278 }
284 }
279
285
280 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
286 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
281 {
287 {
282 if(!DateTimeRangeHelper::hasnan(r))
288 if(!DateTimeRangeHelper::hasnan(r))
283 {
289 {
284 auto group = _maps.group(*variable);
290 auto group = _maps.group(*variable);
285 // Just overwrite next transaction
291 // Just overwrite next transaction
286 {
292 {
287 _transactions.enqueue(*group,std::make_shared<VCTransaction>(variable->ID(), r, static_cast<int>(group->variables().size())));
293 _transactions.enqueue(*group,std::make_shared<VCTransaction>(variable->ID(), r, static_cast<int>(group->variables().size())));
288 }
294 }
289 _processTransactions();
295 _processTransactions();
290 }
296 }
291 else
297 else
292 {
298 {
293 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
299 SCIQLOP_ERROR(VariableController2Private, "Invalid range containing NaN");
294 }
300 }
295 }
301 }
296
302
297 void changeRange(const std::shared_ptr<Variable>& variable, DateTimeRange r)
303 void changeRange(const std::shared_ptr<Variable>& variable, DateTimeRange r)
298 {
304 {
299 asyncChangeRange(variable,r);
305 asyncChangeRange(variable,r);
300 while (hasPendingTransactions(variable))
306 while (hasPendingTransactions(variable))
301 {
307 {
302 QCoreApplication::processEvents();
308 QCoreApplication::processEvents();
303 }
309 }
304 }
310 }
305
311
306 inline void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with)
312 inline void synchronize(const std::shared_ptr<Variable>& var, const std::shared_ptr<Variable>& with)
307 {
313 {
308 _maps.synchronize(var, with);
314 _maps.synchronize(var, with);
309 }
315 }
310
316
311 inline const std::vector<std::shared_ptr<Variable>> variables()
317 inline const std::vector<std::shared_ptr<Variable>> variables()
312 {
318 {
313 return _maps.variables();
319 return _maps.variables();
314 }
320 }
315
321
316 };
322 };
317
323
318 VariableController2::VariableController2()
324 VariableController2::VariableController2()
319 :impl{spimpl::make_unique_impl<VariableController2Private>()}
325 :impl{spimpl::make_unique_impl<VariableController2Private>()}
320 {}
326 {}
321
327
322 std::shared_ptr<Variable> VariableController2::createVariable(const QString &name, const QVariantHash &metadata, const std::shared_ptr<IDataProvider>& provider, const DateTimeRange &range)
328 std::shared_ptr<Variable> VariableController2::createVariable(const QString &name, const QVariantHash &metadata, const std::shared_ptr<IDataProvider>& provider, const DateTimeRange &range)
323 {
329 {
324 auto var = impl->createVariable(name, metadata, provider);
330 auto var = impl->createVariable(name, metadata, provider);
325 emit variableAdded(var);
331 emit variableAdded(var);
326 if(!DateTimeRangeHelper::hasnan(range))
332 if(!DateTimeRangeHelper::hasnan(range))
327 impl->changeRange(var,range);
333 impl->changeRange(var,range);
328 else
334 else
329 SCIQLOP_ERROR(VariableController2, "Creating a variable with default constructed DateTimeRange is an error");
335 SCIQLOP_ERROR(VariableController2, "Creating a variable with default constructed DateTimeRange is an error");
330 return var;
336 return var;
331 }
337 }
332
338
333 std::shared_ptr<Variable> VariableController2::cloneVariable(const std::shared_ptr<Variable> &variable)
339 std::shared_ptr<Variable> VariableController2::cloneVariable(const std::shared_ptr<Variable> &variable)
334 {
340 {
335 return impl->cloneVariable(variable);
341 return impl->cloneVariable(variable);
336 }
342 }
337
343
338 void VariableController2::deleteVariable(const std::shared_ptr<Variable>& variable)
344 void VariableController2::deleteVariable(const std::shared_ptr<Variable>& variable)
339 {
345 {
340 impl->deleteVariable(variable);
346 impl->deleteVariable(variable);
341 emit variableDeleted(variable);
347 emit variableDeleted(variable);
342 }
348 }
343
349
344 void VariableController2::changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
350 void VariableController2::changeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r)
345 {
351 {
346 impl->changeRange(variable, r);
352 impl->changeRange(variable, r);
347 }
353 }
348
354
349 void VariableController2::asyncChangeRange(const std::shared_ptr<Variable> &variable, const DateTimeRange &r)
355 void VariableController2::asyncChangeRange(const std::shared_ptr<Variable> &variable, const DateTimeRange &r)
350 {
356 {
351 impl->asyncChangeRange(variable, r);
357 impl->asyncChangeRange(variable, r);
352 }
358 }
353
359
354 const std::vector<std::shared_ptr<Variable> > VariableController2::variables()
360 const std::vector<std::shared_ptr<Variable> > VariableController2::variables()
355 {
361 {
356 return impl->variables();
362 return impl->variables();
357 }
363 }
358
364
359 bool VariableController2::isReady(const std::shared_ptr<Variable> &variable)
365 bool VariableController2::isReady(const std::shared_ptr<Variable> &variable)
360 {
366 {
361 return impl->hasPendingTransactions(variable);
367 return impl->hasPendingTransactions(variable);
362 }
368 }
363
369
364 void VariableController2::synchronize(const std::shared_ptr<Variable> &var, const std::shared_ptr<Variable> &with)
370 void VariableController2::synchronize(const std::shared_ptr<Variable> &var, const std::shared_ptr<Variable> &with)
365 {
371 {
366 impl->synchronize(var, with);
372 impl->synchronize(var, with);
367 }
373 }
368
374
369 QByteArray VariableController2::mimeData(const std::vector<std::shared_ptr<Variable> > &variables) const
375 const std::vector<std::shared_ptr<Variable>> VariableController2::variables(const std::vector<QUuid> &ids)
370 {
371 auto encodedData = QByteArray{};
372 QDataStream stream{&encodedData, QIODevice::WriteOnly};
373 for (auto &var : variables) {
374 stream << var->ID().toByteArray();
375 }
376 return encodedData;
377 }
378
379 const std::vector<std::shared_ptr<Variable>> VariableController2::variables(QByteArray mimeData)
380 {
376 {
381 std::vector<std::shared_ptr<Variable>> variables;
377 std::vector<std::shared_ptr<Variable>> variables;
382 QDataStream stream{mimeData};
383
384 QVariantList ids;
385 stream >> ids;
386
387 for (const auto& id : ids) {
378 for (const auto& id : ids) {
388 auto uuid = QUuid{id.toByteArray()};
379 variables.push_back(impl->variable(id));
389 variables.push_back (impl->variable(uuid));
390 }
380 }
391
392 return variables;
381 return variables;
393 }
382 }
394
383
395 const std::shared_ptr<Variable> &VariableController2::operator[](int index) const
384 const std::shared_ptr<Variable> &VariableController2::operator[](int index) const
396 {
385 {
397 return impl->variable (index);
386 return impl->variable (index);
398 }
387 }
399
388
400 std::shared_ptr<Variable> VariableController2::operator[](int index)
389 std::shared_ptr<Variable> VariableController2::operator[](int index)
401 {
390 {
402 return impl->variable (index);
391 return impl->variable (index);
403 }
392 }
@@ -1,246 +1,270
1 #include <QMimeData>
2 #include <QSize>
3 #include <QTimer>
4 #include <unordered_map>
5
1 #include <Variable/Variable.h>
6 #include <Variable/Variable.h>
2 #include <Variable/VariableController2.h>
7 #include <Variable/VariableController2.h>
3 #include <Variable/VariableModel2.h>
8 #include <Variable/VariableModel2.h>
4
9
5 #include <Common/DateUtils.h>
10 #include <Common/DateUtils.h>
6 #include <Common/MimeTypesDef.h>
11 #include <Common/MimeTypesDef.h>
7 #include <Common/StringUtils.h>
12 #include <Common/StringUtils.h>
13 #include <Common/containers.h>
8
14
9 #include <Data/IDataSeries.h>
15 #include <Data/IDataSeries.h>
10
16
11 #include <DataSource/DataSourceController.h>
17 #include <DataSource/DataSourceController.h>
12 #include <Time/TimeController.h>
18 #include <Time/TimeController.h>
13
19
14 #include <QMimeData>
15 #include <QSize>
16 #include <QTimer>
17 #include <unordered_map>
18
19 namespace {
20 namespace {
20
21
21 // Column indexes
22 // Column indexes
22 const auto NAME_COLUMN = 0;
23 const auto NAME_COLUMN = 0;
23 const auto TSTART_COLUMN = 1;
24 const auto TSTART_COLUMN = 1;
24 const auto TEND_COLUMN = 2;
25 const auto TEND_COLUMN = 2;
25 const auto NBPOINTS_COLUMN = 3;
26 const auto NBPOINTS_COLUMN = 3;
26 const auto UNIT_COLUMN = 4;
27 const auto UNIT_COLUMN = 4;
27 const auto MISSION_COLUMN = 5;
28 const auto MISSION_COLUMN = 5;
28 const auto PLUGIN_COLUMN = 6;
29 const auto PLUGIN_COLUMN = 6;
29 const auto NB_COLUMNS = 7;
30 const auto NB_COLUMNS = 7;
30
31
31 // Column properties
32 // Column properties
32 const auto DEFAULT_HEIGHT = 25;
33 const auto DEFAULT_HEIGHT = 25;
33 const auto DEFAULT_WIDTH = 100;
34 const auto DEFAULT_WIDTH = 100;
34
35
35 struct ColumnProperties {
36 struct ColumnProperties {
36 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
37 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
37 int height = DEFAULT_HEIGHT)
38 int height = DEFAULT_HEIGHT)
38 : m_Name{name}, m_Width{width}, m_Height{height}
39 : m_Name{name}, m_Width{width}, m_Height{height}
39 {
40 {
40 }
41 }
41
42
42 QString m_Name;
43 QString m_Name;
43 int m_Width;
44 int m_Width;
44 int m_Height;
45 int m_Height;
45 };
46 };
46
47
47 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
48 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
48 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
49 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
49 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {NBPOINTS_COLUMN, {QObject::tr("Nb points")}},
50 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {NBPOINTS_COLUMN, {QObject::tr("Nb points")}},
50 {UNIT_COLUMN, {QObject::tr("Unit")}}, {MISSION_COLUMN, {QObject::tr("Mission")}},
51 {UNIT_COLUMN, {QObject::tr("Unit")}}, {MISSION_COLUMN, {QObject::tr("Mission")}},
51 {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
52 {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
52
53
53 QString uniqueName(const QString &defaultName,
54 QString uniqueName(const QString &defaultName,
54 const std::vector<std::shared_ptr<Variable> > &variables)
55 const std::vector<std::shared_ptr<Variable> > &variables)
55 {
56 {
56 auto forbiddenNames = std::vector<QString>(variables.size());
57 auto forbiddenNames = std::vector<QString>(variables.size());
57 std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
58 std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
58 [](const auto &variable) { return variable->name(); });
59 [](const auto &variable) { return variable->name(); });
59 auto uniqueName = StringUtils::uniqueName(defaultName, forbiddenNames);
60 auto uniqueName = StringUtils::uniqueName(defaultName, forbiddenNames);
60 Q_ASSERT(!uniqueName.isEmpty());
61 Q_ASSERT(!uniqueName.isEmpty());
61
62
62 return uniqueName;
63 return uniqueName;
63 }
64 }
64
65
65 } // namespace
66 } // namespace
66
67
67
68
68
69
69 VariableModel2::VariableModel2(const std::shared_ptr<VariableController2> &variableController, QObject *parent)
70 VariableModel2::VariableModel2(QObject *parent)
70 : QAbstractTableModel{parent}, _variableController{variableController}
71 : QAbstractTableModel{parent}
71 {
72 {
72 }
73 }
73
74
74
75
75 int VariableModel2::columnCount(const QModelIndex &parent) const
76 int VariableModel2::columnCount(const QModelIndex &parent) const
76 {
77 {
77 Q_UNUSED(parent);
78 Q_UNUSED(parent);
78
79
79 return NB_COLUMNS;
80 return NB_COLUMNS;
80 }
81 }
81
82
82 int VariableModel2::rowCount(const QModelIndex &parent) const
83 int VariableModel2::rowCount(const QModelIndex &parent) const
83 {
84 {
84 Q_UNUSED(parent);
85 Q_UNUSED(parent);
85 return static_cast<int>(_variableController->variables().size());
86 return _variables.size();
86 }
87 }
87
88
88 QVariant VariableModel2::data(const QModelIndex &index, int role) const
89 QVariant VariableModel2::data(const QModelIndex &index, int role) const
89 {
90 {
90 if (!index.isValid()) {
91 if (!index.isValid()) {
91 return QVariant{};
92 return QVariant{};
92 }
93 }
93
94
94 if (index.row() < 0 || index.row() >= rowCount()) {
95 if (index.row() < 0 || index.row() >= rowCount()) {
95 return QVariant{};
96 return QVariant{};
96 }
97 }
97
98
98 if (role == Qt::DisplayRole) {
99 if (role == Qt::DisplayRole) {
99 if (auto variable = _variableController->variables()[index.row()]) {
100 if (auto variable = _variables[index.row()]) {
100 switch (index.column()) {
101 switch (index.column()) {
101 case NAME_COLUMN:
102 case NAME_COLUMN:
102 return variable->name();
103 return variable->name();
103 case TSTART_COLUMN: {
104 case TSTART_COLUMN: {
104 if(auto range = variable->realRange(); range.has_value())
105 if(auto range = variable->realRange(); range.has_value())
105 return DateUtils::dateTime(range.value().m_TStart).toString(DATETIME_FORMAT);
106 return DateUtils::dateTime(range.value().m_TStart).toString(DATETIME_FORMAT);
106 return QVariant{};
107 return QVariant{};
107 }
108 }
108 case TEND_COLUMN: {
109 case TEND_COLUMN: {
109 if(auto range = variable->realRange(); range.has_value())
110 if(auto range = variable->realRange(); range.has_value())
110 return DateUtils::dateTime(range.value().m_TEnd).toString(DATETIME_FORMAT);
111 return DateUtils::dateTime(range.value().m_TEnd).toString(DATETIME_FORMAT);
111 return QVariant{};
112 return QVariant{};
112 }
113 }
113 case NBPOINTS_COLUMN:
114 case NBPOINTS_COLUMN:
114 return variable->nbPoints();
115 return variable->nbPoints();
115 case UNIT_COLUMN:
116 case UNIT_COLUMN:
116 return variable->metadata().value(QStringLiteral("units"));
117 return variable->metadata().value(QStringLiteral("units"));
117 case MISSION_COLUMN:
118 case MISSION_COLUMN:
118 return variable->metadata().value(QStringLiteral("mission"));
119 return variable->metadata().value(QStringLiteral("mission"));
119 case PLUGIN_COLUMN:
120 case PLUGIN_COLUMN:
120 return variable->metadata().value(QStringLiteral("plugin"));
121 return variable->metadata().value(QStringLiteral("plugin"));
121 default:
122 default:
122 // No action
123 // No action
123 break;
124 break;
124 }
125 }
125 }
126 }
126 }
127 }
127 else if (role == VariableRoles::ProgressRole) {
128 else if (role == VariableRoles::ProgressRole) {
128 return QVariant{};
129 return QVariant{};
129 }
130 }
130
131
131 return QVariant{};
132 return QVariant{};
132 }
133 }
133
134
134 QVariant VariableModel2::headerData(int section, Qt::Orientation orientation, int role) const
135 QVariant VariableModel2::headerData(int section, Qt::Orientation orientation, int role) const
135 {
136 {
136 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
137 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
137 return QVariant{};
138 return QVariant{};
138 }
139 }
139
140
140 if (orientation == Qt::Horizontal) {
141 if (orientation == Qt::Horizontal) {
141 auto propertiesIt = COLUMN_PROPERTIES.find(section);
142 auto propertiesIt = COLUMN_PROPERTIES.find(section);
142 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
143 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
143 // Role is either DisplayRole or SizeHintRole
144 // Role is either DisplayRole or SizeHintRole
144 return (role == Qt::DisplayRole)
145 return (role == Qt::DisplayRole)
145 ? QVariant{propertiesIt->m_Name}
146 ? QVariant{propertiesIt->m_Name}
146 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
147 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
147 }
148 }
148 }
149 }
149
150
150 return QVariant{};
151 return QVariant{};
151 }
152 }
152
153
153 Qt::ItemFlags VariableModel2::flags(const QModelIndex &index) const
154 Qt::ItemFlags VariableModel2::flags(const QModelIndex &index) const
154 {
155 {
155 return QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
156 return QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
156 }
157 }
157
158
158 Qt::DropActions VariableModel2::supportedDropActions() const
159 Qt::DropActions VariableModel2::supportedDropActions() const
159 {
160 {
160 return Qt::CopyAction | Qt::MoveAction;
161 return Qt::CopyAction | Qt::MoveAction;
161 }
162 }
162
163
163 Qt::DropActions VariableModel2::supportedDragActions() const
164 Qt::DropActions VariableModel2::supportedDragActions() const
164 {
165 {
165 return Qt::CopyAction | Qt::MoveAction;
166 return Qt::CopyAction | Qt::MoveAction;
166 }
167 }
167
168
168 QStringList VariableModel2::mimeTypes() const
169 QStringList VariableModel2::mimeTypes() const
169 {
170 {
170 return {MIME_TYPE_VARIABLE_LIST, MIME_TYPE_TIME_RANGE};
171 return {MIME_TYPE_VARIABLE_LIST, MIME_TYPE_TIME_RANGE};
171 }
172 }
172
173
173 QMimeData *VariableModel2::mimeData(const QModelIndexList &indexes) const
174 QMimeData *VariableModel2::mimeData(const QModelIndexList &indexes) const
174 {
175 {
175 auto mimeData = new QMimeData;
176 auto mimeData = new QMimeData;
176 std::vector<std::shared_ptr<Variable> > variables;
177 std::vector<std::shared_ptr<Variable> > variables;
177
178
178 DateTimeRange firstTimeRange;
179 DateTimeRange firstTimeRange;
179 for (const auto &index : indexes) {
180 for (const auto &index : indexes) {
180 if (index.column() == 0) { // only the first column
181 if (index.column() == 0) { // only the first column
181 auto variable = _variableController->variables()[index.row()];
182 auto variable = _variables[index.row()];
182 if (variable.get() && index.isValid()) {
183 if (variable.get() && index.isValid()) {
183
184
184 if (variables.size()==0) {
185 if (variables.size()==0) {
185 // Gets the range of the first variable
186 // Gets the range of the first variable
186 firstTimeRange = std::move(variable->range());
187 firstTimeRange = variable->range();
187 }
188 }
188 variables.push_back(variable);
189 variables.push_back(variable);
189 }
190 }
190 }
191 }
191 }
192 }
192
193
193 auto variablesEncodedData = _variableController->mimeData(variables);
194 auto variablesEncodedData = Variable::mimeData(variables);
194 mimeData->setData(MIME_TYPE_VARIABLE_LIST, variablesEncodedData);
195 mimeData->setData(MIME_TYPE_VARIABLE_LIST, variablesEncodedData);
195
196
196 if (variables.size() == 1) {
197 if (variables.size() == 1) {
197 // No time range MIME data if multiple variables are dragged
198 // No time range MIME data if multiple variables are dragged
198 auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
199 auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
199 mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
200 mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
200 }
201 }
201
202
202 return mimeData;
203 return mimeData;
203 }
204 }
204
205
205 bool VariableModel2::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row,
206 bool VariableModel2::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row,
206 int column, const QModelIndex &parent) const
207 int column, const QModelIndex &parent) const
207 {
208 {
209 Q_UNUSED(column);
208 // drop of a product
210 // drop of a product
209 return data->hasFormat(MIME_TYPE_PRODUCT_LIST)
211 return data->hasFormat(MIME_TYPE_PRODUCT_LIST)
210 || (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid()
212 || (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid()
211 && !data->hasFormat(MIME_TYPE_VARIABLE_LIST));
213 && !data->hasFormat(MIME_TYPE_VARIABLE_LIST));
212 }
214 }
213
215
214 bool VariableModel2::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
216 bool VariableModel2::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
215 const QModelIndex &parent)
217 const QModelIndex &parent)
216 {
218 {
217 auto dropDone = false;
219 auto dropDone = false;
218
220
219 if (data->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
221 if (data->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
220 auto productList
222 auto productList
221 = DataSourceController::productsDataForMimeData(data->data(MIME_TYPE_PRODUCT_LIST));
223 = DataSourceController::productsDataForMimeData(data->data(MIME_TYPE_PRODUCT_LIST));
222
224
223 for (auto metaData : productList) {
225 for (auto metaData : productList) {
224 //emit requestVariable(metaData.toHash());
226 emit createVariable(metaData.toHash());
225 //@TODO No idea what this does
226 }
227 }
227
228
228 dropDone = true;
229 dropDone = true;
229 }
230 }
230 else if (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid()) {
231 else if (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid()) {
231 auto variable = _variableController->variables()[parent.row()];
232 auto variable = _variables[parent.row()];
232 auto range = TimeController::timeRangeForMimeData(data->data(MIME_TYPE_TIME_RANGE));
233 auto range = TimeController::timeRangeForMimeData(data->data(MIME_TYPE_TIME_RANGE));
233
234
234 _variableController->asyncChangeRange(variable, range);
235 emit asyncChangeRange(variable, range);
235
236
236 dropDone = true;
237 dropDone = true;
237 }
238 }
238
239
239 return dropDone;
240 return dropDone;
240 }
241 }
241
242
242 void VariableModel2::variableUpdated() noexcept
243 void VariableModel2::variableUpdated() noexcept
243 {
244 {
245 emit dataChanged(QModelIndex(),QModelIndex());
246 }
244
247
248 void VariableModel2::variableAdded(const std::shared_ptr<Variable> & variable)
249 {
250 if(!SciQLop::containers::contains(_variables,variable))
251 {
252 beginInsertRows(QModelIndex(), this->_variables.size(), this->_variables.size());
253 this->_variables.push_back(variable);
254 endInsertRows();
255 connect(variable.get(),&Variable::updated,this,&VariableModel2::variableUpdated);
256 }
257 }
258
259 void VariableModel2::variableDeleted(const std::shared_ptr<Variable> &variable)
260 {
261 auto it = std::find(_variables.begin(), _variables.end(), variable);
262 if (it != _variables.end())
263 {
264 auto index = std::distance(_variables.begin(), it);
265 beginRemoveRows(QModelIndex(), index, index);
266 _variables.erase(it);
267 endRemoveRows();
268 }
245 }
269 }
246
270
General Comments 0
You need to be logged in to leave comments. Login now