Auto status change to "Under Review"
@@ -0,0 +1,18 | |||
|
1 | #ifndef SCIQLOP_MIMETYPESDEF_H | |
|
2 | #define SCIQLOP_MIMETYPESDEF_H | |
|
3 | ||
|
4 | #include "CoreGlobal.h" | |
|
5 | ||
|
6 | #include <QString> | |
|
7 | ||
|
8 | // ////////////////// // | |
|
9 | // SciQlop Mime Types // | |
|
10 | // ////////////////// // | |
|
11 | ||
|
12 | extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_GRAPH; | |
|
13 | extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_ZONE; | |
|
14 | extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_VARIABLE_LIST; | |
|
15 | extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_TIME_RANGE; | |
|
16 | ||
|
17 | ||
|
18 | #endif // SCIQLOP_MIMETYPESDEF_H |
@@ -0,0 +1,6 | |||
|
1 | #include "Common/MimeTypesDef.h" | |
|
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"); |
@@ -0,0 +1,7 | |||
|
1 | #ifndef SCIQLOP_VISUALIZATIONDEF_H | |
|
2 | #define SCIQLOP_VISUALIZATIONDEF_H | |
|
3 | ||
|
4 | /// Minimum height for graph added in zones (in pixels) | |
|
5 | extern const int GRAPH_MINIMUM_HEIGHT; | |
|
6 | ||
|
7 | #endif // SCIQLOP_VISUALIZATIONDEF_H |
@@ -68,6 +68,8 public: | |||
|
68 | 68 | */ |
|
69 | 69 | void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept; |
|
70 | 70 | |
|
71 | QByteArray mimeDataForVariables(const QList<std::shared_ptr<Variable> > &variables) const; | |
|
72 | QList<std::shared_ptr<Variable> > variablesForMimeData(const QByteArray &mimeData) const; | |
|
71 | 73 | |
|
72 | 74 | static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange); |
|
73 | 75 | signals: |
@@ -18,6 +18,7 enum VariableRoles { ProgressRole = Qt::UserRole }; | |||
|
18 | 18 | |
|
19 | 19 | class IDataSeries; |
|
20 | 20 | class Variable; |
|
21 | class VariableController; | |
|
21 | 22 | |
|
22 | 23 | /** |
|
23 | 24 | * @brief The VariableModel class aims to hold the variables that have been created in SciQlop |
@@ -25,7 +26,7 class Variable; | |||
|
25 | 26 | class SCIQLOP_CORE_EXPORT VariableModel : public QAbstractTableModel { |
|
26 | 27 | Q_OBJECT |
|
27 | 28 | public: |
|
28 |
explicit VariableModel( |
|
|
29 | explicit VariableModel(VariableController *parent = nullptr); | |
|
29 | 30 | |
|
30 | 31 | /** |
|
31 | 32 | * Adds an existing variable in the model. |
@@ -73,7 +74,20 public: | |||
|
73 | 74 | virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; |
|
74 | 75 | virtual QVariant headerData(int section, Qt::Orientation orientation, |
|
75 | 76 | int role = Qt::DisplayRole) const override; |
|
76 | ||
|
77 | virtual Qt::ItemFlags flags(const QModelIndex &index) const override; | |
|
78 | ||
|
79 | // ///////////////// // | |
|
80 | // Drag&Drop methods // | |
|
81 | // ///////////////// // | |
|
82 | ||
|
83 | virtual Qt::DropActions supportedDropActions() const override; | |
|
84 | virtual Qt::DropActions supportedDragActions() const override; | |
|
85 | virtual QStringList mimeTypes() const override; | |
|
86 | virtual QMimeData *mimeData(const QModelIndexList &indexes) const override; | |
|
87 | virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, | |
|
88 | const QModelIndex &parent) const override; | |
|
89 | virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, | |
|
90 | const QModelIndex &parent) override; | |
|
77 | 91 | |
|
78 | 92 | void abortProgress(const QModelIndex &index); |
|
79 | 93 |
@@ -12,6 +12,7 | |||
|
12 | 12 | #include <Data/VariableRequest.h> |
|
13 | 13 | #include <Time/TimeController.h> |
|
14 | 14 | |
|
15 | #include <QDataStream> | |
|
15 | 16 | #include <QMutex> |
|
16 | 17 | #include <QThread> |
|
17 | 18 | #include <QUuid> |
@@ -277,6 +278,46 void VariableController::deleteVariables( | |||
|
277 | 278 | } |
|
278 | 279 | } |
|
279 | 280 | |
|
281 | QByteArray | |
|
282 | VariableController::mimeDataForVariables(const QList<std::shared_ptr<Variable> > &variables) const | |
|
283 | { | |
|
284 | auto encodedData = QByteArray{}; | |
|
285 | ||
|
286 | QVariantList ids; | |
|
287 | for (auto &var : variables) { | |
|
288 | auto itVar = impl->m_VariableToIdentifierMap.find(var); | |
|
289 | if (itVar == impl->m_VariableToIdentifierMap.cend()) { | |
|
290 | qCCritical(LOG_VariableController()) | |
|
291 | << tr("Impossible to find the data for an unknown variable."); | |
|
292 | } | |
|
293 | ||
|
294 | ids << itVar->second.toByteArray(); | |
|
295 | } | |
|
296 | ||
|
297 | QDataStream stream{&encodedData, QIODevice::WriteOnly}; | |
|
298 | stream << ids; | |
|
299 | ||
|
300 | return encodedData; | |
|
301 | } | |
|
302 | ||
|
303 | QList<std::shared_ptr<Variable> > | |
|
304 | VariableController::variablesForMimeData(const QByteArray &mimeData) const | |
|
305 | { | |
|
306 | auto variables = QList<std::shared_ptr<Variable> >{}; | |
|
307 | QDataStream stream{mimeData}; | |
|
308 | ||
|
309 | QVariantList ids; | |
|
310 | stream >> ids; | |
|
311 | ||
|
312 | for (auto id : ids) { | |
|
313 | auto uuid = QUuid(id.toByteArray()); | |
|
314 | auto var = impl->findVariable(uuid); | |
|
315 | variables << var; | |
|
316 | } | |
|
317 | ||
|
318 | return variables; | |
|
319 | } | |
|
320 | ||
|
280 | 321 | std::shared_ptr<Variable> |
|
281 | 322 | VariableController::createVariable(const QString &name, const QVariantHash &metadata, |
|
282 | 323 | std::shared_ptr<IDataProvider> provider) noexcept |
@@ -1,11 +1,14 | |||
|
1 | 1 | #include <Variable/Variable.h> |
|
2 | #include <Variable/VariableController.h> | |
|
2 | 3 | #include <Variable/VariableModel.h> |
|
3 | 4 | |
|
4 | 5 | #include <Common/DateUtils.h> |
|
6 | #include <Common/MimeTypesDef.h> | |
|
5 | 7 | #include <Common/StringUtils.h> |
|
6 | 8 | |
|
7 | 9 | #include <Data/IDataSeries.h> |
|
8 | 10 | |
|
11 | #include <QMimeData> | |
|
9 | 12 | #include <QSize> |
|
10 | 13 | #include <unordered_map> |
|
11 | 14 | |
@@ -66,14 +69,16 struct VariableModel::VariableModelPrivate { | |||
|
66 | 69 | /// Variables created in SciQlop |
|
67 | 70 | std::vector<std::shared_ptr<Variable> > m_Variables; |
|
68 | 71 | std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress; |
|
72 | VariableController *m_VariableController; | |
|
69 | 73 | |
|
70 | 74 | /// Return the row index of the variable. -1 if it's not found |
|
71 | 75 | int indexOfVariable(Variable *variable) const noexcept; |
|
72 | 76 | }; |
|
73 | 77 | |
|
74 |
VariableModel::VariableModel( |
|
|
78 | VariableModel::VariableModel(VariableController *parent) | |
|
75 | 79 | : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()} |
|
76 | 80 | { |
|
81 | impl->m_VariableController = parent; | |
|
77 | 82 | } |
|
78 | 83 | |
|
79 | 84 | void VariableModel::addVariable(std::shared_ptr<Variable> variable) noexcept |
@@ -255,6 +260,59 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int | |||
|
255 | 260 | return QVariant{}; |
|
256 | 261 | } |
|
257 | 262 | |
|
263 | Qt::ItemFlags VariableModel::flags(const QModelIndex &index) const | |
|
264 | { | |
|
265 | return QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; | |
|
266 | } | |
|
267 | ||
|
268 | Qt::DropActions VariableModel::supportedDropActions() const | |
|
269 | { | |
|
270 | return Qt::MoveAction; | |
|
271 | } | |
|
272 | ||
|
273 | Qt::DropActions VariableModel::supportedDragActions() const | |
|
274 | { | |
|
275 | return Qt::CopyAction | Qt::MoveAction; | |
|
276 | } | |
|
277 | ||
|
278 | QStringList VariableModel::mimeTypes() const | |
|
279 | { | |
|
280 | return {MIME_TYPE_VARIABLE_LIST}; | |
|
281 | } | |
|
282 | ||
|
283 | QMimeData *VariableModel::mimeData(const QModelIndexList &indexes) const | |
|
284 | { | |
|
285 | auto mimeData = new QMimeData; | |
|
286 | ||
|
287 | QList<std::shared_ptr<Variable> > variableList; | |
|
288 | ||
|
289 | for (const auto &index : indexes) { | |
|
290 | if (index.column() == 0) { // only the first column | |
|
291 | auto variable = impl->m_Variables.at(index.row()); | |
|
292 | if (variable.get() && index.isValid()) { | |
|
293 | variableList << variable; | |
|
294 | } | |
|
295 | } | |
|
296 | } | |
|
297 | ||
|
298 | auto encodedData = impl->m_VariableController->mimeDataForVariables(variableList); | |
|
299 | mimeData->setData(MIME_TYPE_VARIABLE_LIST, encodedData); | |
|
300 | ||
|
301 | return mimeData; | |
|
302 | } | |
|
303 | ||
|
304 | bool VariableModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, | |
|
305 | int column, const QModelIndex &parent) const | |
|
306 | { | |
|
307 | return false; | |
|
308 | } | |
|
309 | ||
|
310 | bool VariableModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, | |
|
311 | const QModelIndex &parent) | |
|
312 | { | |
|
313 | return false; | |
|
314 | } | |
|
315 | ||
|
258 | 316 | void VariableModel::abortProgress(const QModelIndex &index) |
|
259 | 317 | { |
|
260 | 318 | if (auto variable = impl->m_Variables.at(index.row())) { |
@@ -2,39 +2,23 | |||
|
2 | 2 | #define SCIQLOP_DRAGDROPHELPER_H |
|
3 | 3 | |
|
4 | 4 | #include <Common/spimpl.h> |
|
5 | #include <QLoggingCategory> | |
|
5 | 6 | #include <QWidget> |
|
6 | 7 | |
|
7 | 8 | class QVBoxLayout; |
|
8 | 9 | class QScrollArea; |
|
9 | 10 | class VisualizationDragWidget; |
|
11 | class VisualizationDragDropContainer; | |
|
10 | 12 | class QMimeData; |
|
11 | 13 | |
|
12 | /** | |
|
13 | * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation. | |
|
14 | * @note A QScrollArea inside an other QScrollArea is not fully supported. | |
|
15 | */ | |
|
16 | class DragDropScroller : public QObject { | |
|
17 | Q_OBJECT | |
|
18 | ||
|
19 | public: | |
|
20 | DragDropScroller(QObject *parent = nullptr); | |
|
21 | ||
|
22 | void addScrollArea(QScrollArea *scrollArea); | |
|
23 | void removeScrollArea(QScrollArea *scrollArea); | |
|
24 | ||
|
25 | protected: | |
|
26 | bool eventFilter(QObject *obj, QEvent *event); | |
|
27 | ||
|
28 | private: | |
|
29 | class DragDropScrollerPrivate; | |
|
30 | spimpl::unique_impl_ptr<DragDropScrollerPrivate> impl; | |
|
31 | ||
|
32 | private slots: | |
|
33 | void onTimer(); | |
|
34 | }; | |
|
14 | Q_DECLARE_LOGGING_CATEGORY(LOG_DragDropHelper) | |
|
35 | 15 | |
|
36 | 16 | /** |
|
37 | 17 | * @brief Helper class for drag&drop operations. |
|
18 | * @note The helper is accessible from the sqpApp singleton and has the same life as the whole | |
|
19 | * application (like a controller). But contrary to a controller, it doesn't live in a thread and | |
|
20 | * can interect with the gui. | |
|
21 | * @see SqpApplication | |
|
38 | 22 | */ |
|
39 | 23 | class DragDropHelper { |
|
40 | 24 | public: |
@@ -44,7 +28,15 public: | |||
|
44 | 28 | DragDropHelper(); |
|
45 | 29 | virtual ~DragDropHelper(); |
|
46 | 30 | |
|
31 | /// Resets some internal variables. Must be called before any new drag&drop operation. | |
|
32 | void resetDragAndDrop(); | |
|
33 | ||
|
34 | /// Sets the visualization widget currently being drag on the visualization. | |
|
47 | 35 | void setCurrentDragWidget(VisualizationDragWidget *dragWidget); |
|
36 | ||
|
37 | /// Returns the visualization widget currently being drag on the visualization. | |
|
38 | /// Can be null if a new visualization widget is intended to be created by the drag&drop | |
|
39 | /// operation. | |
|
48 | 40 | VisualizationDragWidget *getCurrentDragWidget() const; |
|
49 | 41 | |
|
50 | 42 | QWidget &placeHolder() const; |
@@ -52,6 +44,10 public: | |||
|
52 | 44 | void removePlaceHolder(); |
|
53 | 45 | bool isPlaceHolderSet() const; |
|
54 | 46 | |
|
47 | /// Checks if the specified mime data is valid for a drop in the visualization | |
|
48 | bool checkMimeDataForVisualization(const QMimeData *mimeData, | |
|
49 | VisualizationDragDropContainer *dropContainer); | |
|
50 | ||
|
55 | 51 | void addDragDropScrollArea(QScrollArea *scrollArea); |
|
56 | 52 | void removeDragDropScrollArea(QScrollArea *scrollArea); |
|
57 | 53 | |
@@ -62,4 +58,28 private: | |||
|
62 | 58 | spimpl::unique_impl_ptr<DragDropHelperPrivate> impl; |
|
63 | 59 | }; |
|
64 | 60 | |
|
61 | /** | |
|
62 | * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation. | |
|
63 | * @note A QScrollArea inside an other QScrollArea is not fully supported. | |
|
64 | */ | |
|
65 | class DragDropScroller : public QObject { | |
|
66 | Q_OBJECT | |
|
67 | ||
|
68 | public: | |
|
69 | DragDropScroller(QObject *parent = nullptr); | |
|
70 | ||
|
71 | void addScrollArea(QScrollArea *scrollArea); | |
|
72 | void removeScrollArea(QScrollArea *scrollArea); | |
|
73 | ||
|
74 | protected: | |
|
75 | bool eventFilter(QObject *obj, QEvent *event); | |
|
76 | ||
|
77 | private: | |
|
78 | class DragDropScrollerPrivate; | |
|
79 | spimpl::unique_impl_ptr<DragDropScrollerPrivate> impl; | |
|
80 | ||
|
81 | private slots: | |
|
82 | void onTimer(); | |
|
83 | }; | |
|
84 | ||
|
65 | 85 | #endif // SCIQLOP_DRAGDROPHELPER_H |
@@ -45,7 +45,8 public: | |||
|
45 | 45 | VariableController &variableController() noexcept; |
|
46 | 46 | VisualizationController &visualizationController() noexcept; |
|
47 | 47 | |
|
48 | /// Accessors for the differents sciqlop helpers | |
|
48 | /// Accessors for the differents sciqlop helpers, these helpers classes are like controllers but | |
|
49 | /// doesn't live in a thread and access gui | |
|
49 | 50 | DragDropHelper &dragDropHelper() noexcept; |
|
50 | 51 | |
|
51 | 52 | private: |
@@ -2,10 +2,15 | |||
|
2 | 2 | #define SCIQLOP_VISUALIZATIONDRAGDROPCONTAINER_H |
|
3 | 3 | |
|
4 | 4 | #include <Common/spimpl.h> |
|
5 | #include <QLoggingCategory> | |
|
5 | 6 | #include <QMimeData> |
|
6 | 7 | #include <QVBoxLayout> |
|
7 | 8 | #include <QWidget> |
|
8 | 9 | |
|
10 | #include <functional> | |
|
11 | ||
|
12 | Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer) | |
|
13 | ||
|
9 | 14 | class VisualizationDragWidget; |
|
10 | 15 | |
|
11 | 16 | class VisualizationDragDropContainer : public QWidget { |
@@ -15,6 +20,8 signals: | |||
|
15 | 20 | void dropOccured(int dropIndex, const QMimeData *mimeData); |
|
16 | 21 | |
|
17 | 22 | public: |
|
23 | using AcceptMimeDataFunction = std::function<bool(const QMimeData *mimeData)>; | |
|
24 | ||
|
18 | 25 | VisualizationDragDropContainer(QWidget *parent = nullptr); |
|
19 | 26 | |
|
20 | 27 | void addDragWidget(VisualizationDragWidget *dragWidget); |
@@ -25,6 +32,8 public: | |||
|
25 | 32 | |
|
26 | 33 | int countDragWidget() const; |
|
27 | 34 | |
|
35 | void setAcceptMimeDataFunction(AcceptMimeDataFunction fun); | |
|
36 | ||
|
28 | 37 | protected: |
|
29 | 38 | void dragEnterEvent(QDragEnterEvent *event); |
|
30 | 39 | void dragLeaveEvent(QDragLeaveEvent *event); |
@@ -1,6 +1,14 | |||
|
1 | 1 | #include "DragDropHelper.h" |
|
2 | 2 | #include "SqpApplication.h" |
|
3 | #include "Visualization/VisualizationDragDropContainer.h" | |
|
3 | 4 | #include "Visualization/VisualizationDragWidget.h" |
|
5 | #include "Visualization/VisualizationWidget.h" | |
|
6 | #include "Visualization/operations/FindVariableOperation.h" | |
|
7 | ||
|
8 | #include "Variable/VariableController.h" | |
|
9 | ||
|
10 | #include "Common/MimeTypesDef.h" | |
|
11 | #include "Common/VisualizationDef.h" | |
|
4 | 12 | |
|
5 | 13 | #include <QDir> |
|
6 | 14 | #include <QDragEnterEvent> |
@@ -10,12 +18,11 | |||
|
10 | 18 | #include <QTimer> |
|
11 | 19 | #include <QVBoxLayout> |
|
12 | 20 | |
|
13 | const QString DragDropHelper::MIME_TYPE_GRAPH = "scqlop/graph"; | |
|
14 | const QString DragDropHelper::MIME_TYPE_ZONE = "scqlop/zone"; | |
|
15 | ||
|
16 | 21 | const int SCROLL_SPEED = 5; |
|
17 | 22 | const int SCROLL_ZONE_SIZE = 50; |
|
18 | 23 | |
|
24 | Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDrophelper") | |
|
25 | ||
|
19 | 26 | struct DragDropScroller::DragDropScrollerPrivate { |
|
20 | 27 | |
|
21 | 28 | QList<QScrollArea *> m_ScrollAreas; |
@@ -159,7 +166,11 struct DragDropHelper::DragDropHelperPrivate { | |||
|
159 | 166 | m_PlaceHolder->setSizePolicy(m_CurrentDragWidget->sizePolicy()); |
|
160 | 167 | } |
|
161 | 168 | else { |
|
162 | m_PlaceHolder->setMinimumSize(200, 200); | |
|
169 | // Configuration of the placeHolder when there is no dragWidget | |
|
170 | // (for instance with a drag from a variable) | |
|
171 | ||
|
172 | m_PlaceHolder->setMinimumSize(0, GRAPH_MINIMUM_HEIGHT); | |
|
173 | m_PlaceHolder->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | |
|
163 | 174 | } |
|
164 | 175 | } |
|
165 | 176 | }; |
@@ -174,6 +185,11 DragDropHelper::~DragDropHelper() | |||
|
174 | 185 | QFile::remove(impl->m_ImageTempUrl); |
|
175 | 186 | } |
|
176 | 187 | |
|
188 | void DragDropHelper::resetDragAndDrop() | |
|
189 | { | |
|
190 | setCurrentDragWidget(nullptr); | |
|
191 | } | |
|
192 | ||
|
177 | 193 | void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget) |
|
178 | 194 | { |
|
179 | 195 | impl->m_CurrentDragWidget = dragWidget; |
@@ -228,3 +244,46 QUrl DragDropHelper::imageTemporaryUrl(const QImage &image) const | |||
|
228 | 244 | image.save(impl->m_ImageTempUrl); |
|
229 | 245 | return QUrl::fromLocalFile(impl->m_ImageTempUrl); |
|
230 | 246 | } |
|
247 | ||
|
248 | bool DragDropHelper::checkMimeDataForVisualization(const QMimeData *mimeData, | |
|
249 | VisualizationDragDropContainer *dropContainer) | |
|
250 | { | |
|
251 | auto result = true; | |
|
252 | ||
|
253 | if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) { | |
|
254 | auto variables = sqpApp->variableController().variablesForMimeData( | |
|
255 | mimeData->data(MIME_TYPE_VARIABLE_LIST)); | |
|
256 | ||
|
257 | if (variables.count() == 1) { | |
|
258 | // Check that the viariable is not already in a graph | |
|
259 | ||
|
260 | // Search for the top level VisualizationWidget | |
|
261 | auto parent = dropContainer->parentWidget(); | |
|
262 | while (parent && qobject_cast<VisualizationWidget *>(parent) == nullptr) { | |
|
263 | parent = parent->parentWidget(); | |
|
264 | } | |
|
265 | ||
|
266 | if (parent) { | |
|
267 | auto visualizationWidget = static_cast<VisualizationWidget *>(parent); | |
|
268 | ||
|
269 | FindVariableOperation findVariableOperation{variables.first()}; | |
|
270 | visualizationWidget->accept(&findVariableOperation); | |
|
271 | auto variableContainers = findVariableOperation.result(); | |
|
272 | if (!variableContainers.empty()) { | |
|
273 | result = false; | |
|
274 | } | |
|
275 | } | |
|
276 | else { | |
|
277 | qCWarning(LOG_DragDropHelper()) << QObject::tr( | |
|
278 | "DragDropHelper::checkMimeDataForVisualization, the parent " | |
|
279 | "VisualizationWidget cannot be found."); | |
|
280 | result = false; | |
|
281 | } | |
|
282 | } | |
|
283 | else { | |
|
284 | result = false; | |
|
285 | } | |
|
286 | } | |
|
287 | ||
|
288 | return result; | |
|
289 | } |
@@ -12,6 +12,7 | |||
|
12 | 12 | #include <QStyledItemDelegate> |
|
13 | 13 | #include <QWidgetAction> |
|
14 | 14 | |
|
15 | #include <DragDropHelper.h> | |
|
15 | 16 | #include <SqpApplication.h> |
|
16 | 17 | |
|
17 | 18 | Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget") |
@@ -151,6 +152,11 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent) | |||
|
151 | 152 | ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu); |
|
152 | 153 | connect(ui->tableView, &QTableView::customContextMenuRequested, this, |
|
153 | 154 | &VariableInspectorWidget::onTableMenuRequested); |
|
155 | ||
|
156 | // Resets the drag&drop operation on a left-click (the drag&drop is also started by a left | |
|
157 | // click). | |
|
158 | connect(ui->tableView, &QTableView::clicked, | |
|
159 | [](const auto &modelIndex) { sqpApp->dragDropHelper().resetDragAndDrop(); }); | |
|
154 | 160 | } |
|
155 | 161 | |
|
156 | 162 | VariableInspectorWidget::~VariableInspectorWidget() |
@@ -3,6 +3,8 | |||
|
3 | 3 | #include "SqpApplication.h" |
|
4 | 4 | #include "Visualization/VisualizationDragWidget.h" |
|
5 | 5 | |
|
6 | #include "Common/VisualizationDef.h" | |
|
7 | ||
|
6 | 8 | #include <QDrag> |
|
7 | 9 | #include <QDragEnterEvent> |
|
8 | 10 | #include <QVBoxLayout> |
@@ -10,11 +12,15 | |||
|
10 | 12 | #include <cmath> |
|
11 | 13 | #include <memory> |
|
12 | 14 | |
|
15 | Q_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer, "VisualizationDragDropContainer") | |
|
16 | ||
|
13 | 17 | struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate { |
|
14 | 18 | |
|
15 | 19 | QVBoxLayout *m_Layout; |
|
16 | 20 | QStringList m_AcceptedMimeTypes; |
|
17 | 21 | QStringList m_MergeAllowedMimeTypes; |
|
22 | VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun | |
|
23 | = [](auto mimeData) { return true; }; | |
|
18 | 24 | |
|
19 | 25 | explicit VisualizationDragDropContainerPrivate(QWidget *widget) |
|
20 | 26 | { |
@@ -25,7 +31,7 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate { | |||
|
25 | 31 | bool acceptMimeData(const QMimeData *data) const |
|
26 | 32 | { |
|
27 | 33 | for (const auto &type : m_AcceptedMimeTypes) { |
|
28 | if (data->hasFormat(type)) { | |
|
34 | if (data->hasFormat(type) && m_AcceptMimeDataFun(data)) { | |
|
29 | 35 | return true; |
|
30 | 36 | } |
|
31 | 37 | } |
@@ -121,10 +127,17 int VisualizationDragDropContainer::countDragWidget() const | |||
|
121 | 127 | return nbGraph; |
|
122 | 128 | } |
|
123 | 129 | |
|
130 | void VisualizationDragDropContainer::setAcceptMimeDataFunction( | |
|
131 | VisualizationDragDropContainer::AcceptMimeDataFunction fun) | |
|
132 | { | |
|
133 | impl->m_AcceptMimeDataFun = fun; | |
|
134 | } | |
|
135 | ||
|
124 | 136 | void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget, |
|
125 | 137 | const QPoint &dragPosition) |
|
126 | 138 | { |
|
127 | 139 | auto &helper = sqpApp->dragDropHelper(); |
|
140 | helper.resetDragAndDrop(); | |
|
128 | 141 | |
|
129 | 142 | // Note: The management of the drag object is done by Qt |
|
130 | 143 | auto drag = new QDrag{dragWidget}; |
@@ -149,11 +162,16 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidg | |||
|
149 | 162 | helper.insertPlaceHolder(impl->m_Layout, dragWidgetIndex); |
|
150 | 163 | dragWidget->setVisible(false); |
|
151 | 164 | } |
|
152 | } | |
|
153 | 165 | |
|
154 | 166 | // Note: The exec() is blocking on windows but not on linux and macOS |
|
155 | 167 | drag->exec(Qt::MoveAction | Qt::CopyAction); |
|
156 | 168 | } |
|
169 | else { | |
|
170 | qCWarning(LOG_VisualizationDragDropContainer()) | |
|
171 | << tr("VisualizationDragDropContainer::startDrag, drag aborted, the specified " | |
|
172 | "VisualizationDragWidget is not found in this container."); | |
|
173 | } | |
|
174 | } | |
|
157 | 175 | |
|
158 | 176 | void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event) |
|
159 | 177 | { |
@@ -164,20 +182,30 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event) | |||
|
164 | 182 | |
|
165 | 183 | if (!impl->hasPlaceHolder()) { |
|
166 | 184 | auto dragWidget = helper.getCurrentDragWidget(); |
|
185 | ||
|
186 | if (dragWidget) { | |
|
187 | // If the drag&drop is internal to the visualization, entering the container hide | |
|
188 | // the dragWidget which was hidden by the dragLeaveEvent | |
|
167 | 189 | auto parentWidget |
|
168 | 190 | = qobject_cast<VisualizationDragDropContainer *>(dragWidget->parentWidget()); |
|
169 | 191 | if (parentWidget) { |
|
170 | 192 | dragWidget->setVisible(false); |
|
171 | 193 | } |
|
194 | } | |
|
172 | 195 | |
|
173 | 196 | auto dragWidgetHovered = impl->getChildDragWidgetAt(this, event->pos()); |
|
174 | 197 | |
|
175 | 198 | if (dragWidgetHovered) { |
|
176 | 199 | auto hoveredWidgetIndex = impl->m_Layout->indexOf(dragWidgetHovered); |
|
200 | ||
|
201 | if (dragWidget) { | |
|
177 | 202 | auto dragWidgetIndex = impl->m_Layout->indexOf(helper.getCurrentDragWidget()); |
|
178 | 203 | if (dragWidgetIndex >= 0 && dragWidgetIndex <= hoveredWidgetIndex) { |
|
179 | hoveredWidgetIndex | |
|
180 | += 1; // Correction of the index if the drop occurs in the same container | |
|
204 | // Correction of the index if the drop occurs in the same container | |
|
205 | // and if the drag is started from the visualization (in that case, the | |
|
206 | // dragWidget is hidden) | |
|
207 | hoveredWidgetIndex += 1; | |
|
208 | } | |
|
181 | 209 | } |
|
182 | 210 | |
|
183 | 211 | helper.insertPlaceHolder(impl->m_Layout, hoveredWidgetIndex); |
@@ -186,6 +214,9 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event) | |||
|
186 | 214 | helper.insertPlaceHolder(impl->m_Layout, 0); |
|
187 | 215 | } |
|
188 | 216 | } |
|
217 | else { | |
|
218 | // do nothing | |
|
219 | } | |
|
189 | 220 | } |
|
190 | 221 | else { |
|
191 | 222 | event->ignore(); |
@@ -203,19 +234,23 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event) | |||
|
203 | 234 | if (!impl->cursorIsInContainer(this)) { |
|
204 | 235 | helper.removePlaceHolder(); |
|
205 | 236 | |
|
206 | bool isInternal = true; | |
|
207 |
if ( |
|
|
208 |
// |
|
|
209 |
// |
|
|
237 | auto dragWidget = helper.getCurrentDragWidget(); | |
|
238 | if (dragWidget) { | |
|
239 | // dragWidget has a value only if the drag is started from the visualization | |
|
240 | // In that case, shows the drag widget at its original place | |
|
210 | 241 | // So the drag widget doesn't stay hidden if the drop occurs outside the visualization |
|
211 | 242 | // drop zone (It is not possible to catch a drop event outside of the application) |
|
212 | 243 | |
|
213 | auto dragWidget = sqpApp->dragDropHelper().getCurrentDragWidget(); | |
|
214 | 244 | if (dragWidget) { |
|
215 | 245 | dragWidget->setVisible(true); |
|
216 | 246 | } |
|
217 | 247 | } |
|
218 | 248 | } |
|
249 | else { | |
|
250 | // Leave event probably received for a child widget. | |
|
251 | // Do nothing. | |
|
252 | // Note: The DragLeave event, doesn't have any mean to determine who sent it. | |
|
253 | } | |
|
219 | 254 | |
|
220 | 255 | QWidget::dragLeaveEvent(event); |
|
221 | 256 | } |
@@ -229,7 +264,8 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event) | |||
|
229 | 264 | |
|
230 | 265 | auto nbDragWidget = countDragWidget(); |
|
231 | 266 | if (nbDragWidget > 0) { |
|
232 | auto graphHeight = size().height() / nbDragWidget; | |
|
267 | auto graphHeight = qMax(size().height() / nbDragWidget, GRAPH_MINIMUM_HEIGHT); | |
|
268 | ||
|
233 | 269 | auto dropIndex = floor(event->pos().y() / graphHeight); |
|
234 | 270 | auto zoneSize = qMin(graphHeight / 3.0, 150.0); |
|
235 | 271 | |
@@ -244,10 +280,15 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event) | |||
|
244 | 280 | dropIndex += 1; |
|
245 | 281 | } |
|
246 | 282 | |
|
247 |
|
|
|
283 | if (helper.getCurrentDragWidget()) { | |
|
284 | auto dragWidgetIndex | |
|
285 | = impl->m_Layout->indexOf(helper.getCurrentDragWidget()); | |
|
248 | 286 | if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) { |
|
249 |
|
|
|
250 | // container | |
|
287 | // Correction of the index if the drop occurs in the same container | |
|
288 | // and if the drag is started from the visualization (in that case, the | |
|
289 | // dragWidget is hidden) | |
|
290 | dropIndex += 1; | |
|
291 | } | |
|
251 | 292 | } |
|
252 | 293 | |
|
253 | 294 | if (dropIndex != placeHolderIndex) { |
@@ -261,6 +302,15 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event) | |||
|
261 | 302 | } |
|
262 | 303 | } |
|
263 | 304 | } |
|
305 | else { | |
|
306 | qCWarning(LOG_VisualizationDragDropContainer()) | |
|
307 | << tr("VisualizationDragDropContainer::dragMoveEvent, no widget found in the " | |
|
308 | "container"); | |
|
309 | } | |
|
310 | } | |
|
311 | else { | |
|
312 | // No hovered drag widget, the mouse is probably hover the placeHolder | |
|
313 | // Do nothing | |
|
264 | 314 | } |
|
265 | 315 | } |
|
266 | 316 | else { |
@@ -274,18 +324,22 void VisualizationDragDropContainer::dropEvent(QDropEvent *event) | |||
|
274 | 324 | { |
|
275 | 325 | if (impl->acceptMimeData(event->mimeData())) { |
|
276 | 326 | auto dragWidget = sqpApp->dragDropHelper().getCurrentDragWidget(); |
|
277 |
if (impl->hasPlaceHolder() |
|
|
327 | if (impl->hasPlaceHolder()) { | |
|
278 | 328 | auto &helper = sqpApp->dragDropHelper(); |
|
279 | 329 | |
|
280 | 330 | auto droppedIndex = impl->m_Layout->indexOf(&helper.placeHolder()); |
|
281 | 331 | |
|
332 | if (dragWidget) { | |
|
282 | 333 | auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget); |
|
283 | 334 | if (dragWidgetIndex >= 0 && dragWidgetIndex < droppedIndex) { |
|
284 | droppedIndex | |
|
285 | -= 1; // Correction of the index if the drop occurs in the same container | |
|
335 | // Correction of the index if the drop occurs in the same container | |
|
336 | // and if the drag is started from the visualization (in that case, the | |
|
337 | // dragWidget is hidden) | |
|
338 | droppedIndex -= 1; | |
|
286 | 339 | } |
|
287 | 340 | |
|
288 | 341 | dragWidget->setVisible(true); |
|
342 | } | |
|
289 | 343 | |
|
290 | 344 | event->acceptProposedAction(); |
|
291 | 345 | |
@@ -293,6 +347,12 void VisualizationDragDropContainer::dropEvent(QDropEvent *event) | |||
|
293 | 347 | |
|
294 | 348 | emit dropOccured(droppedIndex, event->mimeData()); |
|
295 | 349 | } |
|
350 | else { | |
|
351 | qCWarning(LOG_VisualizationDragDropContainer()) | |
|
352 | << tr("VisualizationDragDropContainer::dropEvent, couldn't drop because the " | |
|
353 | "placeHolder is not found."); | |
|
354 | Q_ASSERT(false); | |
|
355 | } | |
|
296 | 356 | } |
|
297 | 357 | else { |
|
298 | 358 | event->ignore(); |
@@ -6,6 +6,7 | |||
|
6 | 6 | #include "Visualization/VisualizationZoneWidget.h" |
|
7 | 7 | #include "ui_VisualizationGraphWidget.h" |
|
8 | 8 | |
|
9 | #include <Common/MimeTypesDef.h> | |
|
9 | 10 | #include <Data/ArrayData.h> |
|
10 | 11 | #include <Data/IDataSeries.h> |
|
11 | 12 | #include <DragDropHelper.h> |
@@ -232,7 +233,7 QString VisualizationGraphWidget::name() const | |||
|
232 | 233 | QMimeData *VisualizationGraphWidget::mimeData() const |
|
233 | 234 | { |
|
234 | 235 | auto mimeData = new QMimeData; |
|
235 |
mimeData->setData( |
|
|
236 | mimeData->setData(MIME_TYPE_GRAPH, QByteArray()); | |
|
236 | 237 | |
|
237 | 238 | return mimeData; |
|
238 | 239 | } |
@@ -7,6 +7,8 | |||
|
7 | 7 | |
|
8 | 8 | #include "Variable/VariableController.h" |
|
9 | 9 | |
|
10 | #include "Common/MimeTypesDef.h" | |
|
11 | ||
|
10 | 12 | #include "DragDropHelper.h" |
|
11 | 13 | #include "SqpApplication.h" |
|
12 | 14 | |
@@ -52,6 +54,11 struct VisualizationTabWidget::VisualizationTabWidgetPrivate { | |||
|
52 | 54 | explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {} |
|
53 | 55 | |
|
54 | 56 | QString m_Name; |
|
57 | ||
|
58 | void dropGraph(int index, VisualizationTabWidget *tabWidget); | |
|
59 | void dropZone(int index, VisualizationTabWidget *tabWidget); | |
|
60 | void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index, | |
|
61 | VisualizationTabWidget *tabWidget); | |
|
55 | 62 | }; |
|
56 | 63 | |
|
57 | 64 | VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent) |
@@ -62,9 +69,13 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *par | |||
|
62 | 69 | ui->setupUi(this); |
|
63 | 70 | |
|
64 | 71 | ui->dragDropContainer->setAcceptedMimeTypes( |
|
65 |
{ |
|
|
72 | {MIME_TYPE_GRAPH, MIME_TYPE_ZONE, MIME_TYPE_VARIABLE_LIST}); | |
|
66 | 73 | connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this, |
|
67 | 74 | &VisualizationTabWidget::dropMimeData); |
|
75 | ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) { | |
|
76 | return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData, | |
|
77 | ui->dragDropContainer); | |
|
78 | }); | |
|
68 | 79 | sqpApp->dragDropHelper().addDragDropScrollArea(ui->scrollArea); |
|
69 | 80 | |
|
70 | 81 | // Widget is deleted when closed |
@@ -162,12 +173,46 QLayout &VisualizationTabWidget::tabLayout() const noexcept | |||
|
162 | 173 | |
|
163 | 174 | void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData) |
|
164 | 175 | { |
|
176 | if (mimeData->hasFormat(MIME_TYPE_GRAPH)) { | |
|
177 | impl->dropGraph(index, this); | |
|
178 | } | |
|
179 | else if (mimeData->hasFormat(MIME_TYPE_ZONE)) { | |
|
180 | impl->dropZone(index, this); | |
|
181 | } | |
|
182 | else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) { | |
|
183 | auto variables = sqpApp->variableController().variablesForMimeData( | |
|
184 | mimeData->data(MIME_TYPE_VARIABLE_LIST)); | |
|
185 | impl->dropVariables(variables, index, this); | |
|
186 | } | |
|
187 | else { | |
|
188 | qCWarning(LOG_VisualizationZoneWidget()) | |
|
189 | << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received."); | |
|
190 | } | |
|
191 | } | |
|
192 | ||
|
193 | void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph( | |
|
194 | int index, VisualizationTabWidget *tabWidget) | |
|
195 | { | |
|
165 | 196 | auto &helper = sqpApp->dragDropHelper(); |
|
166 | if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_GRAPH)) { | |
|
167 |
|
|
|
197 | ||
|
198 | auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget()); | |
|
199 | if (!graphWidget) { | |
|
200 | qCWarning(LOG_VisualizationZoneWidget()) | |
|
201 | << tr("VisualizationTabWidget::dropGraph, drop aborted, the dropped graph is not " | |
|
202 | "found or invalid."); | |
|
203 | Q_ASSERT(false); | |
|
204 | return; | |
|
205 | } | |
|
206 | ||
|
168 | 207 |
|
|
169 | 208 |
|
|
170 |
|
|
|
209 | if (!parentDragDropContainer) { | |
|
210 | qCWarning(LOG_VisualizationZoneWidget()) | |
|
211 | << tr("VisualizationTabWidget::dropGraph, drop aborted, the parent container of " | |
|
212 | "the dropped graph is not found."); | |
|
213 | Q_ASSERT(false); | |
|
214 | return; | |
|
215 | } | |
|
171 | 216 | |
|
172 | 217 |
|
|
173 | 218 | |
@@ -190,7 +235,7 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData) | |||
|
190 | 235 |
|
|
191 | 236 |
|
|
192 | 237 | |
|
193 |
|
|
|
238 | tabWidget->createZone(variables, index); | |
|
194 | 239 |
|
|
195 | 240 |
|
|
196 | 241 |
|
@@ -199,7 +244,7 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData) | |||
|
199 | 244 | |
|
200 | 245 |
|
|
201 | 246 | |
|
202 |
|
|
|
247 | auto zoneWidget = tabWidget->createEmptyZone(index); | |
|
203 | 248 |
|
|
204 | 249 | |
|
205 | 250 |
|
@@ -208,12 +253,42 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData) | |||
|
208 | 253 |
|
|
209 | 254 |
|
|
210 | 255 | } |
|
211 | else if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_ZONE)) { | |
|
256 | ||
|
257 | void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone( | |
|
258 | int index, VisualizationTabWidget *tabWidget) | |
|
259 | { | |
|
260 | auto &helper = sqpApp->dragDropHelper(); | |
|
261 | ||
|
262 | auto zoneWidget = qobject_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget()); | |
|
263 | if (!zoneWidget) { | |
|
264 | qCWarning(LOG_VisualizationZoneWidget()) | |
|
265 | << tr("VisualizationTabWidget::dropZone, drop aborted, the dropped zone is not " | |
|
266 | "found or invalid."); | |
|
267 | Q_ASSERT(false); | |
|
268 | return; | |
|
269 | } | |
|
270 | ||
|
271 | auto parentDragDropContainer | |
|
272 | = qobject_cast<VisualizationDragDropContainer *>(zoneWidget->parentWidget()); | |
|
273 | if (!parentDragDropContainer) { | |
|
274 | qCWarning(LOG_VisualizationZoneWidget()) | |
|
275 | << tr("VisualizationTabWidget::dropZone, drop aborted, the parent container of " | |
|
276 | "the dropped zone is not found."); | |
|
277 | Q_ASSERT(false); | |
|
278 | return; | |
|
279 | } | |
|
280 | ||
|
212 | 281 |
|
|
213 | auto zoneWidget = static_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget()); | |
|
214 | auto parentDragDropContainer = zoneWidget->parentWidget(); | |
|
215 | 282 |
|
|
216 | ||
|
217 | ui->dragDropContainer->insertDragWidget(index, zoneWidget); | |
|
283 | tabWidget->ui->dragDropContainer->insertDragWidget(index, zoneWidget); | |
|
218 | 284 | } |
|
285 | ||
|
286 | void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables( | |
|
287 | const QList<std::shared_ptr<Variable> > &variables, int index, | |
|
288 | VisualizationTabWidget *tabWidget) | |
|
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. | |
|
293 | tabWidget->createZone(variables, index); | |
|
219 | 294 | } |
@@ -3,12 +3,18 | |||
|
3 | 3 | #include "Visualization/IVisualizationWidgetVisitor.h" |
|
4 | 4 | #include "Visualization/QCustomPlotSynchronizer.h" |
|
5 | 5 | #include "Visualization/VisualizationGraphWidget.h" |
|
6 | #include "Visualization/VisualizationWidget.h" | |
|
6 | 7 | #include "ui_VisualizationZoneWidget.h" |
|
7 | 8 | |
|
9 | #include "Common/MimeTypesDef.h" | |
|
10 | #include "Common/VisualizationDef.h" | |
|
11 | ||
|
8 | 12 | #include <Data/SqpRange.h> |
|
9 | 13 | #include <Variable/Variable.h> |
|
10 | 14 | #include <Variable/VariableController.h> |
|
11 | 15 | |
|
16 | #include <Visualization/operations/FindVariableOperation.h> | |
|
17 | ||
|
12 | 18 | #include <DragDropHelper.h> |
|
13 | 19 | #include <QUuid> |
|
14 | 20 | #include <SqpApplication.h> |
@@ -20,8 +26,6 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget") | |||
|
20 | 26 | |
|
21 | 27 | namespace { |
|
22 | 28 | |
|
23 | /// Minimum height for graph added in zones (in pixels) | |
|
24 | const auto GRAPH_MINIMUM_HEIGHT = 300; | |
|
25 | 29 | |
|
26 | 30 | /// Generates a default name for a new graph, according to the number of graphs already displayed in |
|
27 | 31 | /// the zone |
@@ -66,6 +70,10 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate { | |||
|
66 | 70 | } |
|
67 | 71 | QUuid m_SynchronisationGroupId; |
|
68 | 72 | std::unique_ptr<IGraphSynchronizer> m_Synchronizer; |
|
73 | ||
|
74 | void dropGraph(int index, VisualizationZoneWidget *zoneWidget); | |
|
75 | void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index, | |
|
76 | VisualizationZoneWidget *zoneWidget); | |
|
69 | 77 | }; |
|
70 | 78 | |
|
71 | 79 | VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent) |
@@ -77,7 +85,11 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p | |||
|
77 | 85 | |
|
78 | 86 | ui->zoneNameLabel->setText(name); |
|
79 | 87 | |
|
80 |
ui->dragDropContainer->setAcceptedMimeTypes({ |
|
|
88 | ui->dragDropContainer->setAcceptedMimeTypes({MIME_TYPE_GRAPH, MIME_TYPE_VARIABLE_LIST}); | |
|
89 | ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) { | |
|
90 | return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData, | |
|
91 | ui->dragDropContainer); | |
|
92 | }); | |
|
81 | 93 | connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this, |
|
82 | 94 | &VisualizationZoneWidget::dropMimeData); |
|
83 | 95 | |
@@ -315,7 +327,7 QString VisualizationZoneWidget::name() const | |||
|
315 | 327 | QMimeData *VisualizationZoneWidget::mimeData() const |
|
316 | 328 | { |
|
317 | 329 | auto mimeData = new QMimeData; |
|
318 |
mimeData->setData( |
|
|
330 | mimeData->setData(MIME_TYPE_ZONE, QByteArray()); | |
|
319 | 331 | |
|
320 | 332 | return mimeData; |
|
321 | 333 | } |
@@ -354,16 +366,47 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variabl | |||
|
354 | 366 | |
|
355 | 367 | void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData) |
|
356 | 368 | { |
|
369 | if (mimeData->hasFormat(MIME_TYPE_GRAPH)) { | |
|
370 | impl->dropGraph(index, this); | |
|
371 | } | |
|
372 | else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) { | |
|
373 | auto variables = sqpApp->variableController().variablesForMimeData( | |
|
374 | mimeData->data(MIME_TYPE_VARIABLE_LIST)); | |
|
375 | impl->dropVariables(variables, index, this); | |
|
376 | } | |
|
377 | else { | |
|
378 | qCWarning(LOG_VisualizationZoneWidget()) | |
|
379 | << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received."); | |
|
380 | } | |
|
381 | } | |
|
382 | ||
|
383 | void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph( | |
|
384 | int index, VisualizationZoneWidget *zoneWidget) | |
|
385 | { | |
|
357 | 386 | auto &helper = sqpApp->dragDropHelper(); |
|
358 | if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_GRAPH)) { | |
|
359 |
|
|
|
387 | ||
|
388 | auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget()); | |
|
389 | if (!graphWidget) { | |
|
390 | qCWarning(LOG_VisualizationZoneWidget()) | |
|
391 | << tr("VisualizationZoneWidget::dropGraph, drop aborted, the dropped graph is not " | |
|
392 | "found or invalid."); | |
|
393 | Q_ASSERT(false); | |
|
394 | return; | |
|
395 | } | |
|
396 | ||
|
360 | 397 |
|
|
361 | 398 |
|
|
362 |
|
|
|
399 | if (!parentDragDropContainer) { | |
|
400 | qCWarning(LOG_VisualizationZoneWidget()) | |
|
401 | << tr("VisualizationZoneWidget::dropGraph, drop aborted, the parent container of " | |
|
402 | "the dropped graph is not found."); | |
|
403 | Q_ASSERT(false); | |
|
404 | return; | |
|
405 | } | |
|
363 | 406 | |
|
364 | 407 |
|
|
365 | 408 | |
|
366 |
|
|
|
409 | if (parentDragDropContainer != zoneWidget->ui->dragDropContainer && !variables.isEmpty()) { | |
|
367 | 410 |
|
|
368 | 411 | |
|
369 | 412 |
|
@@ -385,17 +428,17 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData) | |||
|
385 | 428 |
|
|
386 | 429 | |
|
387 | 430 |
|
|
388 |
|
|
|
431 | zoneWidget->createGraph(variables, index); | |
|
389 | 432 |
|
|
390 | 433 |
|
|
391 | 434 |
|
|
392 | 435 |
|
|
393 | 436 |
|
|
394 | 437 | |
|
395 |
|
|
|
438 | if (variables.isEmpty() && parentDragDropContainer != zoneWidget->ui->dragDropContainer) { | |
|
396 | 439 |
|
|
397 | 440 |
|
|
398 |
|
|
|
441 | auto layout = zoneWidget->ui->dragDropContainer->layout(); | |
|
399 | 442 |
|
|
400 | 443 |
|
|
401 | 444 |
|
@@ -404,7 +447,38 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData) | |||
|
404 | 447 |
|
|
405 | 448 |
|
|
406 | 449 | |
|
407 |
|
|
|
450 | zoneWidget->ui->dragDropContainer->insertDragWidget(index, graphWidget); | |
|
451 | } | |
|
452 | } | |
|
453 | ||
|
454 | void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropVariables( | |
|
455 | const QList<std::shared_ptr<Variable> > &variables, int index, | |
|
456 | VisualizationZoneWidget *zoneWidget) | |
|
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) { | |
|
465 | qCWarning(LOG_VisualizationZoneWidget()) | |
|
466 | << tr("VisualizationZoneWidget::dropVariables, drop aborted, the parent " | |
|
467 | "VisualizationWidget cannot be found."); | |
|
468 | Q_ASSERT(false); | |
|
469 | return; | |
|
470 | } | |
|
471 | ||
|
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; | |
|
408 | 482 | } |
|
409 | 483 | } |
|
410 | 484 | } |
General Comments 1
You need to be logged in to leave comments.
Login now