Auto status change to "Under Review"
@@ -14,6 +14,7 extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_ZONE; | |||||
14 | extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_VARIABLE_LIST; |
|
14 | extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_VARIABLE_LIST; | |
15 | extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_PRODUCT_LIST; |
|
15 | extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_PRODUCT_LIST; | |
16 | extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_TIME_RANGE; |
|
16 | extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_TIME_RANGE; | |
|
17 | extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_SELECTION_ZONE; | |||
17 |
|
18 | |||
18 |
|
19 | |||
19 | #endif // SCIQLOP_MIMETYPESDEF_H |
|
20 | #endif // SCIQLOP_MIMETYPESDEF_H |
@@ -5,3 +5,4 const QString MIME_TYPE_ZONE = QStringLiteral("sciqlop/zone"); | |||||
5 | const QString MIME_TYPE_VARIABLE_LIST = QStringLiteral("sciqlop/var-list"); |
|
5 | const QString MIME_TYPE_VARIABLE_LIST = QStringLiteral("sciqlop/var-list"); | |
6 | const QString MIME_TYPE_PRODUCT_LIST = QStringLiteral("sciqlop/product-list"); |
|
6 | const QString MIME_TYPE_PRODUCT_LIST = QStringLiteral("sciqlop/product-list"); | |
7 | const QString MIME_TYPE_TIME_RANGE = QStringLiteral("sciqlop/time-range"); |
|
7 | const QString MIME_TYPE_TIME_RANGE = QStringLiteral("sciqlop/time-range"); | |
|
8 | const QString MIME_TYPE_SELECTION_ZONE = QStringLiteral("sciqlop/selection-zone"); |
@@ -11,9 +11,13 class VisualizationDragWidget : public QWidget { | |||||
11 | public: |
|
11 | public: | |
12 | VisualizationDragWidget(QWidget *parent = nullptr); |
|
12 | VisualizationDragWidget(QWidget *parent = nullptr); | |
13 |
|
13 | |||
14 | virtual QMimeData *mimeData() const = 0; |
|
14 | virtual QMimeData *mimeData(const QPoint &position) const = 0; | |
15 | virtual bool isDragAllowed() const = 0; |
|
15 | virtual bool isDragAllowed() const = 0; | |
16 |
virtual void highlightForMerge(bool highlighted) { Q_UNUSED(highlighted); } |
|
16 | virtual void highlightForMerge(bool highlighted) { Q_UNUSED(highlighted); } | |
|
17 | ||||
|
18 | /// Custom pixmap to display during a drag operation. | |||
|
19 | /// If the provided pixmap is null, a pixmap of the entire widget is used. | |||
|
20 | virtual QPixmap customDragPixmap(const QPoint &dragPosition); | |||
17 |
|
21 | |||
18 | protected: |
|
22 | protected: | |
19 | virtual void mousePressEvent(QMouseEvent *event) override; |
|
23 | virtual void mousePressEvent(QMouseEvent *event) override; |
@@ -61,7 +61,8 public: | |||||
61 | QString name() const override; |
|
61 | QString name() const override; | |
62 |
|
62 | |||
63 | // VisualisationDragWidget |
|
63 | // VisualisationDragWidget | |
64 | QMimeData *mimeData() const override; |
|
64 | QMimeData *mimeData(const QPoint &position) const override; | |
|
65 | QPixmap customDragPixmap(const QPoint &dragPosition) override; | |||
65 | bool isDragAllowed() const override; |
|
66 | bool isDragAllowed() const override; | |
66 | void highlightForMerge(bool highlighted) override; |
|
67 | void highlightForMerge(bool highlighted) override; | |
67 |
|
68 | |||
@@ -92,7 +93,7 protected: | |||||
92 | void enterEvent(QEvent *event) override; |
|
93 | void enterEvent(QEvent *event) override; | |
93 | void leaveEvent(QEvent *event) override; |
|
94 | void leaveEvent(QEvent *event) override; | |
94 |
|
95 | |||
95 | QCustomPlot &plot() noexcept; |
|
96 | QCustomPlot &plot() const noexcept; | |
96 |
|
97 | |||
97 | private: |
|
98 | private: | |
98 | Ui::VisualizationGraphWidget *ui; |
|
99 | Ui::VisualizationGraphWidget *ui; |
@@ -67,7 +67,7 public: | |||||
67 | QString name() const override; |
|
67 | QString name() const override; | |
68 |
|
68 | |||
69 | // VisualisationDragWidget |
|
69 | // VisualisationDragWidget | |
70 | QMimeData *mimeData() const override; |
|
70 | QMimeData *mimeData(const QPoint &position) const override; | |
71 | bool isDragAllowed() const override; |
|
71 | bool isDragAllowed() const override; | |
72 |
|
72 | |||
73 | void notifyMouseMoveInGraph(const QPointF &graphPosition, const QPointF &plotPosition, |
|
73 | void notifyMouseMoveInGraph(const QPointF &graphPosition, const QPointF &plotPosition, |
@@ -212,11 +212,15 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidg | |||||
212 | // Note: The management of the drag object is done by Qt |
|
212 | // Note: The management of the drag object is done by Qt | |
213 | auto drag = new QDrag{dragWidget}; |
|
213 | auto drag = new QDrag{dragWidget}; | |
214 |
|
214 | |||
215 | auto mimeData = dragWidget->mimeData(); |
|
215 | auto mimeData = dragWidget->mimeData(dragPosition); | |
216 | drag->setMimeData(mimeData); |
|
216 | drag->setMimeData(mimeData); | |
217 |
|
217 | |||
218 |
auto pixmap = |
|
218 | auto pixmap = dragWidget->customDragPixmap(dragPosition); | |
|
219 | if (pixmap.isNull()) { | |||
|
220 | pixmap = QPixmap{dragWidget->size()}; | |||
219 | dragWidget->render(&pixmap); |
|
221 | dragWidget->render(&pixmap); | |
|
222 | } | |||
|
223 | ||||
220 | drag->setPixmap(pixmap.scaled(DRAGGED_MINIATURE_WIDTH, DRAGGED_MINIATURE_WIDTH, |
|
224 | drag->setPixmap(pixmap.scaled(DRAGGED_MINIATURE_WIDTH, DRAGGED_MINIATURE_WIDTH, | |
221 | Qt::KeepAspectRatio, Qt::SmoothTransformation)); |
|
225 | Qt::KeepAspectRatio, Qt::SmoothTransformation)); | |
222 |
|
226 | |||
@@ -225,6 +229,8 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidg | |||||
225 | mimeData->setUrls({helper.imageTemporaryUrl(image)}); |
|
229 | mimeData->setUrls({helper.imageTemporaryUrl(image)}); | |
226 |
|
230 | |||
227 | if (impl->m_Layout->indexOf(dragWidget) >= 0) { |
|
231 | if (impl->m_Layout->indexOf(dragWidget) >= 0) { | |
|
232 | ||||
|
233 | if (impl->acceptMimeData(mimeData) && impl->allowInsertForMimeData(mimeData)) { | |||
228 | helper.setCurrentDragWidget(dragWidget); |
|
234 | helper.setCurrentDragWidget(dragWidget); | |
229 |
|
235 | |||
230 | if (impl->cursorIsInContainer(this)) { |
|
236 | if (impl->cursorIsInContainer(this)) { | |
@@ -237,6 +243,7 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidg | |||||
237 | // The drag starts directly outside the drop zone |
|
243 | // The drag starts directly outside the drop zone | |
238 | // do not add the placeHolder |
|
244 | // do not add the placeHolder | |
239 | } |
|
245 | } | |
|
246 | } | |||
240 |
|
247 | |||
241 | drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction); |
|
248 | drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction); | |
242 |
|
249 |
@@ -19,6 +19,12 VisualizationDragWidget::VisualizationDragWidget(QWidget *parent) | |||||
19 | { |
|
19 | { | |
20 | } |
|
20 | } | |
21 |
|
21 | |||
|
22 | virtual QPixmap VisualizationDragWidget::customDragPixmap(const QPoint &dragPosition) | |||
|
23 | { | |||
|
24 | Q_UNUSED(dragPosition); | |||
|
25 | return QPixmap(); | |||
|
26 | } | |||
|
27 | ||||
22 | void VisualizationDragWidget::mousePressEvent(QMouseEvent *event) |
|
28 | void VisualizationDragWidget::mousePressEvent(QMouseEvent *event) | |
23 | { |
|
29 | { | |
24 | if (event->button() == Qt::LeftButton) { |
|
30 | if (event->button() == Qt::LeftButton) { |
@@ -25,6 +25,9 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget") | |||||
25 |
|
25 | |||
26 | namespace { |
|
26 | namespace { | |
27 |
|
27 | |||
|
28 | /// Key pressed to enable drag&drop in all modes | |||
|
29 | const auto DRAG_DROP_MODIFIER = Qt::AltModifier; | |||
|
30 | ||||
28 | /// Key pressed to enable zoom on horizontal axis |
|
31 | /// Key pressed to enable zoom on horizontal axis | |
29 | const auto HORIZONTAL_ZOOM_MODIFIER = Qt::ControlModifier; |
|
32 | const auto HORIZONTAL_ZOOM_MODIFIER = Qt::ControlModifier; | |
30 |
|
33 | |||
@@ -141,6 +144,22 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { | |||||
141 | } |
|
144 | } | |
142 | } |
|
145 | } | |
143 |
|
146 | |||
|
147 | VisualizationSelectionZoneItem *selectionZoneAt(const QPoint &pos, | |||
|
148 | const QCustomPlot &plot) const | |||
|
149 | { | |||
|
150 | VisualizationSelectionZoneItem *selectionZoneItemUnderCursor = nullptr; | |||
|
151 | auto minDistanceToZone = -1; | |||
|
152 | for (auto zone : m_SelectionZones) { | |||
|
153 | auto distanceToZone = zone->selectTest(pos, false); | |||
|
154 | if ((minDistanceToZone < 0 || distanceToZone <= minDistanceToZone) | |||
|
155 | && distanceToZone >= 0 && distanceToZone < plot.selectionTolerance()) { | |||
|
156 | selectionZoneItemUnderCursor = zone; | |||
|
157 | } | |||
|
158 | } | |||
|
159 | ||||
|
160 | return selectionZoneItemUnderCursor; | |||
|
161 | } | |||
|
162 | ||||
144 | QPointF posToAxisPos(const QPoint &pos, QCustomPlot &plot) const |
|
163 | QPointF posToAxisPos(const QPoint &pos, QCustomPlot &plot) const | |
145 | { |
|
164 | { | |
146 | auto axisX = plot.axisRect()->axis(QCPAxis::atBottom); |
|
165 | auto axisX = plot.axisRect()->axis(QCPAxis::atBottom); | |
@@ -371,17 +390,50 QString VisualizationGraphWidget::name() const | |||||
371 | return impl->m_Name; |
|
390 | return impl->m_Name; | |
372 | } |
|
391 | } | |
373 |
|
392 | |||
374 | QMimeData *VisualizationGraphWidget::mimeData() const |
|
393 | QMimeData *VisualizationGraphWidget::mimeData(const QPoint &position) const | |
375 | { |
|
394 | { | |
376 | auto mimeData = new QMimeData; |
|
395 | auto mimeData = new QMimeData; | |
|
396 | ||||
|
397 | auto selectionZoneItemUnderCursor = impl->selectionZoneAt(position, plot()); | |||
|
398 | if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones | |||
|
399 | && selectionZoneItemUnderCursor) { | |||
|
400 | mimeData->setData(MIME_TYPE_TIME_RANGE, TimeController::mimeDataForTimeRange( | |||
|
401 | selectionZoneItemUnderCursor->range())); | |||
|
402 | mimeData->setData(MIME_TYPE_SELECTION_ZONE, TimeController::mimeDataForTimeRange( | |||
|
403 | selectionZoneItemUnderCursor->range())); | |||
|
404 | } | |||
|
405 | else { | |||
377 | mimeData->setData(MIME_TYPE_GRAPH, QByteArray{}); |
|
406 | mimeData->setData(MIME_TYPE_GRAPH, QByteArray{}); | |
378 |
|
407 | |||
379 | auto timeRangeData = TimeController::mimeDataForTimeRange(graphRange()); |
|
408 | auto timeRangeData = TimeController::mimeDataForTimeRange(graphRange()); | |
380 | mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData); |
|
409 | mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData); | |
|
410 | } | |||
381 |
|
411 | |||
382 | return mimeData; |
|
412 | return mimeData; | |
383 | } |
|
413 | } | |
384 |
|
414 | |||
|
415 | QPixmap VisualizationGraphWidget::customDragPixmap(const QPoint &dragPosition) | |||
|
416 | { | |||
|
417 | auto selectionZoneItemUnderCursor = impl->selectionZoneAt(dragPosition, plot()); | |||
|
418 | if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones | |||
|
419 | && selectionZoneItemUnderCursor) { | |||
|
420 | ||||
|
421 | auto zoneTopLeft = selectionZoneItemUnderCursor->topLeft->pixelPosition(); | |||
|
422 | auto zoneBottomRight = selectionZoneItemUnderCursor->bottomRight->pixelPosition(); | |||
|
423 | ||||
|
424 | auto zoneSize = QSizeF{qAbs(zoneBottomRight.x() - zoneTopLeft.x()), | |||
|
425 | qAbs(zoneBottomRight.y() - zoneTopLeft.y())} | |||
|
426 | .toSize(); | |||
|
427 | ||||
|
428 | auto pixmap = QPixmap(zoneSize); | |||
|
429 | render(&pixmap, QPoint(), QRegion{QRect{zoneTopLeft.toPoint(), zoneSize}}); | |||
|
430 | ||||
|
431 | return pixmap; | |||
|
432 | } | |||
|
433 | ||||
|
434 | return QPixmap(); | |||
|
435 | } | |||
|
436 | ||||
385 | bool VisualizationGraphWidget::isDragAllowed() const |
|
437 | bool VisualizationGraphWidget::isDragAllowed() const | |
386 | { |
|
438 | { | |
387 | return true; |
|
439 | return true; | |
@@ -482,7 +534,7 void VisualizationGraphWidget::leaveEvent(QEvent *event) | |||||
482 | } |
|
534 | } | |
483 | } |
|
535 | } | |
484 |
|
536 | |||
485 | QCustomPlot &VisualizationGraphWidget::plot() noexcept |
|
537 | QCustomPlot &VisualizationGraphWidget::plot() const noexcept | |
486 | { |
|
538 | { | |
487 | return *ui->widget; |
|
539 | return *ui->widget; | |
488 | } |
|
540 | } | |
@@ -590,16 +642,7 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept | |||||
590 | } |
|
642 | } | |
591 |
|
643 | |||
592 | // Search for the selection zone under the mouse |
|
644 | // Search for the selection zone under the mouse | |
593 | VisualizationSelectionZoneItem *selectionZoneItemUnderCursor = nullptr; |
|
645 | auto selectionZoneItemUnderCursor = impl->selectionZoneAt(event->pos(), plot()); | |
594 | auto minDistanceToZone = -1; |
|
|||
595 | for (auto zone : impl->m_SelectionZones) { |
|
|||
596 | auto distanceToZone = zone->selectTest(event->pos(), true); |
|
|||
597 | if ((minDistanceToZone < 0 || distanceToZone <= minDistanceToZone) && distanceToZone >= 0 |
|
|||
598 | && distanceToZone < plot().selectionTolerance()) { |
|
|||
599 | selectionZoneItemUnderCursor = zone; |
|
|||
600 | } |
|
|||
601 | } |
|
|||
602 |
|
||||
603 | if (selectionZoneItemUnderCursor && !impl->m_DrawingZone |
|
646 | if (selectionZoneItemUnderCursor && !impl->m_DrawingZone | |
604 | && sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones) { |
|
647 | && sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones) { | |
605 |
|
648 | |||
@@ -663,29 +706,36 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept | |||||
663 |
|
706 | |||
664 | void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept |
|
707 | void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept | |
665 | { |
|
708 | { | |
|
709 | bool isDragDropClick = event->modifiers().testFlag(DRAG_DROP_MODIFIER); | |||
|
710 | ||||
|
711 | if (!isDragDropClick) { | |||
666 | if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::ZoomBox) { |
|
712 | if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::ZoomBox) { | |
667 | // Starts a zoom box |
|
713 | // Starts a zoom box | |
668 | impl->startDrawingRect(event->pos(), plot()); |
|
714 | impl->startDrawingRect(event->pos(), plot()); | |
669 | } |
|
715 | } | |
670 | else if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones |
|
716 | else if (sqpApp->plotsInteractionMode() | |
|
717 | == SqpApplication::PlotsInteractionMode::SelectionZones | |||
671 | && impl->m_DrawingZone == nullptr) { |
|
718 | && impl->m_DrawingZone == nullptr) { | |
672 | // Starts a new selection zone |
|
719 | // Starts a new selection zone | |
673 |
auto |
|
720 | auto zoneAtPos = impl->selectionZoneAt(event->pos(), plot()); | |
674 |
if (! |
|
721 | if (!zoneAtPos) { | |
675 | impl->startDrawingZone(event->pos(), plot()); |
|
722 | impl->startDrawingZone(event->pos(), plot()); | |
676 | } |
|
723 | } | |
677 | } |
|
724 | } | |
|
725 | } | |||
678 | else if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::None) { |
|
726 | else if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::None) { | |
679 | plot().setInteraction(QCP::iRangeDrag, true); |
|
727 | plot().setInteraction(QCP::iRangeDrag, true); | |
680 | } |
|
728 | } | |
681 |
|
729 | |||
682 | // Allows mouse panning only in default mode |
|
730 | // Allows mouse panning only in default mode | |
683 | plot().setInteraction(QCP::iRangeDrag, sqpApp->plotsInteractionMode() |
|
731 | plot().setInteraction(QCP::iRangeDrag, sqpApp->plotsInteractionMode() | |
684 |
== SqpApplication::PlotsInteractionMode::None |
|
732 | == SqpApplication::PlotsInteractionMode::None | |
|
733 | && !isDragDropClick); | |||
685 |
|
734 | |||
686 | // Allows zone edition only in selection zone mode |
|
735 | // Allows zone edition only in selection zone mode without ALT pressed (ALT is for drag&drop) | |
687 |
impl->setSelectionZonesEditionEnabled( |
|
736 | impl->setSelectionZonesEditionEnabled( | |
688 |
|
|
737 | sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones | |
|
738 | && !isDragDropClick); | |||
689 |
|
739 | |||
690 | VisualizationDragWidget::mousePressEvent(event); |
|
740 | VisualizationDragWidget::mousePressEvent(event); | |
691 | } |
|
741 | } |
@@ -33,7 +33,7 struct VisualizationSelectionZoneItem::VisualizationSelectionZoneItemPrivate { | |||||
33 | { |
|
33 | { | |
34 | auto distanceLeft = m_LeftLine->selectTest(pos, false); |
|
34 | auto distanceLeft = m_LeftLine->selectTest(pos, false); | |
35 | auto distanceRight = m_RightLine->selectTest(pos, false); |
|
35 | auto distanceRight = m_RightLine->selectTest(pos, false); | |
36 |
auto distance = zoneItem->selectTest(pos, |
|
36 | auto distance = zoneItem->selectTest(pos, false); | |
37 |
|
37 | |||
38 | if (distanceRight <= distance) { |
|
38 | if (distanceRight <= distance) { | |
39 | return VisualizationSelectionZoneItemPrivate::EditionMode::ResizeRight; |
|
39 | return VisualizationSelectionZoneItemPrivate::EditionMode::ResizeRight; | |
@@ -173,6 +173,7 void VisualizationSelectionZoneItem::setEditionEnabled(bool value) | |||||
173 | setSelectable(value); |
|
173 | setSelectable(value); | |
174 | if (!value) { |
|
174 | if (!value) { | |
175 | setSelected(false); |
|
175 | setSelected(false); | |
|
176 | impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition; | |||
176 | } |
|
177 | } | |
177 | } |
|
178 | } | |
178 |
|
179 |
@@ -110,6 +110,8 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p | |||||
110 | VisualizationDragDropContainer::DropBehavior::Merged); |
|
110 | VisualizationDragDropContainer::DropBehavior::Merged); | |
111 | ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE, |
|
111 | ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE, | |
112 | VisualizationDragDropContainer::DropBehavior::Forbidden); |
|
112 | VisualizationDragDropContainer::DropBehavior::Forbidden); | |
|
113 | ui->dragDropContainer->setMimeType(MIME_TYPE_SELECTION_ZONE, | |||
|
114 | VisualizationDragDropContainer::DropBehavior::Forbidden); | |||
113 | ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) { |
|
115 | ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) { | |
114 | return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData, |
|
116 | return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData, | |
115 | ui->dragDropContainer); |
|
117 | ui->dragDropContainer); | |
@@ -352,8 +354,10 QString VisualizationZoneWidget::name() const | |||||
352 | return ui->zoneNameLabel->text(); |
|
354 | return ui->zoneNameLabel->text(); | |
353 | } |
|
355 | } | |
354 |
|
356 | |||
355 | QMimeData *VisualizationZoneWidget::mimeData() const |
|
357 | QMimeData *VisualizationZoneWidget::mimeData(const QPoint &position) const | |
356 | { |
|
358 | { | |
|
359 | Q_UNUSED(position); | |||
|
360 | ||||
357 | auto mimeData = new QMimeData; |
|
361 | auto mimeData = new QMimeData; | |
358 | mimeData->setData(MIME_TYPE_ZONE, QByteArray{}); |
|
362 | mimeData->setData(MIME_TYPE_ZONE, QByteArray{}); | |
359 |
|
363 |
General Comments 3
Status change > Approved
You need to be logged in to leave comments.
Login now