##// END OF EJS Templates
Merge branch 'feature/DragDropProduct' into develop
trabillard -
r878:4f465f223e95 merge
parent child
Show More
@@ -0,0 +1,14
1 #ifndef SCIQLOP_DATASOURCETREEWIDGET_H
2 #define SCIQLOP_DATASOURCETREEWIDGET_H
3
4 #include <QTreeWidget>
5
6 class DataSourceTreeWidget : public QTreeWidget {
7 public:
8 DataSourceTreeWidget(QWidget *parent);
9
10 protected:
11 QMimeData *mimeData(const QList<QTreeWidgetItem *> items) const override;
12 };
13
14 #endif // SCIQLOP_DATASOURCETREEWIDGET_H
@@ -0,0 +1,37
1 #include "DataSource/DataSourceTreeWidget.h"
2 #include "Common/MimeTypesDef.h"
3 #include "DataSource/DataSourceController.h"
4 #include "DataSource/DataSourceItem.h"
5 #include "DataSource/DataSourceTreeWidgetItem.h"
6
7 #include "SqpApplication.h"
8
9 #include <QMimeData>
10
11 DataSourceTreeWidget::DataSourceTreeWidget(QWidget *parent) : QTreeWidget(parent) {}
12
13 QMimeData *DataSourceTreeWidget::mimeData(const QList<QTreeWidgetItem *> items) const
14 {
15 auto mimeData = new QMimeData;
16
17 // Basic check to ensure the item are correctly typed
18 Q_ASSERT(items.isEmpty() || dynamic_cast<DataSourceTreeWidgetItem *>(items.first()) != nullptr);
19
20 QVariantList productData;
21
22 for (auto item : items) {
23 auto dataSourceTreeItem = static_cast<DataSourceTreeWidgetItem *>(item);
24 auto dataSource = dataSourceTreeItem->data();
25
26 if (dataSource->type() == DataSourceItemType::COMPONENT
27 || dataSource->type() == DataSourceItemType::PRODUCT) {
28 auto metaData = dataSource->data();
29 productData << metaData;
30 }
31 }
32
33 auto encodedData = sqpApp->dataSourceController().mimeDataForProductsData(productData);
34 mimeData->setData(MIME_TYPE_PRODUCT_LIST, encodedData);
35
36 return mimeData;
37 }
@@ -12,6 +12,7
12 12 extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_GRAPH;
13 13 extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_ZONE;
14 14 extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_VARIABLE_LIST;
15 extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_PRODUCT_LIST;
15 16 extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_TIME_RANGE;
16 17
17 18
@@ -64,11 +64,16 public:
64 64 */
65 65 void loadProductItem(const QUuid &dataSourceUid, const DataSourceItem &productItem) noexcept;
66 66
67 QByteArray mimeDataForProductsData(const QVariantList &productsData) const;
68 QVariantList productsDataForMimeData(const QByteArray &mimeData) const;
69
67 70 public slots:
68 71 /// Manage init/end of the controller
69 72 void initialize();
70 73 void finalize();
71 74
75 void requestVariable(const QVariantHash &productData);
76
72 77 signals:
73 78 /// Signal emitted when a structure has been set for a data source
74 79 void dataSourceItemSet(DataSourceItem *dataSourceItem);
@@ -91,6 +91,14 public:
91 91
92 92 DataSourceItemType type() const noexcept;
93 93
94 /**
95 * @brief Searches the first child matching the specified data.
96 * @param data The data to search.
97 * @param recursive So the search recursively.
98 * @return the item matching the data or nullptr if it was not found.
99 */
100 DataSourceItem *findItem(const QVariantHash &data, bool recursive);
101
94 102 bool operator==(const DataSourceItem &other);
95 103 bool operator!=(const DataSourceItem &other);
96 104
@@ -93,6 +93,7 public:
93 93
94 94 signals:
95 95 void abortProgessRequested(std::shared_ptr<Variable> variable);
96 void requestVariable(const QVariantHash &productData);
96 97
97 98 private:
98 99 class VariableModelPrivate;
@@ -3,6 +3,7 core_moc_headers = [
3 3 'include/Data/IDataProvider.h',
4 4 'include/DataSource/DataSourceController.h',
5 5 'include/DataSource/DataSourceItemAction.h',
6 'include/DataSource/DataSourceWidget.h',
6 7 'include/Network/NetworkController.h',
7 8 'include/Time/TimeController.h',
8 9 'include/Variable/Variable.h',
@@ -31,6 +32,7 core_sources = [
31 32 'src/DataSource/DataSourceController.cpp',
32 33 'src/DataSource/DataSourceItem.cpp',
33 34 'src/DataSource/DataSourceItemAction.cpp',
35 'src/DataSource/DataSourceWidget.cpp',
34 36 'src/Network/NetworkController.cpp',
35 37 'src/Plugin/PluginManager.cpp',
36 38 'src/Settings/SqpSettingsDefs.cpp',
@@ -1,6 +1,7
1 1 #include "Common/MimeTypesDef.h"
2 2
3 const QString MIME_TYPE_GRAPH = QStringLiteral("scqlop/graph");
4 const QString MIME_TYPE_ZONE = QStringLiteral("scqlop/zone");
5 const QString MIME_TYPE_VARIABLE_LIST = QStringLiteral("scqlop/var-list");
6 const QString MIME_TYPE_TIME_RANGE = QStringLiteral("scqlop/time-range");
3 const QString MIME_TYPE_GRAPH = QStringLiteral("sciqlop/graph");
4 const QString MIME_TYPE_ZONE = QStringLiteral("sciqlop/zone");
5 const QString MIME_TYPE_VARIABLE_LIST = QStringLiteral("sciqlop/var-list");
6 const QString MIME_TYPE_PRODUCT_LIST = QStringLiteral("sciqlop/product-list");
7 const QString MIME_TYPE_TIME_RANGE = QStringLiteral("sciqlop/time-range");
@@ -6,6 +6,7
6 6 #include <QMutex>
7 7 #include <QThread>
8 8
9 #include <QDataStream>
9 10 #include <QDir>
10 11 #include <QStandardPaths>
11 12
@@ -44,6 +45,20 public:
44 45 /// @remarks Data providers are stored as shared_ptr as they can be sent to a variable and
45 46 /// continue to live without necessarily the data source controller
46 47 std::map<QUuid, std::shared_ptr<IDataProvider> > m_DataProviders;
48
49 // Search for the first datasource item matching the specified data
50 DataSourceItem *findDataSourceItem(const QVariantHash &data)
51 {
52 DataSourceItem *sourceItem = nullptr;
53 for (const auto &item : m_DataSourceItems) {
54 sourceItem = item.second->findItem(data, true);
55 if (sourceItem) {
56 break;
57 }
58 }
59
60 return sourceItem;
61 }
47 62 };
48 63
49 64 DataSourceController::DataSourceController(QObject *parent)
@@ -124,6 +139,26 void DataSourceController::loadProductItem(const QUuid &dataSourceUid,
124 139 }
125 140 }
126 141
142 QByteArray DataSourceController::mimeDataForProductsData(const QVariantList &productsData) const
143 {
144 QByteArray encodedData;
145 QDataStream stream{&encodedData, QIODevice::WriteOnly};
146
147 stream << productsData;
148
149 return encodedData;
150 }
151
152 QVariantList DataSourceController::productsDataForMimeData(const QByteArray &mimeData) const
153 {
154 QDataStream stream{mimeData};
155
156 QVariantList productList;
157 stream >> productList;
158
159 return productList;
160 }
161
127 162 void DataSourceController::initialize()
128 163 {
129 164 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init")
@@ -137,6 +172,20 void DataSourceController::finalize()
137 172 impl->m_WorkingMutex.unlock();
138 173 }
139 174
175 void DataSourceController::requestVariable(const QVariantHash &productData)
176 {
177 DataSourceItem *sourceItem = impl->findDataSourceItem(productData);
178
179 if (sourceItem) {
180 auto sourceName = sourceItem->rootItem().name();
181 auto sourceId = impl->m_DataSources.key(sourceName);
182 loadProductItem(sourceId, *sourceItem);
183 }
184 else {
185 qCWarning(LOG_DataSourceController()) << tr("requestVariable, product data not found");
186 }
187 }
188
140 189 void DataSourceController::waitForFinish()
141 190 {
142 191 QMutexLocker locker{&impl->m_WorkingMutex};
@@ -123,6 +123,24 DataSourceItemType DataSourceItem::type() const noexcept
123 123 return impl->m_Type;
124 124 }
125 125
126 DataSourceItem *DataSourceItem::findItem(const QVariantHash &data, bool recursive)
127 {
128 for (const auto &child : impl->m_Children) {
129 if (child->impl->m_Data == data) {
130 return child.get();
131 }
132
133 if (recursive) {
134 auto foundItem = child->findItem(data, true);
135 if (foundItem) {
136 return foundItem;
137 }
138 }
139 }
140
141 return nullptr;
142 }
143
126 144 bool DataSourceItem::operator==(const DataSourceItem &other)
127 145 {
128 146 // Compares items' attributes
@@ -310,7 +310,7 VariableController::variablesForMimeData(const QByteArray &mimeData) const
310 310 stream >> ids;
311 311
312 312 for (auto id : ids) {
313 auto uuid = QUuid(id.toByteArray());
313 auto uuid = QUuid{id.toByteArray()};
314 314 auto var = impl->findVariable(uuid);
315 315 variables << var;
316 316 }
@@ -8,6 +8,7
8 8
9 9 #include <Data/IDataSeries.h>
10 10
11 #include <QDataStream>
11 12 #include <QMimeData>
12 13 #include <QSize>
13 14 #include <unordered_map>
@@ -267,7 +268,7 Qt::ItemFlags VariableModel::flags(const QModelIndex &index) const
267 268
268 269 Qt::DropActions VariableModel::supportedDropActions() const
269 270 {
270 return Qt::MoveAction;
271 return Qt::CopyAction | Qt::MoveAction;
271 272 }
272 273
273 274 Qt::DropActions VariableModel::supportedDragActions() const
@@ -304,13 +305,29 QMimeData *VariableModel::mimeData(const QModelIndexList &indexes) const
304 305 bool VariableModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row,
305 306 int column, const QModelIndex &parent) const
306 307 {
307 return false;
308 // drop of a product
309 return data->hasFormat(MIME_TYPE_PRODUCT_LIST);
308 310 }
309 311
310 312 bool VariableModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
311 313 const QModelIndex &parent)
312 314 {
313 return false;
315 bool dropDone = false;
316
317 if (data->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
318 QDataStream stream(data->data(MIME_TYPE_PRODUCT_LIST));
319
320 QVariantList productList;
321 stream >> productList;
322
323 for (auto metaData : productList) {
324 emit requestVariable(metaData.toHash());
325 }
326
327 dropDone = true;
328 }
329
330 return dropDone;
314 331 }
315 332
316 333 void VariableModel::abortProgress(const QModelIndex &index)
@@ -129,6 +129,15 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(QTreeWidget *parent, const Da
129 129 auto itemActions = impl->m_Data->actions();
130 130 std::transform(std::cbegin(itemActions), std::cend(itemActions),
131 131 std::back_inserter(impl->m_Actions), createTreeAction);
132
133 // Sets the flags of the items
134 auto flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
135 if (data->type() == DataSourceItemType::COMPONENT
136 || data->type() == DataSourceItemType::PRODUCT) {
137 flags |= Qt::ItemIsDragEnabled;
138 }
139
140 setFlags(flags);
132 141 }
133 142
134 143 const DataSourceItem *DataSourceTreeWidgetItem::data() const
@@ -248,6 +248,12 QUrl DragDropHelper::imageTemporaryUrl(const QImage &image) const
248 248 bool DragDropHelper::checkMimeDataForVisualization(const QMimeData *mimeData,
249 249 VisualizationDragDropContainer *dropContainer)
250 250 {
251 if (!mimeData || !dropContainer) {
252 qCWarning(LOG_DragDropHelper()) << QObject::tr(
253 "DragDropHelper::checkMimeDataForVisualization, invalid input parameters.");
254 Q_ASSERT(false);
255 }
256
251 257 auto result = true;
252 258
253 259 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
@@ -8,6 +8,7
8 8 #include <Time/TimeController.h>
9 9 #include <Variable/Variable.h>
10 10 #include <Variable/VariableController.h>
11 #include <Variable/VariableModel.h>
11 12 #include <Visualization/VisualizationController.h>
12 13
13 14 Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication")
@@ -34,6 +35,9 public:
34 35 SLOT(createVariable(const QString &, const QVariantHash &,
35 36 std::shared_ptr<IDataProvider>)));
36 37
38 connect(m_VariableController->variableModel(), &VariableModel::requestVariable,
39 m_DataSourceController.get(), &DataSourceController::requestVariable);
40
37 41 // VariableController <-> VisualizationController
38 42 connect(m_VariableController.get(),
39 43 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)),
@@ -233,7 +233,7 QString VisualizationGraphWidget::name() const
233 233 QMimeData *VisualizationGraphWidget::mimeData() const
234 234 {
235 235 auto mimeData = new QMimeData;
236 mimeData->setData(MIME_TYPE_GRAPH, QByteArray());
236 mimeData->setData(MIME_TYPE_GRAPH, QByteArray{});
237 237
238 238 return mimeData;
239 239 }
@@ -287,8 +287,14 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables(
287 287 const QList<std::shared_ptr<Variable> > &variables, int index,
288 288 VisualizationTabWidget *tabWidget)
289 289 {
290 // Note: we are sure that there is a single and compatible variable here
291 // because the AcceptMimeDataFunction, set on the drop container, makes the check before the
292 // drop can occur.
290 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
291 // compatible variable here
292 if (variables.count() > 1) {
293 qCWarning(LOG_VisualizationZoneWidget())
294 << tr("VisualizationTabWidget::dropVariables, dropping multiple variables, operation "
295 "aborted.");
296 return;
297 }
298
293 299 tabWidget->createZone(variables, index);
294 300 }
@@ -327,7 +327,7 QString VisualizationZoneWidget::name() const
327 327 QMimeData *VisualizationZoneWidget::mimeData() const
328 328 {
329 329 auto mimeData = new QMimeData;
330 mimeData->setData(MIME_TYPE_ZONE, QByteArray());
330 mimeData->setData(MIME_TYPE_ZONE, QByteArray{});
331 331
332 332 return mimeData;
333 333 }
@@ -455,30 +455,14 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropVariables(
455 455 const QList<std::shared_ptr<Variable> > &variables, int index,
456 456 VisualizationZoneWidget *zoneWidget)
457 457 {
458 // Search for the top level VisualizationWidget
459 auto parent = zoneWidget->parentWidget();
460 while (parent && qobject_cast<VisualizationWidget *>(parent) == nullptr) {
461 parent = parent->parentWidget();
462 }
463
464 if (!parent) {
458 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
459 // compatible variable here
460 if (variables.count() > 1) {
465 461 qCWarning(LOG_VisualizationZoneWidget())
466 << tr("VisualizationZoneWidget::dropVariables, drop aborted, the parent "
467 "VisualizationWidget cannot be found.");
468 Q_ASSERT(false);
462 << tr("VisualizationZoneWidget::dropVariables, dropping multiple variables, operation "
463 "aborted.");
469 464 return;
470 465 }
471 466
472 auto visualizationWidget = static_cast<VisualizationWidget *>(parent);
473
474 // Search for the first variable which can be dropped
475 for (auto variable : variables) {
476 FindVariableOperation findVariableOperation{variable};
477 visualizationWidget->accept(&findVariableOperation);
478 auto variableContainers = findVariableOperation.result();
479 if (variableContainers.empty()) {
480 zoneWidget->createGraph(variable, index);
481 break;
482 }
483 }
467 zoneWidget->createGraph(variables, index);
484 468 }
@@ -18,7 +18,16
18 18 <widget class="QLineEdit" name="filterLineEdit"/>
19 19 </item>
20 20 <item row="1" column="0">
21 <widget class="QTreeWidget" name="treeWidget">
21 <widget class="DataSourceTreeWidget" name="treeWidget">
22 <property name="dragEnabled">
23 <bool>true</bool>
24 </property>
25 <property name="dragDropMode">
26 <enum>QAbstractItemView::DragOnly</enum>
27 </property>
28 <property name="selectionMode">
29 <enum>QAbstractItemView::ExtendedSelection</enum>
30 </property>
22 31 <column>
23 32 <property name="text">
24 33 <string notr="true">1</string>
@@ -28,6 +37,13
28 37 </item>
29 38 </layout>
30 39 </widget>
40 <customwidgets>
41 <customwidget>
42 <class>DataSourceTreeWidget</class>
43 <extends>QTreeWidget</extends>
44 <header>DataSource/DataSourceTreeWidget.h</header>
45 </customwidget>
46 </customwidgets>
31 47 <resources/>
32 48 <connections/>
33 49 </ui>
@@ -16,6 +16,9
16 16 <layout class="QGridLayout" name="gridLayout">
17 17 <item row="0" column="0">
18 18 <widget class="QTableView" name="tableView">
19 <property name="acceptDrops">
20 <bool>true</bool>
21 </property>
19 22 <property name="dragEnabled">
20 23 <bool>true</bool>
21 24 </property>
General Comments 1
Under Review
author

Auto status change to "Under Review"

You need to be logged in to leave comments. Login now