Auto status change to "Under Review"
@@ -0,0 +1,30 | |||
|
1 | #ifndef SCIQLOP_VISUALIZATIONMULTIZONESELECTIONDIALOG_H | |
|
2 | #define SCIQLOP_VISUALIZATIONMULTIZONESELECTIONDIALOG_H | |
|
3 | ||
|
4 | #include <Common/spimpl.h> | |
|
5 | #include <QDialog> | |
|
6 | ||
|
7 | namespace Ui { | |
|
8 | class VisualizationMultiZoneSelectionDialog; | |
|
9 | } | |
|
10 | ||
|
11 | class VisualizationSelectionZoneItem; | |
|
12 | ||
|
13 | class VisualizationMultiZoneSelectionDialog : public QDialog { | |
|
14 | Q_OBJECT | |
|
15 | ||
|
16 | public: | |
|
17 | explicit VisualizationMultiZoneSelectionDialog(QWidget *parent = 0); | |
|
18 | ~VisualizationMultiZoneSelectionDialog(); | |
|
19 | ||
|
20 | void setZones(const QVector<VisualizationSelectionZoneItem *> &zones); | |
|
21 | QMap<VisualizationSelectionZoneItem *, bool> selectedZones() const; | |
|
22 | ||
|
23 | private: | |
|
24 | Ui::VisualizationMultiZoneSelectionDialog *ui; | |
|
25 | ||
|
26 | class VisualizationMultiZoneSelectionDialogPrivate; | |
|
27 | spimpl::unique_impl_ptr<VisualizationMultiZoneSelectionDialogPrivate> impl; | |
|
28 | }; | |
|
29 | ||
|
30 | #endif // SCIQLOP_VISUALIZATIONMULTIZONESELECTIONDIALOG_H |
@@ -0,0 +1,69 | |||
|
1 | #include "Visualization/VisualizationMultiZoneSelectionDialog.h" | |
|
2 | #include "ui_VisualizationMultiZoneSelectionDialog.h" | |
|
3 | ||
|
4 | #include "Common/DateUtils.h" | |
|
5 | #include "Visualization/VisualizationSelectionZoneItem.h" | |
|
6 | ||
|
7 | const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss"); | |
|
8 | ||
|
9 | struct VisualizationMultiZoneSelectionDialog::VisualizationMultiZoneSelectionDialogPrivate { | |
|
10 | QVector<VisualizationSelectionZoneItem *> m_Zones; | |
|
11 | }; | |
|
12 | ||
|
13 | VisualizationMultiZoneSelectionDialog::VisualizationMultiZoneSelectionDialog(QWidget *parent) | |
|
14 | : QDialog(parent, Qt::Tool), | |
|
15 | ui(new Ui::VisualizationMultiZoneSelectionDialog), | |
|
16 | impl{spimpl::make_unique_impl<VisualizationMultiZoneSelectionDialogPrivate>()} | |
|
17 | { | |
|
18 | ui->setupUi(this); | |
|
19 | ||
|
20 | connect(ui->buttonBox, &QDialogButtonBox::accepted, this, | |
|
21 | &VisualizationMultiZoneSelectionDialog::accept); | |
|
22 | connect(ui->buttonBox, &QDialogButtonBox::rejected, this, | |
|
23 | &VisualizationMultiZoneSelectionDialog::reject); | |
|
24 | } | |
|
25 | ||
|
26 | VisualizationMultiZoneSelectionDialog::~VisualizationMultiZoneSelectionDialog() | |
|
27 | { | |
|
28 | delete ui; | |
|
29 | } | |
|
30 | ||
|
31 | void VisualizationMultiZoneSelectionDialog::setZones( | |
|
32 | const QVector<VisualizationSelectionZoneItem *> &zones) | |
|
33 | { | |
|
34 | impl->m_Zones = zones; | |
|
35 | ||
|
36 | // Sorts the zones to display them in temporal order | |
|
37 | std::sort(impl->m_Zones.begin(), impl->m_Zones.end(), [](auto zone1, auto zone2) { | |
|
38 | return zone1->range().m_TStart < zone2->range().m_TStart; | |
|
39 | }); | |
|
40 | ||
|
41 | // Adds the zones in the listwidget | |
|
42 | for (auto zone : impl->m_Zones) { | |
|
43 | auto name = zone->name(); | |
|
44 | if (!name.isEmpty()) { | |
|
45 | name += tr(": "); | |
|
46 | } | |
|
47 | ||
|
48 | auto range = zone->range(); | |
|
49 | name += DateUtils::dateTime(range.m_TStart).toString(DATETIME_FORMAT); | |
|
50 | name += " - "; | |
|
51 | name += DateUtils::dateTime(range.m_TEnd).toString(DATETIME_FORMAT); | |
|
52 | ||
|
53 | auto item = new QListWidgetItem(name, ui->listWidget); | |
|
54 | item->setSelected(zone->selected()); | |
|
55 | } | |
|
56 | } | |
|
57 | ||
|
58 | QMap<VisualizationSelectionZoneItem *, bool> | |
|
59 | VisualizationMultiZoneSelectionDialog::selectedZones() const | |
|
60 | { | |
|
61 | QMap<VisualizationSelectionZoneItem *, bool> selectedZones; | |
|
62 | ||
|
63 | for (auto i = 0; i < ui->listWidget->count(); ++i) { | |
|
64 | auto item = ui->listWidget->item(i); | |
|
65 | selectedZones[impl->m_Zones[i]] = item->isSelected(); | |
|
66 | } | |
|
67 | ||
|
68 | return selectedZones; | |
|
69 | } |
@@ -0,0 +1,47 | |||
|
1 | <?xml version="1.0" encoding="UTF-8"?> | |
|
2 | <ui version="4.0"> | |
|
3 | <class>VisualizationMultiZoneSelectionDialog</class> | |
|
4 | <widget class="QDialog" name="VisualizationMultiZoneSelectionDialog"> | |
|
5 | <property name="geometry"> | |
|
6 | <rect> | |
|
7 | <x>0</x> | |
|
8 | <y>0</y> | |
|
9 | <width>270</width> | |
|
10 | <height>175</height> | |
|
11 | </rect> | |
|
12 | </property> | |
|
13 | <property name="windowTitle"> | |
|
14 | <string>Select...</string> | |
|
15 | </property> | |
|
16 | <layout class="QVBoxLayout" name="verticalLayout"> | |
|
17 | <property name="leftMargin"> | |
|
18 | <number>0</number> | |
|
19 | </property> | |
|
20 | <property name="topMargin"> | |
|
21 | <number>0</number> | |
|
22 | </property> | |
|
23 | <property name="rightMargin"> | |
|
24 | <number>0</number> | |
|
25 | </property> | |
|
26 | <property name="bottomMargin"> | |
|
27 | <number>0</number> | |
|
28 | </property> | |
|
29 | <item> | |
|
30 | <widget class="QListWidget" name="listWidget"> | |
|
31 | <property name="selectionMode"> | |
|
32 | <enum>QAbstractItemView::ExtendedSelection</enum> | |
|
33 | </property> | |
|
34 | </widget> | |
|
35 | </item> | |
|
36 | <item> | |
|
37 | <widget class="QDialogButtonBox" name="buttonBox"> | |
|
38 | <property name="standardButtons"> | |
|
39 | <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> | |
|
40 | </property> | |
|
41 | </widget> | |
|
42 | </item> | |
|
43 | </layout> | |
|
44 | </widget> | |
|
45 | <resources/> | |
|
46 | <connections/> | |
|
47 | </ui> |
@@ -28,6 +28,10 public: | |||
|
28 | 28 | void setEditionEnabled(bool value); |
|
29 | 29 | bool isEditionEnabled() const; |
|
30 | 30 | |
|
31 | /// Moves the item at the top of its QCPLayer. It will then receive the mouse events if multiple | |
|
32 | /// items are stacked on top of each others. | |
|
33 | void moveToTop(); | |
|
34 | ||
|
31 | 35 | Qt::CursorShape curshorShapeForPosition(const QPoint &position) const; |
|
32 | 36 | void setHovered(bool value); |
|
33 | 37 |
@@ -18,7 +18,8 gui_moc_headers = [ | |||
|
18 | 18 | 'include/Visualization/VisualizationDragDropContainer.h', |
|
19 | 19 | 'include/Visualization/VisualizationDragWidget.h', |
|
20 | 20 | 'include/Visualization/ColorScaleEditor.h', |
|
21 | 'include/Visualization/SelectionZoneAction.h' | |
|
21 | 'include/Visualization/SelectionZoneAction.h', | |
|
22 | 'include/Visualization/VisualizationMultiZoneSelectionDialog.h' | |
|
22 | 23 | ] |
|
23 | 24 | |
|
24 | 25 | gui_ui_files = [ |
@@ -34,7 +35,8 gui_ui_files = [ | |||
|
34 | 35 | 'ui/Visualization/VisualizationTabWidget.ui', |
|
35 | 36 | 'ui/Visualization/VisualizationWidget.ui', |
|
36 | 37 | 'ui/Visualization/VisualizationZoneWidget.ui', |
|
37 | 'ui/Visualization/ColorScaleEditor.ui' | |
|
38 | 'ui/Visualization/ColorScaleEditor.ui', | |
|
39 | 'ui/Visualization/VisualizationMultiZoneSelectionDialog.ui' | |
|
38 | 40 | ] |
|
39 | 41 | |
|
40 | 42 | gui_qresources = ['resources/sqpguiresources.qrc'] |
@@ -88,7 +90,8 gui_sources = [ | |||
|
88 | 90 | 'src/Visualization/VisualizationSelectionZoneManager.cpp', |
|
89 | 91 | 'src/Visualization/SelectionZoneAction.cpp', |
|
90 | 92 | 'src/Visualization/ActionsGuiController.cpp', |
|
91 | 'src/Visualization/VisualizationActionManager.cpp' | |
|
93 | 'src/Visualization/VisualizationActionManager.cpp', | |
|
94 | 'src/Visualization/VisualizationMultiZoneSelectionDialog.cpp' | |
|
92 | 95 | ] |
|
93 | 96 | |
|
94 | 97 | gui_inc = include_directories(['include']) |
@@ -4,6 +4,7 | |||
|
4 | 4 | #include "Visualization/VisualizationDefs.h" |
|
5 | 5 | #include "Visualization/VisualizationGraphHelper.h" |
|
6 | 6 | #include "Visualization/VisualizationGraphRenderingDelegate.h" |
|
7 | #include "Visualization/VisualizationMultiZoneSelectionDialog.h" | |
|
7 | 8 | #include "Visualization/VisualizationSelectionZoneItem.h" |
|
8 | 9 | #include "Visualization/VisualizationSelectionZoneManager.h" |
|
9 | 10 | #include "Visualization/VisualizationWidget.h" |
@@ -170,6 +171,29 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { | |||
|
170 | 171 | return selectionZoneItemUnderCursor; |
|
171 | 172 | } |
|
172 | 173 | |
|
174 | QVector<VisualizationSelectionZoneItem *> selectionZonesAt(const QPoint &pos, | |
|
175 | const QCustomPlot &plot) const | |
|
176 | { | |
|
177 | QVector<VisualizationSelectionZoneItem *> zones; | |
|
178 | for (auto zone : m_SelectionZones) { | |
|
179 | auto distanceToZone = zone->selectTest(pos, false); | |
|
180 | if (distanceToZone >= 0 && distanceToZone < plot.selectionTolerance()) { | |
|
181 | zones << zone; | |
|
182 | } | |
|
183 | } | |
|
184 | ||
|
185 | return zones; | |
|
186 | } | |
|
187 | ||
|
188 | void moveSelectionZoneOnTop(VisualizationSelectionZoneItem *zone, QCustomPlot &plot) | |
|
189 | { | |
|
190 | if (!m_SelectionZones.isEmpty() && m_SelectionZones.last() != zone) { | |
|
191 | zone->moveToTop(); | |
|
192 | m_SelectionZones.removeAll(zone); | |
|
193 | m_SelectionZones.append(zone); | |
|
194 | } | |
|
195 | } | |
|
196 | ||
|
173 | 197 | QPointF posToAxisPos(const QPoint &pos, QCustomPlot &plot) const |
|
174 | 198 | { |
|
175 | 199 | auto axisX = plot.axisRect()->axis(QCPAxis::atBottom); |
@@ -902,17 +926,51 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept | |||
|
902 | 926 | if (isSelectionZoneMode) { |
|
903 | 927 | auto isMultiSelectionClick = event->modifiers().testFlag(MULTI_ZONE_SELECTION_MODIFIER); |
|
904 | 928 | auto selectionZoneItemUnderCursor = impl->selectionZoneAt(event->pos(), plot()); |
|
905 |
if (selectionZoneItemUnderCursor && event->button() == Qt::LeftButton |
|
|
906 |
|
|
|
929 | if (selectionZoneItemUnderCursor && event->button() == Qt::LeftButton | |
|
930 | && !impl->m_HasMovedMouse) { | |
|
931 | ||
|
932 | auto zonesUnderCursor = impl->selectionZonesAt(event->pos(), plot()); | |
|
933 | if (zonesUnderCursor.count() > 1) { | |
|
934 | // There are multiple zones under the mouse. | |
|
935 | // Performs the selection with a selection dialog. | |
|
936 | VisualizationMultiZoneSelectionDialog dialog{this}; | |
|
937 | dialog.setZones(zonesUnderCursor); | |
|
938 | dialog.move(mapToGlobal(event->pos() - QPoint(dialog.width() / 2, 20))); | |
|
939 | dialog.activateWindow(); | |
|
940 | dialog.raise(); | |
|
941 | if (dialog.exec() == QDialog::Accepted) { | |
|
942 | auto selection = dialog.selectedZones(); | |
|
943 | ||
|
944 | if (!isMultiSelectionClick) { | |
|
945 | parentVisualizationWidget()->selectionZoneManager().clearSelection(); | |
|
946 | } | |
|
947 | ||
|
948 | for (auto it = selection.cbegin(); it != selection.cend(); ++it) { | |
|
949 | auto zone = it.key(); | |
|
950 | auto isSelected = it.value(); | |
|
951 | parentVisualizationWidget()->selectionZoneManager().setSelected(zone, | |
|
952 | isSelected); | |
|
953 | ||
|
954 | if (isSelected) { | |
|
955 | // Puts the zone on top of the stack so it can be moved or resized | |
|
956 | impl->moveSelectionZoneOnTop(zone, plot()); | |
|
957 | } | |
|
958 | } | |
|
959 | } | |
|
960 | } | |
|
961 | else { | |
|
962 | if (!isMultiSelectionClick) { | |
|
907 | 963 | parentVisualizationWidget()->selectionZoneManager().select( |
|
908 | 964 | {selectionZoneItemUnderCursor}); |
|
965 | impl->moveSelectionZoneOnTop(selectionZoneItemUnderCursor, plot()); | |
|
909 | 966 | } |
|
910 | else if (!impl->m_HasMovedMouse) { | |
|
967 | else { | |
|
911 | 968 | parentVisualizationWidget()->selectionZoneManager().setSelected( |
|
912 | 969 | selectionZoneItemUnderCursor, !selectionZoneItemUnderCursor->selected() |
|
913 | 970 | || event->button() == Qt::RightButton); |
|
914 | 971 | } |
|
915 | 972 | } |
|
973 | } | |
|
916 | 974 | else { |
|
917 | 975 | // No selection change |
|
918 | 976 | } |
@@ -253,6 +253,11 bool VisualizationSelectionZoneItem::isEditionEnabled() const | |||
|
253 | 253 | return impl->m_IsEditionEnabled; |
|
254 | 254 | } |
|
255 | 255 | |
|
256 | void VisualizationSelectionZoneItem::moveToTop() | |
|
257 | { | |
|
258 | moveToLayer(layer(), false); | |
|
259 | } | |
|
260 | ||
|
256 | 261 | Qt::CursorShape |
|
257 | 262 | VisualizationSelectionZoneItem::curshorShapeForPosition(const QPoint &position) const |
|
258 | 263 | { |
@@ -327,6 +332,8 bool VisualizationSelectionZoneItem::alignZonesTemporallyOnRight( | |||
|
327 | 332 | |
|
328 | 333 | void VisualizationSelectionZoneItem::mousePressEvent(QMouseEvent *event, const QVariant &details) |
|
329 | 334 | { |
|
335 | Q_UNUSED(details); | |
|
336 | ||
|
330 | 337 | if (isEditionEnabled() && event->button() == Qt::LeftButton) { |
|
331 | 338 | impl->m_CurrentEditionMode = impl->getEditionMode(event->pos(), this); |
|
332 | 339 | |
@@ -394,6 +401,8 void VisualizationSelectionZoneItem::mouseMoveEvent(QMouseEvent *event, const QP | |||
|
394 | 401 | |
|
395 | 402 | void VisualizationSelectionZoneItem::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) |
|
396 | 403 | { |
|
404 | Q_UNUSED(startPos); | |
|
405 | ||
|
397 | 406 | if (isEditionEnabled()) { |
|
398 | 407 | impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition; |
|
399 | 408 | } |
@@ -39,7 +39,7 void VisualizationSelectionZoneManager::clearSelection() | |||
|
39 | 39 | { |
|
40 | 40 | for (auto item : impl->m_SelectedItems) { |
|
41 | 41 | item->setSelected(false); |
|
42 | item->parentPlot()->replot(); | |
|
42 | item->parentPlot()->replot(QCustomPlot::rpQueuedReplot); | |
|
43 | 43 | } |
|
44 | 44 | |
|
45 | 45 | impl->m_SelectedItems.clear(); |
General Comments 4
Status change > Approved
Status change > Approved
You need to be logged in to leave comments.
Login now