@@ -0,0 +1,27 | |||
|
1 | #ifndef SCIQLOP_ACTIONSGUICONTROLLER_H | |
|
2 | #define SCIQLOP_ACTIONSGUICONTROLLER_H | |
|
3 | ||
|
4 | #include <Actions/SelectionZoneAction.h> | |
|
5 | #include <Common/spimpl.h> | |
|
6 | ||
|
7 | #include <memory> | |
|
8 | ||
|
9 | class ActionsGuiController { | |
|
10 | public: | |
|
11 | ActionsGuiController(); | |
|
12 | ||
|
13 | std::shared_ptr<SelectionZoneAction> | |
|
14 | addSectionZoneAction(const QString &name, SelectionZoneAction::ExecuteFunction function); | |
|
15 | ||
|
16 | std::shared_ptr<SelectionZoneAction> | |
|
17 | addSectionZoneAction(const QStringList &subMenuList, const QString &name, | |
|
18 | SelectionZoneAction::ExecuteFunction function); | |
|
19 | ||
|
20 | QVector<std::shared_ptr<SelectionZoneAction> > selectionZoneActions() const; | |
|
21 | ||
|
22 | private: | |
|
23 | class ActionsGuiControllerPrivate; | |
|
24 | spimpl::unique_impl_ptr<ActionsGuiControllerPrivate> impl; | |
|
25 | }; | |
|
26 | ||
|
27 | #endif // SCIQLOP_ACTIONSGUICONTROLLER_H |
@@ -0,0 +1,75 | |||
|
1 | #ifndef SCIQLOP_SELECTIONZONEACTION_H | |
|
2 | #define SCIQLOP_SELECTIONZONEACTION_H | |
|
3 | ||
|
4 | #include <Common/spimpl.h> | |
|
5 | ||
|
6 | #include <QLoggingCategory> | |
|
7 | #include <QObject> | |
|
8 | ||
|
9 | #include <functional> | |
|
10 | ||
|
11 | class VisualizationSelectionZoneItem; | |
|
12 | ||
|
13 | Q_DECLARE_LOGGING_CATEGORY(LOG_SelectionZoneAction) | |
|
14 | ||
|
15 | /** | |
|
16 | * @brief The SelectionZoneAction class represents an action on a selection zone in the | |
|
17 | * visualization. | |
|
18 | * | |
|
19 | * The action is a function that will be executed when the slot execute() is called. | |
|
20 | */ | |
|
21 | class SelectionZoneAction : public QObject { | |
|
22 | ||
|
23 | Q_OBJECT | |
|
24 | ||
|
25 | public: | |
|
26 | /// Signature of the function associated to the action | |
|
27 | using ExecuteFunction | |
|
28 | = std::function<void(const QVector<VisualizationSelectionZoneItem *> &item)>; | |
|
29 | ||
|
30 | using EnableFunction | |
|
31 | = std::function<bool(const QVector<VisualizationSelectionZoneItem *> &item)>; | |
|
32 | ||
|
33 | /** | |
|
34 | * @param name the name of the action, displayed to the user | |
|
35 | * @param fun the function that will be called when the action is executed | |
|
36 | * @sa execute() | |
|
37 | */ | |
|
38 | explicit SelectionZoneAction(const QString &name, ExecuteFunction fun); | |
|
39 | ||
|
40 | /** | |
|
41 | * @param name the name of the action, displayed to the user | |
|
42 | * @param subMenusList the list of sub menus where the action should be inserted | |
|
43 | * @param fun the function that will be called when the action is executed | |
|
44 | * @sa execute() | |
|
45 | */ | |
|
46 | explicit SelectionZoneAction(const QStringList &subMenuList, const QString &name, | |
|
47 | ExecuteFunction fun); | |
|
48 | ||
|
49 | /// Sets the function which determine if the action should be enabled or disabled | |
|
50 | void setEnableFunction(EnableFunction fun); | |
|
51 | ||
|
52 | /// Sets the shortcut displayed by the action. | |
|
53 | /// Note: The shortcut is only displayed and not active because it is not permanently stored | |
|
54 | void setDisplayedShortcut(const QKeySequence &shortcut); | |
|
55 | QKeySequence displayedShortcut() const; | |
|
56 | ||
|
57 | /// The name of the action | |
|
58 | QString name() const noexcept; | |
|
59 | ||
|
60 | /// The path in the sub menus, if any | |
|
61 | QStringList subMenuList() const noexcept; | |
|
62 | ||
|
63 | public slots: | |
|
64 | /// Executes the action | |
|
65 | void execute(const QVector<VisualizationSelectionZoneItem *> &item); | |
|
66 | ||
|
67 | /// Returns true if the action is enabled | |
|
68 | bool isEnabled(const QVector<VisualizationSelectionZoneItem *> &item); | |
|
69 | ||
|
70 | private: | |
|
71 | class SelectionZoneActionPrivate; | |
|
72 | spimpl::unique_impl_ptr<SelectionZoneActionPrivate> impl; | |
|
73 | }; | |
|
74 | ||
|
75 | #endif // SCIQLOP_SELECTIONZONEACTION_H |
@@ -0,0 +1,12 | |||
|
1 | #ifndef SCIQLOP_VISUALIZATIONACTIONMANAGER_H | |
|
2 | #define SCIQLOP_VISUALIZATIONACTIONMANAGER_H | |
|
3 | ||
|
4 | ||
|
5 | class VisualizationActionManager { | |
|
6 | public: | |
|
7 | VisualizationActionManager(); | |
|
8 | ||
|
9 | void installSelectionZoneActions(); | |
|
10 | }; | |
|
11 | ||
|
12 | #endif // SCIQLOP_VISUALIZATIONACTIONMANAGER_H |
@@ -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,36 | |||
|
1 | #include "Actions/ActionsGuiController.h" | |
|
2 | ||
|
3 | struct ActionsGuiController::ActionsGuiControllerPrivate { | |
|
4 | ||
|
5 | QVector<std::shared_ptr<SelectionZoneAction> > m_SelectionZoneActions; | |
|
6 | }; | |
|
7 | ||
|
8 | ActionsGuiController::ActionsGuiController() | |
|
9 | : impl{spimpl::make_unique_impl<ActionsGuiControllerPrivate>()} | |
|
10 | { | |
|
11 | } | |
|
12 | ||
|
13 | std::shared_ptr<SelectionZoneAction> | |
|
14 | ActionsGuiController::addSectionZoneAction(const QString &name, | |
|
15 | SelectionZoneAction::ExecuteFunction function) | |
|
16 | { | |
|
17 | auto action = std::make_shared<SelectionZoneAction>(name, function); | |
|
18 | impl->m_SelectionZoneActions.push_back(action); | |
|
19 | ||
|
20 | return action; | |
|
21 | } | |
|
22 | ||
|
23 | std::shared_ptr<SelectionZoneAction> | |
|
24 | ActionsGuiController::addSectionZoneAction(const QStringList &subMenuList, const QString &name, | |
|
25 | SelectionZoneAction::ExecuteFunction function) | |
|
26 | { | |
|
27 | auto action = std::make_shared<SelectionZoneAction>(subMenuList, name, function); | |
|
28 | impl->m_SelectionZoneActions.push_back(action); | |
|
29 | ||
|
30 | return action; | |
|
31 | } | |
|
32 | ||
|
33 | QVector<std::shared_ptr<SelectionZoneAction> > ActionsGuiController::selectionZoneActions() const | |
|
34 | { | |
|
35 | return impl->m_SelectionZoneActions; | |
|
36 | } |
@@ -0,0 +1,66 | |||
|
1 | #include <Actions/SelectionZoneAction.h> | |
|
2 | #include <Visualization/VisualizationSelectionZoneItem.h> | |
|
3 | ||
|
4 | Q_LOGGING_CATEGORY(LOG_SelectionZoneAction, "SelectionZoneAction") | |
|
5 | ||
|
6 | struct SelectionZoneAction::SelectionZoneActionPrivate { | |
|
7 | explicit SelectionZoneActionPrivate(const QString &name, const QStringList &subMenuList, | |
|
8 | SelectionZoneAction::ExecuteFunction fun) | |
|
9 | : m_Name{name}, m_SubMenuList{subMenuList}, m_Fun{std::move(fun)} | |
|
10 | { | |
|
11 | } | |
|
12 | ||
|
13 | QString m_Name; | |
|
14 | QStringList m_SubMenuList; | |
|
15 | QKeySequence m_DisplayedShortcut; | |
|
16 | SelectionZoneAction::ExecuteFunction m_Fun; | |
|
17 | SelectionZoneAction::EnableFunction m_EnableFun = [](auto zones) { return true; }; | |
|
18 | }; | |
|
19 | ||
|
20 | SelectionZoneAction::SelectionZoneAction(const QString &name, ExecuteFunction fun) | |
|
21 | : impl{spimpl::make_unique_impl<SelectionZoneActionPrivate>(name, QStringList{}, | |
|
22 | std::move(fun))} | |
|
23 | { | |
|
24 | } | |
|
25 | ||
|
26 | SelectionZoneAction::SelectionZoneAction(const QStringList &subMenuList, const QString &name, | |
|
27 | SelectionZoneAction::ExecuteFunction fun) | |
|
28 | : impl{spimpl::make_unique_impl<SelectionZoneActionPrivate>(name, subMenuList, | |
|
29 | std::move(fun))} | |
|
30 | { | |
|
31 | } | |
|
32 | ||
|
33 | void SelectionZoneAction::setEnableFunction(EnableFunction fun) | |
|
34 | { | |
|
35 | impl->m_EnableFun = std::move(fun); | |
|
36 | } | |
|
37 | ||
|
38 | void SelectionZoneAction::setDisplayedShortcut(const QKeySequence &shortcut) | |
|
39 | { | |
|
40 | impl->m_DisplayedShortcut = shortcut; | |
|
41 | } | |
|
42 | ||
|
43 | QKeySequence SelectionZoneAction::displayedShortcut() const | |
|
44 | { | |
|
45 | return impl->m_DisplayedShortcut; | |
|
46 | } | |
|
47 | ||
|
48 | QString SelectionZoneAction::name() const noexcept | |
|
49 | { | |
|
50 | return impl->m_Name; | |
|
51 | } | |
|
52 | ||
|
53 | QStringList SelectionZoneAction::subMenuList() const noexcept | |
|
54 | { | |
|
55 | return impl->m_SubMenuList; | |
|
56 | } | |
|
57 | ||
|
58 | void SelectionZoneAction::execute(const QVector<VisualizationSelectionZoneItem *> &item) | |
|
59 | { | |
|
60 | impl->m_Fun(item); | |
|
61 | } | |
|
62 | ||
|
63 | bool SelectionZoneAction::isEnabled(const QVector<VisualizationSelectionZoneItem *> &item) | |
|
64 | { | |
|
65 | return impl->m_EnableFun(item); | |
|
66 | } |
@@ -0,0 +1,109 | |||
|
1 | #include "Visualization/VisualizationActionManager.h" | |
|
2 | #include "Visualization/VisualizationGraphWidget.h" | |
|
3 | #include "Visualization/VisualizationSelectionZoneItem.h" | |
|
4 | ||
|
5 | #include <Actions/ActionsGuiController.h> | |
|
6 | #include <SqpApplication.h> | |
|
7 | ||
|
8 | VisualizationActionManager::VisualizationActionManager() {} | |
|
9 | ||
|
10 | void VisualizationActionManager::installSelectionZoneActions() | |
|
11 | { | |
|
12 | auto &actionController = sqpApp->actionsGuiController(); | |
|
13 | ||
|
14 | auto removeZonesAction | |
|
15 | = actionController.addSectionZoneAction("Remove Selected Zone(s)", [](auto zones) { | |
|
16 | for (auto selectionZone : zones) { | |
|
17 | if (auto graph = selectionZone->parentGraphWidget()) { | |
|
18 | graph->removeSelectionZone(selectionZone); | |
|
19 | } | |
|
20 | } | |
|
21 | }); | |
|
22 | removeZonesAction->setDisplayedShortcut(QKeySequence::Delete); | |
|
23 | ||
|
24 | auto alignEnableFuntion = [](auto items) { return items.count() > 1; }; | |
|
25 | ||
|
26 | // Vertical alignment actions | |
|
27 | auto alignLeftAction = actionController.addSectionZoneAction( | |
|
28 | QStringList{"Align Vertically"}, "Left", [](auto zones) { | |
|
29 | Q_ASSERT(zones.count() > 1); | |
|
30 | auto ref = zones.takeFirst(); | |
|
31 | ref->alignZonesVerticallyOnLeft(zones, false); | |
|
32 | }); | |
|
33 | alignLeftAction->setEnableFunction(alignEnableFuntion); | |
|
34 | ||
|
35 | auto alignLeftBorderAction = actionController.addSectionZoneAction( | |
|
36 | QStringList{"Align Vertically"}, "Left Borders", [](auto zones) { | |
|
37 | Q_ASSERT(zones.count() > 1); | |
|
38 | auto ref = zones.takeFirst(); | |
|
39 | ref->alignZonesVerticallyOnLeft(zones, true); | |
|
40 | }); | |
|
41 | alignLeftBorderAction->setEnableFunction(alignEnableFuntion); | |
|
42 | ||
|
43 | auto alignRightAction = actionController.addSectionZoneAction( | |
|
44 | QStringList{"Align Vertically"}, "Right", [](auto zones) { | |
|
45 | Q_ASSERT(zones.count() > 1); | |
|
46 | auto ref = zones.takeFirst(); | |
|
47 | ref->alignZonesVerticallyOnRight(zones, false); | |
|
48 | }); | |
|
49 | alignRightAction->setEnableFunction(alignEnableFuntion); | |
|
50 | ||
|
51 | auto alignRightBorderAction = actionController.addSectionZoneAction( | |
|
52 | QStringList{"Align Vertically"}, "Right Borders", [](auto zones) { | |
|
53 | Q_ASSERT(zones.count() > 1); | |
|
54 | auto ref = zones.takeFirst(); | |
|
55 | ref->alignZonesVerticallyOnRight(zones, true); | |
|
56 | }); | |
|
57 | alignRightBorderAction->setEnableFunction(alignEnableFuntion); | |
|
58 | ||
|
59 | auto alignLeftAndRightAction = actionController.addSectionZoneAction( | |
|
60 | QStringList{"Align Vertically"}, "Left and Right", [](auto zones) { | |
|
61 | Q_ASSERT(zones.count() > 1); | |
|
62 | auto ref = zones.takeFirst(); | |
|
63 | ref->alignZonesVerticallyOnLeft(zones, false); | |
|
64 | ref->alignZonesVerticallyOnRight(zones, true); | |
|
65 | }); | |
|
66 | alignLeftAndRightAction->setEnableFunction(alignEnableFuntion); | |
|
67 | ||
|
68 | // Temporal alignment actions | |
|
69 | auto alignLeftTemporallyAction = actionController.addSectionZoneAction( | |
|
70 | QStringList{"Align Temporally"}, "Left", [](auto zones) { | |
|
71 | Q_ASSERT(zones.count() > 1); | |
|
72 | auto ref = zones.takeFirst(); | |
|
73 | ref->alignZonesTemporallyOnLeft(zones, false); | |
|
74 | }); | |
|
75 | alignLeftTemporallyAction->setEnableFunction(alignEnableFuntion); | |
|
76 | ||
|
77 | auto alignLeftBorderTemporallyAction = actionController.addSectionZoneAction( | |
|
78 | QStringList{"Align Temporally"}, "Left Borders", [](auto zones) { | |
|
79 | Q_ASSERT(zones.count() > 1); | |
|
80 | auto ref = zones.takeFirst(); | |
|
81 | ref->alignZonesTemporallyOnLeft(zones, true); | |
|
82 | }); | |
|
83 | alignLeftBorderTemporallyAction->setEnableFunction(alignEnableFuntion); | |
|
84 | ||
|
85 | auto alignRightTemporallyAction = actionController.addSectionZoneAction( | |
|
86 | QStringList{"Align Temporally"}, "Right", [](auto zones) { | |
|
87 | Q_ASSERT(zones.count() > 1); | |
|
88 | auto ref = zones.takeFirst(); | |
|
89 | ref->alignZonesTemporallyOnRight(zones, false); | |
|
90 | }); | |
|
91 | alignRightTemporallyAction->setEnableFunction(alignEnableFuntion); | |
|
92 | ||
|
93 | auto alignRightBorderTemporallyAction = actionController.addSectionZoneAction( | |
|
94 | QStringList{"Align Temporally"}, "Right Borders", [](auto zones) { | |
|
95 | Q_ASSERT(zones.count() > 1); | |
|
96 | auto ref = zones.takeFirst(); | |
|
97 | ref->alignZonesTemporallyOnRight(zones, true); | |
|
98 | }); | |
|
99 | alignRightBorderTemporallyAction->setEnableFunction(alignEnableFuntion); | |
|
100 | ||
|
101 | auto alignLeftAndRightTemporallyAction = actionController.addSectionZoneAction( | |
|
102 | QStringList{"Align Temporally"}, "Left and Right", [](auto zones) { | |
|
103 | Q_ASSERT(zones.count() > 1); | |
|
104 | auto ref = zones.takeFirst(); | |
|
105 | ref->alignZonesTemporallyOnLeft(zones, false); | |
|
106 | ref->alignZonesTemporallyOnRight(zones, true); | |
|
107 | }); | |
|
108 | alignLeftAndRightTemporallyAction->setEnableFunction(alignEnableFuntion); | |
|
109 | } |
@@ -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,50 | |||
|
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>303</width> | |
|
10 | <height>139</height> | |
|
11 | </rect> | |
|
12 | </property> | |
|
13 | <property name="windowTitle"> | |
|
14 | <string>Select...</string> | |
|
15 | </property> | |
|
16 | <layout class="QVBoxLayout" name="verticalLayout"> | |
|
17 | <property name="spacing"> | |
|
18 | <number>6</number> | |
|
19 | </property> | |
|
20 | <property name="leftMargin"> | |
|
21 | <number>0</number> | |
|
22 | </property> | |
|
23 | <property name="topMargin"> | |
|
24 | <number>0</number> | |
|
25 | </property> | |
|
26 | <property name="rightMargin"> | |
|
27 | <number>0</number> | |
|
28 | </property> | |
|
29 | <property name="bottomMargin"> | |
|
30 | <number>0</number> | |
|
31 | </property> | |
|
32 | <item> | |
|
33 | <widget class="QListWidget" name="listWidget"> | |
|
34 | <property name="selectionMode"> | |
|
35 | <enum>QAbstractItemView::ExtendedSelection</enum> | |
|
36 | </property> | |
|
37 | </widget> | |
|
38 | </item> | |
|
39 | <item> | |
|
40 | <widget class="QDialogButtonBox" name="buttonBox"> | |
|
41 | <property name="standardButtons"> | |
|
42 | <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> | |
|
43 | </property> | |
|
44 | </widget> | |
|
45 | </item> | |
|
46 | </layout> | |
|
47 | </widget> | |
|
48 | <resources/> | |
|
49 | <connections/> | |
|
50 | </ui> |
@@ -1,5 +1,5 | |||
|
1 |
#ifndef SCIQLOP_DRAGDROP |
|
|
2 |
#define SCIQLOP_DRAGDROP |
|
|
1 | #ifndef SCIQLOP_DRAGDROPGUICONTROLLER_H | |
|
2 | #define SCIQLOP_DRAGDROPGUICONTROLLER_H | |
|
3 | 3 | |
|
4 | 4 | #include <Common/spimpl.h> |
|
5 | 5 | #include <QLoggingCategory> |
@@ -12,7 +12,7 class VisualizationDragWidget; | |||
|
12 | 12 | class VisualizationDragDropContainer; |
|
13 | 13 | class QMimeData; |
|
14 | 14 | |
|
15 |
Q_DECLARE_LOGGING_CATEGORY(LOG_DragDrop |
|
|
15 | Q_DECLARE_LOGGING_CATEGORY(LOG_DragDropGuiController) | |
|
16 | 16 | |
|
17 | 17 | /** |
|
18 | 18 | * @brief Helper class for drag&drop operations. |
@@ -21,15 +21,15 Q_DECLARE_LOGGING_CATEGORY(LOG_DragDropHelper) | |||
|
21 | 21 | * can interect with the gui. |
|
22 | 22 | * @see SqpApplication |
|
23 | 23 | */ |
|
24 |
class DragDrop |
|
|
24 | class DragDropGuiController { | |
|
25 | 25 | public: |
|
26 | 26 | static const QString MIME_TYPE_GRAPH; |
|
27 | 27 | static const QString MIME_TYPE_ZONE; |
|
28 | 28 | |
|
29 | 29 | enum class PlaceHolderType { Default, Graph, Zone }; |
|
30 | 30 | |
|
31 |
DragDrop |
|
|
32 |
virtual ~DragDrop |
|
|
31 | DragDropGuiController(); | |
|
32 | virtual ~DragDropGuiController(); | |
|
33 | 33 | |
|
34 | 34 | /// Resets some internal variables. Must be called before any new drag&drop operation. |
|
35 | 35 | void resetDragAndDrop(); |
@@ -68,8 +68,8 public: | |||
|
68 | 68 | void doCloseWidgets(); |
|
69 | 69 | |
|
70 | 70 | private: |
|
71 |
class DragDrop |
|
|
72 |
spimpl::unique_impl_ptr<DragDrop |
|
|
71 | class DragDropGuiControllerPrivate; | |
|
72 | spimpl::unique_impl_ptr<DragDropGuiControllerPrivate> impl; | |
|
73 | 73 | }; |
|
74 | 74 | |
|
75 |
#endif // SCIQLOP_DRAGDROP |
|
|
75 | #endif // SCIQLOP_DRAGDROPGUICONTROLLER_H |
@@ -20,7 +20,8 class NetworkController; | |||
|
20 | 20 | class TimeController; |
|
21 | 21 | class VariableController; |
|
22 | 22 | class VisualizationController; |
|
23 |
class DragDrop |
|
|
23 | class DragDropGuiController; | |
|
24 | class ActionsGuiController; | |
|
24 | 25 | |
|
25 | 26 | /** |
|
26 | 27 | * @brief The SqpApplication class aims to make the link between SciQlop |
@@ -47,7 +48,8 public: | |||
|
47 | 48 | |
|
48 | 49 | /// Accessors for the differents sciqlop helpers, these helpers classes are like controllers but |
|
49 | 50 | /// doesn't live in a thread and access gui |
|
50 |
DragDrop |
|
|
51 | DragDropGuiController &dragDropGuiController() noexcept; | |
|
52 | ActionsGuiController &actionsGuiController() noexcept; | |
|
51 | 53 | |
|
52 | 54 | enum class PlotsInteractionMode { None, ZoomBox, DragAndDrop, SelectionZones }; |
|
53 | 55 |
@@ -9,7 +9,7 | |||
|
9 | 9 | |
|
10 | 10 | #include <functional> |
|
11 | 11 | |
|
12 |
#include <DragAndDrop/DragDrop |
|
|
12 | #include <DragAndDrop/DragDropGuiController.h> | |
|
13 | 13 | |
|
14 | 14 | Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer) |
|
15 | 15 | |
@@ -41,7 +41,7 public: | |||
|
41 | 41 | |
|
42 | 42 | void setAcceptDragWidgetFunction(AcceptDragWidgetFunction fun); |
|
43 | 43 | |
|
44 |
void setPlaceHolderType(DragDrop |
|
|
44 | void setPlaceHolderType(DragDropGuiController::PlaceHolderType type, | |
|
45 | 45 | const QString &placeHolderText = QString()); |
|
46 | 46 | |
|
47 | 47 | protected: |
@@ -19,6 +19,7 class SqpRange; | |||
|
19 | 19 | class Variable; |
|
20 | 20 | class VisualizationWidget; |
|
21 | 21 | class VisualizationZoneWidget; |
|
22 | class VisualizationSelectionZoneItem; | |
|
22 | 23 | |
|
23 | 24 | namespace Ui { |
|
24 | 25 | class VisualizationGraphWidget; |
@@ -56,11 +57,13 public: | |||
|
56 | 57 | SqpRange graphRange() const noexcept; |
|
57 | 58 | void setGraphRange(const SqpRange &range); |
|
58 | 59 | |
|
60 | // Zones | |
|
59 | 61 | /// Returns the ranges of all the selection zones on the graph |
|
60 | 62 | QVector<SqpRange> selectionZoneRanges() const; |
|
61 | ||
|
62 | 63 | /// Adds new selection zones in the graph |
|
63 | 64 | void addSelectionZones(const QVector<SqpRange> &ranges); |
|
65 | /// Removes the specified selection zone | |
|
66 | void removeSelectionZone(VisualizationSelectionZoneItem *selectionZone); | |
|
64 | 67 | |
|
65 | 68 | /// Undo the last zoom done with a zoom box |
|
66 | 69 | void undoZoom(); |
@@ -5,12 +5,16 | |||
|
5 | 5 | #include <Data/SqpRange.h> |
|
6 | 6 | #include <Visualization/qcustomplot.h> |
|
7 | 7 | |
|
8 | class VisualizationGraphWidget; | |
|
9 | ||
|
8 | 10 | class VisualizationSelectionZoneItem : public QCPItemRect { |
|
9 | 11 | |
|
10 | 12 | public: |
|
11 | 13 | VisualizationSelectionZoneItem(QCustomPlot *plot); |
|
12 | 14 | virtual ~VisualizationSelectionZoneItem(); |
|
13 | 15 | |
|
16 | VisualizationGraphWidget *parentGraphWidget() const noexcept; | |
|
17 | ||
|
14 | 18 | void setName(const QString &name); |
|
15 | 19 | QString name() const; |
|
16 | 20 | |
@@ -24,11 +28,29 public: | |||
|
24 | 28 | void setEditionEnabled(bool value); |
|
25 | 29 | bool isEditionEnabled() const; |
|
26 | 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 | ||
|
27 | 35 | Qt::CursorShape curshorShapeForPosition(const QPoint &position) const; |
|
28 | 36 | void setHovered(bool value); |
|
29 | 37 | |
|
38 | /// Sets the zones which should be moved or reisized together with this zone | |
|
30 | 39 | void setAssociatedEditedZones(const QVector<VisualizationSelectionZoneItem *> &associatedZones); |
|
31 | 40 | |
|
41 | /// Align the specified zones with this one, vertically with the left border | |
|
42 | bool alignZonesVerticallyOnLeft(const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, | |
|
43 | bool allowResize); | |
|
44 | /// Align the specified zones with this one, vertically with the right border | |
|
45 | bool alignZonesVerticallyOnRight(const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, | |
|
46 | bool allowResize); | |
|
47 | /// Align the specified zones with this one, temporally with the left border | |
|
48 | bool alignZonesTemporallyOnLeft(const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, | |
|
49 | bool allowResize); | |
|
50 | /// Align the specified zones with this one, temporally with the right border | |
|
51 | bool alignZonesTemporallyOnRight(const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, | |
|
52 | bool allowResize); | |
|
53 | ||
|
32 | 54 | protected: |
|
33 | 55 | void mousePressEvent(QMouseEvent *event, const QVariant &details) override; |
|
34 | 56 | void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) override; |
@@ -38,7 +60,6 protected: | |||
|
38 | 60 | void resizeRight(double pixelDiff); |
|
39 | 61 | void move(double pixelDiff); |
|
40 | 62 | |
|
41 | ||
|
42 | 63 | private: |
|
43 | 64 | class VisualizationSelectionZoneItemPrivate; |
|
44 | 65 | spimpl::unique_impl_ptr<VisualizationSelectionZoneItemPrivate> impl; |
@@ -17,7 +17,9 gui_moc_headers = [ | |||
|
17 | 17 | 'include/Visualization/VisualizationZoneWidget.h', |
|
18 | 18 | 'include/Visualization/VisualizationDragDropContainer.h', |
|
19 | 19 | 'include/Visualization/VisualizationDragWidget.h', |
|
20 | 'include/Visualization/ColorScaleEditor.h' | |
|
20 | 'include/Visualization/ColorScaleEditor.h', | |
|
21 | 'include/Actions/SelectionZoneAction.h', | |
|
22 | 'include/Visualization/VisualizationMultiZoneSelectionDialog.h' | |
|
21 | 23 | ] |
|
22 | 24 | |
|
23 | 25 | gui_ui_files = [ |
@@ -33,7 +35,8 gui_ui_files = [ | |||
|
33 | 35 | 'ui/Visualization/VisualizationTabWidget.ui', |
|
34 | 36 | 'ui/Visualization/VisualizationWidget.ui', |
|
35 | 37 | 'ui/Visualization/VisualizationZoneWidget.ui', |
|
36 | 'ui/Visualization/ColorScaleEditor.ui' | |
|
38 | 'ui/Visualization/ColorScaleEditor.ui', | |
|
39 | 'ui/Visualization/VisualizationMultiZoneSelectionDialog.ui' | |
|
37 | 40 | ] |
|
38 | 41 | |
|
39 | 42 | gui_qresources = ['resources/sqpguiresources.qrc'] |
@@ -44,7 +47,7 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers, | |||
|
44 | 47 | |
|
45 | 48 | gui_sources = [ |
|
46 | 49 | 'src/SqpApplication.cpp', |
|
47 |
'src/DragAndDrop/DragDrop |
|
|
50 | 'src/DragAndDrop/DragDropGuiController.cpp', | |
|
48 | 51 | 'src/DragAndDrop/DragDropScroller.cpp', |
|
49 | 52 | 'src/DragAndDrop/DragDropTabSwitcher.cpp', |
|
50 | 53 | 'src/Common/ColorUtils.cpp', |
@@ -84,7 +87,11 gui_sources = [ | |||
|
84 | 87 | 'src/Visualization/SqpColorScale.cpp', |
|
85 | 88 | 'src/Visualization/QCPColorMapIterator.cpp', |
|
86 | 89 | 'src/Visualization/VisualizationSelectionZoneItem.cpp', |
|
87 | 'src/Visualization/VisualizationSelectionZoneManager.cpp' | |
|
90 | 'src/Visualization/VisualizationSelectionZoneManager.cpp', | |
|
91 | 'src/Actions/SelectionZoneAction.cpp', | |
|
92 | 'src/Actions/ActionsGuiController.cpp', | |
|
93 | 'src/Visualization/VisualizationActionManager.cpp', | |
|
94 | 'src/Visualization/VisualizationMultiZoneSelectionDialog.cpp' | |
|
88 | 95 | ] |
|
89 | 96 | |
|
90 | 97 | gui_inc = include_directories(['include']) |
@@ -4,7 +4,7 | |||
|
4 | 4 | #include "DataSource/DataSourceItem.h" |
|
5 | 5 | #include "DataSource/DataSourceTreeWidgetItem.h" |
|
6 | 6 | |
|
7 |
#include "DragAndDrop/DragDrop |
|
|
7 | #include "DragAndDrop/DragDropGuiController.h" | |
|
8 | 8 | #include "SqpApplication.h" |
|
9 | 9 | |
|
10 | 10 | #include <QMimeData> |
@@ -42,6 +42,6 QMimeData *DataSourceTreeWidget::mimeData(const QList<QTreeWidgetItem *> items) | |||
|
42 | 42 | void DataSourceTreeWidget::startDrag(Qt::DropActions supportedActions) |
|
43 | 43 | { |
|
44 | 44 | // Resets the drag&drop operations before it's starting |
|
45 |
sqpApp->dragDrop |
|
|
45 | sqpApp->dragDropGuiController().resetDragAndDrop(); | |
|
46 | 46 | QTreeWidget::startDrag(supportedActions); |
|
47 | 47 | } |
@@ -1,4 +1,4 | |||
|
1 |
#include "DragAndDrop/DragDrop |
|
|
1 | #include "DragAndDrop/DragDropGuiController.h" | |
|
2 | 2 | #include "DragAndDrop/DragDropScroller.h" |
|
3 | 3 | #include "DragAndDrop/DragDropTabSwitcher.h" |
|
4 | 4 | #include "SqpApplication.h" |
@@ -19,10 +19,10 | |||
|
19 | 19 | #include <QVBoxLayout> |
|
20 | 20 | |
|
21 | 21 | |
|
22 |
Q_LOGGING_CATEGORY(LOG_DragDrop |
|
|
22 | Q_LOGGING_CATEGORY(LOG_DragDropGuiController, "DragDropGuiController") | |
|
23 | 23 | |
|
24 | 24 | |
|
25 |
struct DragDrop |
|
|
25 | struct DragDropGuiController::DragDropGuiControllerPrivate { | |
|
26 | 26 | |
|
27 | 27 | VisualizationDragWidget *m_CurrentDragWidget = nullptr; |
|
28 | 28 | std::unique_ptr<QWidget> m_PlaceHolder = nullptr; |
@@ -40,7 +40,7 struct DragDropHelper::DragDropHelperPrivate { | |||
|
40 | 40 | |
|
41 | 41 | QList<QWidget *> m_WidgetToClose; |
|
42 | 42 | |
|
43 |
explicit DragDrop |
|
|
43 | explicit DragDropGuiControllerPrivate() | |
|
44 | 44 | : m_PlaceHolder{std::make_unique<QWidget>()}, |
|
45 | 45 | m_DragDropScroller{std::make_unique<DragDropScroller>()}, |
|
46 | 46 | m_DragDropTabSwitcher{std::make_unique<DragDropTabSwitcher>()} |
@@ -64,7 +64,8 struct DragDropHelper::DragDropHelperPrivate { | |||
|
64 | 64 | m_ImageTempUrl = QDir::temp().absoluteFilePath("Sciqlop_graph.png"); |
|
65 | 65 | } |
|
66 | 66 | |
|
67 |
void preparePlaceHolder(DragDrop |
|
|
67 | void preparePlaceHolder(DragDropGuiController::PlaceHolderType type, | |
|
68 | const QString &topLabelText) const | |
|
68 | 69 | { |
|
69 | 70 | if (m_CurrentDragWidget) { |
|
70 | 71 | m_PlaceHolder->setMinimumSize(m_CurrentDragWidget->size()); |
@@ -79,12 +80,12 struct DragDropHelper::DragDropHelperPrivate { | |||
|
79 | 80 | } |
|
80 | 81 | |
|
81 | 82 | switch (type) { |
|
82 |
case DragDrop |
|
|
83 | case DragDropGuiController::PlaceHolderType::Graph: | |
|
83 | 84 | m_PlaceBackground->setStyleSheet( |
|
84 | 85 | "background-color: #BBD5EE; border: 1px solid #2A7FD4"); |
|
85 | 86 | break; |
|
86 |
case DragDrop |
|
|
87 |
case DragDrop |
|
|
87 | case DragDropGuiController::PlaceHolderType::Zone: | |
|
88 | case DragDropGuiController::PlaceHolderType::Default: | |
|
88 | 89 | m_PlaceBackground->setStyleSheet( |
|
89 | 90 | "background-color: #BBD5EE; border: 2px solid #2A7FD4"); |
|
90 | 91 | m_PlaceHolderLabel->setStyleSheet("color: #2A7FD4"); |
@@ -97,22 +98,23 struct DragDropHelper::DragDropHelperPrivate { | |||
|
97 | 98 | }; |
|
98 | 99 | |
|
99 | 100 | |
|
100 | DragDropHelper::DragDropHelper() : impl{spimpl::make_unique_impl<DragDropHelperPrivate>()} | |
|
101 | DragDropGuiController::DragDropGuiController() | |
|
102 | : impl{spimpl::make_unique_impl<DragDropGuiControllerPrivate>()} | |
|
101 | 103 | { |
|
102 | 104 | } |
|
103 | 105 | |
|
104 |
DragDrop |
|
|
106 | DragDropGuiController::~DragDropGuiController() | |
|
105 | 107 | { |
|
106 | 108 | QFile::remove(impl->m_ImageTempUrl); |
|
107 | 109 | } |
|
108 | 110 | |
|
109 |
void DragDrop |
|
|
111 | void DragDropGuiController::resetDragAndDrop() | |
|
110 | 112 | { |
|
111 | 113 | setCurrentDragWidget(nullptr); |
|
112 | 114 | impl->m_HighlightedDragWidget = nullptr; |
|
113 | 115 | } |
|
114 | 116 | |
|
115 |
void DragDrop |
|
|
117 | void DragDropGuiController::setCurrentDragWidget(VisualizationDragWidget *dragWidget) | |
|
116 | 118 | { |
|
117 | 119 | if (impl->m_CurrentDragWidget) { |
|
118 | 120 | |
@@ -129,17 +131,17 void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget) | |||
|
129 | 131 | impl->m_CurrentDragWidget = dragWidget; |
|
130 | 132 | } |
|
131 | 133 | |
|
132 |
VisualizationDragWidget *DragDrop |
|
|
134 | VisualizationDragWidget *DragDropGuiController::getCurrentDragWidget() const | |
|
133 | 135 | { |
|
134 | 136 | return impl->m_CurrentDragWidget; |
|
135 | 137 | } |
|
136 | 138 | |
|
137 |
QWidget &DragDrop |
|
|
139 | QWidget &DragDropGuiController::placeHolder() const | |
|
138 | 140 | { |
|
139 | 141 | return *impl->m_PlaceHolder; |
|
140 | 142 | } |
|
141 | 143 | |
|
142 |
void DragDrop |
|
|
144 | void DragDropGuiController::insertPlaceHolder(QVBoxLayout *layout, int index, PlaceHolderType type, | |
|
143 | 145 | const QString &topLabelText) |
|
144 | 146 | { |
|
145 | 147 | removePlaceHolder(); |
@@ -148,7 +150,7 void DragDropHelper::insertPlaceHolder(QVBoxLayout *layout, int index, PlaceHold | |||
|
148 | 150 | impl->m_PlaceHolder->show(); |
|
149 | 151 | } |
|
150 | 152 | |
|
151 |
void DragDrop |
|
|
153 | void DragDropGuiController::removePlaceHolder() | |
|
152 | 154 | { |
|
153 | 155 | auto parentWidget = impl->m_PlaceHolder->parentWidget(); |
|
154 | 156 | if (parentWidget) { |
@@ -158,38 +160,38 void DragDropHelper::removePlaceHolder() | |||
|
158 | 160 | } |
|
159 | 161 | } |
|
160 | 162 | |
|
161 |
bool DragDrop |
|
|
163 | bool DragDropGuiController::isPlaceHolderSet() const | |
|
162 | 164 | { |
|
163 | 165 | return impl->m_PlaceHolder->parentWidget(); |
|
164 | 166 | } |
|
165 | 167 | |
|
166 |
void DragDrop |
|
|
168 | void DragDropGuiController::addDragDropScrollArea(QScrollArea *scrollArea) | |
|
167 | 169 | { |
|
168 | 170 | impl->m_DragDropScroller->addScrollArea(scrollArea); |
|
169 | 171 | } |
|
170 | 172 | |
|
171 |
void DragDrop |
|
|
173 | void DragDropGuiController::removeDragDropScrollArea(QScrollArea *scrollArea) | |
|
172 | 174 | { |
|
173 | 175 | impl->m_DragDropScroller->removeScrollArea(scrollArea); |
|
174 | 176 | } |
|
175 | 177 | |
|
176 |
void DragDrop |
|
|
178 | void DragDropGuiController::addDragDropTabBar(QTabBar *tabBar) | |
|
177 | 179 | { |
|
178 | 180 | impl->m_DragDropTabSwitcher->addTabBar(tabBar); |
|
179 | 181 | } |
|
180 | 182 | |
|
181 |
void DragDrop |
|
|
183 | void DragDropGuiController::removeDragDropTabBar(QTabBar *tabBar) | |
|
182 | 184 | { |
|
183 | 185 | impl->m_DragDropTabSwitcher->removeTabBar(tabBar); |
|
184 | 186 | } |
|
185 | 187 | |
|
186 |
QUrl DragDrop |
|
|
188 | QUrl DragDropGuiController::imageTemporaryUrl(const QImage &image) const | |
|
187 | 189 | { |
|
188 | 190 | image.save(impl->m_ImageTempUrl); |
|
189 | 191 | return QUrl::fromLocalFile(impl->m_ImageTempUrl); |
|
190 | 192 | } |
|
191 | 193 | |
|
192 |
void DragDrop |
|
|
194 | void DragDropGuiController::setHightlightedDragWidget(VisualizationDragWidget *dragWidget) | |
|
193 | 195 | { |
|
194 | 196 | if (impl->m_HighlightedDragWidget) { |
|
195 | 197 | impl->m_HighlightedDragWidget->highlightForMerge(false); |
@@ -208,18 +210,18 void DragDropHelper::setHightlightedDragWidget(VisualizationDragWidget *dragWidg | |||
|
208 | 210 | impl->m_HighlightedDragWidget = dragWidget; |
|
209 | 211 | } |
|
210 | 212 | |
|
211 |
VisualizationDragWidget *DragDrop |
|
|
213 | VisualizationDragWidget *DragDropGuiController::getHightlightedDragWidget() const | |
|
212 | 214 | { |
|
213 | 215 | return impl->m_HighlightedDragWidget; |
|
214 | 216 | } |
|
215 | 217 | |
|
216 |
void DragDrop |
|
|
218 | void DragDropGuiController::delayedCloseWidget(QWidget *widget) | |
|
217 | 219 | { |
|
218 | 220 | widget->hide(); |
|
219 | 221 | impl->m_WidgetToClose << widget; |
|
220 | 222 | } |
|
221 | 223 | |
|
222 |
void DragDrop |
|
|
224 | void DragDropGuiController::doCloseWidgets() | |
|
223 | 225 | { |
|
224 | 226 | for (auto widget : impl->m_WidgetToClose) { |
|
225 | 227 | widget->close(); |
@@ -228,12 +230,12 void DragDropHelper::doCloseWidgets() | |||
|
228 | 230 | impl->m_WidgetToClose.clear(); |
|
229 | 231 | } |
|
230 | 232 | |
|
231 |
bool DragDrop |
|
|
232 |
|
|
|
233 | bool DragDropGuiController::checkMimeDataForVisualization( | |
|
234 | const QMimeData *mimeData, VisualizationDragDropContainer *dropContainer) | |
|
233 | 235 | { |
|
234 | 236 | if (!mimeData || !dropContainer) { |
|
235 |
qCWarning(LOG_DragDrop |
|
|
236 |
"DragDrop |
|
|
237 | qCWarning(LOG_DragDropGuiController()) << QObject::tr( | |
|
238 | "DragDropGuiController::checkMimeDataForVisualization, invalid input parameters."); | |
|
237 | 239 | Q_ASSERT(false); |
|
238 | 240 | return false; |
|
239 | 241 | } |
@@ -270,8 +272,8 bool DragDropHelper::checkMimeDataForVisualization(const QMimeData *mimeData, | |||
|
270 | 272 | } |
|
271 | 273 | } |
|
272 | 274 | else { |
|
273 |
qCWarning(LOG_DragDrop |
|
|
274 |
"DragDrop |
|
|
275 | qCWarning(LOG_DragDropGuiController()) << QObject::tr( | |
|
276 | "DragDropGuiController::checkMimeDataForVisualization, the parent " | |
|
275 | 277 | "VisualizationWidget cannot be found. Cannot check if the variable is " |
|
276 | 278 | "already used or not."); |
|
277 | 279 | } |
@@ -1,9 +1,10 | |||
|
1 | 1 | #include "SqpApplication.h" |
|
2 | 2 | |
|
3 | #include <Actions/ActionsGuiController.h> | |
|
3 | 4 | #include <Catalogue/CatalogueController.h> |
|
4 | 5 | #include <Data/IDataProvider.h> |
|
5 | 6 | #include <DataSource/DataSourceController.h> |
|
6 |
#include <DragAndDrop/DragDrop |
|
|
7 | #include <DragAndDrop/DragDropGuiController.h> | |
|
7 | 8 | #include <Network/NetworkController.h> |
|
8 | 9 | #include <QThread> |
|
9 | 10 | #include <Time/TimeController.h> |
@@ -22,8 +23,9 public: | |||
|
22 | 23 | m_TimeController{std::make_unique<TimeController>()}, |
|
23 | 24 | m_NetworkController{std::make_unique<NetworkController>()}, |
|
24 | 25 | m_VisualizationController{std::make_unique<VisualizationController>()}, |
|
25 |
m_DragDrop |
|
|
26 | m_DragDropGuiController{std::make_unique<DragDropGuiController>()}, | |
|
26 | 27 | m_CatalogueController{std::make_unique<CatalogueController>()}, |
|
28 | m_ActionsGuiController{std::make_unique<ActionsGuiController>()}, | |
|
27 | 29 | m_PlotInterractionMode(SqpApplication::PlotsInteractionMode::None), |
|
28 | 30 | m_PlotCursorMode(SqpApplication::PlotsCursorMode::NoCursor) |
|
29 | 31 | { |
@@ -94,13 +96,15 public: | |||
|
94 | 96 | std::unique_ptr<NetworkController> m_NetworkController; |
|
95 | 97 | std::unique_ptr<VisualizationController> m_VisualizationController; |
|
96 | 98 | std::unique_ptr<CatalogueController> m_CatalogueController; |
|
99 | ||
|
97 | 100 | QThread m_DataSourceControllerThread; |
|
98 | 101 | QThread m_NetworkControllerThread; |
|
99 | 102 | QThread m_VariableControllerThread; |
|
100 | 103 | QThread m_VisualizationControllerThread; |
|
101 | 104 | QThread m_CatalogueControllerThread; |
|
102 | 105 | |
|
103 |
std::unique_ptr<DragDrop |
|
|
106 | std::unique_ptr<DragDropGuiController> m_DragDropGuiController; | |
|
107 | std::unique_ptr<ActionsGuiController> m_ActionsGuiController; | |
|
104 | 108 | |
|
105 | 109 | SqpApplication::PlotsInteractionMode m_PlotInterractionMode; |
|
106 | 110 | SqpApplication::PlotsCursorMode m_PlotCursorMode; |
@@ -177,9 +181,14 VisualizationController &SqpApplication::visualizationController() noexcept | |||
|
177 | 181 | return *impl->m_VisualizationController; |
|
178 | 182 | } |
|
179 | 183 | |
|
180 |
DragDrop |
|
|
184 | DragDropGuiController &SqpApplication::dragDropGuiController() noexcept | |
|
185 | { | |
|
186 | return *impl->m_DragDropGuiController; | |
|
187 | } | |
|
188 | ||
|
189 | ActionsGuiController &SqpApplication::actionsGuiController() noexcept | |
|
181 | 190 | { |
|
182 |
return *impl->m_ |
|
|
191 | return *impl->m_ActionsGuiController; | |
|
183 | 192 | } |
|
184 | 193 | |
|
185 | 194 | SqpApplication::PlotsInteractionMode SqpApplication::plotsInteractionMode() const |
@@ -4,7 +4,7 | |||
|
4 | 4 | #include <Common/DateUtils.h> |
|
5 | 5 | #include <Common/MimeTypesDef.h> |
|
6 | 6 | |
|
7 |
#include <DragAndDrop/DragDrop |
|
|
7 | #include <DragAndDrop/DragDropGuiController.h> | |
|
8 | 8 | #include <SqpApplication.h> |
|
9 | 9 | #include <Time/TimeController.h> |
|
10 | 10 | |
@@ -145,7 +145,7 void TimeWidget::mouseMoveEvent(QMouseEvent *event) | |||
|
145 | 145 | auto pixmap = QPixmap{":/icones/time.png"}; |
|
146 | 146 | drag->setPixmap(pixmap.scaledToWidth(22)); |
|
147 | 147 | |
|
148 |
sqpApp->dragDrop |
|
|
148 | sqpApp->dragDropGuiController().resetDragAndDrop(); | |
|
149 | 149 | |
|
150 | 150 | // Note: The exec() is blocking on windows but not on linux and macOS |
|
151 | 151 | drag->exec(Qt::MoveAction | Qt::CopyAction); |
@@ -1,6 +1,6 | |||
|
1 | 1 | #include "Variable/VariableInspectorTableView.h" |
|
2 | 2 | |
|
3 |
#include "DragAndDrop/DragDrop |
|
|
3 | #include "DragAndDrop/DragDropGuiController.h" | |
|
4 | 4 | #include "SqpApplication.h" |
|
5 | 5 | |
|
6 | 6 | VariableInspectorTableView::VariableInspectorTableView(QWidget *parent) : QTableView(parent) |
@@ -10,6 +10,6 VariableInspectorTableView::VariableInspectorTableView(QWidget *parent) : QTable | |||
|
10 | 10 | void VariableInspectorTableView::startDrag(Qt::DropActions supportedActions) |
|
11 | 11 | { |
|
12 | 12 | // Resets the drag&drop operations before it's starting |
|
13 |
sqpApp->dragDrop |
|
|
13 | sqpApp->dragDropGuiController().resetDragAndDrop(); | |
|
14 | 14 | QTableView::startDrag(supportedActions); |
|
15 | 15 | } |
@@ -12,7 +12,7 | |||
|
12 | 12 | #include <QStyledItemDelegate> |
|
13 | 13 | #include <QWidgetAction> |
|
14 | 14 | |
|
15 |
#include <DragAndDrop/DragDrop |
|
|
15 | #include <DragAndDrop/DragDropGuiController.h> | |
|
16 | 16 | #include <SqpApplication.h> |
|
17 | 17 | |
|
18 | 18 | Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget") |
@@ -1,5 +1,5 | |||
|
1 | 1 | #include "Visualization/VisualizationDragDropContainer.h" |
|
2 |
#include "DragAndDrop/DragDrop |
|
|
2 | #include "DragAndDrop/DragDropGuiController.h" | |
|
3 | 3 | #include "SqpApplication.h" |
|
4 | 4 | #include "Visualization/VisualizationDragWidget.h" |
|
5 | 5 | |
@@ -21,7 +21,7 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate { | |||
|
21 | 21 | QVBoxLayout *m_Layout; |
|
22 | 22 | QHash<QString, VisualizationDragDropContainer::DropBehavior> m_AcceptedMimeTypes; |
|
23 | 23 | QString m_PlaceHolderText; |
|
24 |
DragDrop |
|
|
24 | DragDropGuiController::PlaceHolderType m_PlaceHolderType; | |
|
25 | 25 | |
|
26 | 26 | VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun |
|
27 | 27 | = [](auto mimeData) { return true; }; |
@@ -31,7 +31,7 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate { | |||
|
31 | 31 | int m_MinContainerHeight = 0; |
|
32 | 32 | |
|
33 | 33 | explicit VisualizationDragDropContainerPrivate(QWidget *widget) |
|
34 |
: m_PlaceHolderType(DragDrop |
|
|
34 | : m_PlaceHolderType(DragDropGuiController::PlaceHolderType::Graph) | |
|
35 | 35 | { |
|
36 | 36 | m_Layout = new QVBoxLayout(widget); |
|
37 | 37 | m_Layout->setContentsMargins(0, 0, 0, 0); |
@@ -104,7 +104,8 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate { | |||
|
104 | 104 | |
|
105 | 105 | bool hasPlaceHolder() const |
|
106 | 106 | { |
|
107 |
return sqpApp->dragDrop |
|
|
107 | return sqpApp->dragDropGuiController().placeHolder().parentWidget() | |
|
108 | == m_Layout->parentWidget(); | |
|
108 | 109 | } |
|
109 | 110 | |
|
110 | 111 | VisualizationDragWidget *getChildDragWidgetAt(const QWidget *parent, const QPoint &pos) const |
@@ -128,7 +129,7 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate { | |||
|
128 | 129 | { |
|
129 | 130 | auto widgetUnderMouse = sqpApp->widgetAt(QCursor::pos()); |
|
130 | 131 | return container->isAncestorOf(widgetUnderMouse) && widgetUnderMouse != container |
|
131 |
&& sqpApp->dragDrop |
|
|
132 | && sqpApp->dragDropGuiController().placeHolder().isAncestorOf(widgetUnderMouse); | |
|
132 | 133 | } |
|
133 | 134 | |
|
134 | 135 | int countDragWidget(const QWidget *parent, bool onlyVisible = false) const |
@@ -196,7 +197,7 void VisualizationDragDropContainer::setAcceptDragWidgetFunction( | |||
|
196 | 197 | impl->m_AcceptDragWidgetFun = fun; |
|
197 | 198 | } |
|
198 | 199 | |
|
199 |
void VisualizationDragDropContainer::setPlaceHolderType(DragDrop |
|
|
200 | void VisualizationDragDropContainer::setPlaceHolderType(DragDropGuiController::PlaceHolderType type, | |
|
200 | 201 | const QString &placeHolderText) |
|
201 | 202 | { |
|
202 | 203 | impl->m_PlaceHolderType = type; |
@@ -206,7 +207,7 void VisualizationDragDropContainer::setPlaceHolderType(DragDropHelper::PlaceHol | |||
|
206 | 207 | void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget, |
|
207 | 208 | const QPoint &dragPosition) |
|
208 | 209 | { |
|
209 |
auto &helper = sqpApp->dragDrop |
|
|
210 | auto &helper = sqpApp->dragDropGuiController(); | |
|
210 | 211 | helper.resetDragAndDrop(); |
|
211 | 212 | |
|
212 | 213 | // Note: The management of the drag object is done by Qt |
@@ -261,7 +262,7 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event) | |||
|
261 | 262 | if (impl->acceptMimeData(event->mimeData())) { |
|
262 | 263 | event->acceptProposedAction(); |
|
263 | 264 | |
|
264 |
auto &helper = sqpApp->dragDrop |
|
|
265 | auto &helper = sqpApp->dragDropGuiController(); | |
|
265 | 266 | |
|
266 | 267 | if (!impl->hasPlaceHolder()) { |
|
267 | 268 | auto dragWidget = helper.getCurrentDragWidget(); |
@@ -298,7 +299,7 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event) | |||
|
298 | 299 | { |
|
299 | 300 | Q_UNUSED(event); |
|
300 | 301 | |
|
301 |
auto &helper = sqpApp->dragDrop |
|
|
302 | auto &helper = sqpApp->dragDropGuiController(); | |
|
302 | 303 | |
|
303 | 304 | if (!impl->cursorIsInContainer(this)) { |
|
304 | 305 | helper.removePlaceHolder(); |
@@ -342,7 +343,7 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event) | |||
|
342 | 343 | |
|
343 | 344 | void VisualizationDragDropContainer::dropEvent(QDropEvent *event) |
|
344 | 345 | { |
|
345 |
auto &helper = sqpApp->dragDrop |
|
|
346 | auto &helper = sqpApp->dragDropGuiController(); | |
|
346 | 347 | |
|
347 | 348 | if (impl->acceptMimeData(event->mimeData())) { |
|
348 | 349 | auto dragWidget = helper.getCurrentDragWidget(); |
@@ -398,7 +399,7 void VisualizationDragDropContainer::dropEvent(QDropEvent *event) | |||
|
398 | 399 | event->ignore(); |
|
399 | 400 | } |
|
400 | 401 | |
|
401 |
sqpApp->dragDrop |
|
|
402 | sqpApp->dragDropGuiController().setHightlightedDragWidget(nullptr); | |
|
402 | 403 | impl->m_MinContainerHeight = 0; |
|
403 | 404 | |
|
404 | 405 | QWidget::dropEvent(event); |
@@ -409,7 +410,7 bool VisualizationDragDropContainer::VisualizationDragDropContainerPrivate::find | |||
|
409 | 410 | const QPoint &pos, const QMimeData *mimeData, bool canInsert, bool canMerge, |
|
410 | 411 | const VisualizationDragDropContainer *container) |
|
411 | 412 | { |
|
412 |
auto &helper = sqpApp->dragDrop |
|
|
413 | auto &helper = sqpApp->dragDropGuiController(); | |
|
413 | 414 | |
|
414 | 415 | auto absPos = container->mapToGlobal(pos); |
|
415 | 416 | auto isOnPlaceHolder = helper.placeHolder().isAncestorOf(sqpApp->widgetAt(absPos)); |
@@ -431,7 +432,7 bool VisualizationDragDropContainer::VisualizationDragDropContainerPrivate::find | |||
|
431 | 432 | |
|
432 | 433 | auto posY = pos.y(); |
|
433 | 434 | auto dropIndex = floor(posY / graphHeight); |
|
434 |
auto zoneSize = |
|
|
435 | auto zoneSize = graphHeight / 4.0; | |
|
435 | 436 | |
|
436 | 437 | |
|
437 | 438 | auto isOnTop = posY < dropIndex * graphHeight + zoneSize; |
@@ -441,8 +442,10 bool VisualizationDragDropContainer::VisualizationDragDropContainerPrivate::find | |||
|
441 | 442 | |
|
442 | 443 | auto dragWidgetHovered = getChildDragWidgetAt(container, pos); |
|
443 | 444 | |
|
444 | if (canInsert && (isOnTop || isOnBottom || !canMerge)) { | |
|
445 | if (isOnBottom) { | |
|
445 | auto acceptMerge = m_AcceptDragWidgetFun(dragWidgetHovered, mimeData); | |
|
446 | ||
|
447 | if (canInsert && (isOnTop || isOnBottom || !canMerge || !acceptMerge)) { | |
|
448 | if (posY > (dropIndex + 1) * graphHeight - graphHeight / 2.0) { | |
|
446 | 449 | dropIndex += 1; |
|
447 | 450 | } |
|
448 | 451 | |
@@ -469,13 +472,7 bool VisualizationDragDropContainer::VisualizationDragDropContainerPrivate::find | |||
|
469 | 472 | helper.removePlaceHolder(); |
|
470 | 473 | } |
|
471 | 474 | |
|
472 | if (m_AcceptDragWidgetFun(dragWidgetHovered, mimeData)) { | |
|
473 | 475 |
|
|
474 | return true; | |
|
475 | } | |
|
476 | else { | |
|
477 | return false; | |
|
478 | } | |
|
479 | 476 | } |
|
480 | 477 | else { |
|
481 | 478 | qCWarning(LOG_VisualizationDragDropContainer()) |
@@ -484,7 +481,7 bool VisualizationDragDropContainer::VisualizationDragDropContainerPrivate::find | |||
|
484 | 481 | } |
|
485 | 482 | } |
|
486 | 483 | else { |
|
487 |
qC |
|
|
484 | qCInfo(LOG_VisualizationDragDropContainer()) | |
|
488 | 485 | << tr("VisualizationDragDropContainer::findPlaceHolderPosition, no widget " |
|
489 | 486 | "found in the " |
|
490 | 487 | "container"); |
@@ -4,17 +4,19 | |||
|
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" |
|
10 | 11 | #include "Visualization/VisualizationZoneWidget.h" |
|
11 | 12 | #include "ui_VisualizationGraphWidget.h" |
|
12 | 13 | |
|
14 | #include <Actions/ActionsGuiController.h> | |
|
13 | 15 | #include <Common/MimeTypesDef.h> |
|
14 | 16 | #include <Data/ArrayData.h> |
|
15 | 17 | #include <Data/IDataSeries.h> |
|
16 | 18 | #include <Data/SpectrogramSeries.h> |
|
17 |
#include <DragAndDrop/DragDrop |
|
|
19 | #include <DragAndDrop/DragDropGuiController.h> | |
|
18 | 20 | #include <Settings/SqpSettingsDefs.h> |
|
19 | 21 | #include <SqpApplication.h> |
|
20 | 22 | #include <Time/TimeController.h> |
@@ -169,6 +171,29 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { | |||
|
169 | 171 | return selectionZoneItemUnderCursor; |
|
170 | 172 | } |
|
171 | 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 | ||
|
172 | 197 | QPointF posToAxisPos(const QPoint &pos, QCustomPlot &plot) const |
|
173 | 198 | { |
|
174 | 199 | auto axisX = plot.axisRect()->axis(QCPAxis::atBottom); |
@@ -377,6 +402,20 void VisualizationGraphWidget::addSelectionZones(const QVector<SqpRange> &ranges | |||
|
377 | 402 | plot().replot(QCustomPlot::rpQueuedReplot); |
|
378 | 403 | } |
|
379 | 404 | |
|
405 | void VisualizationGraphWidget::removeSelectionZone(VisualizationSelectionZoneItem *selectionZone) | |
|
406 | { | |
|
407 | parentVisualizationWidget()->selectionZoneManager().setSelected(selectionZone, false); | |
|
408 | ||
|
409 | if (impl->m_HoveredZone == selectionZone) { | |
|
410 | impl->m_HoveredZone = nullptr; | |
|
411 | setCursor(Qt::ArrowCursor); | |
|
412 | } | |
|
413 | ||
|
414 | impl->m_SelectionZones.removeAll(selectionZone); | |
|
415 | plot().removeItem(selectionZone); | |
|
416 | plot().replot(QCustomPlot::rpQueuedReplot); | |
|
417 | } | |
|
418 | ||
|
380 | 419 | void VisualizationGraphWidget::undoZoom() |
|
381 | 420 | { |
|
382 | 421 | auto zoom = impl->m_ZoomStack.pop(); |
@@ -602,6 +641,53 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept | |||
|
602 | 641 | graphMenu.addAction(tr("Undo Zoom"), [this]() { undoZoom(); }); |
|
603 | 642 | } |
|
604 | 643 | |
|
644 | // Selection Zone Actions | |
|
645 | auto selectionZoneItem = impl->selectionZoneAt(pos, plot()); | |
|
646 | if (selectionZoneItem) { | |
|
647 | auto selectedItems = parentVisualizationWidget()->selectionZoneManager().selectedItems(); | |
|
648 | selectedItems.removeAll(selectionZoneItem); | |
|
649 | selectedItems.prepend(selectionZoneItem); // Put the current selection zone first | |
|
650 | ||
|
651 | auto zoneActions = sqpApp->actionsGuiController().selectionZoneActions(); | |
|
652 | if (!zoneActions.isEmpty() && !graphMenu.isEmpty()) { | |
|
653 | graphMenu.addSeparator(); | |
|
654 | } | |
|
655 | ||
|
656 | QHash<QString, QMenu *> subMenus; | |
|
657 | QHash<QString, bool> subMenusEnabled; | |
|
658 | ||
|
659 | for (auto zoneAction : zoneActions) { | |
|
660 | ||
|
661 | auto isEnabled = zoneAction->isEnabled(selectedItems); | |
|
662 | ||
|
663 | auto menu = &graphMenu; | |
|
664 | for (auto subMenuName : zoneAction->subMenuList()) { | |
|
665 | if (!subMenus.contains(subMenuName)) { | |
|
666 | menu = menu->addMenu(subMenuName); | |
|
667 | subMenus[subMenuName] = menu; | |
|
668 | subMenusEnabled[subMenuName] = isEnabled; | |
|
669 | } | |
|
670 | else { | |
|
671 | menu = subMenus.value(subMenuName); | |
|
672 | if (isEnabled) { | |
|
673 | // The sub menu is enabled if at least one of its actions is enabled | |
|
674 | subMenusEnabled[subMenuName] = true; | |
|
675 | } | |
|
676 | } | |
|
677 | } | |
|
678 | ||
|
679 | auto action = menu->addAction(zoneAction->name()); | |
|
680 | action->setEnabled(isEnabled); | |
|
681 | action->setShortcut(zoneAction->displayedShortcut()); | |
|
682 | QObject::connect(action, &QAction::triggered, | |
|
683 | [zoneAction, selectedItems]() { zoneAction->execute(selectedItems); }); | |
|
684 | } | |
|
685 | ||
|
686 | for (auto it = subMenus.cbegin(); it != subMenus.cend(); ++it) { | |
|
687 | it.value()->setEnabled(subMenusEnabled[it.key()]); | |
|
688 | } | |
|
689 | } | |
|
690 | ||
|
605 | 691 | if (!graphMenu.isEmpty()) { |
|
606 | 692 | graphMenu.exec(QCursor::pos()); |
|
607 | 693 | } |
@@ -780,16 +866,24 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept | |||
|
780 | 866 | if (isSelectionZoneMode) { |
|
781 | 867 | auto isMultiSelectionClick = event->modifiers().testFlag(MULTI_ZONE_SELECTION_MODIFIER); |
|
782 | 868 | auto selectionZoneItemUnderCursor = impl->selectionZoneAt(event->pos(), plot()); |
|
783 | if (selectionZoneItemUnderCursor && isLeftClick) { | |
|
784 | selectionZoneItemUnderCursor->setAssociatedEditedZones( | |
|
785 | parentVisualizationWidget()->selectionZoneManager().selectedItems()); | |
|
869 | ||
|
870 | ||
|
871 | if (selectionZoneItemUnderCursor && !selectionZoneItemUnderCursor->selected() | |
|
872 | && !isMultiSelectionClick) { | |
|
873 | parentVisualizationWidget()->selectionZoneManager().select( | |
|
874 | {selectionZoneItemUnderCursor}); | |
|
786 | 875 | } |
|
787 | else if (!isMultiSelectionClick && isLeftClick) { | |
|
876 | else if (!selectionZoneItemUnderCursor && !isMultiSelectionClick && isLeftClick) { | |
|
788 | 877 | parentVisualizationWidget()->selectionZoneManager().clearSelection(); |
|
789 | 878 | } |
|
790 | 879 | else { |
|
791 | 880 | // No selection change |
|
792 | 881 | } |
|
882 | ||
|
883 | if (selectionZoneItemUnderCursor && isLeftClick) { | |
|
884 | selectionZoneItemUnderCursor->setAssociatedEditedZones( | |
|
885 | parentVisualizationWidget()->selectionZoneManager().selectedItems()); | |
|
886 | } | |
|
793 | 887 | } |
|
794 | 888 | |
|
795 | 889 | |
@@ -832,17 +926,51 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept | |||
|
832 | 926 | if (isSelectionZoneMode) { |
|
833 | 927 | auto isMultiSelectionClick = event->modifiers().testFlag(MULTI_ZONE_SELECTION_MODIFIER); |
|
834 | 928 | auto selectionZoneItemUnderCursor = impl->selectionZoneAt(event->pos(), plot()); |
|
835 |
if (selectionZoneItemUnderCursor && event->button() == Qt::LeftButton |
|
|
836 |
|
|
|
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) { | |
|
837 | 963 | parentVisualizationWidget()->selectionZoneManager().select( |
|
838 | 964 | {selectionZoneItemUnderCursor}); |
|
965 | impl->moveSelectionZoneOnTop(selectionZoneItemUnderCursor, plot()); | |
|
839 | 966 | } |
|
840 | else if (!impl->m_HasMovedMouse) { | |
|
967 | else { | |
|
841 | 968 | parentVisualizationWidget()->selectionZoneManager().setSelected( |
|
842 | 969 | selectionZoneItemUnderCursor, !selectionZoneItemUnderCursor->selected() |
|
843 | 970 | || event->button() == Qt::RightButton); |
|
844 | 971 | } |
|
845 | 972 | } |
|
973 | } | |
|
846 | 974 | else { |
|
847 | 975 | // No selection change |
|
848 | 976 | } |
@@ -1,4 +1,7 | |||
|
1 | 1 | #include "Visualization/VisualizationSelectionZoneItem.h" |
|
2 | #include "Visualization/VisualizationGraphWidget.h" | |
|
3 | #include "Visualization/VisualizationSelectionZoneManager.h" | |
|
4 | #include "Visualization/VisualizationWidget.h" | |
|
2 | 5 | |
|
3 | 6 | const QString &DEFAULT_COLOR = QStringLiteral("#E79D41"); |
|
4 | 7 | |
@@ -54,6 +57,53 struct VisualizationSelectionZoneItem::VisualizationSelectionZoneItemPrivate { | |||
|
54 | 57 | auto axis = m_Plot->axisRect()->axis(QCPAxis::atBottom); |
|
55 | 58 | return axis->pixelToCoord(pixels) - axis->pixelToCoord(0); |
|
56 | 59 | } |
|
60 | ||
|
61 | bool alignZones(VisualizationSelectionZoneItem *referenceZone, | |
|
62 | const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool alignOnLeft, | |
|
63 | bool allowResize, bool vertically) | |
|
64 | { | |
|
65 | auto result = false; | |
|
66 | ||
|
67 | auto referenceTime | |
|
68 | = alignOnLeft ? referenceZone->range().m_TStart : referenceZone->range().m_TEnd; | |
|
69 | ||
|
70 | auto referenceBottomAxis = m_Plot->axisRect()->axis(QCPAxis::atBottom); | |
|
71 | auto referenceVerticalPosition = referenceBottomAxis->coordToPixel(referenceTime); | |
|
72 | ||
|
73 | for (auto otherZone : zonesToAlign) { | |
|
74 | ||
|
75 | auto otherZoneRange = otherZone->range(); | |
|
76 | auto newZoneStart = otherZoneRange.m_TStart; | |
|
77 | auto newZoneEnd = otherZoneRange.m_TEnd; | |
|
78 | ||
|
79 | auto alignedTime = referenceTime; | |
|
80 | if (vertically) { | |
|
81 | auto otherZoneAxis = otherZone->parentPlot()->axisRect()->axis(QCPAxis::atBottom); | |
|
82 | alignedTime = otherZoneAxis->pixelToCoord(referenceVerticalPosition); | |
|
83 | } | |
|
84 | ||
|
85 | if (alignOnLeft) { | |
|
86 | newZoneStart = alignedTime; | |
|
87 | if (!allowResize) { | |
|
88 | newZoneEnd = alignedTime + (otherZoneRange.m_TEnd - otherZoneRange.m_TStart); | |
|
89 | } | |
|
90 | } | |
|
91 | else { // align on right | |
|
92 | newZoneEnd = alignedTime; | |
|
93 | if (!allowResize) { | |
|
94 | newZoneStart = alignedTime - (otherZoneRange.m_TEnd - otherZoneRange.m_TStart); | |
|
95 | } | |
|
96 | } | |
|
97 | ||
|
98 | if (newZoneStart < newZoneEnd) { | |
|
99 | result = true; | |
|
100 | otherZone->setRange(newZoneStart, newZoneEnd); | |
|
101 | otherZone->parentPlot()->replot(); | |
|
102 | } | |
|
103 | } | |
|
104 | ||
|
105 | return result; | |
|
106 | } | |
|
57 | 107 | }; |
|
58 | 108 | |
|
59 | 109 | VisualizationSelectionZoneItem::VisualizationSelectionZoneItem(QCustomPlot *plot) |
@@ -94,8 +144,16 VisualizationSelectionZoneItem::VisualizationSelectionZoneItem(QCustomPlot *plot | |||
|
94 | 144 | |
|
95 | 145 | VisualizationSelectionZoneItem::~VisualizationSelectionZoneItem() |
|
96 | 146 | { |
|
97 | impl->m_Plot->removeItem(impl->m_RightLine); | |
|
98 | impl->m_Plot->removeItem(impl->m_LeftLine); | |
|
147 | } | |
|
148 | ||
|
149 | VisualizationGraphWidget *VisualizationSelectionZoneItem::parentGraphWidget() const noexcept | |
|
150 | { | |
|
151 | auto parent = impl->m_Plot->parentWidget(); | |
|
152 | while (parent != nullptr && !qobject_cast<VisualizationGraphWidget *>(parent)) { | |
|
153 | parent = parent->parentWidget(); | |
|
154 | } | |
|
155 | ||
|
156 | return qobject_cast<VisualizationGraphWidget *>(parent); | |
|
99 | 157 | } |
|
100 | 158 | |
|
101 | 159 | void VisualizationSelectionZoneItem::setName(const QString &name) |
@@ -193,6 +251,11 bool VisualizationSelectionZoneItem::isEditionEnabled() const | |||
|
193 | 251 | return impl->m_IsEditionEnabled; |
|
194 | 252 | } |
|
195 | 253 | |
|
254 | void VisualizationSelectionZoneItem::moveToTop() | |
|
255 | { | |
|
256 | moveToLayer(layer(), false); | |
|
257 | } | |
|
258 | ||
|
196 | 259 | Qt::CursorShape |
|
197 | 260 | VisualizationSelectionZoneItem::curshorShapeForPosition(const QPoint &position) const |
|
198 | 261 | { |
@@ -241,8 +304,34 void VisualizationSelectionZoneItem::setAssociatedEditedZones( | |||
|
241 | 304 | impl->m_AssociatedEditedZones.removeAll(this); |
|
242 | 305 | } |
|
243 | 306 | |
|
307 | bool VisualizationSelectionZoneItem::alignZonesVerticallyOnLeft( | |
|
308 | const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool allowResize) | |
|
309 | { | |
|
310 | return impl->alignZones(this, zonesToAlign, true, allowResize, true); | |
|
311 | } | |
|
312 | ||
|
313 | bool VisualizationSelectionZoneItem::alignZonesVerticallyOnRight( | |
|
314 | const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool allowResize) | |
|
315 | { | |
|
316 | return impl->alignZones(this, zonesToAlign, false, allowResize, true); | |
|
317 | } | |
|
318 | ||
|
319 | bool VisualizationSelectionZoneItem::alignZonesTemporallyOnLeft( | |
|
320 | const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool allowResize) | |
|
321 | { | |
|
322 | return impl->alignZones(this, zonesToAlign, true, allowResize, false); | |
|
323 | } | |
|
324 | ||
|
325 | bool VisualizationSelectionZoneItem::alignZonesTemporallyOnRight( | |
|
326 | const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool allowResize) | |
|
327 | { | |
|
328 | return impl->alignZones(this, zonesToAlign, false, allowResize, false); | |
|
329 | } | |
|
330 | ||
|
244 | 331 | void VisualizationSelectionZoneItem::mousePressEvent(QMouseEvent *event, const QVariant &details) |
|
245 | 332 | { |
|
333 | Q_UNUSED(details); | |
|
334 | ||
|
246 | 335 | if (isEditionEnabled() && event->button() == Qt::LeftButton) { |
|
247 | 336 | impl->m_CurrentEditionMode = impl->getEditionMode(event->pos(), this); |
|
248 | 337 | |
@@ -262,6 +351,12 void VisualizationSelectionZoneItem::mousePressEvent(QMouseEvent *event, const Q | |||
|
262 | 351 | void VisualizationSelectionZoneItem::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) |
|
263 | 352 | { |
|
264 | 353 | if (isEditionEnabled()) { |
|
354 | if (!selected()) { | |
|
355 | // Force the item to be selected during the edition | |
|
356 | parentGraphWidget()->parentVisualizationWidget()->selectionZoneManager().setSelected( | |
|
357 | this, true); | |
|
358 | } | |
|
359 | ||
|
265 | 360 | auto axis = impl->m_Plot->axisRect()->axis(QCPAxis::atBottom); |
|
266 | 361 | auto pixelDiff = event->pos().x() - startPos.x(); |
|
267 | 362 | auto diff = impl->pixelSizeToAxisXSize(pixelDiff); |
@@ -304,6 +399,8 void VisualizationSelectionZoneItem::mouseMoveEvent(QMouseEvent *event, const QP | |||
|
304 | 399 | |
|
305 | 400 | void VisualizationSelectionZoneItem::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) |
|
306 | 401 | { |
|
402 | Q_UNUSED(startPos); | |
|
403 | ||
|
307 | 404 | if (isEditionEnabled()) { |
|
308 | 405 | impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition; |
|
309 | 406 | } |
@@ -24,7 +24,7 void VisualizationSelectionZoneManager::setSelected(VisualizationSelectionZoneIt | |||
|
24 | 24 | { |
|
25 | 25 | if (value != item->selected()) { |
|
26 | 26 | item->setSelected(value); |
|
27 | item->parentPlot()->replot(); | |
|
27 | item->parentPlot()->replot(QCustomPlot::rpQueuedReplot); | |
|
28 | 28 | } |
|
29 | 29 | |
|
30 | 30 | if (!value && impl->m_SelectedItems.contains(item)) { |
@@ -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(); |
@@ -11,7 +11,7 | |||
|
11 | 11 | |
|
12 | 12 | #include "Common/MimeTypesDef.h" |
|
13 | 13 | |
|
14 |
#include "DragAndDrop/DragDrop |
|
|
14 | #include "DragAndDrop/DragDropGuiController.h" | |
|
15 | 15 | #include "SqpApplication.h" |
|
16 | 16 | |
|
17 | 17 | Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget") |
@@ -78,7 +78,7 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *par | |||
|
78 | 78 | impl->m_MacScrollBarStyle->selfInstallOn(ui->scrollArea, true); |
|
79 | 79 | #endif |
|
80 | 80 | |
|
81 |
ui->dragDropContainer->setPlaceHolderType(DragDrop |
|
|
81 | ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Zone, "Zone"); | |
|
82 | 82 | ui->dragDropContainer->layout()->setContentsMargins(0, 0, 0, 12); |
|
83 | 83 | ui->dragDropContainer->layout()->setSpacing(0); |
|
84 | 84 | ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH, |
@@ -89,14 +89,14 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *par | |||
|
89 | 89 | VisualizationDragDropContainer::DropBehavior::Inserted); |
|
90 | 90 | |
|
91 | 91 | ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) { |
|
92 |
return sqpApp->dragDrop |
|
|
92 | return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData, | |
|
93 | 93 | ui->dragDropContainer); |
|
94 | 94 | }); |
|
95 | 95 | |
|
96 | 96 | connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this, |
|
97 | 97 | &VisualizationTabWidget::dropMimeData); |
|
98 | 98 | |
|
99 |
sqpApp->dragDrop |
|
|
99 | sqpApp->dragDropGuiController().addDragDropScrollArea(ui->scrollArea); | |
|
100 | 100 | |
|
101 | 101 | // Widget is deleted when closed |
|
102 | 102 | setAttribute(Qt::WA_DeleteOnClose); |
@@ -104,7 +104,7 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *par | |||
|
104 | 104 | |
|
105 | 105 | VisualizationTabWidget::~VisualizationTabWidget() |
|
106 | 106 | { |
|
107 |
sqpApp->dragDrop |
|
|
107 | sqpApp->dragDropGuiController().removeDragDropScrollArea(ui->scrollArea); | |
|
108 | 108 | delete ui; |
|
109 | 109 | } |
|
110 | 110 | |
@@ -213,7 +213,7 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData) | |||
|
213 | 213 | void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph( |
|
214 | 214 | int index, VisualizationTabWidget *tabWidget) |
|
215 | 215 | { |
|
216 |
auto &helper = sqpApp->dragDrop |
|
|
216 | auto &helper = sqpApp->dragDropGuiController(); | |
|
217 | 217 | |
|
218 | 218 | auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget()); |
|
219 | 219 | if (!graphWidget) { |
@@ -286,7 +286,7 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph( | |||
|
286 | 286 | void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone( |
|
287 | 287 | int index, VisualizationTabWidget *tabWidget) |
|
288 | 288 | { |
|
289 |
auto &helper = sqpApp->dragDrop |
|
|
289 | auto &helper = sqpApp->dragDropGuiController(); | |
|
290 | 290 | |
|
291 | 291 | auto zoneWidget = qobject_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget()); |
|
292 | 292 | if (!zoneWidget) { |
@@ -1,6 +1,8 | |||
|
1 | 1 | #include "Visualization/VisualizationWidget.h" |
|
2 | 2 | #include "Visualization/IVisualizationWidgetVisitor.h" |
|
3 | #include "Visualization/VisualizationActionManager.h" | |
|
3 | 4 | #include "Visualization/VisualizationGraphWidget.h" |
|
5 | #include "Visualization/VisualizationSelectionZoneItem.h" | |
|
4 | 6 | #include "Visualization/VisualizationSelectionZoneManager.h" |
|
5 | 7 | #include "Visualization/VisualizationTabWidget.h" |
|
6 | 8 | #include "Visualization/VisualizationZoneWidget.h" |
@@ -12,7 +14,7 | |||
|
12 | 14 | |
|
13 | 15 | #include "ui_VisualizationWidget.h" |
|
14 | 16 | |
|
15 |
#include "DragAndDrop/DragDrop |
|
|
17 | #include "DragAndDrop/DragDropGuiController.h" | |
|
16 | 18 | #include "SqpApplication.h" |
|
17 | 19 | |
|
18 | 20 | #include <QToolButton> |
@@ -23,6 +25,7 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget") | |||
|
23 | 25 | |
|
24 | 26 | struct VisualizationWidget::VisualizationWidgetPrivate { |
|
25 | 27 | std::unique_ptr<VisualizationSelectionZoneManager> m_ZoneSelectionManager = nullptr; |
|
28 | VisualizationActionManager m_ActionManager; | |
|
26 | 29 | |
|
27 | 30 | VisualizationWidgetPrivate() |
|
28 | 31 | : m_ZoneSelectionManager(std::make_unique<VisualizationSelectionZoneManager>()) |
@@ -84,7 +87,22 VisualizationWidget::VisualizationWidget(QWidget *parent) | |||
|
84 | 87 | connect(addTabViewButton, &QToolButton::clicked, addTabView); |
|
85 | 88 | connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView); |
|
86 | 89 | |
|
87 |
sqpApp->dragDrop |
|
|
90 | sqpApp->dragDropGuiController().addDragDropTabBar(ui->tabWidget->tabBar()); | |
|
91 | ||
|
92 | // Actions | |
|
93 | impl->m_ActionManager.installSelectionZoneActions(); | |
|
94 | ||
|
95 | auto removeZoneAction = new QAction("Remove selected zone(s)"); | |
|
96 | removeZoneAction->setShortcut(QKeySequence::Delete); | |
|
97 | connect(removeZoneAction, &QAction::triggered, [this]() { | |
|
98 | auto selection = impl->m_ZoneSelectionManager->selectedItems(); | |
|
99 | for (auto selectionZone : selection) { | |
|
100 | if (auto graph = selectionZone->parentGraphWidget()) { | |
|
101 | graph->removeSelectionZone(selectionZone); | |
|
102 | } | |
|
103 | } | |
|
104 | }); | |
|
105 | addAction(removeZoneAction); | |
|
88 | 106 | |
|
89 | 107 | // Adds default tab |
|
90 | 108 | addTabView(); |
@@ -92,7 +110,7 VisualizationWidget::VisualizationWidget(QWidget *parent) | |||
|
92 | 110 | |
|
93 | 111 | VisualizationWidget::~VisualizationWidget() |
|
94 | 112 | { |
|
95 |
sqpApp->dragDrop |
|
|
113 | sqpApp->dragDropGuiController().removeDragDropTabBar(ui->tabWidget->tabBar()); | |
|
96 | 114 | delete ui; |
|
97 | 115 | } |
|
98 | 116 |
@@ -16,7 +16,7 | |||
|
16 | 16 | |
|
17 | 17 | #include <Visualization/operations/FindVariableOperation.h> |
|
18 | 18 | |
|
19 |
#include <DragAndDrop/DragDrop |
|
|
19 | #include <DragAndDrop/DragDropGuiController.h> | |
|
20 | 20 | #include <QUuid> |
|
21 | 21 | #include <SqpApplication.h> |
|
22 | 22 | #include <cmath> |
@@ -86,7 +86,7 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p | |||
|
86 | 86 | |
|
87 | 87 | ui->zoneNameLabel->setText(name); |
|
88 | 88 | |
|
89 |
ui->dragDropContainer->setPlaceHolderType(DragDrop |
|
|
89 | ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Graph); | |
|
90 | 90 | ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH, |
|
91 | 91 | VisualizationDragDropContainer::DropBehavior::Inserted); |
|
92 | 92 | ui->dragDropContainer->setMimeType( |
@@ -98,7 +98,7 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p | |||
|
98 | 98 | ui->dragDropContainer->setMimeType(MIME_TYPE_SELECTION_ZONE, |
|
99 | 99 | VisualizationDragDropContainer::DropBehavior::Forbidden); |
|
100 | 100 | ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) { |
|
101 |
return sqpApp->dragDrop |
|
|
101 | return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData, | |
|
102 | 102 | ui->dragDropContainer); |
|
103 | 103 | }); |
|
104 | 104 | |
@@ -501,7 +501,7 void VisualizationZoneWidget::dropMimeDataOnGraph(VisualizationDragWidget *dragW | |||
|
501 | 501 | void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph( |
|
502 | 502 | int index, VisualizationZoneWidget *zoneWidget) |
|
503 | 503 | { |
|
504 |
auto &helper = sqpApp->dragDrop |
|
|
504 | auto &helper = sqpApp->dragDropGuiController(); | |
|
505 | 505 | |
|
506 | 506 | auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget()); |
|
507 | 507 | if (!graphWidget) { |
General Comments 0
You need to be logged in to leave comments.
Login now