##// END OF EJS Templates
Merge pull request 323 from SciQLop-fork develop...
leroux -
r889:756d7fefd6f4 merge
parent child
Show More
@@ -0,0 +1,32
1 #ifndef SCIQLOP_DRAGDROPSCROLLER_H
2 #define SCIQLOP_DRAGDROPSCROLLER_H
3
4 #include <Common/spimpl.h>
5 #include <QScrollArea>
6
7 /**
8 * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation.
9 * @note A QScrollArea inside an other QScrollArea is not fully supported.
10 */
11 class DragDropScroller : public QObject {
12 Q_OBJECT
13
14 public:
15 DragDropScroller(QObject *parent = nullptr);
16
17 void addScrollArea(QScrollArea *scrollArea);
18 void removeScrollArea(QScrollArea *scrollArea);
19
20 protected:
21 bool eventFilter(QObject *obj, QEvent *event);
22
23 private:
24 class DragDropScrollerPrivate;
25 spimpl::unique_impl_ptr<DragDropScrollerPrivate> impl;
26
27 private slots:
28 void onTimer();
29 };
30
31
32 #endif // SCIQLOP_DRAGDROPSCROLLER_H
@@ -0,0 +1,29
1 #ifndef SCIQLOP_DRAGDROPTABSWITCHER_H
2 #define SCIQLOP_DRAGDROPTABSWITCHER_H
3
4 #include <Common/spimpl.h>
5
6 #include <QLoggingCategory>
7 #include <QTabBar>
8
9 Q_DECLARE_LOGGING_CATEGORY(LOG_DragDropTabSwitcher)
10
11 class DragDropTabSwitcher : public QObject {
12 Q_OBJECT
13
14 public:
15 DragDropTabSwitcher(QObject *parent = nullptr);
16
17 void addTabBar(QTabBar *tabBar);
18 void removeTabBar(QTabBar *tabBar);
19
20 protected:
21 bool eventFilter(QObject *obj, QEvent *event);
22
23 private:
24 class DragDropTabSwitcherPrivate;
25 spimpl::unique_impl_ptr<DragDropTabSwitcherPrivate> impl;
26 };
27
28
29 #endif // SCIQLOP_DRAGDROPTABSWITCHER_H
@@ -0,0 +1,14
1 #ifndef SCIQLOP_VARIABLEINSPECTORTABLEVIEW_H
2 #define SCIQLOP_VARIABLEINSPECTORTABLEVIEW_H
3
4 #include <QTableView>
5
6 class VariableInspectorTableView : public QTableView {
7 public:
8 VariableInspectorTableView(QWidget *parent = nullptr);
9
10 protected:
11 void startDrag(Qt::DropActions supportedActions);
12 };
13
14 #endif // SCIQLOP_VARIABLEINSPECTORTABLEVIEW_H
@@ -0,0 +1,275
1 #include "DragAndDrop/DragDropHelper.h"
2 #include "DragAndDrop/DragDropScroller.h"
3 #include "DragAndDrop/DragDropTabSwitcher.h"
4 #include "SqpApplication.h"
5 #include "Visualization/VisualizationDragDropContainer.h"
6 #include "Visualization/VisualizationDragWidget.h"
7 #include "Visualization/VisualizationWidget.h"
8 #include "Visualization/operations/FindVariableOperation.h"
9
10 #include "Variable/Variable.h"
11 #include "Variable/VariableController.h"
12
13 #include "Common/MimeTypesDef.h"
14 #include "Common/VisualizationDef.h"
15
16 #include <QDir>
17 #include <QLabel>
18 #include <QUrl>
19 #include <QVBoxLayout>
20
21
22 Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDropHelper")
23
24
25 struct DragDropHelper::DragDropHelperPrivate {
26
27 VisualizationDragWidget *m_CurrentDragWidget = nullptr;
28 std::unique_ptr<QWidget> m_PlaceHolder = nullptr;
29 QLabel *m_PlaceHolderLabel;
30 QWidget *m_PlaceBackground;
31 std::unique_ptr<DragDropScroller> m_DragDropScroller = nullptr;
32 std::unique_ptr<DragDropTabSwitcher> m_DragDropTabSwitcher = nullptr;
33 QString m_ImageTempUrl; // Temporary file for image url generated by the drag & drop. Not using
34 // QTemporaryFile to have a name which is not generated.
35
36 VisualizationDragWidget *m_HighlightedDragWidget = nullptr;
37
38 QMetaObject::Connection m_DragWidgetDestroyedConnection;
39 QMetaObject::Connection m_HighlightedWidgetDestroyedConnection;
40
41 explicit DragDropHelperPrivate()
42 : m_PlaceHolder{std::make_unique<QWidget>()},
43 m_DragDropScroller{std::make_unique<DragDropScroller>()},
44 m_DragDropTabSwitcher{std::make_unique<DragDropTabSwitcher>()}
45 {
46
47 auto layout = new QVBoxLayout{m_PlaceHolder.get()};
48 layout->setSpacing(0);
49 layout->setContentsMargins(0, 0, 0, 0);
50
51 m_PlaceHolderLabel = new QLabel{"", m_PlaceHolder.get()};
52 m_PlaceHolderLabel->setMinimumHeight(25);
53 layout->addWidget(m_PlaceHolderLabel);
54
55 m_PlaceBackground = new QWidget{m_PlaceHolder.get()};
56 m_PlaceBackground->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
57 layout->addWidget(m_PlaceBackground);
58
59 sqpApp->installEventFilter(m_DragDropScroller.get());
60 sqpApp->installEventFilter(m_DragDropTabSwitcher.get());
61
62 m_ImageTempUrl = QDir::temp().absoluteFilePath("Sciqlop_graph.png");
63 }
64
65 void preparePlaceHolder(DragDropHelper::PlaceHolderType type, const QString &topLabelText) const
66 {
67 if (m_CurrentDragWidget) {
68 m_PlaceHolder->setMinimumSize(m_CurrentDragWidget->size());
69 m_PlaceHolder->setSizePolicy(m_CurrentDragWidget->sizePolicy());
70 }
71 else {
72 // Configuration of the placeHolder when there is no dragWidget
73 // (for instance with a drag from a variable)
74
75 m_PlaceHolder->setMinimumSize(0, GRAPH_MINIMUM_HEIGHT);
76 m_PlaceHolder->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
77 }
78
79 switch (type) {
80 case DragDropHelper::PlaceHolderType::Graph:
81 m_PlaceBackground->setStyleSheet(
82 "background-color: #BBD5EE; border: 1px solid #2A7FD4");
83 break;
84 case DragDropHelper::PlaceHolderType::Zone:
85 case DragDropHelper::PlaceHolderType::Default:
86 m_PlaceBackground->setStyleSheet(
87 "background-color: #BBD5EE; border: 2px solid #2A7FD4");
88 m_PlaceHolderLabel->setStyleSheet("color: #2A7FD4");
89 break;
90 }
91
92 m_PlaceHolderLabel->setText(topLabelText);
93 m_PlaceHolderLabel->setVisible(!topLabelText.isEmpty());
94 }
95 };
96
97
98 DragDropHelper::DragDropHelper() : impl{spimpl::make_unique_impl<DragDropHelperPrivate>()} {}
99
100 DragDropHelper::~DragDropHelper()
101 {
102 QFile::remove(impl->m_ImageTempUrl);
103 }
104
105 void DragDropHelper::resetDragAndDrop()
106 {
107 setCurrentDragWidget(nullptr);
108 impl->m_HighlightedDragWidget = nullptr;
109 }
110
111 void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget)
112 {
113 if (impl->m_CurrentDragWidget) {
114
115 QObject::disconnect(impl->m_DragWidgetDestroyedConnection);
116 }
117
118 if (dragWidget) {
119 // ensures the impl->m_CurrentDragWidget is reset when the widget is destroyed
120 impl->m_DragWidgetDestroyedConnection
121 = QObject::connect(dragWidget, &VisualizationDragWidget::destroyed,
122 [this]() { impl->m_CurrentDragWidget = nullptr; });
123 }
124
125 impl->m_CurrentDragWidget = dragWidget;
126 }
127
128 VisualizationDragWidget *DragDropHelper::getCurrentDragWidget() const
129 {
130 return impl->m_CurrentDragWidget;
131 }
132
133 QWidget &DragDropHelper::placeHolder() const
134 {
135 return *impl->m_PlaceHolder;
136 }
137
138 void DragDropHelper::insertPlaceHolder(QVBoxLayout *layout, int index, PlaceHolderType type,
139 const QString &topLabelText)
140 {
141 removePlaceHolder();
142 impl->preparePlaceHolder(type, topLabelText);
143 layout->insertWidget(index, impl->m_PlaceHolder.get());
144 impl->m_PlaceHolder->show();
145 }
146
147 void DragDropHelper::removePlaceHolder()
148 {
149 auto parentWidget = impl->m_PlaceHolder->parentWidget();
150 if (parentWidget) {
151 parentWidget->layout()->removeWidget(impl->m_PlaceHolder.get());
152 impl->m_PlaceHolder->setParent(nullptr);
153 impl->m_PlaceHolder->hide();
154 }
155 }
156
157 bool DragDropHelper::isPlaceHolderSet() const
158 {
159 return impl->m_PlaceHolder->parentWidget();
160 }
161
162 void DragDropHelper::addDragDropScrollArea(QScrollArea *scrollArea)
163 {
164 impl->m_DragDropScroller->addScrollArea(scrollArea);
165 }
166
167 void DragDropHelper::removeDragDropScrollArea(QScrollArea *scrollArea)
168 {
169 impl->m_DragDropScroller->removeScrollArea(scrollArea);
170 }
171
172 void DragDropHelper::addDragDropTabBar(QTabBar *tabBar)
173 {
174 impl->m_DragDropTabSwitcher->addTabBar(tabBar);
175 }
176
177 void DragDropHelper::removeDragDropTabBar(QTabBar *tabBar)
178 {
179 impl->m_DragDropTabSwitcher->removeTabBar(tabBar);
180 }
181
182 QUrl DragDropHelper::imageTemporaryUrl(const QImage &image) const
183 {
184 image.save(impl->m_ImageTempUrl);
185 return QUrl::fromLocalFile(impl->m_ImageTempUrl);
186 }
187
188 void DragDropHelper::setHightlightedDragWidget(VisualizationDragWidget *dragWidget)
189 {
190 if (impl->m_HighlightedDragWidget) {
191 impl->m_HighlightedDragWidget->highlightForMerge(false);
192 QObject::disconnect(impl->m_HighlightedWidgetDestroyedConnection);
193 }
194
195 if (dragWidget) {
196 dragWidget->highlightForMerge(true);
197
198 // ensures the impl->m_HighlightedDragWidget is reset when the widget is destroyed
199 impl->m_DragWidgetDestroyedConnection
200 = QObject::connect(dragWidget, &VisualizationDragWidget::destroyed,
201 [this]() { impl->m_HighlightedDragWidget = nullptr; });
202 }
203
204 impl->m_HighlightedDragWidget = dragWidget;
205 }
206
207 VisualizationDragWidget *DragDropHelper::getHightlightedDragWidget() const
208 {
209 return impl->m_HighlightedDragWidget;
210 }
211
212 bool DragDropHelper::checkMimeDataForVisualization(const QMimeData *mimeData,
213 VisualizationDragDropContainer *dropContainer)
214 {
215 if (!mimeData || !dropContainer) {
216 qCWarning(LOG_DragDropHelper()) << QObject::tr(
217 "DragDropHelper::checkMimeDataForVisualization, invalid input parameters.");
218 Q_ASSERT(false);
219 return false;
220 }
221
222 auto result = false;
223
224 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
225 auto variables = sqpApp->variableController().variablesForMimeData(
226 mimeData->data(MIME_TYPE_VARIABLE_LIST));
227
228 if (variables.count() == 1) {
229
230 auto variable = variables.first();
231 if (variable->dataSeries() != nullptr) {
232
233 // Check that the variable is not already in a graph
234
235 auto parent = dropContainer->parentWidget();
236 while (parent && qobject_cast<VisualizationWidget *>(parent) == nullptr) {
237 parent = parent->parentWidget(); // Search for the top level VisualizationWidget
238 }
239
240 if (parent) {
241 auto visualizationWidget = static_cast<VisualizationWidget *>(parent);
242
243 FindVariableOperation findVariableOperation{variable};
244 visualizationWidget->accept(&findVariableOperation);
245 auto variableContainers = findVariableOperation.result();
246 if (variableContainers.empty()) {
247 result = true;
248 }
249 else {
250 // result = false: the variable already exist in the visualisation
251 }
252 }
253 else {
254 qCWarning(LOG_DragDropHelper()) << QObject::tr(
255 "DragDropHelper::checkMimeDataForVisualization, the parent "
256 "VisualizationWidget cannot be found. Cannot check if the variable is "
257 "already used or not.");
258 }
259 }
260 else {
261 // result = false: the variable is not fully loaded
262 }
263 }
264 else {
265 // result = false: cannot drop multiple variables in the visualisation
266 }
267 }
268 else {
269 // Other MIME data
270 // no special rules, accepted by default
271 result = true;
272 }
273
274 return result;
275 }
@@ -0,0 +1,180
1 #include "DragAndDrop/DragDropTabSwitcher.h"
2
3 #include <QAbstractButton>
4 #include <QDragEnterEvent>
5 #include <QDragMoveEvent>
6 #include <QTimer>
7
8 #include "SqpApplication.h"
9
10 Q_LOGGING_CATEGORY(LOG_DragDropTabSwitcher, "DragDropTabSwitcher")
11
12 const int CHANGE_TAB_INTERVAL = 400; // time necessary over a tab to accept the switch
13 const int SCROLL_BUTTON_AUTO_CLICK_INTERVAL
14 = 500; // time between 2 auto clicks on a scroll button of the tab bar
15
16 struct DragDropTabSwitcher::DragDropTabSwitcherPrivate {
17
18 QList<QTabBar *> m_TabBarList;
19 QTabBar *m_CurrentTabBar = nullptr;
20
21 int m_HoveredTabIndex = -1;
22 std::unique_ptr<QTimer> m_TabSwitchTimer = nullptr;
23
24 QAbstractButton *m_HoveredScrollButton = nullptr;
25 std::unique_ptr<QTimer> m_ScrollButtonsTimer = nullptr;
26
27 explicit DragDropTabSwitcherPrivate()
28 : m_TabSwitchTimer{std::make_unique<QTimer>()},
29 m_ScrollButtonsTimer{std::make_unique<QTimer>()}
30 {
31 m_TabSwitchTimer->setSingleShot(true);
32 m_TabSwitchTimer->setInterval(CHANGE_TAB_INTERVAL);
33 QObject::connect(m_TabSwitchTimer.get(), &QTimer::timeout, [this]() {
34 if (m_CurrentTabBar) {
35 m_CurrentTabBar->setCurrentIndex(m_HoveredTabIndex);
36 }
37 else {
38 qCWarning(LOG_DragDropTabSwitcher()) << "DragDropTabSwitcherPrivate::timeout: "
39 "Cannot select a new tab: unknown current "
40 "tab bar.";
41 }
42 });
43
44 m_ScrollButtonsTimer->setInterval(SCROLL_BUTTON_AUTO_CLICK_INTERVAL);
45 QObject::connect(m_ScrollButtonsTimer.get(), &QTimer::timeout, [this]() {
46 if (m_HoveredScrollButton) {
47 m_HoveredScrollButton->animateClick();
48 }
49 else {
50 qCWarning(LOG_DragDropTabSwitcher())
51 << "DragDropTabSwitcherPrivate::timeoutScroll: "
52 "Unknown scroll button";
53 }
54 });
55 }
56
57 bool isScrollTabButton(QAbstractButton *button, QTabBar *tabBar)
58 {
59 auto isNextOrPreviousTabButton = true;
60
61 if (tabBar->isAncestorOf(button)) {
62 for (auto i = 0; i < tabBar->count(); ++i) {
63 if (tabBar->tabButton(i, QTabBar::RightSide) == button
64 || tabBar->tabButton(i, QTabBar::LeftSide) == button) {
65 isNextOrPreviousTabButton = false;
66 break;
67 }
68 }
69 }
70 else {
71 isNextOrPreviousTabButton = false;
72 }
73
74 return isNextOrPreviousTabButton;
75 }
76
77 QAbstractButton *tabScrollButtonAt(const QPoint &pos, QTabBar *tabBar)
78 {
79
80 auto globalPos = tabBar->mapToGlobal(pos);
81
82 auto widgetUnderMouse = sqpApp->widgetAt(globalPos);
83 if (auto btn = qobject_cast<QAbstractButton *>(widgetUnderMouse)) {
84
85 if (isScrollTabButton(btn, tabBar)) {
86 return btn;
87 }
88 }
89
90 return nullptr;
91 }
92 };
93
94 DragDropTabSwitcher::DragDropTabSwitcher(QObject *parent)
95 : QObject(parent), impl{spimpl::make_unique_impl<DragDropTabSwitcherPrivate>()}
96 {
97 }
98
99 void DragDropTabSwitcher::addTabBar(QTabBar *tabBar)
100 {
101 impl->m_TabBarList << tabBar;
102 tabBar->setAcceptDrops(true);
103 }
104
105 void DragDropTabSwitcher::removeTabBar(QTabBar *tabBar)
106 {
107 impl->m_TabBarList.removeAll(tabBar);
108 tabBar->setAcceptDrops(false);
109 }
110
111 bool DragDropTabSwitcher::eventFilter(QObject *obj, QEvent *event)
112 {
113 if (event->type() == QEvent::DragMove) {
114
115 if (impl->m_CurrentTabBar) {
116
117 QWidget *w = static_cast<QWidget *>(obj);
118 if (!impl->m_CurrentTabBar->isAncestorOf(w)) {
119 return false;
120 }
121
122 auto moveEvent = static_cast<QDragMoveEvent *>(event);
123
124 auto scrollButton = impl->tabScrollButtonAt(moveEvent->pos(), impl->m_CurrentTabBar);
125
126 if (!scrollButton) {
127
128 auto tabIndex = impl->m_CurrentTabBar->tabAt(moveEvent->pos());
129 if (tabIndex >= 0 && tabIndex != impl->m_CurrentTabBar->currentIndex()) {
130 // The mouse is over an unselected tab
131 if (!impl->m_TabSwitchTimer->isActive()
132 || tabIndex != impl->m_HoveredTabIndex) {
133 impl->m_HoveredTabIndex = tabIndex;
134 impl->m_TabSwitchTimer->start();
135 }
136 else {
137 // do nothing, timer already running
138 }
139 }
140 else {
141 impl->m_TabSwitchTimer->stop();
142 }
143
144 impl->m_ScrollButtonsTimer->stop();
145 }
146 else {
147 // The mouse is over a scroll button
148 // click it in a loop with a timer
149 if (!impl->m_ScrollButtonsTimer->isActive()
150 || impl->m_HoveredScrollButton != scrollButton) {
151 impl->m_HoveredScrollButton = scrollButton;
152 impl->m_ScrollButtonsTimer->start();
153 }
154 }
155 }
156 }
157 else if (event->type() == QEvent::DragEnter) {
158 QWidget *w = static_cast<QWidget *>(obj);
159
160 for (auto tabBar : impl->m_TabBarList) {
161 if (w == tabBar) {
162 auto enterEvent = static_cast<QDragEnterEvent *>(event);
163 enterEvent->acceptProposedAction();
164 enterEvent->setDropAction(Qt::IgnoreAction);
165 impl->m_CurrentTabBar = tabBar;
166 break;
167 }
168 }
169 }
170 else if (event->type() == QEvent::DragLeave || event->type() == QEvent::Drop) {
171 if (impl->m_CurrentTabBar) {
172 impl->m_HoveredTabIndex = -1;
173 impl->m_TabSwitchTimer->stop();
174 impl->m_CurrentTabBar = nullptr;
175 impl->m_ScrollButtonsTimer->stop();
176 }
177 }
178
179 return false;
180 }
@@ -0,0 +1,13
1 #include "Variable/VariableInspectorTableView.h"
2
3 #include "DragAndDrop/DragDropHelper.h"
4 #include "SqpApplication.h"
5
6 VariableInspectorTableView::VariableInspectorTableView(QWidget *parent) : QTableView(parent) {}
7
8 void VariableInspectorTableView::startDrag(Qt::DropActions supportedActions)
9 {
10 // Resets the drag&drop operations before it's starting
11 sqpApp->dragDropHelper().resetDragAndDrop();
12 QTableView::startDrag(supportedActions);
13 }
@@ -64,8 +64,11 public:
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 QByteArray mimeDataForProductsData(const QVariantList &productsData) const;
67 /// Returns the MIME data associated to a list of product meta data
68 QVariantList productsDataForMimeData(const QByteArray &mimeData) const;
68 static QByteArray mimeDataForProductsData(const QVariantList &productsData);
69
70 /// Returns the list of meta data contained in a MIME data
71 static QVariantList productsDataForMimeData(const QByteArray &mimeData);
69
72
70 public slots:
73 public slots:
71 /// Manage init/end of the controller
74 /// Manage init/end of the controller
@@ -23,6 +23,12 public:
23
23
24 SqpRange dateTime() const noexcept;
24 SqpRange dateTime() const noexcept;
25
25
26 /// Returns the MIME data associated to a time range
27 static QByteArray mimeDataForTimeRange(const SqpRange &timeRange);
28
29 /// Returns the time range contained in a MIME data
30 static SqpRange timeRangeForMimeData(const QByteArray &mimeData);
31
26 signals:
32 signals:
27 /// Signal emitted to notify that time parameters has beed updated
33 /// Signal emitted to notify that time parameters has beed updated
28 void timeUpdated(SqpRange time);
34 void timeUpdated(SqpRange time);
@@ -68,7 +68,10 public:
68 */
68 */
69 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
69 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
70
70
71 /// Returns the MIME data associated to a list of variables
71 QByteArray mimeDataForVariables(const QList<std::shared_ptr<Variable> > &variables) const;
72 QByteArray mimeDataForVariables(const QList<std::shared_ptr<Variable> > &variables) const;
73
74 /// Returns the list of variables contained in a MIME data
72 QList<std::shared_ptr<Variable> > variablesForMimeData(const QByteArray &mimeData) const;
75 QList<std::shared_ptr<Variable> > variablesForMimeData(const QByteArray &mimeData) const;
73
76
74 static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange);
77 static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange);
@@ -3,7 +3,6 core_moc_headers = [
3 'include/Data/IDataProvider.h',
3 'include/Data/IDataProvider.h',
4 'include/DataSource/DataSourceController.h',
4 'include/DataSource/DataSourceController.h',
5 'include/DataSource/DataSourceItemAction.h',
5 'include/DataSource/DataSourceItemAction.h',
6 'include/DataSource/DataSourceWidget.h',
7 'include/Network/NetworkController.h',
6 'include/Network/NetworkController.h',
8 'include/Time/TimeController.h',
7 'include/Time/TimeController.h',
9 'include/Variable/Variable.h',
8 'include/Variable/Variable.h',
@@ -32,7 +31,6 core_sources = [
32 'src/DataSource/DataSourceController.cpp',
31 'src/DataSource/DataSourceController.cpp',
33 'src/DataSource/DataSourceItem.cpp',
32 'src/DataSource/DataSourceItem.cpp',
34 'src/DataSource/DataSourceItemAction.cpp',
33 'src/DataSource/DataSourceItemAction.cpp',
35 'src/DataSource/DataSourceWidget.cpp',
36 'src/Network/NetworkController.cpp',
34 'src/Network/NetworkController.cpp',
37 'src/Plugin/PluginManager.cpp',
35 'src/Plugin/PluginManager.cpp',
38 'src/Settings/SqpSettingsDefs.cpp',
36 'src/Settings/SqpSettingsDefs.cpp',
@@ -139,7 +139,7 void DataSourceController::loadProductItem(const QUuid &dataSourceUid,
139 }
139 }
140 }
140 }
141
141
142 QByteArray DataSourceController::mimeDataForProductsData(const QVariantList &productsData) const
142 QByteArray DataSourceController::mimeDataForProductsData(const QVariantList &productsData)
143 {
143 {
144 QByteArray encodedData;
144 QByteArray encodedData;
145 QDataStream stream{&encodedData, QIODevice::WriteOnly};
145 QDataStream stream{&encodedData, QIODevice::WriteOnly};
@@ -149,7 +149,7 QByteArray DataSourceController::mimeDataForProductsData(const QVariantList &pro
149 return encodedData;
149 return encodedData;
150 }
150 }
151
151
152 QVariantList DataSourceController::productsDataForMimeData(const QByteArray &mimeData) const
152 QVariantList DataSourceController::productsDataForMimeData(const QByteArray &mimeData)
153 {
153 {
154 QDataStream stream{mimeData};
154 QDataStream stream{mimeData};
155
155
@@ -174,7 +174,7 void DataSourceController::finalize()
174
174
175 void DataSourceController::requestVariable(const QVariantHash &productData)
175 void DataSourceController::requestVariable(const QVariantHash &productData)
176 {
176 {
177 DataSourceItem *sourceItem = impl->findDataSourceItem(productData);
177 auto sourceItem = impl->findDataSourceItem(productData);
178
178
179 if (sourceItem) {
179 if (sourceItem) {
180 auto sourceName = sourceItem->rootItem().name();
180 auto sourceName = sourceItem->rootItem().name();
@@ -131,8 +131,7 DataSourceItem *DataSourceItem::findItem(const QVariantHash &data, bool recursiv
131 }
131 }
132
132
133 if (recursive) {
133 if (recursive) {
134 auto foundItem = child->findItem(data, true);
134 if (auto foundItem = child->findItem(data, true)) {
135 if (foundItem) {
136 return foundItem;
135 return foundItem;
137 }
136 }
138 }
137 }
@@ -1,5 +1,7
1 #include "Time/TimeController.h"
1 #include "Time/TimeController.h"
2
2
3 #include <QDataStream>
4
3 Q_LOGGING_CATEGORY(LOG_TimeController, "TimeController")
5 Q_LOGGING_CATEGORY(LOG_TimeController, "TimeController")
4
6
5 struct TimeController::TimeControllerPrivate {
7 struct TimeController::TimeControllerPrivate {
@@ -18,6 +20,26 SqpRange TimeController::dateTime() const noexcept
18 return impl->m_DateTime;
20 return impl->m_DateTime;
19 }
21 }
20
22
23 QByteArray TimeController::mimeDataForTimeRange(const SqpRange &timeRange)
24 {
25 QByteArray encodedData;
26 QDataStream stream{&encodedData, QIODevice::WriteOnly};
27
28 stream << timeRange.m_TStart << timeRange.m_TEnd;
29
30 return encodedData;
31 }
32
33 SqpRange TimeController::timeRangeForMimeData(const QByteArray &mimeData)
34 {
35 QDataStream stream{mimeData};
36
37 SqpRange timeRange;
38 stream >> timeRange.m_TStart >> timeRange.m_TEnd;
39
40 return timeRange;
41 }
42
21 void TimeController::onTimeToUpdate(SqpRange dateTime)
43 void TimeController::onTimeToUpdate(SqpRange dateTime)
22 {
44 {
23 impl->m_DateTime = dateTime;
45 impl->m_DateTime = dateTime;
@@ -8,7 +8,9
8
8
9 #include <Data/IDataSeries.h>
9 #include <Data/IDataSeries.h>
10
10
11 #include <QDataStream>
11 #include <DataSource/DataSourceController.h>
12 #include <Time/TimeController.h>
13
12 #include <QMimeData>
14 #include <QMimeData>
13 #include <QSize>
15 #include <QSize>
14 #include <unordered_map>
16 #include <unordered_map>
@@ -278,7 +280,7 Qt::DropActions VariableModel::supportedDragActions() const
278
280
279 QStringList VariableModel::mimeTypes() const
281 QStringList VariableModel::mimeTypes() const
280 {
282 {
281 return {MIME_TYPE_VARIABLE_LIST};
283 return {MIME_TYPE_VARIABLE_LIST, MIME_TYPE_TIME_RANGE};
282 }
284 }
283
285
284 QMimeData *VariableModel::mimeData(const QModelIndexList &indexes) const
286 QMimeData *VariableModel::mimeData(const QModelIndexList &indexes) const
@@ -287,17 +289,31 QMimeData *VariableModel::mimeData(const QModelIndexList &indexes) const
287
289
288 QList<std::shared_ptr<Variable> > variableList;
290 QList<std::shared_ptr<Variable> > variableList;
289
291
292
293 SqpRange firstTimeRange;
290 for (const auto &index : indexes) {
294 for (const auto &index : indexes) {
291 if (index.column() == 0) { // only the first column
295 if (index.column() == 0) { // only the first column
292 auto variable = impl->m_Variables.at(index.row());
296 auto variable = impl->m_Variables.at(index.row());
293 if (variable.get() && index.isValid()) {
297 if (variable.get() && index.isValid()) {
298
299 if (variableList.isEmpty()) {
300 // Gets the range of the first variable
301 firstTimeRange = std::move(variable->range());
302 }
303
294 variableList << variable;
304 variableList << variable;
295 }
305 }
296 }
306 }
297 }
307 }
298
308
299 auto encodedData = impl->m_VariableController->mimeDataForVariables(variableList);
309 auto variablesEncodedData = impl->m_VariableController->mimeDataForVariables(variableList);
300 mimeData->setData(MIME_TYPE_VARIABLE_LIST, encodedData);
310 mimeData->setData(MIME_TYPE_VARIABLE_LIST, variablesEncodedData);
311
312 if (variableList.count() == 1) {
313 // No time range MIME data if multiple variables are dragged
314 auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
315 mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
316 }
301
317
302 return mimeData;
318 return mimeData;
303 }
319 }
@@ -312,13 +328,12 bool VariableModel::canDropMimeData(const QMimeData *data, Qt::DropAction action
312 bool VariableModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
328 bool VariableModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
313 const QModelIndex &parent)
329 const QModelIndex &parent)
314 {
330 {
315 bool dropDone = false;
331 auto dropDone = false;
316
332
317 if (data->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
333 if (data->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
318 QDataStream stream(data->data(MIME_TYPE_PRODUCT_LIST));
319
334
320 QVariantList productList;
335 auto productList
321 stream >> productList;
336 = DataSourceController::productsDataForMimeData(data->data(MIME_TYPE_PRODUCT_LIST));
322
337
323 for (auto metaData : productList) {
338 for (auto metaData : productList) {
324 emit requestVariable(metaData.toHash());
339 emit requestVariable(metaData.toHash());
@@ -14,10 +14,18 tests = [
14 [['Variable/TestVariableSync.cpp'],'test_variable_sync','Variable synchronization test']
14 [['Variable/TestVariableSync.cpp'],'test_variable_sync','Variable synchronization test']
15 ]
15 ]
16
16
17 amdatest_sources = [
18 'Data/DataSeriesBuilders.h',
19 'Data/DataSeriesBuilders.cpp',
20 'Data/DataSeriesUtils.h',
21 'Data/DataSeriesUtils.cpp'
22 ]
23
17 foreach unit_test : tests
24 foreach unit_test : tests
18 test_moc_files = qt5.preprocess(moc_sources : unit_test[0])
25 test_moc_files = qt5.preprocess(moc_sources : unit_test[0])
19 test_exe = executable(unit_test[1],unit_test[0] , test_moc_files,
26 test_exe = executable(unit_test[1],unit_test[0] , test_moc_files,
20 dependencies : [sciqlop_core, qt5test])
27 dependencies : [sciqlop_core, qt5test],
28 sources : [amdatest_sources])
21 test(unit_test[2], test_exe, args: ['-teamcity', '-o', '@0@.teamcity.txt'.format(unit_test[1])])
29 test(unit_test[2], test_exe, args: ['-teamcity', '-o', '@0@.teamcity.txt'.format(unit_test[1])])
22 endforeach
30 endforeach
23
31
@@ -9,6 +9,7 public:
9
9
10 protected:
10 protected:
11 QMimeData *mimeData(const QList<QTreeWidgetItem *> items) const override;
11 QMimeData *mimeData(const QList<QTreeWidgetItem *> items) const override;
12 void startDrag(Qt::DropActions supportedActions) override;
12 };
13 };
13
14
14 #endif // SCIQLOP_DATASOURCETREEWIDGET_H
15 #endif // SCIQLOP_DATASOURCETREEWIDGET_H
@@ -7,6 +7,7
7
7
8 class QVBoxLayout;
8 class QVBoxLayout;
9 class QScrollArea;
9 class QScrollArea;
10 class QTabBar;
10 class VisualizationDragWidget;
11 class VisualizationDragWidget;
11 class VisualizationDragDropContainer;
12 class VisualizationDragDropContainer;
12 class QMimeData;
13 class QMimeData;
@@ -25,6 +26,8 public:
25 static const QString MIME_TYPE_GRAPH;
26 static const QString MIME_TYPE_GRAPH;
26 static const QString MIME_TYPE_ZONE;
27 static const QString MIME_TYPE_ZONE;
27
28
29 enum class PlaceHolderType { Default, Graph, Zone };
30
28 DragDropHelper();
31 DragDropHelper();
29 virtual ~DragDropHelper();
32 virtual ~DragDropHelper();
30
33
@@ -40,7 +43,8 public:
40 VisualizationDragWidget *getCurrentDragWidget() const;
43 VisualizationDragWidget *getCurrentDragWidget() const;
41
44
42 QWidget &placeHolder() const;
45 QWidget &placeHolder() const;
43 void insertPlaceHolder(QVBoxLayout *layout, int index);
46 void insertPlaceHolder(QVBoxLayout *layout, int index, PlaceHolderType type,
47 const QString &topLabelText);
44 void removePlaceHolder();
48 void removePlaceHolder();
45 bool isPlaceHolderSet() const;
49 bool isPlaceHolderSet() const;
46
50
@@ -51,35 +55,17 public:
51 void addDragDropScrollArea(QScrollArea *scrollArea);
55 void addDragDropScrollArea(QScrollArea *scrollArea);
52 void removeDragDropScrollArea(QScrollArea *scrollArea);
56 void removeDragDropScrollArea(QScrollArea *scrollArea);
53
57
58 void addDragDropTabBar(QTabBar *tabBar);
59 void removeDragDropTabBar(QTabBar *tabBar);
60
54 QUrl imageTemporaryUrl(const QImage &image) const;
61 QUrl imageTemporaryUrl(const QImage &image) const;
55
62
63 void setHightlightedDragWidget(VisualizationDragWidget *dragWidget);
64 VisualizationDragWidget *getHightlightedDragWidget() const;
65
56 private:
66 private:
57 class DragDropHelperPrivate;
67 class DragDropHelperPrivate;
58 spimpl::unique_impl_ptr<DragDropHelperPrivate> impl;
68 spimpl::unique_impl_ptr<DragDropHelperPrivate> impl;
59 };
69 };
60
70
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
85 #endif // SCIQLOP_DRAGDROPHELPER_H
71 #endif // SCIQLOP_DRAGDROPHELPER_H
@@ -5,6 +5,8
5
5
6 #include <Data/SqpRange.h>
6 #include <Data/SqpRange.h>
7
7
8 #include <Common/spimpl.h>
9
8 namespace Ui {
10 namespace Ui {
9 class TimeWidget;
11 class TimeWidget;
10 } // Ui
12 } // Ui
@@ -16,6 +18,9 public:
16 explicit TimeWidget(QWidget *parent = 0);
18 explicit TimeWidget(QWidget *parent = 0);
17 virtual ~TimeWidget();
19 virtual ~TimeWidget();
18
20
21 void setTimeRange(SqpRange time);
22 SqpRange timeRange() const;
23
19 signals:
24 signals:
20 /// Signal emitted when the time parameters has beed updated
25 /// Signal emitted when the time parameters has beed updated
21 void timeUpdated(SqpRange time);
26 void timeUpdated(SqpRange time);
@@ -24,9 +29,19 public slots:
24 /// slot called when time parameters update has ben requested
29 /// slot called when time parameters update has ben requested
25 void onTimeUpdateRequested();
30 void onTimeUpdateRequested();
26
31
32 protected:
33 void dragEnterEvent(QDragEnterEvent *event) override;
34 void dragLeaveEvent(QDragLeaveEvent *event) override;
35 void dropEvent(QDropEvent *event) override;
36
37 void mousePressEvent(QMouseEvent *event) override;
38 void mouseMoveEvent(QMouseEvent *event) override;
27
39
28 private:
40 private:
29 Ui::TimeWidget *ui;
41 Ui::TimeWidget *ui;
42
43 class TimeWidgetPrivate;
44 spimpl::unique_impl_ptr<TimeWidgetPrivate> impl;
30 };
45 };
31
46
32 #endif // SCIQLOP_ SQPSIDEPANE_H
47 #endif // SCIQLOP_ SQPSIDEPANE_H
@@ -2,24 +2,28
2 #define SCIQLOP_VISUALIZATIONDRAGDROPCONTAINER_H
2 #define SCIQLOP_VISUALIZATIONDRAGDROPCONTAINER_H
3
3
4 #include <Common/spimpl.h>
4 #include <Common/spimpl.h>
5 #include <QFrame>
5 #include <QLoggingCategory>
6 #include <QLoggingCategory>
6 #include <QMimeData>
7 #include <QMimeData>
7 #include <QVBoxLayout>
8 #include <QVBoxLayout>
8 #include <QWidget>
9
9
10 #include <functional>
10 #include <functional>
11
11
12 #include <DragAndDrop/DragDropHelper.h>
13
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer)
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer)
13
15
14 class VisualizationDragWidget;
16 class VisualizationDragWidget;
15
17
16 class VisualizationDragDropContainer : public QWidget {
18 class VisualizationDragDropContainer : public QFrame {
17 Q_OBJECT
19 Q_OBJECT
18
20
19 signals:
21 signals:
20 void dropOccured(int dropIndex, const QMimeData *mimeData);
22 void dropOccuredInContainer(int dropIndex, const QMimeData *mimeData);
23 void dropOccuredOnWidget(VisualizationDragWidget *dragWidget, const QMimeData *mimeData);
21
24
22 public:
25 public:
26 enum class DropBehavior { Inserted, Merged, InsertedAndMerged };
23 using AcceptMimeDataFunction = std::function<bool(const QMimeData *mimeData)>;
27 using AcceptMimeDataFunction = std::function<bool(const QMimeData *mimeData)>;
24
28
25 VisualizationDragDropContainer(QWidget *parent = nullptr);
29 VisualizationDragDropContainer(QWidget *parent = nullptr);
@@ -27,13 +31,15 public:
27 void addDragWidget(VisualizationDragWidget *dragWidget);
31 void addDragWidget(VisualizationDragWidget *dragWidget);
28 void insertDragWidget(int index, VisualizationDragWidget *dragWidget);
32 void insertDragWidget(int index, VisualizationDragWidget *dragWidget);
29
33
30 void setAcceptedMimeTypes(const QStringList &mimeTypes);
34 void addAcceptedMimeType(const QString &mimeType, DropBehavior behavior);
31 void setMergeAllowedMimeTypes(const QStringList &mimeTypes);
32
35
33 int countDragWidget() const;
36 int countDragWidget() const;
34
37
35 void setAcceptMimeDataFunction(AcceptMimeDataFunction fun);
38 void setAcceptMimeDataFunction(AcceptMimeDataFunction fun);
36
39
40 void setPlaceHolderType(DragDropHelper::PlaceHolderType type,
41 const QString &placeHolderText = QString());
42
37 protected:
43 protected:
38 void dragEnterEvent(QDragEnterEvent *event);
44 void dragEnterEvent(QDragEnterEvent *event);
39 void dragLeaveEvent(QDragLeaveEvent *event);
45 void dragLeaveEvent(QDragLeaveEvent *event);
@@ -13,6 +13,7 public:
13
13
14 virtual QMimeData *mimeData() const = 0;
14 virtual QMimeData *mimeData() const = 0;
15 virtual bool isDragAllowed() const = 0;
15 virtual bool isDragAllowed() const = 0;
16 virtual void highlightForMerge(bool highlighted) { Q_UNUSED(highlighted); };
16
17
17 protected:
18 protected:
18 virtual void mousePressEvent(QMouseEvent *event) override;
19 virtual void mousePressEvent(QMouseEvent *event) override;
@@ -59,6 +59,7 public:
59 // VisualisationDragWidget
59 // VisualisationDragWidget
60 QMimeData *mimeData() const override;
60 QMimeData *mimeData() const override;
61 bool isDragAllowed() const override;
61 bool isDragAllowed() const override;
62 void highlightForMerge(bool highlighted) override;
62
63
63 signals:
64 signals:
64 void synchronize(const SqpRange &range, const SqpRange &oldRange);
65 void synchronize(const SqpRange &range, const SqpRange &oldRange);
@@ -85,6 +85,7 private slots:
85 void onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable);
85 void onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable);
86
86
87 void dropMimeData(int index, const QMimeData *mimeData);
87 void dropMimeData(int index, const QMimeData *mimeData);
88 void dropMimeDataOnGraph(VisualizationDragWidget *dragWidget, const QMimeData *mimeData);
88 };
89 };
89
90
90 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
91 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -1,13 +1,17
1
1
2 gui_moc_headers = [
2 gui_moc_headers = [
3 'include/DataSource/DataSourceWidget.h',
3 'include/DataSource/DataSourceWidget.h',
4 'include/DataSource/DataSourceTreeWidget.h',
4 'include/Settings/SqpSettingsDialog.h',
5 'include/Settings/SqpSettingsDialog.h',
5 'include/Settings/SqpSettingsGeneralWidget.h',
6 'include/Settings/SqpSettingsGeneralWidget.h',
6 'include/SidePane/SqpSidePane.h',
7 'include/SidePane/SqpSidePane.h',
7 'include/SqpApplication.h',
8 'include/SqpApplication.h',
8 'include/DragDropHelper.h',
9 'include/DragAndDrop/DragDropHelper.h',
10 'include/DragAndDrop/DragDropScroller.h',
11 'include/DragAndDrop/DragDropTabSwitcher.h',
9 'include/TimeWidget/TimeWidget.h',
12 'include/TimeWidget/TimeWidget.h',
10 'include/Variable/VariableInspectorWidget.h',
13 'include/Variable/VariableInspectorWidget.h',
14 'include/Variable/VariableInspectorTableView.h',
11 'include/Variable/RenameVariableDialog.h',
15 'include/Variable/RenameVariableDialog.h',
12 'include/Visualization/qcustomplot.h',
16 'include/Visualization/qcustomplot.h',
13 'include/Visualization/VisualizationGraphWidget.h',
17 'include/Visualization/VisualizationGraphWidget.h',
@@ -41,17 +45,21 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers,
41
45
42 gui_sources = [
46 gui_sources = [
43 'src/SqpApplication.cpp',
47 'src/SqpApplication.cpp',
44 'src/DragDropHelper.cpp',
48 'src/DragAndDrop/DragDropHelper.cpp',
49 'src/DragAndDrop/DragDropScroller.cpp',
50 'src/DragAndDrop/DragDropTabSwitcher.cpp',
45 'src/Common/ColorUtils.cpp',
51 'src/Common/ColorUtils.cpp',
46 'src/Common/VisualizationDef.cpp',
52 'src/Common/VisualizationDef.cpp',
47 'src/DataSource/DataSourceTreeWidgetItem.cpp',
53 'src/DataSource/DataSourceTreeWidgetItem.cpp',
48 'src/DataSource/DataSourceTreeWidgetHelper.cpp',
54 'src/DataSource/DataSourceTreeWidgetHelper.cpp',
49 'src/DataSource/DataSourceWidget.cpp',
55 'src/DataSource/DataSourceWidget.cpp',
56 'src/DataSource/DataSourceTreeWidget.cpp',
50 'src/Settings/SqpSettingsDialog.cpp',
57 'src/Settings/SqpSettingsDialog.cpp',
51 'src/Settings/SqpSettingsGeneralWidget.cpp',
58 'src/Settings/SqpSettingsGeneralWidget.cpp',
52 'src/SidePane/SqpSidePane.cpp',
59 'src/SidePane/SqpSidePane.cpp',
53 'src/TimeWidget/TimeWidget.cpp',
60 'src/TimeWidget/TimeWidget.cpp',
54 'src/Variable/VariableInspectorWidget.cpp',
61 'src/Variable/VariableInspectorWidget.cpp',
62 'src/Variable/VariableInspectorTableView.cpp',
55 'src/Variable/VariableMenuHeaderWidget.cpp',
63 'src/Variable/VariableMenuHeaderWidget.cpp',
56 'src/Variable/RenameVariableDialog.cpp',
64 'src/Variable/RenameVariableDialog.cpp',
57 'src/Visualization/VisualizationGraphHelper.cpp',
65 'src/Visualization/VisualizationGraphHelper.cpp',
@@ -4,6 +4,7
4 #include "DataSource/DataSourceItem.h"
4 #include "DataSource/DataSourceItem.h"
5 #include "DataSource/DataSourceTreeWidgetItem.h"
5 #include "DataSource/DataSourceTreeWidgetItem.h"
6
6
7 #include "DragAndDrop/DragDropHelper.h"
7 #include "SqpApplication.h"
8 #include "SqpApplication.h"
8
9
9 #include <QMimeData>
10 #include <QMimeData>
@@ -35,3 +36,10 QMimeData *DataSourceTreeWidget::mimeData(const QList<QTreeWidgetItem *> items)
35
36
36 return mimeData;
37 return mimeData;
37 }
38 }
39
40 void DataSourceTreeWidget::startDrag(Qt::DropActions supportedActions)
41 {
42 // Resets the drag&drop operations before it's starting
43 sqpApp->dragDropHelper().resetDragAndDrop();
44 QTreeWidget::startDrag(supportedActions);
45 }
@@ -1,35 +1,19
1 #include "DragDropHelper.h"
1 #include "DragAndDrop/DragDropScroller.h"
2 #include "SqpApplication.h"
3 #include "Visualization/VisualizationDragDropContainer.h"
4 #include "Visualization/VisualizationDragWidget.h"
5 #include "Visualization/VisualizationWidget.h"
6 #include "Visualization/operations/FindVariableOperation.h"
7
2
8 #include "Variable/VariableController.h"
9
10 #include "Common/MimeTypesDef.h"
11 #include "Common/VisualizationDef.h"
12
13 #include <QDir>
14 #include <QDragEnterEvent>
3 #include <QDragEnterEvent>
15 #include <QDragMoveEvent>
4 #include <QDragMoveEvent>
16 #include <QScrollArea>
17 #include <QScrollBar>
5 #include <QScrollBar>
18 #include <QTimer>
6 #include <QTimer>
19 #include <QVBoxLayout>
20
7
21 const int SCROLL_SPEED = 5;
8 const int SCROLL_SPEED = 5;
22 const int SCROLL_ZONE_SIZE = 50;
9 const int SCROLL_ZONE_SIZE = 50;
23
10
24 Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDrophelper")
25
26 struct DragDropScroller::DragDropScrollerPrivate {
11 struct DragDropScroller::DragDropScrollerPrivate {
27
12
28 QList<QScrollArea *> m_ScrollAreas;
13 QList<QScrollArea *> m_ScrollAreas;
29 QScrollArea *m_CurrentScrollArea = nullptr;
14 QScrollArea *m_CurrentScrollArea = nullptr;
30 std::unique_ptr<QTimer> m_Timer = nullptr;
15 std::unique_ptr<QTimer> m_Timer = nullptr;
31
16
32
33 enum class ScrollDirection { up, down, unknown };
17 enum class ScrollDirection { up, down, unknown };
34 ScrollDirection m_Direction = ScrollDirection::unknown;
18 ScrollDirection m_Direction = ScrollDirection::unknown;
35
19
@@ -139,157 +123,3 void DragDropScroller::onTimer()
139 impl->m_CurrentScrollArea->verticalScrollBar()->value() + mvt);
123 impl->m_CurrentScrollArea->verticalScrollBar()->value() + mvt);
140 }
124 }
141 }
125 }
142
143 struct DragDropHelper::DragDropHelperPrivate {
144
145 VisualizationDragWidget *m_CurrentDragWidget = nullptr;
146 std::unique_ptr<QWidget> m_PlaceHolder = nullptr;
147 std::unique_ptr<DragDropScroller> m_DragDropScroller = nullptr;
148 QString m_ImageTempUrl; // Temporary file for image url generated by the drag & drop. Not using
149 // QTemporaryFile to have a name which is not generated.
150
151 explicit DragDropHelperPrivate()
152 : m_PlaceHolder{std::make_unique<QWidget>()},
153 m_DragDropScroller{std::make_unique<DragDropScroller>()}
154 {
155 m_PlaceHolder->setStyleSheet("background-color: #BBD5EE; border:2px solid #2A7FD4");
156 sqpApp->installEventFilter(m_DragDropScroller.get());
157
158
159 m_ImageTempUrl = QDir::temp().absoluteFilePath("Scqlop_graph.png");
160 }
161
162 void preparePlaceHolder() const
163 {
164 if (m_CurrentDragWidget) {
165 m_PlaceHolder->setMinimumSize(m_CurrentDragWidget->size());
166 m_PlaceHolder->setSizePolicy(m_CurrentDragWidget->sizePolicy());
167 }
168 else {
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);
174 }
175 }
176 };
177
178
179 DragDropHelper::DragDropHelper() : impl{spimpl::make_unique_impl<DragDropHelperPrivate>()}
180 {
181 }
182
183 DragDropHelper::~DragDropHelper()
184 {
185 QFile::remove(impl->m_ImageTempUrl);
186 }
187
188 void DragDropHelper::resetDragAndDrop()
189 {
190 setCurrentDragWidget(nullptr);
191 }
192
193 void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget)
194 {
195 impl->m_CurrentDragWidget = dragWidget;
196 }
197
198 VisualizationDragWidget *DragDropHelper::getCurrentDragWidget() const
199 {
200 return impl->m_CurrentDragWidget;
201 }
202
203
204 QWidget &DragDropHelper::placeHolder() const
205 {
206 return *impl->m_PlaceHolder;
207 }
208
209 void DragDropHelper::insertPlaceHolder(QVBoxLayout *layout, int index)
210 {
211 removePlaceHolder();
212 impl->preparePlaceHolder();
213 layout->insertWidget(index, impl->m_PlaceHolder.get());
214 impl->m_PlaceHolder->show();
215 }
216
217 void DragDropHelper::removePlaceHolder()
218 {
219 auto parentWidget = impl->m_PlaceHolder->parentWidget();
220 if (parentWidget) {
221 parentWidget->layout()->removeWidget(impl->m_PlaceHolder.get());
222 impl->m_PlaceHolder->setParent(nullptr);
223 impl->m_PlaceHolder->hide();
224 }
225 }
226
227 bool DragDropHelper::isPlaceHolderSet() const
228 {
229 return impl->m_PlaceHolder->parentWidget();
230 }
231
232 void DragDropHelper::addDragDropScrollArea(QScrollArea *scrollArea)
233 {
234 impl->m_DragDropScroller->addScrollArea(scrollArea);
235 }
236
237 void DragDropHelper::removeDragDropScrollArea(QScrollArea *scrollArea)
238 {
239 impl->m_DragDropScroller->removeScrollArea(scrollArea);
240 }
241
242 QUrl DragDropHelper::imageTemporaryUrl(const QImage &image) const
243 {
244 image.save(impl->m_ImageTempUrl);
245 return QUrl::fromLocalFile(impl->m_ImageTempUrl);
246 }
247
248 bool DragDropHelper::checkMimeDataForVisualization(const QMimeData *mimeData,
249 VisualizationDragDropContainer *dropContainer)
250 {
251 if (!mimeData || !dropContainer) {
252 qCWarning(LOG_DragDropHelper()) << QObject::tr(
253 "DragDropHelper::checkMimeDataForVisualization, invalid input parameters.");
254 Q_ASSERT(false);
255 }
256
257 auto result = true;
258
259 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
260 auto variables = sqpApp->variableController().variablesForMimeData(
261 mimeData->data(MIME_TYPE_VARIABLE_LIST));
262
263 if (variables.count() == 1) {
264 // Check that the viariable is not already in a graph
265
266 // Search for the top level VisualizationWidget
267 auto parent = dropContainer->parentWidget();
268 while (parent && qobject_cast<VisualizationWidget *>(parent) == nullptr) {
269 parent = parent->parentWidget();
270 }
271
272 if (parent) {
273 auto visualizationWidget = static_cast<VisualizationWidget *>(parent);
274
275 FindVariableOperation findVariableOperation{variables.first()};
276 visualizationWidget->accept(&findVariableOperation);
277 auto variableContainers = findVariableOperation.result();
278 if (!variableContainers.empty()) {
279 result = false;
280 }
281 }
282 else {
283 qCWarning(LOG_DragDropHelper()) << QObject::tr(
284 "DragDropHelper::checkMimeDataForVisualization, the parent "
285 "VisualizationWidget cannot be found.");
286 result = false;
287 }
288 }
289 else {
290 result = false;
291 }
292 }
293
294 return result;
295 }
@@ -2,7 +2,7
2
2
3 #include <Data/IDataProvider.h>
3 #include <Data/IDataProvider.h>
4 #include <DataSource/DataSourceController.h>
4 #include <DataSource/DataSourceController.h>
5 #include <DragDropHelper.h>
5 #include <DragAndDrop/DragDropHelper.h>
6 #include <Network/NetworkController.h>
6 #include <Network/NetworkController.h>
7 #include <QThread>
7 #include <QThread>
8 #include <Time/TimeController.h>
8 #include <Time/TimeController.h>
@@ -2,10 +2,29
2 #include "ui_TimeWidget.h"
2 #include "ui_TimeWidget.h"
3
3
4 #include <Common/DateUtils.h>
4 #include <Common/DateUtils.h>
5 #include <Common/MimeTypesDef.h>
6
7 #include <DragAndDrop/DragDropHelper.h>
5 #include <SqpApplication.h>
8 #include <SqpApplication.h>
6 #include <Time/TimeController.h>
9 #include <Time/TimeController.h>
7
10
8 TimeWidget::TimeWidget(QWidget *parent) : QWidget{parent}, ui{new Ui::TimeWidget}
11 #include <QDrag>
12 #include <QDragEnterEvent>
13 #include <QDropEvent>
14 #include <QMimeData>
15
16
17 struct TimeWidget::TimeWidgetPrivate {
18
19 explicit TimeWidgetPrivate() {}
20
21 QPoint m_DragStartPosition;
22 };
23
24 TimeWidget::TimeWidget(QWidget *parent)
25 : QWidget{parent},
26 ui{new Ui::TimeWidget},
27 impl{spimpl::make_unique_impl<TimeWidgetPrivate>()}
9 {
28 {
10 ui->setupUi(this);
29 ui->setupUi(this);
11
30
@@ -41,10 +60,97 TimeWidget::~TimeWidget()
41 delete ui;
60 delete ui;
42 }
61 }
43
62
44 void TimeWidget::onTimeUpdateRequested()
63 void TimeWidget::setTimeRange(SqpRange time)
64 {
65 auto startDateTime = DateUtils::dateTime(time.m_TStart);
66 auto endDateTime = DateUtils::dateTime(time.m_TEnd);
67
68 ui->startDateTimeEdit->setDateTime(startDateTime);
69 ui->endDateTimeEdit->setDateTime(endDateTime);
70 }
71
72 SqpRange TimeWidget::timeRange() const
45 {
73 {
46 auto dateTime = SqpRange{DateUtils::secondsSinceEpoch(ui->startDateTimeEdit->dateTime()),
74 return SqpRange{DateUtils::secondsSinceEpoch(ui->startDateTimeEdit->dateTime()),
47 DateUtils::secondsSinceEpoch(ui->endDateTimeEdit->dateTime())};
75 DateUtils::secondsSinceEpoch(ui->endDateTimeEdit->dateTime())};
76 }
48
77
78 void TimeWidget::onTimeUpdateRequested()
79 {
80 auto dateTime = timeRange();
49 emit timeUpdated(std::move(dateTime));
81 emit timeUpdated(std::move(dateTime));
50 }
82 }
83
84 void TimeWidget::dragEnterEvent(QDragEnterEvent *event)
85 {
86 if (event->mimeData()->hasFormat(MIME_TYPE_TIME_RANGE)) {
87 event->acceptProposedAction();
88 setStyleSheet("QDateTimeEdit{background-color: #BBD5EE; border:2px solid #2A7FD4}");
89 }
90 else {
91 event->ignore();
92 }
93 }
94
95 void TimeWidget::dragLeaveEvent(QDragLeaveEvent *event)
96 {
97 setStyleSheet(QString());
98 }
99
100 void TimeWidget::dropEvent(QDropEvent *event)
101 {
102 if (event->mimeData()->hasFormat(MIME_TYPE_TIME_RANGE)) {
103 auto mimeData = event->mimeData()->data(MIME_TYPE_TIME_RANGE);
104 auto timeRange = TimeController::timeRangeForMimeData(mimeData);
105
106 setTimeRange(timeRange);
107 }
108 else {
109 event->ignore();
110 }
111
112 setStyleSheet(QString());
113 }
114
115
116 void TimeWidget::mousePressEvent(QMouseEvent *event)
117 {
118 if (event->button() == Qt::LeftButton) {
119 impl->m_DragStartPosition = event->pos();
120 }
121
122 QWidget::mousePressEvent(event);
123 }
124
125 void TimeWidget::mouseMoveEvent(QMouseEvent *event)
126 {
127 if (!(event->buttons() & Qt::LeftButton)) {
128 return;
129 }
130
131 if ((event->pos() - impl->m_DragStartPosition).manhattanLength()
132 < QApplication::startDragDistance()) {
133 return;
134 }
135
136 // Note: The management of the drag object is done by Qt
137 auto drag = new QDrag{this};
138
139 auto mimeData = new QMimeData;
140 auto timeData = TimeController::mimeDataForTimeRange(timeRange());
141 mimeData->setData(MIME_TYPE_TIME_RANGE, timeData);
142
143 drag->setMimeData(mimeData);
144
145 auto pixmap = QPixmap(size());
146 render(&pixmap);
147 drag->setPixmap(pixmap);
148 drag->setHotSpot(impl->m_DragStartPosition);
149
150 sqpApp->dragDropHelper().resetDragAndDrop();
151
152 // Note: The exec() is blocking on windows but not on linux and macOS
153 drag->exec(Qt::MoveAction | Qt::CopyAction);
154
155 QWidget::mouseMoveEvent(event);
156 }
@@ -12,7 +12,7
12 #include <QStyledItemDelegate>
12 #include <QStyledItemDelegate>
13 #include <QWidgetAction>
13 #include <QWidgetAction>
14
14
15 #include <DragDropHelper.h>
15 #include <DragAndDrop/DragDropHelper.h>
16 #include <SqpApplication.h>
16 #include <SqpApplication.h>
17
17
18 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
18 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
@@ -152,11 +152,6 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
152 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
152 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
153 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
153 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
154 &VariableInspectorWidget::onTableMenuRequested);
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(); });
160 }
155 }
161
156
162 VariableInspectorWidget::~VariableInspectorWidget()
157 VariableInspectorWidget::~VariableInspectorWidget()
@@ -1,5 +1,5
1 #include "Visualization/VisualizationDragDropContainer.h"
1 #include "Visualization/VisualizationDragDropContainer.h"
2 #include "DragDropHelper.h"
2 #include "DragAndDrop/DragDropHelper.h"
3 #include "SqpApplication.h"
3 #include "SqpApplication.h"
4 #include "Visualization/VisualizationDragWidget.h"
4 #include "Visualization/VisualizationDragWidget.h"
5
5
@@ -17,11 +17,15 Q_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer, "VisualizationDragDropCon
17 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
17 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
18
18
19 QVBoxLayout *m_Layout;
19 QVBoxLayout *m_Layout;
20 QStringList m_AcceptedMimeTypes;
20 QHash<QString, VisualizationDragDropContainer::DropBehavior> m_AcceptedMimeTypes;
21 QStringList m_MergeAllowedMimeTypes;
21 QString m_PlaceHolderText;
22 DragDropHelper::PlaceHolderType m_PlaceHolderType = DragDropHelper::PlaceHolderType::Graph;
23
22 VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun
24 VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun
23 = [](auto mimeData) { return true; };
25 = [](auto mimeData) { return true; };
24
26
27 int m_MinContainerHeight = 0;
28
25 explicit VisualizationDragDropContainerPrivate(QWidget *widget)
29 explicit VisualizationDragDropContainerPrivate(QWidget *widget)
26 {
30 {
27 m_Layout = new QVBoxLayout(widget);
31 m_Layout = new QVBoxLayout(widget);
@@ -30,7 +34,7 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
30
34
31 bool acceptMimeData(const QMimeData *data) const
35 bool acceptMimeData(const QMimeData *data) const
32 {
36 {
33 for (const auto &type : m_AcceptedMimeTypes) {
37 for (const auto &type : m_AcceptedMimeTypes.keys()) {
34 if (data->hasFormat(type) && m_AcceptMimeDataFun(data)) {
38 if (data->hasFormat(type) && m_AcceptMimeDataFun(data)) {
35 return true;
39 return true;
36 }
40 }
@@ -39,10 +43,38 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
39 return false;
43 return false;
40 }
44 }
41
45
42 bool allowMergeMimeData(const QMimeData *data) const
46 bool allowMergeForMimeData(const QMimeData *data) const
47 {
48 bool result = false;
49 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
50 ++it) {
51
52 if (data->hasFormat(it.key())
53 && (it.value() == VisualizationDragDropContainer::DropBehavior::Merged
54 || it.value()
55 == VisualizationDragDropContainer::DropBehavior::InsertedAndMerged)) {
56 result = true;
57 }
58 else if (data->hasFormat(it.key())
59 && it.value() == VisualizationDragDropContainer::DropBehavior::Inserted) {
60 // Merge is forbidden if the mime data contain an acceptable type which cannot be
61 // merged
62 result = false;
63 break;
64 }
65 }
66
67 return result;
68 }
69
70 bool allowInsertForMimeData(const QMimeData *data) const
43 {
71 {
44 for (const auto &type : m_MergeAllowedMimeTypes) {
72 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
45 if (data->hasFormat(type)) {
73 ++it) {
74 if (data->hasFormat(it.key())
75 && (it.value() == VisualizationDragDropContainer::DropBehavior::Inserted
76 || it.value()
77 == VisualizationDragDropContainer::DropBehavior::InsertedAndMerged)) {
46 return true;
78 return true;
47 }
79 }
48 }
80 }
@@ -55,7 +87,7 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
55 return sqpApp->dragDropHelper().placeHolder().parentWidget() == m_Layout->parentWidget();
87 return sqpApp->dragDropHelper().placeHolder().parentWidget() == m_Layout->parentWidget();
56 }
88 }
57
89
58 VisualizationDragWidget *getChildDragWidgetAt(QWidget *parent, const QPoint &pos) const
90 VisualizationDragWidget *getChildDragWidgetAt(const QWidget *parent, const QPoint &pos) const
59 {
91 {
60 VisualizationDragWidget *dragWidget = nullptr;
92 VisualizationDragWidget *dragWidget = nullptr;
61
93
@@ -74,15 +106,29 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
74
106
75 bool cursorIsInContainer(QWidget *container) const
107 bool cursorIsInContainer(QWidget *container) const
76 {
108 {
77 auto adustNum = 18; // to be safe, in case of scrollbar on the side
109 return container->isAncestorOf(sqpApp->widgetAt(QCursor::pos()));
78 auto containerRect = QRect(QPoint(), container->contentsRect().size())
110 }
79 .adjusted(adustNum, adustNum, -adustNum, -adustNum);
111
80 return containerRect.contains(container->mapFromGlobal(QCursor::pos()));
112 int countDragWidget(const QWidget *parent, bool onlyVisible = false) const
113 {
114 auto nbGraph = 0;
115 for (auto child : parent->children()) {
116 if (qobject_cast<VisualizationDragWidget *>(child)) {
117 if (!onlyVisible || qobject_cast<VisualizationDragWidget *>(child)->isVisible()) {
118 nbGraph += 1;
119 }
120 }
81 }
121 }
122
123 return nbGraph;
124 }
125
126 void findPlaceHolderPosition(const QPoint &pos, bool canInsert, bool canMerge,
127 const VisualizationDragDropContainer *container);
82 };
128 };
83
129
84 VisualizationDragDropContainer::VisualizationDragDropContainer(QWidget *parent)
130 VisualizationDragDropContainer::VisualizationDragDropContainer(QWidget *parent)
85 : QWidget{parent},
131 : QFrame{parent},
86 impl{spimpl::make_unique_impl<VisualizationDragDropContainerPrivate>(this)}
132 impl{spimpl::make_unique_impl<VisualizationDragDropContainerPrivate>(this)}
87 {
133 {
88 setAcceptDrops(true);
134 setAcceptDrops(true);
@@ -105,26 +151,15 void VisualizationDragDropContainer::insertDragWidget(int index,
105 &VisualizationDragDropContainer::startDrag);
151 &VisualizationDragDropContainer::startDrag);
106 }
152 }
107
153
108 void VisualizationDragDropContainer::setAcceptedMimeTypes(const QStringList &mimeTypes)
154 void VisualizationDragDropContainer::addAcceptedMimeType(
155 const QString &mimeType, VisualizationDragDropContainer::DropBehavior behavior)
109 {
156 {
110 impl->m_AcceptedMimeTypes = mimeTypes;
157 impl->m_AcceptedMimeTypes[mimeType] = behavior;
111 }
112
113 void VisualizationDragDropContainer::setMergeAllowedMimeTypes(const QStringList &mimeTypes)
114 {
115 impl->m_MergeAllowedMimeTypes = mimeTypes;
116 }
158 }
117
159
118 int VisualizationDragDropContainer::countDragWidget() const
160 int VisualizationDragDropContainer::countDragWidget() const
119 {
161 {
120 auto nbGraph = 0;
162 return impl->countDragWidget(this);
121 for (auto child : children()) {
122 if (qobject_cast<VisualizationDragWidget *>(child)) {
123 nbGraph += 1;
124 }
125 }
126
127 return nbGraph;
128 }
163 }
129
164
130 void VisualizationDragDropContainer::setAcceptMimeDataFunction(
165 void VisualizationDragDropContainer::setAcceptMimeDataFunction(
@@ -133,6 +168,13 void VisualizationDragDropContainer::setAcceptMimeDataFunction(
133 impl->m_AcceptMimeDataFun = fun;
168 impl->m_AcceptMimeDataFun = fun;
134 }
169 }
135
170
171 void VisualizationDragDropContainer::setPlaceHolderType(DragDropHelper::PlaceHolderType type,
172 const QString &placeHolderText)
173 {
174 impl->m_PlaceHolderType = type;
175 impl->m_PlaceHolderText = placeHolderText;
176 }
177
136 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget,
178 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget,
137 const QPoint &dragPosition)
179 const QPoint &dragPosition)
138 {
180 {
@@ -159,9 +201,14 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidg
159
201
160 if (impl->cursorIsInContainer(this)) {
202 if (impl->cursorIsInContainer(this)) {
161 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
203 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
162 helper.insertPlaceHolder(impl->m_Layout, dragWidgetIndex);
204 helper.insertPlaceHolder(impl->m_Layout, dragWidgetIndex, impl->m_PlaceHolderType,
205 impl->m_PlaceHolderText);
163 dragWidget->setVisible(false);
206 dragWidget->setVisible(false);
164 }
207 }
208 else {
209 // The drag starts directly outside the drop zone
210 // do not add the placeHolder
211 }
165
212
166 // Note: The exec() is blocking on windows but not on linux and macOS
213 // Note: The exec() is blocking on windows but not on linux and macOS
167 drag->exec(Qt::MoveAction | Qt::CopyAction);
214 drag->exec(Qt::MoveAction | Qt::CopyAction);
@@ -185,7 +232,7 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
185
232
186 if (dragWidget) {
233 if (dragWidget) {
187 // If the drag&drop is internal to the visualization, entering the container hide
234 // If the drag&drop is internal to the visualization, entering the container hide
188 // the dragWidget which was hidden by the dragLeaveEvent
235 // the dragWidget which was made visible by the dragLeaveEvent
189 auto parentWidget
236 auto parentWidget
190 = qobject_cast<VisualizationDragDropContainer *>(dragWidget->parentWidget());
237 = qobject_cast<VisualizationDragDropContainer *>(dragWidget->parentWidget());
191 if (parentWidget) {
238 if (parentWidget) {
@@ -193,26 +240,9 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
193 }
240 }
194 }
241 }
195
242
196 auto dragWidgetHovered = impl->getChildDragWidgetAt(this, event->pos());
243 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
197
244 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
198 if (dragWidgetHovered) {
245 impl->findPlaceHolderPosition(event->pos(), canInsert, canMerge, this);
199 auto hoveredWidgetIndex = impl->m_Layout->indexOf(dragWidgetHovered);
200
201 if (dragWidget) {
202 auto dragWidgetIndex = impl->m_Layout->indexOf(helper.getCurrentDragWidget());
203 if (dragWidgetIndex >= 0 && dragWidgetIndex <= hoveredWidgetIndex) {
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 }
209 }
210
211 helper.insertPlaceHolder(impl->m_Layout, hoveredWidgetIndex);
212 }
213 else {
214 helper.insertPlaceHolder(impl->m_Layout, 0);
215 }
216 }
246 }
217 else {
247 else {
218 // do nothing
248 // do nothing
@@ -233,6 +263,8 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event)
233
263
234 if (!impl->cursorIsInContainer(this)) {
264 if (!impl->cursorIsInContainer(this)) {
235 helper.removePlaceHolder();
265 helper.removePlaceHolder();
266 helper.setHightlightedDragWidget(nullptr);
267 impl->m_MinContainerHeight = 0;
236
268
237 auto dragWidget = helper.getCurrentDragWidget();
269 auto dragWidget = helper.getCurrentDragWidget();
238 if (dragWidget) {
270 if (dragWidget) {
@@ -258,105 +290,164 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event)
258 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event)
290 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event)
259 {
291 {
260 if (impl->acceptMimeData(event->mimeData())) {
292 if (impl->acceptMimeData(event->mimeData())) {
261 auto dragWidgetHovered = impl->getChildDragWidgetAt(this, event->pos());
293 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
262 if (dragWidgetHovered) {
294 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
263 auto canMerge = impl->allowMergeMimeData(event->mimeData());
295 impl->findPlaceHolderPosition(event->pos(), canInsert, canMerge, this);
264
296 }
265 auto nbDragWidget = countDragWidget();
297 else {
266 if (nbDragWidget > 0) {
298 event->ignore();
267 auto graphHeight = qMax(size().height() / nbDragWidget, GRAPH_MINIMUM_HEIGHT);
299 }
268
269 auto dropIndex = floor(event->pos().y() / graphHeight);
270 auto zoneSize = qMin(graphHeight / 3.0, 150.0);
271
300
272 auto isOnTop = event->pos().y() < dropIndex * graphHeight + zoneSize;
301 QWidget::dragMoveEvent(event);
273 auto isOnBottom = event->pos().y() > (dropIndex + 1) * graphHeight - zoneSize;
302 }
274
303
304 void VisualizationDragDropContainer::dropEvent(QDropEvent *event)
305 {
275 auto &helper = sqpApp->dragDropHelper();
306 auto &helper = sqpApp->dragDropHelper();
276 auto placeHolderIndex = impl->m_Layout->indexOf(&(helper.placeHolder()));
277
307
278 if (isOnTop || isOnBottom) {
308 if (impl->acceptMimeData(event->mimeData())) {
279 if (isOnBottom) {
309 auto dragWidget = helper.getCurrentDragWidget();
280 dropIndex += 1;
310 if (impl->hasPlaceHolder()) {
281 }
311 // drop where the placeHolder is located
282
312
283 if (helper.getCurrentDragWidget()) {
313 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
284 auto dragWidgetIndex
314 if (canInsert) {
285 = impl->m_Layout->indexOf(helper.getCurrentDragWidget());
315 auto droppedIndex = impl->m_Layout->indexOf(&helper.placeHolder());
286 if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) {
316
317 if (dragWidget) {
318 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
319 if (dragWidgetIndex >= 0 && dragWidgetIndex < droppedIndex) {
287 // Correction of the index if the drop occurs in the same container
320 // 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
321 // and if the drag is started from the visualization (in that case, the
289 // dragWidget is hidden)
322 // dragWidget is hidden)
290 dropIndex += 1;
323 droppedIndex -= 1;
291 }
292 }
324 }
293
325
294 if (dropIndex != placeHolderIndex) {
326 dragWidget->setVisible(true);
295 helper.insertPlaceHolder(impl->m_Layout, dropIndex);
296 }
297 }
327 }
298 else if (canMerge) {
328
299 // drop on the middle -> merge
329 event->acceptProposedAction();
300 if (impl->hasPlaceHolder()) {
330
301 helper.removePlaceHolder();
331 helper.removePlaceHolder();
332
333 emit dropOccuredInContainer(droppedIndex, event->mimeData());
302 }
334 }
335 else {
336 qCWarning(LOG_VisualizationDragDropContainer()) << tr(
337 "VisualizationDragDropContainer::dropEvent, dropping on the placeHolder, but "
338 "the insertion is forbidden.");
339 Q_ASSERT(false);
303 }
340 }
304 }
341 }
342 else if (helper.getHightlightedDragWidget()) {
343 // drop on the highlighted widget
344
345 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
346 if (canMerge) {
347 event->acceptProposedAction();
348 emit dropOccuredOnWidget(helper.getHightlightedDragWidget(), event->mimeData());
349 }
305 else {
350 else {
306 qCWarning(LOG_VisualizationDragDropContainer())
351 qCWarning(LOG_VisualizationDragDropContainer())
307 << tr("VisualizationDragDropContainer::dragMoveEvent, no widget found in the "
352 << tr("VisualizationDragDropContainer::dropEvent, dropping on a widget, but "
308 "container");
353 "the merge is forbidden.");
354 Q_ASSERT(false);
309 }
355 }
310 }
356 }
311 else {
312 // No hovered drag widget, the mouse is probably hover the placeHolder
313 // Do nothing
314 }
315 }
357 }
316 else {
358 else {
317 event->ignore();
359 event->ignore();
318 }
360 }
319
361
320 QWidget::dragMoveEvent(event);
362 sqpApp->dragDropHelper().setHightlightedDragWidget(nullptr);
363 impl->m_MinContainerHeight = 0;
364
365 QWidget::dropEvent(event);
321 }
366 }
322
367
323 void VisualizationDragDropContainer::dropEvent(QDropEvent *event)
368
369 void VisualizationDragDropContainer::VisualizationDragDropContainerPrivate::findPlaceHolderPosition(
370 const QPoint &pos, bool canInsert, bool canMerge,
371 const VisualizationDragDropContainer *container)
324 {
372 {
325 if (impl->acceptMimeData(event->mimeData())) {
326 auto dragWidget = sqpApp->dragDropHelper().getCurrentDragWidget();
327 if (impl->hasPlaceHolder()) {
328 auto &helper = sqpApp->dragDropHelper();
373 auto &helper = sqpApp->dragDropHelper();
329
374
330 auto droppedIndex = impl->m_Layout->indexOf(&helper.placeHolder());
375 auto absPos = container->mapToGlobal(pos);
376 auto isOnPlaceHolder = sqpApp->widgetAt(absPos) == &(helper.placeHolder());
331
377
332 if (dragWidget) {
378 if (countDragWidget(container, true) == 0) {
333 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
379 // Drop on an empty container, just add the placeHolder at the top
334 if (dragWidgetIndex >= 0 && dragWidgetIndex < droppedIndex) {
380 helper.insertPlaceHolder(m_Layout, 0, m_PlaceHolderType, m_PlaceHolderText);
381 }
382 else if (!isOnPlaceHolder) {
383 auto nbDragWidget = countDragWidget(container);
384 if (nbDragWidget > 0) {
385
386 if (m_MinContainerHeight == 0) {
387 m_MinContainerHeight = container->size().height();
388 }
389
390 m_MinContainerHeight = qMin(m_MinContainerHeight, container->size().height());
391 auto graphHeight = qMax(m_MinContainerHeight / nbDragWidget, GRAPH_MINIMUM_HEIGHT);
392
393 auto posY = pos.y();
394 auto dropIndex = floor(posY / graphHeight);
395 auto zoneSize = qMin(graphHeight / 4.0, 75.0);
396
397
398 auto isOnTop = posY < dropIndex * graphHeight + zoneSize;
399 auto isOnBottom = posY > (dropIndex + 1) * graphHeight - zoneSize;
400
401 auto placeHolderIndex = m_Layout->indexOf(&(helper.placeHolder()));
402
403 auto dragWidgetHovered = getChildDragWidgetAt(container, pos);
404
405 if (canInsert && (isOnTop || isOnBottom || !canMerge)) {
406 if (isOnBottom) {
407 dropIndex += 1;
408 }
409
410 if (helper.getCurrentDragWidget()) {
411 auto dragWidgetIndex = m_Layout->indexOf(helper.getCurrentDragWidget());
412 if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) {
335 // Correction of the index if the drop occurs in the same container
413 // 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
414 // and if the drag is started from the visualization (in that case, the
337 // dragWidget is hidden)
415 // dragWidget is hidden)
338 droppedIndex -= 1;
416 dropIndex += 1;
339 }
417 }
340
341 dragWidget->setVisible(true);
342 }
418 }
343
419
344 event->acceptProposedAction();
420 if (dropIndex != placeHolderIndex) {
421 helper.insertPlaceHolder(m_Layout, dropIndex, m_PlaceHolderType,
422 m_PlaceHolderText);
423 }
345
424
425 helper.setHightlightedDragWidget(nullptr);
426 }
427 else if (canMerge && dragWidgetHovered) {
428 // drop on the middle -> merge
429 if (hasPlaceHolder()) {
346 helper.removePlaceHolder();
430 helper.removePlaceHolder();
431 }
347
432
348 emit dropOccured(droppedIndex, event->mimeData());
433 helper.setHightlightedDragWidget(dragWidgetHovered);
349 }
434 }
350 else {
435 else {
351 qCWarning(LOG_VisualizationDragDropContainer())
436 qCWarning(LOG_VisualizationDragDropContainer())
352 << tr("VisualizationDragDropContainer::dropEvent, couldn't drop because the "
437 << tr("VisualizationDragDropContainer::findPlaceHolderPosition, no valid drop "
353 "placeHolder is not found.");
438 "action.");
354 Q_ASSERT(false);
439 Q_ASSERT(false);
355 }
440 }
356 }
441 }
357 else {
442 else {
358 event->ignore();
443 qCWarning(LOG_VisualizationDragDropContainer())
444 << tr("VisualizationDragDropContainer::findPlaceHolderPosition, no widget "
445 "found in the "
446 "container");
447 }
448 }
449 else {
450 // the mouse is hover the placeHolder
451 // Do nothing
359 }
452 }
360
361 QWidget::dropEvent(event);
362 }
453 }
@@ -9,9 +9,10
9 #include <Common/MimeTypesDef.h>
9 #include <Common/MimeTypesDef.h>
10 #include <Data/ArrayData.h>
10 #include <Data/ArrayData.h>
11 #include <Data/IDataSeries.h>
11 #include <Data/IDataSeries.h>
12 #include <DragDropHelper.h>
12 #include <DragAndDrop/DragDropHelper.h>
13 #include <Settings/SqpSettingsDefs.h>
13 #include <Settings/SqpSettingsDefs.h>
14 #include <SqpApplication.h>
14 #include <SqpApplication.h>
15 #include <Time/TimeController.h>
15 #include <Variable/Variable.h>
16 #include <Variable/Variable.h>
16 #include <Variable/VariableController.h>
17 #include <Variable/VariableController.h>
17
18
@@ -235,6 +236,9 QMimeData *VisualizationGraphWidget::mimeData() const
235 auto mimeData = new QMimeData;
236 auto mimeData = new QMimeData;
236 mimeData->setData(MIME_TYPE_GRAPH, QByteArray{});
237 mimeData->setData(MIME_TYPE_GRAPH, QByteArray{});
237
238
239 auto timeRangeData = TimeController::mimeDataForTimeRange(graphRange());
240 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
241
238 return mimeData;
242 return mimeData;
239 }
243 }
240
244
@@ -243,6 +247,18 bool VisualizationGraphWidget::isDragAllowed() const
243 return true;
247 return true;
244 }
248 }
245
249
250 void VisualizationGraphWidget::highlightForMerge(bool highlighted)
251 {
252 if (highlighted) {
253 plot().setBackground(QBrush(QColor("#BBD5EE")));
254 }
255 else {
256 plot().setBackground(QBrush(Qt::white));
257 }
258
259 plot().update();
260 }
261
246 void VisualizationGraphWidget::closeEvent(QCloseEvent *event)
262 void VisualizationGraphWidget::closeEvent(QCloseEvent *event)
247 {
263 {
248 Q_UNUSED(event);
264 Q_UNUSED(event);
@@ -9,7 +9,7
9
9
10 #include "Common/MimeTypesDef.h"
10 #include "Common/MimeTypesDef.h"
11
11
12 #include "DragDropHelper.h"
12 #include "DragAndDrop/DragDropHelper.h"
13 #include "SqpApplication.h"
13 #include "SqpApplication.h"
14
14
15 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
15 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
@@ -68,14 +68,23 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *par
68 {
68 {
69 ui->setupUi(this);
69 ui->setupUi(this);
70
70
71 ui->dragDropContainer->setAcceptedMimeTypes(
71 ui->dragDropContainer->setPlaceHolderType(DragDropHelper::PlaceHolderType::Zone, "Zone");
72 {MIME_TYPE_GRAPH, MIME_TYPE_ZONE, MIME_TYPE_VARIABLE_LIST});
72 ui->dragDropContainer->layout()->setContentsMargins(0, 0, 0, 5);
73 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this,
73 ui->dragDropContainer->addAcceptedMimeType(
74 &VisualizationTabWidget::dropMimeData);
74 MIME_TYPE_GRAPH, VisualizationDragDropContainer::DropBehavior::Inserted);
75 ui->dragDropContainer->addAcceptedMimeType(
76 MIME_TYPE_ZONE, VisualizationDragDropContainer::DropBehavior::Inserted);
77 ui->dragDropContainer->addAcceptedMimeType(
78 MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::Inserted);
79
75 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
80 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
76 return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData,
81 return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData,
77 ui->dragDropContainer);
82 ui->dragDropContainer);
78 });
83 });
84
85 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
86 &VisualizationTabWidget::dropMimeData);
87
79 sqpApp->dragDropHelper().addDragDropScrollArea(ui->scrollArea);
88 sqpApp->dragDropHelper().addDragDropScrollArea(ui->scrollArea);
80
89
81 // Widget is deleted when closed
90 // Widget is deleted when closed
@@ -11,6 +11,9
11
11
12 #include "ui_VisualizationWidget.h"
12 #include "ui_VisualizationWidget.h"
13
13
14 #include "DragAndDrop/DragDropHelper.h"
15 #include "SqpApplication.h"
16
14 #include <QToolButton>
17 #include <QToolButton>
15
18
16 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
19 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
@@ -67,12 +70,15 VisualizationWidget::VisualizationWidget(QWidget *parent)
67 connect(addTabViewButton, &QToolButton::clicked, addTabView);
70 connect(addTabViewButton, &QToolButton::clicked, addTabView);
68 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
71 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
69
72
73 sqpApp->dragDropHelper().addDragDropTabBar(ui->tabWidget->tabBar());
74
70 // Adds default tab
75 // Adds default tab
71 addTabView();
76 addTabView();
72 }
77 }
73
78
74 VisualizationWidget::~VisualizationWidget()
79 VisualizationWidget::~VisualizationWidget()
75 {
80 {
81 sqpApp->dragDropHelper().removeDragDropTabBar(ui->tabWidget->tabBar());
76 delete ui;
82 delete ui;
77 }
83 }
78
84
@@ -10,12 +10,13
10 #include "Common/VisualizationDef.h"
10 #include "Common/VisualizationDef.h"
11
11
12 #include <Data/SqpRange.h>
12 #include <Data/SqpRange.h>
13 #include <Time/TimeController.h>
13 #include <Variable/Variable.h>
14 #include <Variable/Variable.h>
14 #include <Variable/VariableController.h>
15 #include <Variable/VariableController.h>
15
16
16 #include <Visualization/operations/FindVariableOperation.h>
17 #include <Visualization/operations/FindVariableOperation.h>
17
18
18 #include <DragDropHelper.h>
19 #include <DragAndDrop/DragDropHelper.h>
19 #include <QUuid>
20 #include <QUuid>
20 #include <SqpApplication.h>
21 #include <SqpApplication.h>
21 #include <cmath>
22 #include <cmath>
@@ -71,6 +72,21 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
71 QUuid m_SynchronisationGroupId;
72 QUuid m_SynchronisationGroupId;
72 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
73 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
73
74
75 // Returns the first graph in the zone or nullptr if there is no graph inside
76 VisualizationGraphWidget *firstGraph(const VisualizationZoneWidget *zoneWidget) const
77 {
78 VisualizationGraphWidget *firstGraph = nullptr;
79 auto layout = zoneWidget->ui->dragDropContainer->layout();
80 if (layout->count() > 0) {
81 if (auto visualizationGraphWidget
82 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
83 firstGraph = visualizationGraphWidget;
84 }
85 }
86
87 return firstGraph;
88 }
89
74 void dropGraph(int index, VisualizationZoneWidget *zoneWidget);
90 void dropGraph(int index, VisualizationZoneWidget *zoneWidget);
75 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
91 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
76 VisualizationZoneWidget *zoneWidget);
92 VisualizationZoneWidget *zoneWidget);
@@ -85,13 +101,22 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p
85
101
86 ui->zoneNameLabel->setText(name);
102 ui->zoneNameLabel->setText(name);
87
103
88 ui->dragDropContainer->setAcceptedMimeTypes({MIME_TYPE_GRAPH, MIME_TYPE_VARIABLE_LIST});
104 ui->dragDropContainer->setPlaceHolderType(DragDropHelper::PlaceHolderType::Graph);
105 ui->dragDropContainer->addAcceptedMimeType(
106 MIME_TYPE_GRAPH, VisualizationDragDropContainer::DropBehavior::Inserted);
107 ui->dragDropContainer->addAcceptedMimeType(
108 MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
109 ui->dragDropContainer->addAcceptedMimeType(
110 MIME_TYPE_TIME_RANGE, VisualizationDragDropContainer::DropBehavior::Merged);
89 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
111 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
90 return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData,
112 return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData,
91 ui->dragDropContainer);
113 ui->dragDropContainer);
92 });
114 });
93 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this,
115
116 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
94 &VisualizationZoneWidget::dropMimeData);
117 &VisualizationZoneWidget::dropMimeData);
118 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredOnWidget, this,
119 &VisualizationZoneWidget::dropMimeDataOnGraph);
95
120
96 // 'Close' options : widget is deleted when closed
121 // 'Close' options : widget is deleted when closed
97 setAttribute(Qt::WA_DeleteOnClose);
122 setAttribute(Qt::WA_DeleteOnClose);
@@ -234,15 +259,9 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<V
234 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
259 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
235
260
236 auto range = SqpRange{};
261 auto range = SqpRange{};
237
262 if (auto firstGraph = impl->firstGraph(this)) {
238 // Apply visitor to graph children
239 auto layout = ui->dragDropContainer->layout();
240 if (layout->count() > 0) {
241 // Case of a new graph in a existant zone
263 // Case of a new graph in a existant zone
242 if (auto visualizationGraphWidget
264 range = firstGraph->graphRange();
243 = dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
244 range = visualizationGraphWidget->graphRange();
245 }
246 }
265 }
247 else {
266 else {
248 // Case of a new graph as the first of the zone
267 // Case of a new graph as the first of the zone
@@ -380,6 +399,35 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
380 }
399 }
381 }
400 }
382
401
402 void VisualizationZoneWidget::dropMimeDataOnGraph(VisualizationDragWidget *dragWidget,
403 const QMimeData *mimeData)
404 {
405 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(dragWidget);
406 if (!graphWidget) {
407 qCWarning(LOG_VisualizationZoneWidget())
408 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, dropping in an unknown widget, "
409 "drop aborted");
410 Q_ASSERT(false);
411 return;
412 }
413
414 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
415 auto variables = sqpApp->variableController().variablesForMimeData(
416 mimeData->data(MIME_TYPE_VARIABLE_LIST));
417 for (const auto &var : variables) {
418 graphWidget->addVariable(var, graphWidget->graphRange());
419 }
420 }
421 else if (mimeData->hasFormat(MIME_TYPE_TIME_RANGE)) {
422 auto range = TimeController::timeRangeForMimeData(mimeData->data(MIME_TYPE_TIME_RANGE));
423 graphWidget->setGraphRange(range);
424 }
425 else {
426 qCWarning(LOG_VisualizationZoneWidget())
427 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, unknown MIME data received.");
428 }
429 }
430
383 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
431 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
384 int index, VisualizationZoneWidget *zoneWidget)
432 int index, VisualizationZoneWidget *zoneWidget)
385 {
433 {
@@ -16,9 +16,15
16 <verstretch>0</verstretch>
16 <verstretch>0</verstretch>
17 </sizepolicy>
17 </sizepolicy>
18 </property>
18 </property>
19 <property name="acceptDrops">
20 <bool>true</bool>
21 </property>
19 <property name="windowTitle">
22 <property name="windowTitle">
20 <string>Form</string>
23 <string>Form</string>
21 </property>
24 </property>
25 <property name="styleSheet">
26 <string notr="true">b</string>
27 </property>
22 <layout class="QHBoxLayout" name="horizontalLayout_2">
28 <layout class="QHBoxLayout" name="horizontalLayout_2">
23 <item>
29 <item>
24 <widget class="QLabel" name="label">
30 <widget class="QLabel" name="label">
@@ -15,7 +15,7
15 </property>
15 </property>
16 <layout class="QGridLayout" name="gridLayout">
16 <layout class="QGridLayout" name="gridLayout">
17 <item row="0" column="0">
17 <item row="0" column="0">
18 <widget class="QTableView" name="tableView">
18 <widget class="VariableInspectorTableView" name="tableView">
19 <property name="acceptDrops">
19 <property name="acceptDrops">
20 <bool>true</bool>
20 <bool>true</bool>
21 </property>
21 </property>
@@ -35,6 +35,13
35 </item>
35 </item>
36 </layout>
36 </layout>
37 </widget>
37 </widget>
38 <customwidgets>
39 <customwidget>
40 <class>VariableInspectorTableView</class>
41 <extends>QTableView</extends>
42 <header>Variable/VariableInspectorTableView.h</header>
43 </customwidget>
44 </customwidgets>
38 <resources/>
45 <resources/>
39 <connections/>
46 <connections/>
40 </ui>
47 </ui>
@@ -63,7 +63,11
63 <number>0</number>
63 <number>0</number>
64 </property>
64 </property>
65 <item>
65 <item>
66 <widget class="VisualizationDragDropContainer" name="dragDropContainer" native="true"/>
66 <widget class="VisualizationDragDropContainer" name="dragDropContainer">
67 <property name="lineWidth">
68 <number>0</number>
69 </property>
70 </widget>
67 </item>
71 </item>
68 </layout>
72 </layout>
69 </widget>
73 </widget>
@@ -74,7 +78,7
74 <customwidgets>
78 <customwidgets>
75 <customwidget>
79 <customwidget>
76 <class>VisualizationDragDropContainer</class>
80 <class>VisualizationDragDropContainer</class>
77 <extends>QWidget</extends>
81 <extends>QFrame</extends>
78 <header>Visualization/VisualizationDragDropContainer.h</header>
82 <header>Visualization/VisualizationDragDropContainer.h</header>
79 <container>1</container>
83 <container>1</container>
80 </customwidget>
84 </customwidget>
@@ -78,7 +78,7
78 </widget>
78 </widget>
79 </item>
79 </item>
80 <item>
80 <item>
81 <widget class="QFrame" name="visualizationZoneFrame">
81 <widget class="VisualizationDragDropContainer" name="dragDropContainer">
82 <property name="sizePolicy">
82 <property name="sizePolicy">
83 <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
83 <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
84 <horstretch>0</horstretch>
84 <horstretch>0</horstretch>
@@ -107,9 +107,6
107 <property name="bottomMargin">
107 <property name="bottomMargin">
108 <number>0</number>
108 <number>0</number>
109 </property>
109 </property>
110 <item>
111 <widget class="VisualizationDragDropContainer" name="dragDropContainer" native="true"/>
112 </item>
113 </layout>
110 </layout>
114 </widget>
111 </widget>
115 </item>
112 </item>
@@ -118,7 +115,7
118 <customwidgets>
115 <customwidgets>
119 <customwidget>
116 <customwidget>
120 <class>VisualizationDragDropContainer</class>
117 <class>VisualizationDragDropContainer</class>
121 <extends>QWidget</extends>
118 <extends>QFrame</extends>
122 <header>Visualization/VisualizationDragDropContainer.h</header>
119 <header>Visualization/VisualizationDragDropContainer.h</header>
123 <container>1</container>
120 <container>1</container>
124 </customwidget>
121 </customwidget>
General Comments 0
You need to be logged in to leave comments. Login now