##// END OF EJS Templates
code improvements
trabillard -
r980:53840da09aee
parent child
Show More
@@ -1,18 +1,18
1 #ifndef SCIQLOP_MACSCROLLBARSTYLE_H
1 #ifndef SCIQLOP_MACSCROLLBARSTYLE_H
2 #define SCIQLOP_MACSCROLLBARSTYLE_H
2 #define SCIQLOP_MACSCROLLBARSTYLE_H
3
3
4 #include <QProxyStyle>
4 #include <QProxyStyle>
5
5
6 /**
6 /**
7 * @brief Special style to always display the scrollbars on MAC.
7 * @brief Special style to always display the scrollbars on MAC.
8 */
8 */
9 class MacScrollBarStyle : public QProxyStyle {
9 class MacScrollBarStyle : public QProxyStyle {
10
10
11 public:
11 public:
12 int styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
12 int styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
13 QStyleHintReturn *returnData) const;
13 QStyleHintReturn *returnData) const override;
14
14
15 void selfInstallOn(QWidget *widget, bool installOnSubWidgets);
15 void selfInstallOn(QWidget *widget, bool installOnSubWidgets);
16 };
16 };
17
17
18 #endif // SCIQLOP_MACSCROLLBARSTYLE_H
18 #endif // SCIQLOP_MACSCROLLBARSTYLE_H
@@ -1,154 +1,154
1 #include "TimeWidget/TimeWidget.h"
1 #include "TimeWidget/TimeWidget.h"
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>
5 #include <Common/MimeTypesDef.h>
6
6
7 #include <DragAndDrop/DragDropHelper.h>
7 #include <DragAndDrop/DragDropHelper.h>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9 #include <Time/TimeController.h>
9 #include <Time/TimeController.h>
10
10
11 #include <QDrag>
11 #include <QDrag>
12 #include <QDragEnterEvent>
12 #include <QDragEnterEvent>
13 #include <QDropEvent>
13 #include <QDropEvent>
14 #include <QMimeData>
14 #include <QMimeData>
15
15
16
16
17 struct TimeWidget::TimeWidgetPrivate {
17 struct TimeWidget::TimeWidgetPrivate {
18
18
19 explicit TimeWidgetPrivate() {}
19 explicit TimeWidgetPrivate() {}
20
20
21 QPoint m_DragStartPosition;
21 QPoint m_DragStartPosition;
22 };
22 };
23
23
24 TimeWidget::TimeWidget(QWidget *parent)
24 TimeWidget::TimeWidget(QWidget *parent)
25 : QWidget{parent},
25 : QWidget{parent},
26 ui{new Ui::TimeWidget},
26 ui{new Ui::TimeWidget},
27 impl{spimpl::make_unique_impl<TimeWidgetPrivate>()}
27 impl{spimpl::make_unique_impl<TimeWidgetPrivate>()}
28 {
28 {
29 ui->setupUi(this);
29 ui->setupUi(this);
30
30
31 ui->applyToolButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_DialogApplyButton));
31 ui->applyToolButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_DialogApplyButton));
32
32
33 // Connection
33 // Connection
34 connect(ui->startDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this,
34 connect(ui->startDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this,
35 &TimeWidget::onTimeUpdateRequested);
35 &TimeWidget::onTimeUpdateRequested);
36
36
37 connect(ui->endDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this,
37 connect(ui->endDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this,
38 &TimeWidget::onTimeUpdateRequested);
38 &TimeWidget::onTimeUpdateRequested);
39
39
40
40
41 connect(ui->applyToolButton, &QToolButton::clicked, &sqpApp->timeController(),
41 connect(ui->applyToolButton, &QToolButton::clicked, &sqpApp->timeController(),
42 &TimeController::onTimeNotify);
42 &TimeController::onTimeNotify);
43
43
44 // Initialisation
44 // Initialisation
45 auto endDateTime = QDateTime::currentDateTimeUtc();
45 auto endDateTime = QDateTime::currentDateTimeUtc();
46 auto startDateTime = endDateTime.addSecs(-3600); // one hour before
46 auto startDateTime = endDateTime.addSecs(-3600); // one hour before
47
47
48 ui->startDateTimeEdit->setDateTime(startDateTime);
48 ui->startDateTimeEdit->setDateTime(startDateTime);
49 ui->endDateTimeEdit->setDateTime(endDateTime);
49 ui->endDateTimeEdit->setDateTime(endDateTime);
50
50
51 auto dateTime = SqpRange{DateUtils::secondsSinceEpoch(startDateTime),
51 auto dateTime = SqpRange{DateUtils::secondsSinceEpoch(startDateTime),
52 DateUtils::secondsSinceEpoch(endDateTime)};
52 DateUtils::secondsSinceEpoch(endDateTime)};
53
53
54 sqpApp->timeController().onTimeToUpdate(dateTime);
54 sqpApp->timeController().onTimeToUpdate(dateTime);
55 }
55 }
56
56
57
57
58 TimeWidget::~TimeWidget()
58 TimeWidget::~TimeWidget()
59 {
59 {
60 delete ui;
60 delete ui;
61 }
61 }
62
62
63 void TimeWidget::setTimeRange(SqpRange time)
63 void TimeWidget::setTimeRange(SqpRange time)
64 {
64 {
65 auto startDateTime = DateUtils::dateTime(time.m_TStart);
65 auto startDateTime = DateUtils::dateTime(time.m_TStart);
66 auto endDateTime = DateUtils::dateTime(time.m_TEnd);
66 auto endDateTime = DateUtils::dateTime(time.m_TEnd);
67
67
68 ui->startDateTimeEdit->setDateTime(startDateTime);
68 ui->startDateTimeEdit->setDateTime(startDateTime);
69 ui->endDateTimeEdit->setDateTime(endDateTime);
69 ui->endDateTimeEdit->setDateTime(endDateTime);
70 }
70 }
71
71
72 SqpRange TimeWidget::timeRange() const
72 SqpRange TimeWidget::timeRange() const
73 {
73 {
74 return SqpRange{DateUtils::secondsSinceEpoch(ui->startDateTimeEdit->dateTime()),
74 return SqpRange{DateUtils::secondsSinceEpoch(ui->startDateTimeEdit->dateTime()),
75 DateUtils::secondsSinceEpoch(ui->endDateTimeEdit->dateTime())};
75 DateUtils::secondsSinceEpoch(ui->endDateTimeEdit->dateTime())};
76 }
76 }
77
77
78 void TimeWidget::onTimeUpdateRequested()
78 void TimeWidget::onTimeUpdateRequested()
79 {
79 {
80 auto dateTime = timeRange();
80 auto dateTime = timeRange();
81 emit timeUpdated(std::move(dateTime));
81 emit timeUpdated(std::move(dateTime));
82 }
82 }
83
83
84 void TimeWidget::dragEnterEvent(QDragEnterEvent *event)
84 void TimeWidget::dragEnterEvent(QDragEnterEvent *event)
85 {
85 {
86 if (event->mimeData()->hasFormat(MIME_TYPE_TIME_RANGE)) {
86 if (event->mimeData()->hasFormat(MIME_TYPE_TIME_RANGE)) {
87 event->acceptProposedAction();
87 event->acceptProposedAction();
88 setStyleSheet("QDateTimeEdit{background-color: #BBD5EE; border:2px solid #2A7FD4}");
88 setStyleSheet("QDateTimeEdit{background-color: #BBD5EE; border:2px solid #2A7FD4}");
89 }
89 }
90 else {
90 else {
91 event->ignore();
91 event->ignore();
92 }
92 }
93 }
93 }
94
94
95 void TimeWidget::dragLeaveEvent(QDragLeaveEvent *event)
95 void TimeWidget::dragLeaveEvent(QDragLeaveEvent *event)
96 {
96 {
97 setStyleSheet(QString());
97 setStyleSheet(QString{});
98 }
98 }
99
99
100 void TimeWidget::dropEvent(QDropEvent *event)
100 void TimeWidget::dropEvent(QDropEvent *event)
101 {
101 {
102 if (event->mimeData()->hasFormat(MIME_TYPE_TIME_RANGE)) {
102 if (event->mimeData()->hasFormat(MIME_TYPE_TIME_RANGE)) {
103 auto mimeData = event->mimeData()->data(MIME_TYPE_TIME_RANGE);
103 auto mimeData = event->mimeData()->data(MIME_TYPE_TIME_RANGE);
104 auto timeRange = TimeController::timeRangeForMimeData(mimeData);
104 auto timeRange = TimeController::timeRangeForMimeData(mimeData);
105
105
106 setTimeRange(timeRange);
106 setTimeRange(timeRange);
107 }
107 }
108 else {
108 else {
109 event->ignore();
109 event->ignore();
110 }
110 }
111
111
112 setStyleSheet(QString());
112 setStyleSheet(QString{});
113 }
113 }
114
114
115
115
116 void TimeWidget::mousePressEvent(QMouseEvent *event)
116 void TimeWidget::mousePressEvent(QMouseEvent *event)
117 {
117 {
118 if (event->button() == Qt::LeftButton) {
118 if (event->button() == Qt::LeftButton) {
119 impl->m_DragStartPosition = event->pos();
119 impl->m_DragStartPosition = event->pos();
120 }
120 }
121
121
122 QWidget::mousePressEvent(event);
122 QWidget::mousePressEvent(event);
123 }
123 }
124
124
125 void TimeWidget::mouseMoveEvent(QMouseEvent *event)
125 void TimeWidget::mouseMoveEvent(QMouseEvent *event)
126 {
126 {
127 if (!(event->buttons() & Qt::LeftButton)) {
127 if (!(event->buttons() & Qt::LeftButton)) {
128 return;
128 return;
129 }
129 }
130
130
131 if ((event->pos() - impl->m_DragStartPosition).manhattanLength()
131 if ((event->pos() - impl->m_DragStartPosition).manhattanLength()
132 < QApplication::startDragDistance()) {
132 < QApplication::startDragDistance()) {
133 return;
133 return;
134 }
134 }
135
135
136 // Note: The management of the drag object is done by Qt
136 // Note: The management of the drag object is done by Qt
137 auto drag = new QDrag{this};
137 auto drag = new QDrag{this};
138
138
139 auto mimeData = new QMimeData;
139 auto mimeData = new QMimeData;
140 auto timeData = TimeController::mimeDataForTimeRange(timeRange());
140 auto timeData = TimeController::mimeDataForTimeRange(timeRange());
141 mimeData->setData(MIME_TYPE_TIME_RANGE, timeData);
141 mimeData->setData(MIME_TYPE_TIME_RANGE, timeData);
142
142
143 drag->setMimeData(mimeData);
143 drag->setMimeData(mimeData);
144
144
145 auto pixmap = QPixmap{":/icones/time.png"};
145 auto pixmap = QPixmap{":/icones/time.png"};
146 drag->setPixmap(pixmap.scaledToWidth(22));
146 drag->setPixmap(pixmap.scaledToWidth(22));
147
147
148 sqpApp->dragDropHelper().resetDragAndDrop();
148 sqpApp->dragDropHelper().resetDragAndDrop();
149
149
150 // Note: The exec() is blocking on windows but not on linux and macOS
150 // Note: The exec() is blocking on windows but not on linux and macOS
151 drag->exec(Qt::MoveAction | Qt::CopyAction);
151 drag->exec(Qt::MoveAction | Qt::CopyAction);
152
152
153 QWidget::mouseMoveEvent(event);
153 QWidget::mouseMoveEvent(event);
154 }
154 }
@@ -1,472 +1,472
1 #include "Visualization/VisualizationDragDropContainer.h"
1 #include "Visualization/VisualizationDragDropContainer.h"
2 #include "DragAndDrop/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
6 #include "Common/VisualizationDef.h"
6 #include "Common/VisualizationDef.h"
7
7
8 #include <QDrag>
8 #include <QDrag>
9 #include <QDragEnterEvent>
9 #include <QDragEnterEvent>
10 #include <QVBoxLayout>
10 #include <QVBoxLayout>
11
11
12 #include <cmath>
12 #include <cmath>
13 #include <memory>
13 #include <memory>
14
14
15 Q_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer, "VisualizationDragDropContainer")
15 Q_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer, "VisualizationDragDropContainer")
16
16
17 auto DRAGGED_MINIATURE_WIDTH = 200; // in pixels
17 auto DRAGGED_MINIATURE_WIDTH = 200; // in pixels
18
18
19 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
19 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
20
20
21 QVBoxLayout *m_Layout;
21 QVBoxLayout *m_Layout;
22 QHash<QString, VisualizationDragDropContainer::DropBehavior> m_AcceptedMimeTypes;
22 QHash<QString, VisualizationDragDropContainer::DropBehavior> m_AcceptedMimeTypes;
23 QString m_PlaceHolderText;
23 QString m_PlaceHolderText;
24 DragDropHelper::PlaceHolderType m_PlaceHolderType = DragDropHelper::PlaceHolderType::Graph;
24 DragDropHelper::PlaceHolderType m_PlaceHolderType = DragDropHelper::PlaceHolderType::Graph;
25
25
26 VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun
26 VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun
27 = [](auto mimeData) { return true; };
27 = [](auto mimeData) { return true; };
28
28
29 int m_MinContainerHeight = 0;
29 int m_MinContainerHeight = 0;
30
30
31 explicit VisualizationDragDropContainerPrivate(QWidget *widget)
31 explicit VisualizationDragDropContainerPrivate(QWidget *widget)
32 {
32 {
33 m_Layout = new QVBoxLayout(widget);
33 m_Layout = new QVBoxLayout(widget);
34 m_Layout->setContentsMargins(0, 0, 0, 0);
34 m_Layout->setContentsMargins(0, 0, 0, 0);
35 }
35 }
36
36
37 bool acceptMimeData(const QMimeData *data) const
37 bool acceptMimeData(const QMimeData *data) const
38 {
38 {
39 auto accepted = false;
39 auto accepted = false;
40 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
40 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
41 ++it) {
41 ++it) {
42 const auto &type = it.key();
42 const auto &type = it.key();
43 const auto &behavior = it.value();
43 const auto &behavior = it.value();
44
44
45 if (data->hasFormat(type)) {
45 if (data->hasFormat(type)) {
46 if (behavior != DropBehavior::Forbidden) {
46 if (behavior != DropBehavior::Forbidden) {
47 accepted = true;
47 accepted = true;
48 }
48 }
49 else {
49 else {
50 accepted = false;
50 accepted = false;
51 break;
51 break;
52 }
52 }
53 }
53 }
54 }
54 }
55
55
56 if (accepted) {
56 if (accepted) {
57 accepted = m_AcceptMimeDataFun(data);
57 accepted = m_AcceptMimeDataFun(data);
58 }
58 }
59
59
60 return accepted;
60 return accepted;
61 }
61 }
62
62
63 bool allowMergeForMimeData(const QMimeData *data) const
63 bool allowMergeForMimeData(const QMimeData *data) const
64 {
64 {
65 bool result = false;
65 auto result = false;
66 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
66 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
67 ++it) {
67 ++it) {
68
68
69 if (data->hasFormat(it.key())
69 if (data->hasFormat(it.key())
70 && (it.value() == VisualizationDragDropContainer::DropBehavior::Merged
70 && (it.value() == VisualizationDragDropContainer::DropBehavior::Merged
71 || it.value()
71 || it.value()
72 == VisualizationDragDropContainer::DropBehavior::InsertedAndMerged)) {
72 == VisualizationDragDropContainer::DropBehavior::InsertedAndMerged)) {
73 result = true;
73 result = true;
74 }
74 }
75 else if (data->hasFormat(it.key())
75 else if (data->hasFormat(it.key())
76 && it.value() == VisualizationDragDropContainer::DropBehavior::Inserted) {
76 && it.value() == VisualizationDragDropContainer::DropBehavior::Inserted) {
77 // Merge is forbidden if the mime data contain an acceptable type which cannot be
77 // Merge is forbidden if the mime data contain an acceptable type which cannot be
78 // merged
78 // merged
79 result = false;
79 result = false;
80 break;
80 break;
81 }
81 }
82 }
82 }
83
83
84 return result;
84 return result;
85 }
85 }
86
86
87 bool allowInsertForMimeData(const QMimeData *data) const
87 bool allowInsertForMimeData(const QMimeData *data) const
88 {
88 {
89 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
89 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
90 ++it) {
90 ++it) {
91 if (data->hasFormat(it.key())
91 if (data->hasFormat(it.key())
92 && (it.value() == VisualizationDragDropContainer::DropBehavior::Inserted
92 && (it.value() == VisualizationDragDropContainer::DropBehavior::Inserted
93 || it.value()
93 || it.value()
94 == VisualizationDragDropContainer::DropBehavior::InsertedAndMerged)) {
94 == VisualizationDragDropContainer::DropBehavior::InsertedAndMerged)) {
95 return true;
95 return true;
96 }
96 }
97 }
97 }
98
98
99 return false;
99 return false;
100 }
100 }
101
101
102 bool hasPlaceHolder() const
102 bool hasPlaceHolder() const
103 {
103 {
104 return sqpApp->dragDropHelper().placeHolder().parentWidget() == m_Layout->parentWidget();
104 return sqpApp->dragDropHelper().placeHolder().parentWidget() == m_Layout->parentWidget();
105 }
105 }
106
106
107 VisualizationDragWidget *getChildDragWidgetAt(const QWidget *parent, const QPoint &pos) const
107 VisualizationDragWidget *getChildDragWidgetAt(const QWidget *parent, const QPoint &pos) const
108 {
108 {
109 VisualizationDragWidget *dragWidget = nullptr;
109 VisualizationDragWidget *dragWidget = nullptr;
110
110
111 for (auto child : parent->children()) {
111 for (auto child : parent->children()) {
112 auto widget = qobject_cast<VisualizationDragWidget *>(child);
112 auto widget = qobject_cast<VisualizationDragWidget *>(child);
113 if (widget && widget->isVisible()) {
113 if (widget && widget->isVisible()) {
114 if (widget->frameGeometry().contains(pos)) {
114 if (widget->frameGeometry().contains(pos)) {
115 dragWidget = widget;
115 dragWidget = widget;
116 break;
116 break;
117 }
117 }
118 }
118 }
119 }
119 }
120
120
121 return dragWidget;
121 return dragWidget;
122 }
122 }
123
123
124 bool cursorIsInContainer(QWidget *container) const
124 bool cursorIsInContainer(QWidget *container) const
125 {
125 {
126 auto widgetUnderMouse = sqpApp->widgetAt(QCursor::pos());
126 auto widgetUnderMouse = sqpApp->widgetAt(QCursor::pos());
127 return container->isAncestorOf(widgetUnderMouse) && widgetUnderMouse != container
127 return container->isAncestorOf(widgetUnderMouse) && widgetUnderMouse != container
128 && sqpApp->dragDropHelper().placeHolder().isAncestorOf(widgetUnderMouse);
128 && sqpApp->dragDropHelper().placeHolder().isAncestorOf(widgetUnderMouse);
129 }
129 }
130
130
131 int countDragWidget(const QWidget *parent, bool onlyVisible = false) const
131 int countDragWidget(const QWidget *parent, bool onlyVisible = false) const
132 {
132 {
133 auto nbGraph = 0;
133 auto nbGraph = 0;
134 for (auto child : parent->children()) {
134 for (auto child : parent->children()) {
135 if (qobject_cast<VisualizationDragWidget *>(child)) {
135 if (qobject_cast<VisualizationDragWidget *>(child)) {
136 if (!onlyVisible || qobject_cast<VisualizationDragWidget *>(child)->isVisible()) {
136 if (!onlyVisible || qobject_cast<VisualizationDragWidget *>(child)->isVisible()) {
137 nbGraph += 1;
137 nbGraph += 1;
138 }
138 }
139 }
139 }
140 }
140 }
141
141
142 return nbGraph;
142 return nbGraph;
143 }
143 }
144
144
145 void findPlaceHolderPosition(const QPoint &pos, bool canInsert, bool canMerge,
145 void findPlaceHolderPosition(const QPoint &pos, bool canInsert, bool canMerge,
146 const VisualizationDragDropContainer *container);
146 const VisualizationDragDropContainer *container);
147 };
147 };
148
148
149 VisualizationDragDropContainer::VisualizationDragDropContainer(QWidget *parent)
149 VisualizationDragDropContainer::VisualizationDragDropContainer(QWidget *parent)
150 : QFrame{parent},
150 : QFrame{parent},
151 impl{spimpl::make_unique_impl<VisualizationDragDropContainerPrivate>(this)}
151 impl{spimpl::make_unique_impl<VisualizationDragDropContainerPrivate>(this)}
152 {
152 {
153 setAcceptDrops(true);
153 setAcceptDrops(true);
154 }
154 }
155
155
156 void VisualizationDragDropContainer::addDragWidget(VisualizationDragWidget *dragWidget)
156 void VisualizationDragDropContainer::addDragWidget(VisualizationDragWidget *dragWidget)
157 {
157 {
158 impl->m_Layout->addWidget(dragWidget);
158 impl->m_Layout->addWidget(dragWidget);
159 disconnect(dragWidget, &VisualizationDragWidget::dragDetected, nullptr, nullptr);
159 disconnect(dragWidget, &VisualizationDragWidget::dragDetected, nullptr, nullptr);
160 connect(dragWidget, &VisualizationDragWidget::dragDetected, this,
160 connect(dragWidget, &VisualizationDragWidget::dragDetected, this,
161 &VisualizationDragDropContainer::startDrag);
161 &VisualizationDragDropContainer::startDrag);
162 }
162 }
163
163
164 void VisualizationDragDropContainer::insertDragWidget(int index,
164 void VisualizationDragDropContainer::insertDragWidget(int index,
165 VisualizationDragWidget *dragWidget)
165 VisualizationDragWidget *dragWidget)
166 {
166 {
167 impl->m_Layout->insertWidget(index, dragWidget);
167 impl->m_Layout->insertWidget(index, dragWidget);
168 disconnect(dragWidget, &VisualizationDragWidget::dragDetected, nullptr, nullptr);
168 disconnect(dragWidget, &VisualizationDragWidget::dragDetected, nullptr, nullptr);
169 connect(dragWidget, &VisualizationDragWidget::dragDetected, this,
169 connect(dragWidget, &VisualizationDragWidget::dragDetected, this,
170 &VisualizationDragDropContainer::startDrag);
170 &VisualizationDragDropContainer::startDrag);
171 }
171 }
172
172
173 void VisualizationDragDropContainer::setMimeType(
173 void VisualizationDragDropContainer::setMimeType(
174 const QString &mimeType, VisualizationDragDropContainer::DropBehavior behavior)
174 const QString &mimeType, VisualizationDragDropContainer::DropBehavior behavior)
175 {
175 {
176 impl->m_AcceptedMimeTypes[mimeType] = behavior;
176 impl->m_AcceptedMimeTypes[mimeType] = behavior;
177 }
177 }
178
178
179 int VisualizationDragDropContainer::countDragWidget() const
179 int VisualizationDragDropContainer::countDragWidget() const
180 {
180 {
181 return impl->countDragWidget(this);
181 return impl->countDragWidget(this);
182 }
182 }
183
183
184 void VisualizationDragDropContainer::setAcceptMimeDataFunction(
184 void VisualizationDragDropContainer::setAcceptMimeDataFunction(
185 VisualizationDragDropContainer::AcceptMimeDataFunction fun)
185 VisualizationDragDropContainer::AcceptMimeDataFunction fun)
186 {
186 {
187 impl->m_AcceptMimeDataFun = fun;
187 impl->m_AcceptMimeDataFun = fun;
188 }
188 }
189
189
190 void VisualizationDragDropContainer::setPlaceHolderType(DragDropHelper::PlaceHolderType type,
190 void VisualizationDragDropContainer::setPlaceHolderType(DragDropHelper::PlaceHolderType type,
191 const QString &placeHolderText)
191 const QString &placeHolderText)
192 {
192 {
193 impl->m_PlaceHolderType = type;
193 impl->m_PlaceHolderType = type;
194 impl->m_PlaceHolderText = placeHolderText;
194 impl->m_PlaceHolderText = placeHolderText;
195 }
195 }
196
196
197 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget,
197 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget,
198 const QPoint &dragPosition)
198 const QPoint &dragPosition)
199 {
199 {
200 auto &helper = sqpApp->dragDropHelper();
200 auto &helper = sqpApp->dragDropHelper();
201 helper.resetDragAndDrop();
201 helper.resetDragAndDrop();
202
202
203 // Note: The management of the drag object is done by Qt
203 // Note: The management of the drag object is done by Qt
204 auto drag = new QDrag{dragWidget};
204 auto drag = new QDrag{dragWidget};
205
205
206 auto mimeData = dragWidget->mimeData();
206 auto mimeData = dragWidget->mimeData();
207 drag->setMimeData(mimeData);
207 drag->setMimeData(mimeData);
208
208
209 auto pixmap = QPixmap(dragWidget->size());
209 auto pixmap = QPixmap(dragWidget->size());
210 dragWidget->render(&pixmap);
210 dragWidget->render(&pixmap);
211 drag->setPixmap(pixmap.scaled(DRAGGED_MINIATURE_WIDTH, DRAGGED_MINIATURE_WIDTH,
211 drag->setPixmap(pixmap.scaled(DRAGGED_MINIATURE_WIDTH, DRAGGED_MINIATURE_WIDTH,
212 Qt::KeepAspectRatio, Qt::SmoothTransformation));
212 Qt::KeepAspectRatio, Qt::SmoothTransformation));
213
213
214 auto image = pixmap.toImage();
214 auto image = pixmap.toImage();
215 mimeData->setImageData(image);
215 mimeData->setImageData(image);
216 mimeData->setUrls({helper.imageTemporaryUrl(image)});
216 mimeData->setUrls({helper.imageTemporaryUrl(image)});
217
217
218 if (impl->m_Layout->indexOf(dragWidget) >= 0) {
218 if (impl->m_Layout->indexOf(dragWidget) >= 0) {
219 helper.setCurrentDragWidget(dragWidget);
219 helper.setCurrentDragWidget(dragWidget);
220
220
221 if (impl->cursorIsInContainer(this)) {
221 if (impl->cursorIsInContainer(this)) {
222 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
222 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
223 helper.insertPlaceHolder(impl->m_Layout, dragWidgetIndex, impl->m_PlaceHolderType,
223 helper.insertPlaceHolder(impl->m_Layout, dragWidgetIndex, impl->m_PlaceHolderType,
224 impl->m_PlaceHolderText);
224 impl->m_PlaceHolderText);
225 dragWidget->setVisible(false);
225 dragWidget->setVisible(false);
226 }
226 }
227 else {
227 else {
228 // The drag starts directly outside the drop zone
228 // The drag starts directly outside the drop zone
229 // do not add the placeHolder
229 // do not add the placeHolder
230 }
230 }
231
231
232 drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction);
232 drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction);
233
233
234 helper.doCloseWidgets();
234 helper.doCloseWidgets();
235 }
235 }
236 else {
236 else {
237 qCWarning(LOG_VisualizationDragDropContainer())
237 qCWarning(LOG_VisualizationDragDropContainer())
238 << tr("VisualizationDragDropContainer::startDrag, drag aborted, the specified "
238 << tr("VisualizationDragDropContainer::startDrag, drag aborted, the specified "
239 "VisualizationDragWidget is not found in this container.");
239 "VisualizationDragWidget is not found in this container.");
240 }
240 }
241 }
241 }
242
242
243 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
243 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
244 {
244 {
245 if (impl->acceptMimeData(event->mimeData())) {
245 if (impl->acceptMimeData(event->mimeData())) {
246 event->acceptProposedAction();
246 event->acceptProposedAction();
247
247
248 auto &helper = sqpApp->dragDropHelper();
248 auto &helper = sqpApp->dragDropHelper();
249
249
250 if (!impl->hasPlaceHolder()) {
250 if (!impl->hasPlaceHolder()) {
251 auto dragWidget = helper.getCurrentDragWidget();
251 auto dragWidget = helper.getCurrentDragWidget();
252
252
253 if (dragWidget) {
253 if (dragWidget) {
254 // If the drag&drop is internal to the visualization, entering the container hide
254 // If the drag&drop is internal to the visualization, entering the container hide
255 // the dragWidget which was made visible by the dragLeaveEvent
255 // the dragWidget which was made visible by the dragLeaveEvent
256 auto parentWidget
256 auto parentWidget
257 = qobject_cast<VisualizationDragDropContainer *>(dragWidget->parentWidget());
257 = qobject_cast<VisualizationDragDropContainer *>(dragWidget->parentWidget());
258 if (parentWidget) {
258 if (parentWidget) {
259 dragWidget->setVisible(false);
259 dragWidget->setVisible(false);
260 }
260 }
261 }
261 }
262
262
263 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
263 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
264 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
264 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
265 impl->findPlaceHolderPosition(event->pos(), canInsert, canMerge, this);
265 impl->findPlaceHolderPosition(event->pos(), canInsert, canMerge, this);
266 }
266 }
267 else {
267 else {
268 // do nothing
268 // do nothing
269 }
269 }
270 }
270 }
271 else {
271 else {
272 event->ignore();
272 event->ignore();
273 }
273 }
274
274
275 QWidget::dragEnterEvent(event);
275 QWidget::dragEnterEvent(event);
276 }
276 }
277
277
278 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event)
278 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event)
279 {
279 {
280 Q_UNUSED(event);
280 Q_UNUSED(event);
281
281
282 auto &helper = sqpApp->dragDropHelper();
282 auto &helper = sqpApp->dragDropHelper();
283
283
284 if (!impl->cursorIsInContainer(this)) {
284 if (!impl->cursorIsInContainer(this)) {
285 helper.removePlaceHolder();
285 helper.removePlaceHolder();
286 helper.setHightlightedDragWidget(nullptr);
286 helper.setHightlightedDragWidget(nullptr);
287 impl->m_MinContainerHeight = 0;
287 impl->m_MinContainerHeight = 0;
288
288
289 auto dragWidget = helper.getCurrentDragWidget();
289 auto dragWidget = helper.getCurrentDragWidget();
290 if (dragWidget) {
290 if (dragWidget) {
291 // dragWidget has a value only if the drag is started from the visualization
291 // dragWidget has a value only if the drag is started from the visualization
292 // In that case, shows the drag widget at its original place
292 // In that case, shows the drag widget at its original place
293 // So the drag widget doesn't stay hidden if the drop occurs outside the visualization
293 // So the drag widget doesn't stay hidden if the drop occurs outside the visualization
294 // drop zone (It is not possible to catch a drop event outside of the application)
294 // drop zone (It is not possible to catch a drop event outside of the application)
295
295
296 if (dragWidget) {
296 if (dragWidget) {
297 dragWidget->setVisible(true);
297 dragWidget->setVisible(true);
298 }
298 }
299 }
299 }
300 }
300 }
301 else {
301 else {
302 // Leave event probably received for a child widget.
302 // Leave event probably received for a child widget.
303 // Do nothing.
303 // Do nothing.
304 // Note: The DragLeave event, doesn't have any mean to determine who sent it.
304 // Note: The DragLeave event, doesn't have any mean to determine who sent it.
305 }
305 }
306
306
307 QWidget::dragLeaveEvent(event);
307 QWidget::dragLeaveEvent(event);
308 }
308 }
309
309
310 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event)
310 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event)
311 {
311 {
312 if (impl->acceptMimeData(event->mimeData())) {
312 if (impl->acceptMimeData(event->mimeData())) {
313 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
313 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
314 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
314 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
315 impl->findPlaceHolderPosition(event->pos(), canInsert, canMerge, this);
315 impl->findPlaceHolderPosition(event->pos(), canInsert, canMerge, this);
316 }
316 }
317 else {
317 else {
318 event->ignore();
318 event->ignore();
319 }
319 }
320
320
321 QWidget::dragMoveEvent(event);
321 QWidget::dragMoveEvent(event);
322 }
322 }
323
323
324 void VisualizationDragDropContainer::dropEvent(QDropEvent *event)
324 void VisualizationDragDropContainer::dropEvent(QDropEvent *event)
325 {
325 {
326 auto &helper = sqpApp->dragDropHelper();
326 auto &helper = sqpApp->dragDropHelper();
327
327
328 if (impl->acceptMimeData(event->mimeData())) {
328 if (impl->acceptMimeData(event->mimeData())) {
329 auto dragWidget = helper.getCurrentDragWidget();
329 auto dragWidget = helper.getCurrentDragWidget();
330 if (impl->hasPlaceHolder()) {
330 if (impl->hasPlaceHolder()) {
331 // drop where the placeHolder is located
331 // drop where the placeHolder is located
332
332
333 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
333 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
334 if (canInsert) {
334 if (canInsert) {
335 auto droppedIndex = impl->m_Layout->indexOf(&helper.placeHolder());
335 auto droppedIndex = impl->m_Layout->indexOf(&helper.placeHolder());
336
336
337 if (dragWidget) {
337 if (dragWidget) {
338 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
338 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
339 if (dragWidgetIndex >= 0 && dragWidgetIndex < droppedIndex) {
339 if (dragWidgetIndex >= 0 && dragWidgetIndex < droppedIndex) {
340 // Correction of the index if the drop occurs in the same container
340 // Correction of the index if the drop occurs in the same container
341 // and if the drag is started from the visualization (in that case, the
341 // and if the drag is started from the visualization (in that case, the
342 // dragWidget is hidden)
342 // dragWidget is hidden)
343 droppedIndex -= 1;
343 droppedIndex -= 1;
344 }
344 }
345
345
346 dragWidget->setVisible(true);
346 dragWidget->setVisible(true);
347 }
347 }
348
348
349 event->acceptProposedAction();
349 event->acceptProposedAction();
350
350
351 helper.removePlaceHolder();
351 helper.removePlaceHolder();
352
352
353 emit dropOccuredInContainer(droppedIndex, event->mimeData());
353 emit dropOccuredInContainer(droppedIndex, event->mimeData());
354 }
354 }
355 else {
355 else {
356 qCWarning(LOG_VisualizationDragDropContainer()) << tr(
356 qCWarning(LOG_VisualizationDragDropContainer()) << tr(
357 "VisualizationDragDropContainer::dropEvent, dropping on the placeHolder, but "
357 "VisualizationDragDropContainer::dropEvent, dropping on the placeHolder, but "
358 "the insertion is forbidden.");
358 "the insertion is forbidden.");
359 Q_ASSERT(false);
359 Q_ASSERT(false);
360 }
360 }
361 }
361 }
362 else if (helper.getHightlightedDragWidget()) {
362 else if (helper.getHightlightedDragWidget()) {
363 // drop on the highlighted widget
363 // drop on the highlighted widget
364
364
365 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
365 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
366 if (canMerge) {
366 if (canMerge) {
367 event->acceptProposedAction();
367 event->acceptProposedAction();
368 emit dropOccuredOnWidget(helper.getHightlightedDragWidget(), event->mimeData());
368 emit dropOccuredOnWidget(helper.getHightlightedDragWidget(), event->mimeData());
369 }
369 }
370 else {
370 else {
371 qCWarning(LOG_VisualizationDragDropContainer())
371 qCWarning(LOG_VisualizationDragDropContainer())
372 << tr("VisualizationDragDropContainer::dropEvent, dropping on a widget, but "
372 << tr("VisualizationDragDropContainer::dropEvent, dropping on a widget, but "
373 "the merge is forbidden.");
373 "the merge is forbidden.");
374 Q_ASSERT(false);
374 Q_ASSERT(false);
375 }
375 }
376 }
376 }
377 }
377 }
378 else {
378 else {
379 event->ignore();
379 event->ignore();
380 }
380 }
381
381
382 sqpApp->dragDropHelper().setHightlightedDragWidget(nullptr);
382 sqpApp->dragDropHelper().setHightlightedDragWidget(nullptr);
383 impl->m_MinContainerHeight = 0;
383 impl->m_MinContainerHeight = 0;
384
384
385 QWidget::dropEvent(event);
385 QWidget::dropEvent(event);
386 }
386 }
387
387
388
388
389 void VisualizationDragDropContainer::VisualizationDragDropContainerPrivate::findPlaceHolderPosition(
389 void VisualizationDragDropContainer::VisualizationDragDropContainerPrivate::findPlaceHolderPosition(
390 const QPoint &pos, bool canInsert, bool canMerge,
390 const QPoint &pos, bool canInsert, bool canMerge,
391 const VisualizationDragDropContainer *container)
391 const VisualizationDragDropContainer *container)
392 {
392 {
393 auto &helper = sqpApp->dragDropHelper();
393 auto &helper = sqpApp->dragDropHelper();
394
394
395 auto absPos = container->mapToGlobal(pos);
395 auto absPos = container->mapToGlobal(pos);
396 auto isOnPlaceHolder = helper.placeHolder().isAncestorOf(sqpApp->widgetAt(absPos));
396 auto isOnPlaceHolder = helper.placeHolder().isAncestorOf(sqpApp->widgetAt(absPos));
397
397
398 if (countDragWidget(container, true) == 0) {
398 if (countDragWidget(container, true) == 0) {
399 // Drop on an empty container, just add the placeHolder at the top
399 // Drop on an empty container, just add the placeHolder at the top
400 helper.insertPlaceHolder(m_Layout, 0, m_PlaceHolderType, m_PlaceHolderText);
400 helper.insertPlaceHolder(m_Layout, 0, m_PlaceHolderType, m_PlaceHolderText);
401 }
401 }
402 else if (!isOnPlaceHolder) {
402 else if (!isOnPlaceHolder) {
403 auto nbDragWidget = countDragWidget(container);
403 auto nbDragWidget = countDragWidget(container);
404 if (nbDragWidget > 0) {
404 if (nbDragWidget > 0) {
405
405
406 if (m_MinContainerHeight == 0) {
406 if (m_MinContainerHeight == 0) {
407 m_MinContainerHeight = container->size().height();
407 m_MinContainerHeight = container->size().height();
408 }
408 }
409
409
410 m_MinContainerHeight = qMin(m_MinContainerHeight, container->size().height());
410 m_MinContainerHeight = qMin(m_MinContainerHeight, container->size().height());
411 auto graphHeight = qMax(m_MinContainerHeight / nbDragWidget, GRAPH_MINIMUM_HEIGHT);
411 auto graphHeight = qMax(m_MinContainerHeight / nbDragWidget, GRAPH_MINIMUM_HEIGHT);
412
412
413 auto posY = pos.y();
413 auto posY = pos.y();
414 auto dropIndex = floor(posY / graphHeight);
414 auto dropIndex = floor(posY / graphHeight);
415 auto zoneSize = qMin(graphHeight / 4.0, 75.0);
415 auto zoneSize = qMin(graphHeight / 4.0, 75.0);
416
416
417
417
418 auto isOnTop = posY < dropIndex * graphHeight + zoneSize;
418 auto isOnTop = posY < dropIndex * graphHeight + zoneSize;
419 auto isOnBottom = posY > (dropIndex + 1) * graphHeight - zoneSize;
419 auto isOnBottom = posY > (dropIndex + 1) * graphHeight - zoneSize;
420
420
421 auto placeHolderIndex = m_Layout->indexOf(&(helper.placeHolder()));
421 auto placeHolderIndex = m_Layout->indexOf(&(helper.placeHolder()));
422
422
423 auto dragWidgetHovered = getChildDragWidgetAt(container, pos);
423 auto dragWidgetHovered = getChildDragWidgetAt(container, pos);
424
424
425 if (canInsert && (isOnTop || isOnBottom || !canMerge)) {
425 if (canInsert && (isOnTop || isOnBottom || !canMerge)) {
426 if (isOnBottom) {
426 if (isOnBottom) {
427 dropIndex += 1;
427 dropIndex += 1;
428 }
428 }
429
429
430 if (helper.getCurrentDragWidget()) {
430 if (helper.getCurrentDragWidget()) {
431 auto dragWidgetIndex = m_Layout->indexOf(helper.getCurrentDragWidget());
431 auto dragWidgetIndex = m_Layout->indexOf(helper.getCurrentDragWidget());
432 if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) {
432 if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) {
433 // Correction of the index if the drop occurs in the same container
433 // Correction of the index if the drop occurs in the same container
434 // and if the drag is started from the visualization (in that case, the
434 // and if the drag is started from the visualization (in that case, the
435 // dragWidget is hidden)
435 // dragWidget is hidden)
436 dropIndex += 1;
436 dropIndex += 1;
437 }
437 }
438 }
438 }
439
439
440 if (dropIndex != placeHolderIndex) {
440 if (dropIndex != placeHolderIndex) {
441 helper.insertPlaceHolder(m_Layout, dropIndex, m_PlaceHolderType,
441 helper.insertPlaceHolder(m_Layout, dropIndex, m_PlaceHolderType,
442 m_PlaceHolderText);
442 m_PlaceHolderText);
443 }
443 }
444
444
445 helper.setHightlightedDragWidget(nullptr);
445 helper.setHightlightedDragWidget(nullptr);
446 }
446 }
447 else if (canMerge && dragWidgetHovered) {
447 else if (canMerge && dragWidgetHovered) {
448 // drop on the middle -> merge
448 // drop on the middle -> merge
449 if (hasPlaceHolder()) {
449 if (hasPlaceHolder()) {
450 helper.removePlaceHolder();
450 helper.removePlaceHolder();
451 }
451 }
452
452
453 helper.setHightlightedDragWidget(dragWidgetHovered);
453 helper.setHightlightedDragWidget(dragWidgetHovered);
454 }
454 }
455 else {
455 else {
456 qCWarning(LOG_VisualizationDragDropContainer())
456 qCWarning(LOG_VisualizationDragDropContainer())
457 << tr("VisualizationDragDropContainer::findPlaceHolderPosition, no valid drop "
457 << tr("VisualizationDragDropContainer::findPlaceHolderPosition, no valid drop "
458 "action.");
458 "action.");
459 }
459 }
460 }
460 }
461 else {
461 else {
462 qCWarning(LOG_VisualizationDragDropContainer())
462 qCWarning(LOG_VisualizationDragDropContainer())
463 << tr("VisualizationDragDropContainer::findPlaceHolderPosition, no widget "
463 << tr("VisualizationDragDropContainer::findPlaceHolderPosition, no widget "
464 "found in the "
464 "found in the "
465 "container");
465 "container");
466 }
466 }
467 }
467 }
468 else {
468 else {
469 // the mouse is hover the placeHolder
469 // the mouse is hover the placeHolder
470 // Do nothing
470 // Do nothing
471 }
471 }
472 }
472 }
General Comments 1
Under Review
author

Auto status change to "Under Review"

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