@@ -0,0 +1,18 | |||||
|
1 | #ifndef SCIQLOP_MACSCROLLBARSTYLE_H | |||
|
2 | #define SCIQLOP_MACSCROLLBARSTYLE_H | |||
|
3 | ||||
|
4 | #include <QProxyStyle> | |||
|
5 | ||||
|
6 | /** | |||
|
7 | * @brief Special style to always display the scrollbars on MAC. | |||
|
8 | */ | |||
|
9 | class MacScrollBarStyle : public QProxyStyle { | |||
|
10 | ||||
|
11 | public: | |||
|
12 | int styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, | |||
|
13 | QStyleHintReturn *returnData) const; | |||
|
14 | ||||
|
15 | void selfInstallOn(QWidget *widget, bool installOnSubWidgets); | |||
|
16 | }; | |||
|
17 | ||||
|
18 | #endif // SCIQLOP_MACSCROLLBARSTYLE_H |
@@ -0,0 +1,40 | |||||
|
1 | #include "Visualization/MacScrollBarStyle.h" | |||
|
2 | ||||
|
3 | #include <QWidget> | |||
|
4 | ||||
|
5 | int MacScrollBarStyle::styleHint(QStyle::StyleHint hint, const QStyleOption *option, | |||
|
6 | const QWidget *widget, QStyleHintReturn *returnData) const | |||
|
7 | { | |||
|
8 | switch (hint) { | |||
|
9 | case SH_ScrollBar_Transient: | |||
|
10 | return false; // Makes the scrollbar always visible | |||
|
11 | case SH_ScrollView_FrameOnlyAroundContents: | |||
|
12 | return true; // Avoid that the scrollbar is drawn on top of the widget | |||
|
13 | default: | |||
|
14 | break; | |||
|
15 | } | |||
|
16 | ||||
|
17 | return QProxyStyle::styleHint(hint, option, widget, returnData); | |||
|
18 | } | |||
|
19 | ||||
|
20 | void MacScrollBarStyle::selfInstallOn(QWidget *widget, bool installOnSubWidgets) | |||
|
21 | { | |||
|
22 | // Note: a style can be installed on a particular widget but it is not automatically applied its | |||
|
23 | // children widgets. | |||
|
24 | ||||
|
25 | QList<QWidget *> widgetsToStyle{widget}; | |||
|
26 | while (!widgetsToStyle.isEmpty()) { | |||
|
27 | ||||
|
28 | auto widget = widgetsToStyle.takeFirst(); | |||
|
29 | widget->setStyle(this); | |||
|
30 | ||||
|
31 | if (installOnSubWidgets) { | |||
|
32 | for (auto child : widget->children()) { | |||
|
33 | auto childWidget = qobject_cast<QWidget *>(child); | |||
|
34 | if (childWidget) { | |||
|
35 | widgetsToStyle << childWidget; | |||
|
36 | } | |||
|
37 | } | |||
|
38 | } | |||
|
39 | } | |||
|
40 | } |
@@ -1,34 +1,37 | |||||
1 | #ifndef SCIQLOP_AXISRENDERINGUTILS_H |
|
1 | #ifndef SCIQLOP_AXISRENDERINGUTILS_H | |
2 | #define SCIQLOP_AXISRENDERINGUTILS_H |
|
2 | #define SCIQLOP_AXISRENDERINGUTILS_H | |
3 |
|
3 | |||
4 | #include <memory> |
|
4 | #include <memory> | |
5 |
|
5 | |||
|
6 | #include <QtCore/QLoggingCategory> | |||
6 | #include <QtCore/QString> |
|
7 | #include <QtCore/QString> | |
7 |
|
8 | |||
|
9 | Q_DECLARE_LOGGING_CATEGORY(LOG_AxisRenderingUtils) | |||
|
10 | ||||
8 | class IDataSeries; |
|
11 | class IDataSeries; | |
9 | class QCPAxis; |
|
12 | class QCPAxis; | |
10 | class QCPColorScale; |
|
13 | class QCPColorScale; | |
11 | class QCustomPlot; |
|
14 | class QCustomPlot; | |
12 |
|
15 | |||
13 | /// Formats a data value according to the axis on which it is present |
|
16 | /// Formats a data value according to the axis on which it is present | |
14 | QString formatValue(double value, const QCPAxis &axis); |
|
17 | QString formatValue(double value, const QCPAxis &axis); | |
15 |
|
18 | |||
16 | /** |
|
19 | /** | |
17 | * Helper used to handle axes rendering |
|
20 | * Helper used to handle axes rendering | |
18 | */ |
|
21 | */ | |
19 | struct IAxisHelper { |
|
22 | struct IAxisHelper { | |
20 | virtual ~IAxisHelper() noexcept = default; |
|
23 | virtual ~IAxisHelper() noexcept = default; | |
21 |
|
24 | |||
22 | /// Set properties of the plot's axes and the color scale associated to plot passed as |
|
25 | /// Set properties of the plot's axes and the color scale associated to plot passed as | |
23 | /// parameters |
|
26 | /// parameters | |
24 | /// @param plot the plot for which to set axe properties |
|
27 | /// @param plot the plot for which to set axe properties | |
25 | /// @param colorScale the color scale for which to set properties |
|
28 | /// @param colorScale the color scale for which to set properties | |
26 | virtual void setProperties(QCustomPlot &plot, QCPColorScale &colorScale) = 0; |
|
29 | virtual void setProperties(QCustomPlot &plot, QCPColorScale &colorScale) = 0; | |
27 | }; |
|
30 | }; | |
28 |
|
31 | |||
29 | struct IAxisHelperFactory { |
|
32 | struct IAxisHelperFactory { | |
30 | /// Creates IAxisHelper according to a data series |
|
33 | /// Creates IAxisHelper according to a data series | |
31 | static std::unique_ptr<IAxisHelper> create(std::shared_ptr<IDataSeries> dataSeries) noexcept; |
|
34 | static std::unique_ptr<IAxisHelper> create(std::shared_ptr<IDataSeries> dataSeries) noexcept; | |
32 | }; |
|
35 | }; | |
33 |
|
36 | |||
34 | #endif // SCIQLOP_AXISRENDERINGUTILS_H |
|
37 | #endif // SCIQLOP_AXISRENDERINGUTILS_H |
@@ -1,29 +1,33 | |||||
1 | #ifndef SCIQLOP_PLOTTABLESRENDERINGUTILS_H |
|
1 | #ifndef SCIQLOP_PLOTTABLESRENDERINGUTILS_H | |
2 | #define SCIQLOP_PLOTTABLESRENDERINGUTILS_H |
|
2 | #define SCIQLOP_PLOTTABLESRENDERINGUTILS_H | |
3 |
|
3 | |||
4 | #include <Visualization/VisualizationDefs.h> |
|
4 | #include <Visualization/VisualizationDefs.h> | |
5 |
|
5 | |||
6 | #include <memory> |
|
6 | #include <memory> | |
7 |
|
7 | |||
|
8 | #include <QtCore/QLoggingCategory> | |||
|
9 | ||||
|
10 | Q_DECLARE_LOGGING_CATEGORY(LOG_PlottablesRenderingUtils) | |||
|
11 | ||||
8 | class IDataSeries; |
|
12 | class IDataSeries; | |
9 | class QCPColorScale; |
|
13 | class QCPColorScale; | |
10 | class QCustomPlot; |
|
14 | class QCustomPlot; | |
11 |
|
15 | |||
12 | /** |
|
16 | /** | |
13 | * Helper used to handle plottables rendering |
|
17 | * Helper used to handle plottables rendering | |
14 | */ |
|
18 | */ | |
15 | struct IPlottablesHelper { |
|
19 | struct IPlottablesHelper { | |
16 | virtual ~IPlottablesHelper() noexcept = default; |
|
20 | virtual ~IPlottablesHelper() noexcept = default; | |
17 |
|
21 | |||
18 | /// Set properties of the plottables passed as parameter |
|
22 | /// Set properties of the plottables passed as parameter | |
19 | /// @param plottables the plottables for which to set properties |
|
23 | /// @param plottables the plottables for which to set properties | |
20 | virtual void setProperties(PlottablesMap &plottables) = 0; |
|
24 | virtual void setProperties(PlottablesMap &plottables) = 0; | |
21 | }; |
|
25 | }; | |
22 |
|
26 | |||
23 | struct IPlottablesHelperFactory { |
|
27 | struct IPlottablesHelperFactory { | |
24 | /// Creates IPlottablesHelper according to a data series |
|
28 | /// Creates IPlottablesHelper according to a data series | |
25 | static std::unique_ptr<IPlottablesHelper> |
|
29 | static std::unique_ptr<IPlottablesHelper> | |
26 | create(std::shared_ptr<IDataSeries> dataSeries) noexcept; |
|
30 | create(std::shared_ptr<IDataSeries> dataSeries) noexcept; | |
27 | }; |
|
31 | }; | |
28 |
|
32 | |||
29 | #endif // SCIQLOP_PLOTTABLESRENDERINGUTILS_H |
|
33 | #endif // SCIQLOP_PLOTTABLESRENDERINGUTILS_H |
@@ -1,97 +1,98 | |||||
1 |
|
1 | |||
2 | gui_moc_headers = [ |
|
2 | gui_moc_headers = [ | |
3 | 'include/DataSource/DataSourceWidget.h', |
|
3 | 'include/DataSource/DataSourceWidget.h', | |
4 | 'include/DataSource/DataSourceTreeWidget.h', |
|
4 | 'include/DataSource/DataSourceTreeWidget.h', | |
5 | 'include/Settings/SqpSettingsDialog.h', |
|
5 | 'include/Settings/SqpSettingsDialog.h', | |
6 | 'include/Settings/SqpSettingsGeneralWidget.h', |
|
6 | 'include/Settings/SqpSettingsGeneralWidget.h', | |
7 | 'include/SidePane/SqpSidePane.h', |
|
7 | 'include/SidePane/SqpSidePane.h', | |
8 | 'include/SqpApplication.h', |
|
8 | 'include/SqpApplication.h', | |
9 | 'include/DragAndDrop/DragDropHelper.h', |
|
9 | 'include/DragAndDrop/DragDropHelper.h', | |
10 | 'include/DragAndDrop/DragDropScroller.h', |
|
10 | 'include/DragAndDrop/DragDropScroller.h', | |
11 | 'include/DragAndDrop/DragDropTabSwitcher.h', |
|
11 | 'include/DragAndDrop/DragDropTabSwitcher.h', | |
12 | 'include/TimeWidget/TimeWidget.h', |
|
12 | 'include/TimeWidget/TimeWidget.h', | |
13 | 'include/Variable/VariableInspectorWidget.h', |
|
13 | 'include/Variable/VariableInspectorWidget.h', | |
14 | 'include/Variable/VariableInspectorTableView.h', |
|
14 | 'include/Variable/VariableInspectorTableView.h', | |
15 | 'include/Variable/RenameVariableDialog.h', |
|
15 | 'include/Variable/RenameVariableDialog.h', | |
16 | 'include/Visualization/qcustomplot.h', |
|
16 | 'include/Visualization/qcustomplot.h', | |
17 | 'include/Visualization/VisualizationGraphWidget.h', |
|
17 | 'include/Visualization/VisualizationGraphWidget.h', | |
18 | 'include/Visualization/VisualizationTabWidget.h', |
|
18 | 'include/Visualization/VisualizationTabWidget.h', | |
19 | 'include/Visualization/VisualizationWidget.h', |
|
19 | 'include/Visualization/VisualizationWidget.h', | |
20 | 'include/Visualization/VisualizationZoneWidget.h', |
|
20 | 'include/Visualization/VisualizationZoneWidget.h', | |
21 | 'include/Visualization/VisualizationDragDropContainer.h', |
|
21 | 'include/Visualization/VisualizationDragDropContainer.h', | |
22 | 'include/Visualization/VisualizationDragWidget.h' |
|
22 | 'include/Visualization/VisualizationDragWidget.h' | |
23 | ] |
|
23 | ] | |
24 |
|
24 | |||
25 | gui_ui_files = [ |
|
25 | gui_ui_files = [ | |
26 | 'ui/DataSource/DataSourceWidget.ui', |
|
26 | 'ui/DataSource/DataSourceWidget.ui', | |
27 | 'ui/Settings/SqpSettingsDialog.ui', |
|
27 | 'ui/Settings/SqpSettingsDialog.ui', | |
28 | 'ui/Settings/SqpSettingsGeneralWidget.ui', |
|
28 | 'ui/Settings/SqpSettingsGeneralWidget.ui', | |
29 | 'ui/SidePane/SqpSidePane.ui', |
|
29 | 'ui/SidePane/SqpSidePane.ui', | |
30 | 'ui/TimeWidget/TimeWidget.ui', |
|
30 | 'ui/TimeWidget/TimeWidget.ui', | |
31 | 'ui/Variable/VariableInspectorWidget.ui', |
|
31 | 'ui/Variable/VariableInspectorWidget.ui', | |
32 | 'ui/Variable/RenameVariableDialog.ui', |
|
32 | 'ui/Variable/RenameVariableDialog.ui', | |
33 | 'ui/Variable/VariableMenuHeaderWidget.ui', |
|
33 | 'ui/Variable/VariableMenuHeaderWidget.ui', | |
34 | 'ui/Visualization/VisualizationGraphWidget.ui', |
|
34 | 'ui/Visualization/VisualizationGraphWidget.ui', | |
35 | 'ui/Visualization/VisualizationTabWidget.ui', |
|
35 | 'ui/Visualization/VisualizationTabWidget.ui', | |
36 | 'ui/Visualization/VisualizationWidget.ui', |
|
36 | 'ui/Visualization/VisualizationWidget.ui', | |
37 | 'ui/Visualization/VisualizationZoneWidget.ui' |
|
37 | 'ui/Visualization/VisualizationZoneWidget.ui' | |
38 | ] |
|
38 | ] | |
39 |
|
39 | |||
40 | gui_qresources = ['resources/sqpguiresources.qrc'] |
|
40 | gui_qresources = ['resources/sqpguiresources.qrc'] | |
41 |
|
41 | |||
42 | gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers, |
|
42 | gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers, | |
43 | ui_files : gui_ui_files, |
|
43 | ui_files : gui_ui_files, | |
44 | qresources : gui_qresources) |
|
44 | qresources : gui_qresources) | |
45 |
|
45 | |||
46 | gui_sources = [ |
|
46 | gui_sources = [ | |
47 | 'src/SqpApplication.cpp', |
|
47 | 'src/SqpApplication.cpp', | |
48 | 'src/DragAndDrop/DragDropHelper.cpp', |
|
48 | 'src/DragAndDrop/DragDropHelper.cpp', | |
49 | 'src/DragAndDrop/DragDropScroller.cpp', |
|
49 | 'src/DragAndDrop/DragDropScroller.cpp', | |
50 | 'src/DragAndDrop/DragDropTabSwitcher.cpp', |
|
50 | 'src/DragAndDrop/DragDropTabSwitcher.cpp', | |
51 | 'src/Common/ColorUtils.cpp', |
|
51 | 'src/Common/ColorUtils.cpp', | |
52 | 'src/Common/VisualizationDef.cpp', |
|
52 | 'src/Common/VisualizationDef.cpp', | |
53 | 'src/DataSource/DataSourceTreeWidgetItem.cpp', |
|
53 | 'src/DataSource/DataSourceTreeWidgetItem.cpp', | |
54 | 'src/DataSource/DataSourceTreeWidgetHelper.cpp', |
|
54 | 'src/DataSource/DataSourceTreeWidgetHelper.cpp', | |
55 | 'src/DataSource/DataSourceWidget.cpp', |
|
55 | 'src/DataSource/DataSourceWidget.cpp', | |
56 | 'src/DataSource/DataSourceTreeWidget.cpp', |
|
56 | 'src/DataSource/DataSourceTreeWidget.cpp', | |
57 | 'src/Settings/SqpSettingsDialog.cpp', |
|
57 | 'src/Settings/SqpSettingsDialog.cpp', | |
58 | 'src/Settings/SqpSettingsGeneralWidget.cpp', |
|
58 | 'src/Settings/SqpSettingsGeneralWidget.cpp', | |
59 | 'src/SidePane/SqpSidePane.cpp', |
|
59 | 'src/SidePane/SqpSidePane.cpp', | |
60 | 'src/TimeWidget/TimeWidget.cpp', |
|
60 | 'src/TimeWidget/TimeWidget.cpp', | |
61 | 'src/Variable/VariableInspectorWidget.cpp', |
|
61 | 'src/Variable/VariableInspectorWidget.cpp', | |
62 | 'src/Variable/VariableInspectorTableView.cpp', |
|
62 | 'src/Variable/VariableInspectorTableView.cpp', | |
63 | 'src/Variable/VariableMenuHeaderWidget.cpp', |
|
63 | 'src/Variable/VariableMenuHeaderWidget.cpp', | |
64 | 'src/Variable/RenameVariableDialog.cpp', |
|
64 | 'src/Variable/RenameVariableDialog.cpp', | |
65 | 'src/Visualization/VisualizationGraphHelper.cpp', |
|
65 | 'src/Visualization/VisualizationGraphHelper.cpp', | |
66 | 'src/Visualization/VisualizationGraphRenderingDelegate.cpp', |
|
66 | 'src/Visualization/VisualizationGraphRenderingDelegate.cpp', | |
67 | 'src/Visualization/VisualizationGraphWidget.cpp', |
|
67 | 'src/Visualization/VisualizationGraphWidget.cpp', | |
68 | 'src/Visualization/VisualizationTabWidget.cpp', |
|
68 | 'src/Visualization/VisualizationTabWidget.cpp', | |
69 | 'src/Visualization/VisualizationWidget.cpp', |
|
69 | 'src/Visualization/VisualizationWidget.cpp', | |
70 | 'src/Visualization/VisualizationZoneWidget.cpp', |
|
70 | 'src/Visualization/VisualizationZoneWidget.cpp', | |
71 | 'src/Visualization/qcustomplot.cpp', |
|
71 | 'src/Visualization/qcustomplot.cpp', | |
72 | 'src/Visualization/QCustomPlotSynchronizer.cpp', |
|
72 | 'src/Visualization/QCustomPlotSynchronizer.cpp', | |
73 | 'src/Visualization/operations/FindVariableOperation.cpp', |
|
73 | 'src/Visualization/operations/FindVariableOperation.cpp', | |
74 | 'src/Visualization/operations/GenerateVariableMenuOperation.cpp', |
|
74 | 'src/Visualization/operations/GenerateVariableMenuOperation.cpp', | |
75 | 'src/Visualization/operations/MenuBuilder.cpp', |
|
75 | 'src/Visualization/operations/MenuBuilder.cpp', | |
76 | 'src/Visualization/operations/RemoveVariableOperation.cpp', |
|
76 | 'src/Visualization/operations/RemoveVariableOperation.cpp', | |
77 | 'src/Visualization/operations/RescaleAxeOperation.cpp', |
|
77 | 'src/Visualization/operations/RescaleAxeOperation.cpp', | |
78 | 'src/Visualization/VisualizationDragDropContainer.cpp', |
|
78 | 'src/Visualization/VisualizationDragDropContainer.cpp', | |
79 | 'src/Visualization/VisualizationDragWidget.cpp' |
|
79 | 'src/Visualization/VisualizationDragWidget.cpp', | |
80 | 'src/Visualization/AxisRenderingUtils.cpp', |
|
80 | 'src/Visualization/AxisRenderingUtils.cpp', | |
81 | 'src/Visualization/PlottablesRenderingUtils.cpp' |
|
81 | 'src/Visualization/PlottablesRenderingUtils.cpp', | |
|
82 | 'src/Visualization/MacScrollBarStyle.cpp' | |||
82 | ] |
|
83 | ] | |
83 |
|
84 | |||
84 | gui_inc = include_directories(['include']) |
|
85 | gui_inc = include_directories(['include']) | |
85 |
|
86 | |||
86 | sciqlop_gui_lib = library('sciqlopgui', |
|
87 | sciqlop_gui_lib = library('sciqlopgui', | |
87 | gui_sources, |
|
88 | gui_sources, | |
88 | gui_moc_files, |
|
89 | gui_moc_files, | |
89 | include_directories : [gui_inc], |
|
90 | include_directories : [gui_inc], | |
90 | dependencies : [ qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core], |
|
91 | dependencies : [ qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core], | |
91 | install : true |
|
92 | install : true | |
92 | ) |
|
93 | ) | |
93 |
|
94 | |||
94 | sciqlop_gui = declare_dependency(link_with : sciqlop_gui_lib, |
|
95 | sciqlop_gui = declare_dependency(link_with : sciqlop_gui_lib, | |
95 | include_directories : gui_inc, |
|
96 | include_directories : gui_inc, | |
96 | dependencies : [qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core]) |
|
97 | dependencies : [qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core]) | |
97 |
|
98 |
@@ -1,163 +1,173 | |||||
1 | #include "Visualization/AxisRenderingUtils.h" |
|
1 | #include "Visualization/AxisRenderingUtils.h" | |
2 |
|
2 | |||
3 | #include <Data/ScalarSeries.h> |
|
3 | #include <Data/ScalarSeries.h> | |
4 | #include <Data/SpectrogramSeries.h> |
|
4 | #include <Data/SpectrogramSeries.h> | |
5 | #include <Data/VectorSeries.h> |
|
5 | #include <Data/VectorSeries.h> | |
6 |
|
6 | |||
7 | #include <Visualization/qcustomplot.h> |
|
7 | #include <Visualization/qcustomplot.h> | |
8 |
|
8 | |||
|
9 | Q_LOGGING_CATEGORY(LOG_AxisRenderingUtils, "AxisRenderingUtils") | |||
|
10 | ||||
9 | namespace { |
|
11 | namespace { | |
10 |
|
12 | |||
11 | const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz"); |
|
13 | const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz"); | |
12 |
|
14 | |||
13 | /// Format for datetimes on a axis |
|
15 | /// Format for datetimes on a axis | |
14 | const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss"); |
|
16 | const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss"); | |
15 |
|
17 | |||
16 | /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or |
|
18 | /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or | |
17 | /// non-time data |
|
19 | /// non-time data | |
18 | QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis) |
|
20 | QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis, QCPAxis::ScaleType scaleType) | |
19 | { |
|
21 | { | |
20 | if (isTimeAxis) { |
|
22 | if (isTimeAxis) { | |
21 | auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create(); |
|
23 | auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create(); | |
22 | dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT); |
|
24 | dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT); | |
23 | dateTicker->setDateTimeSpec(Qt::UTC); |
|
25 | dateTicker->setDateTimeSpec(Qt::UTC); | |
24 |
|
26 | |||
25 | return dateTicker; |
|
27 | return dateTicker; | |
26 | } |
|
28 | } | |
|
29 | else if (scaleType == QCPAxis::stLogarithmic) { | |||
|
30 | return QSharedPointer<QCPAxisTickerLog>::create(); | |||
|
31 | } | |||
27 | else { |
|
32 | else { | |
28 | // default ticker |
|
33 | // default ticker | |
29 | return QSharedPointer<QCPAxisTicker>::create(); |
|
34 | return QSharedPointer<QCPAxisTicker>::create(); | |
30 | } |
|
35 | } | |
31 | } |
|
36 | } | |
32 |
|
37 | |||
33 | /** |
|
38 | /** | |
34 | * Sets properties of the axis passed as parameter |
|
39 | * Sets properties of the axis passed as parameter | |
35 | * @param axis the axis to set |
|
40 | * @param axis the axis to set | |
36 | * @param unit the unit to set for the axis |
|
41 | * @param unit the unit to set for the axis | |
37 | * @param scaleType the scale type to set for the axis |
|
42 | * @param scaleType the scale type to set for the axis | |
38 | */ |
|
43 | */ | |
39 | void setAxisProperties(QCPAxis &axis, const Unit &unit, |
|
44 | void setAxisProperties(QCPAxis &axis, const Unit &unit, | |
40 | QCPAxis::ScaleType scaleType = QCPAxis::stLinear) |
|
45 | QCPAxis::ScaleType scaleType = QCPAxis::stLinear) | |
41 | { |
|
46 | { | |
42 | // label (unit name) |
|
47 | // label (unit name) | |
43 | axis.setLabel(unit.m_Name); |
|
48 | axis.setLabel(unit.m_Name); | |
44 |
|
49 | |||
45 | // scale type |
|
50 | // scale type | |
46 | axis.setScaleType(scaleType); |
|
51 | axis.setScaleType(scaleType); | |
|
52 | if (scaleType == QCPAxis::stLogarithmic) { | |||
|
53 | // Scientific notation | |||
|
54 | axis.setNumberPrecision(0); | |||
|
55 | axis.setNumberFormat("eb"); | |||
|
56 | } | |||
47 |
|
57 | |||
48 | // ticker (depending on the type of unit) |
|
58 | // ticker (depending on the type of unit) | |
49 | axis.setTicker(axisTicker(unit.m_TimeUnit)); |
|
59 | axis.setTicker(axisTicker(unit.m_TimeUnit, scaleType)); | |
50 | } |
|
60 | } | |
51 |
|
61 | |||
52 | /** |
|
62 | /** | |
53 | * Delegate used to set axes properties |
|
63 | * Delegate used to set axes properties | |
54 | */ |
|
64 | */ | |
55 | template <typename T, typename Enabled = void> |
|
65 | template <typename T, typename Enabled = void> | |
56 | struct AxisSetter { |
|
66 | struct AxisSetter { | |
57 | static void setProperties(T &, QCustomPlot &, QCPColorScale &) |
|
67 | static void setProperties(T &, QCustomPlot &, QCPColorScale &) | |
58 | { |
|
68 | { | |
59 | // Default implementation does nothing |
|
69 | // Default implementation does nothing | |
|
70 | qCCritical(LOG_AxisRenderingUtils()) << "Can't set axis properties: unmanaged type of data"; | |||
60 | } |
|
71 | } | |
61 | }; |
|
72 | }; | |
62 |
|
73 | |||
63 | /** |
|
74 | /** | |
64 | * Specialization of AxisSetter for scalars and vectors |
|
75 | * Specialization of AxisSetter for scalars and vectors | |
65 | * @sa ScalarSeries |
|
76 | * @sa ScalarSeries | |
66 | * @sa VectorSeries |
|
77 | * @sa VectorSeries | |
67 | */ |
|
78 | */ | |
68 | template <typename T> |
|
79 | template <typename T> | |
69 | struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value |
|
80 | struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value | |
70 | or std::is_base_of<VectorSeries, T>::value> > { |
|
81 | or std::is_base_of<VectorSeries, T>::value> > { | |
71 | static void setProperties(T &dataSeries, QCustomPlot &plot, QCPColorScale &) |
|
82 | static void setProperties(T &dataSeries, QCustomPlot &plot, QCPColorScale &) | |
72 | { |
|
83 | { | |
73 | dataSeries.lockRead(); |
|
84 | dataSeries.lockRead(); | |
74 | auto xAxisUnit = dataSeries.xAxisUnit(); |
|
85 | auto xAxisUnit = dataSeries.xAxisUnit(); | |
75 | auto valuesUnit = dataSeries.valuesUnit(); |
|
86 | auto valuesUnit = dataSeries.valuesUnit(); | |
76 | dataSeries.unlock(); |
|
87 | dataSeries.unlock(); | |
77 |
|
88 | |||
78 | setAxisProperties(*plot.xAxis, xAxisUnit); |
|
89 | setAxisProperties(*plot.xAxis, xAxisUnit); | |
79 | setAxisProperties(*plot.yAxis, valuesUnit); |
|
90 | setAxisProperties(*plot.yAxis, valuesUnit); | |
80 | } |
|
91 | } | |
81 | }; |
|
92 | }; | |
82 |
|
93 | |||
83 | /** |
|
94 | /** | |
84 | * Specialization of AxisSetter for spectrograms |
|
95 | * Specialization of AxisSetter for spectrograms | |
85 | * @sa SpectrogramSeries |
|
96 | * @sa SpectrogramSeries | |
86 | */ |
|
97 | */ | |
87 | template <typename T> |
|
98 | template <typename T> | |
88 | struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > { |
|
99 | struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > { | |
89 | static void setProperties(T &dataSeries, QCustomPlot &plot, QCPColorScale &colorScale) |
|
100 | static void setProperties(T &dataSeries, QCustomPlot &plot, QCPColorScale &colorScale) | |
90 | { |
|
101 | { | |
91 | dataSeries.lockRead(); |
|
102 | dataSeries.lockRead(); | |
92 | auto xAxisUnit = dataSeries.xAxisUnit(); |
|
103 | auto xAxisUnit = dataSeries.xAxisUnit(); | |
93 | /// @todo ALX: use iterators here |
|
104 | /// @todo ALX: use iterators here | |
94 | auto yAxisUnit = dataSeries.yAxis().unit(); |
|
105 | auto yAxisUnit = dataSeries.yAxis().unit(); | |
95 | auto valuesUnit = dataSeries.valuesUnit(); |
|
106 | auto valuesUnit = dataSeries.valuesUnit(); | |
96 | dataSeries.unlock(); |
|
107 | dataSeries.unlock(); | |
97 |
|
108 | |||
98 | setAxisProperties(*plot.xAxis, xAxisUnit); |
|
109 | setAxisProperties(*plot.xAxis, xAxisUnit); | |
99 | setAxisProperties(*plot.yAxis, yAxisUnit); |
|
110 | setAxisProperties(*plot.yAxis, yAxisUnit, QCPAxis::stLogarithmic); | |
100 |
|
111 | |||
101 | // Displays color scale in plot |
|
112 | // Displays color scale in plot | |
102 | plot.plotLayout()->insertRow(0); |
|
113 | plot.plotLayout()->insertRow(0); | |
103 | plot.plotLayout()->addElement(0, 0, &colorScale); |
|
114 | plot.plotLayout()->addElement(0, 0, &colorScale); | |
104 | colorScale.setType(QCPAxis::atTop); |
|
115 | colorScale.setType(QCPAxis::atTop); | |
105 | colorScale.setMinimumMargins(QMargins{0, 0, 0, 0}); |
|
116 | colorScale.setMinimumMargins(QMargins{0, 0, 0, 0}); | |
106 |
|
117 | |||
107 | // Aligns color scale with axes |
|
118 | // Aligns color scale with axes | |
108 | auto marginGroups = plot.axisRect()->marginGroups(); |
|
119 | auto marginGroups = plot.axisRect()->marginGroups(); | |
109 | for (auto it = marginGroups.begin(), end = marginGroups.end(); it != end; ++it) { |
|
120 | for (auto it = marginGroups.begin(), end = marginGroups.end(); it != end; ++it) { | |
110 | colorScale.setMarginGroup(it.key(), it.value()); |
|
121 | colorScale.setMarginGroup(it.key(), it.value()); | |
111 | } |
|
122 | } | |
112 |
|
123 | |||
113 | // Set color scale properties |
|
124 | // Set color scale properties | |
114 | colorScale.setLabel(valuesUnit.m_Name); |
|
125 | setAxisProperties(*colorScale.axis(), valuesUnit, QCPAxis::stLogarithmic); | |
115 | colorScale.setDataScaleType(QCPAxis::stLogarithmic); // Logarithmic scale |
|
|||
116 | } |
|
126 | } | |
117 | }; |
|
127 | }; | |
118 |
|
128 | |||
119 | /** |
|
129 | /** | |
120 | * Default implementation of IAxisHelper, which takes data series to set axes properties |
|
130 | * Default implementation of IAxisHelper, which takes data series to set axes properties | |
121 | * @tparam T the data series' type |
|
131 | * @tparam T the data series' type | |
122 | */ |
|
132 | */ | |
123 | template <typename T> |
|
133 | template <typename T> | |
124 | struct AxisHelper : public IAxisHelper { |
|
134 | struct AxisHelper : public IAxisHelper { | |
125 | explicit AxisHelper(T &dataSeries) : m_DataSeries{dataSeries} {} |
|
135 | explicit AxisHelper(T &dataSeries) : m_DataSeries{dataSeries} {} | |
126 |
|
136 | |||
127 | void setProperties(QCustomPlot &plot, QCPColorScale &colorScale) override |
|
137 | void setProperties(QCustomPlot &plot, QCPColorScale &colorScale) override | |
128 | { |
|
138 | { | |
129 | AxisSetter<T>::setProperties(m_DataSeries, plot, colorScale); |
|
139 | AxisSetter<T>::setProperties(m_DataSeries, plot, colorScale); | |
130 | } |
|
140 | } | |
131 |
|
141 | |||
132 | T &m_DataSeries; |
|
142 | T &m_DataSeries; | |
133 | }; |
|
143 | }; | |
134 |
|
144 | |||
135 | } // namespace |
|
145 | } // namespace | |
136 |
|
146 | |||
137 | QString formatValue(double value, const QCPAxis &axis) |
|
147 | QString formatValue(double value, const QCPAxis &axis) | |
138 | { |
|
148 | { | |
139 | // If the axis is a time axis, formats the value as a date |
|
149 | // If the axis is a time axis, formats the value as a date | |
140 | if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())) { |
|
150 | if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())) { | |
141 | return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT); |
|
151 | return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT); | |
142 | } |
|
152 | } | |
143 | else { |
|
153 | else { | |
144 | return QString::number(value); |
|
154 | return QString::number(value); | |
145 | } |
|
155 | } | |
146 | } |
|
156 | } | |
147 |
|
157 | |||
148 | std::unique_ptr<IAxisHelper> |
|
158 | std::unique_ptr<IAxisHelper> | |
149 | IAxisHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept |
|
159 | IAxisHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept | |
150 | { |
|
160 | { | |
151 | if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) { |
|
161 | if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) { | |
152 | return std::make_unique<AxisHelper<ScalarSeries> >(*scalarSeries); |
|
162 | return std::make_unique<AxisHelper<ScalarSeries> >(*scalarSeries); | |
153 | } |
|
163 | } | |
154 | else if (auto spectrogramSeries = std::dynamic_pointer_cast<SpectrogramSeries>(dataSeries)) { |
|
164 | else if (auto spectrogramSeries = std::dynamic_pointer_cast<SpectrogramSeries>(dataSeries)) { | |
155 | return std::make_unique<AxisHelper<SpectrogramSeries> >(*spectrogramSeries); |
|
165 | return std::make_unique<AxisHelper<SpectrogramSeries> >(*spectrogramSeries); | |
156 | } |
|
166 | } | |
157 | else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) { |
|
167 | else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) { | |
158 | return std::make_unique<AxisHelper<VectorSeries> >(*vectorSeries); |
|
168 | return std::make_unique<AxisHelper<VectorSeries> >(*vectorSeries); | |
159 | } |
|
169 | } | |
160 | else { |
|
170 | else { | |
161 | return std::make_unique<AxisHelper<IDataSeries> >(*dataSeries); |
|
171 | return std::make_unique<AxisHelper<IDataSeries> >(*dataSeries); | |
162 | } |
|
172 | } | |
163 | } |
|
173 | } |
@@ -1,120 +1,127 | |||||
1 | #include "Visualization/PlottablesRenderingUtils.h" |
|
1 | #include "Visualization/PlottablesRenderingUtils.h" | |
2 |
|
2 | |||
3 | #include <Common/ColorUtils.h> |
|
3 | #include <Common/ColorUtils.h> | |
4 |
|
4 | |||
5 | #include <Data/ScalarSeries.h> |
|
5 | #include <Data/ScalarSeries.h> | |
6 | #include <Data/SpectrogramSeries.h> |
|
6 | #include <Data/SpectrogramSeries.h> | |
7 | #include <Data/VectorSeries.h> |
|
7 | #include <Data/VectorSeries.h> | |
8 |
|
8 | |||
9 | #include <Visualization/qcustomplot.h> |
|
9 | #include <Visualization/qcustomplot.h> | |
10 |
|
10 | |||
|
11 | Q_LOGGING_CATEGORY(LOG_PlottablesRenderingUtils, "PlottablesRenderingUtils") | |||
|
12 | ||||
11 | namespace { |
|
13 | namespace { | |
12 |
|
14 | |||
13 | /// Default gradient used for colormap |
|
15 | /// Default gradient used for colormap | |
14 | const auto DEFAULT_COLORMAP_GRADIENT = QCPColorGradient::gpJet; |
|
16 | const auto DEFAULT_COLORMAP_GRADIENT = QCPColorGradient::gpJet; | |
15 |
|
17 | |||
16 | /** |
|
18 | /** | |
17 | * Delegate used to set plottables properties |
|
19 | * Delegate used to set plottables properties | |
18 | */ |
|
20 | */ | |
19 | template <typename T, typename Enabled = void> |
|
21 | template <typename T, typename Enabled = void> | |
20 | struct PlottablesSetter { |
|
22 | struct PlottablesSetter { | |
21 | static void setProperties(T &, PlottablesMap &) |
|
23 | static void setProperties(T &, PlottablesMap &) | |
22 | { |
|
24 | { | |
23 | // Default implementation does nothing |
|
25 | // Default implementation does nothing | |
|
26 | qCCritical(LOG_PlottablesRenderingUtils()) | |||
|
27 | << "Can't set plottables properties: unmanaged type of data"; | |||
24 | } |
|
28 | } | |
25 | }; |
|
29 | }; | |
26 |
|
30 | |||
27 | /** |
|
31 | /** | |
28 | * Specialization of PlottablesSetter for scalars and vectors |
|
32 | * Specialization of PlottablesSetter for scalars and vectors | |
29 | * @sa ScalarSeries |
|
33 | * @sa ScalarSeries | |
30 | * @sa VectorSeries |
|
34 | * @sa VectorSeries | |
31 | */ |
|
35 | */ | |
32 | template <typename T> |
|
36 | template <typename T> | |
33 | struct PlottablesSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value |
|
37 | struct PlottablesSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value | |
34 | or std::is_base_of<VectorSeries, T>::value> > { |
|
38 | or std::is_base_of<VectorSeries, T>::value> > { | |
35 | static void setProperties(T &dataSeries, PlottablesMap &plottables) |
|
39 | static void setProperties(T &dataSeries, PlottablesMap &plottables) | |
36 | { |
|
40 | { | |
37 | // Gets the number of components of the data series |
|
41 | // Gets the number of components of the data series | |
38 | dataSeries.lockRead(); |
|
42 | dataSeries.lockRead(); | |
39 | auto componentCount = dataSeries.valuesData()->componentCount(); |
|
43 | auto componentCount = dataSeries.valuesData()->componentCount(); | |
40 | dataSeries.unlock(); |
|
44 | dataSeries.unlock(); | |
41 |
|
45 | |||
42 | // Generates colors for each component |
|
46 | // Generates colors for each component | |
43 | auto colors = ColorUtils::colors(Qt::blue, Qt::red, componentCount); |
|
47 | auto colors = ColorUtils::colors(Qt::blue, Qt::red, componentCount); | |
44 |
|
48 | |||
45 | // For each component of the data series, creates a QCPGraph to add to the plot |
|
49 | // For each component of the data series, creates a QCPGraph to add to the plot | |
46 | for (auto i = 0; i < componentCount; ++i) { |
|
50 | for (auto i = 0; i < componentCount; ++i) { | |
47 | auto graph = plottables.at(i); |
|
51 | auto graph = plottables.at(i); | |
48 | graph->setPen(QPen{colors.at(i)}); |
|
52 | graph->setPen(QPen{colors.at(i)}); | |
49 | } |
|
53 | } | |
50 | } |
|
54 | } | |
51 | }; |
|
55 | }; | |
52 |
|
56 | |||
53 | /** |
|
57 | /** | |
54 | * Specialization of PlottablesSetter for spectrograms |
|
58 | * Specialization of PlottablesSetter for spectrograms | |
55 | * @sa SpectrogramSeries |
|
59 | * @sa SpectrogramSeries | |
56 | */ |
|
60 | */ | |
57 | template <typename T> |
|
61 | template <typename T> | |
58 | struct PlottablesSetter<T, |
|
62 | struct PlottablesSetter<T, | |
59 | typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > { |
|
63 | typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > { | |
60 | static void setProperties(T &, PlottablesMap &plottables) |
|
64 | static void setProperties(T &, PlottablesMap &plottables) | |
61 | { |
|
65 | { | |
62 | // Checks that for a spectrogram there is only one plottable, that is a colormap |
|
66 | // Checks that for a spectrogram there is only one plottable, that is a colormap | |
63 | if (plottables.size() != 1) { |
|
67 | if (plottables.size() != 1) { | |
64 | return; |
|
68 | return; | |
65 | } |
|
69 | } | |
66 |
|
70 | |||
67 | if (auto colormap = dynamic_cast<QCPColorMap *>(plottables.begin()->second)) { |
|
71 | if (auto colormap = dynamic_cast<QCPColorMap *>(plottables.begin()->second)) { | |
68 | colormap->setInterpolate(false); // No value interpolation |
|
72 | colormap->setInterpolate(false); // No value interpolation | |
69 | colormap->setTightBoundary(true); |
|
73 | colormap->setTightBoundary(true); | |
70 |
|
74 | |||
71 | // Finds color scale in the colormap's plot to associate with it |
|
75 | // Finds color scale in the colormap's plot to associate with it | |
72 | auto plot = colormap->parentPlot(); |
|
76 | auto plot = colormap->parentPlot(); | |
73 | auto plotElements = plot->plotLayout()->elements(false); |
|
77 | auto plotElements = plot->plotLayout()->elements(false); | |
74 | for (auto plotElement : plotElements) { |
|
78 | for (auto plotElement : plotElements) { | |
75 | if (auto colorScale = dynamic_cast<QCPColorScale *>(plotElement)) { |
|
79 | if (auto colorScale = dynamic_cast<QCPColorScale *>(plotElement)) { | |
76 | colormap->setColorScale(colorScale); |
|
80 | colormap->setColorScale(colorScale); | |
77 | } |
|
81 | } | |
78 | } |
|
82 | } | |
79 |
|
83 | |||
80 | // Sets gradient used for color scale |
|
84 | // Sets gradient used for color scale | |
81 | colormap->setGradient(DEFAULT_COLORMAP_GRADIENT); |
|
85 | colormap->setGradient(DEFAULT_COLORMAP_GRADIENT); | |
82 | colormap->rescaleDataRange(); |
|
86 | colormap->rescaleDataRange(); | |
83 | } |
|
87 | } | |
|
88 | else { | |||
|
89 | qCCritical(LOG_PlottablesRenderingUtils()) << "Can't get colormap of the spectrogram"; | |||
|
90 | } | |||
84 | } |
|
91 | } | |
85 | }; |
|
92 | }; | |
86 |
|
93 | |||
87 | /** |
|
94 | /** | |
88 | * Default implementation of IPlottablesHelper, which takes data series to set plottables properties |
|
95 | * Default implementation of IPlottablesHelper, which takes data series to set plottables properties | |
89 | * @tparam T the data series' type |
|
96 | * @tparam T the data series' type | |
90 | */ |
|
97 | */ | |
91 | template <typename T> |
|
98 | template <typename T> | |
92 | struct PlottablesHelper : public IPlottablesHelper { |
|
99 | struct PlottablesHelper : public IPlottablesHelper { | |
93 | explicit PlottablesHelper(T &dataSeries) : m_DataSeries{dataSeries} {} |
|
100 | explicit PlottablesHelper(T &dataSeries) : m_DataSeries{dataSeries} {} | |
94 |
|
101 | |||
95 | void setProperties(PlottablesMap &plottables) override |
|
102 | void setProperties(PlottablesMap &plottables) override | |
96 | { |
|
103 | { | |
97 | PlottablesSetter<T>::setProperties(m_DataSeries, plottables); |
|
104 | PlottablesSetter<T>::setProperties(m_DataSeries, plottables); | |
98 | } |
|
105 | } | |
99 |
|
106 | |||
100 | T &m_DataSeries; |
|
107 | T &m_DataSeries; | |
101 | }; |
|
108 | }; | |
102 |
|
109 | |||
103 | } // namespace |
|
110 | } // namespace | |
104 |
|
111 | |||
105 | std::unique_ptr<IPlottablesHelper> |
|
112 | std::unique_ptr<IPlottablesHelper> | |
106 | IPlottablesHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept |
|
113 | IPlottablesHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept | |
107 | { |
|
114 | { | |
108 | if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) { |
|
115 | if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) { | |
109 | return std::make_unique<PlottablesHelper<ScalarSeries> >(*scalarSeries); |
|
116 | return std::make_unique<PlottablesHelper<ScalarSeries> >(*scalarSeries); | |
110 | } |
|
117 | } | |
111 | else if (auto spectrogramSeries = std::dynamic_pointer_cast<SpectrogramSeries>(dataSeries)) { |
|
118 | else if (auto spectrogramSeries = std::dynamic_pointer_cast<SpectrogramSeries>(dataSeries)) { | |
112 | return std::make_unique<PlottablesHelper<SpectrogramSeries> >(*spectrogramSeries); |
|
119 | return std::make_unique<PlottablesHelper<SpectrogramSeries> >(*spectrogramSeries); | |
113 | } |
|
120 | } | |
114 | else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) { |
|
121 | else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) { | |
115 | return std::make_unique<PlottablesHelper<VectorSeries> >(*vectorSeries); |
|
122 | return std::make_unique<PlottablesHelper<VectorSeries> >(*vectorSeries); | |
116 | } |
|
123 | } | |
117 | else { |
|
124 | else { | |
118 | return std::make_unique<PlottablesHelper<IDataSeries> >(*dataSeries); |
|
125 | return std::make_unique<PlottablesHelper<IDataSeries> >(*dataSeries); | |
119 | } |
|
126 | } | |
120 | } |
|
127 | } |
@@ -1,309 +1,319 | |||||
1 | #include "Visualization/VisualizationTabWidget.h" |
|
1 | #include "Visualization/VisualizationTabWidget.h" | |
2 | #include "Visualization/IVisualizationWidgetVisitor.h" |
|
2 | #include "Visualization/IVisualizationWidgetVisitor.h" | |
3 | #include "ui_VisualizationTabWidget.h" |
|
3 | #include "ui_VisualizationTabWidget.h" | |
4 |
|
4 | |||
5 | #include "Visualization/VisualizationGraphWidget.h" |
|
5 | #include "Visualization/VisualizationGraphWidget.h" | |
6 | #include "Visualization/VisualizationZoneWidget.h" |
|
6 | #include "Visualization/VisualizationZoneWidget.h" | |
7 |
|
7 | |||
|
8 | #include "Visualization/MacScrollBarStyle.h" | |||
|
9 | ||||
8 | #include "Variable/VariableController.h" |
|
10 | #include "Variable/VariableController.h" | |
9 |
|
11 | |||
10 | #include "Common/MimeTypesDef.h" |
|
12 | #include "Common/MimeTypesDef.h" | |
11 |
|
13 | |||
12 | #include "DragAndDrop/DragDropHelper.h" |
|
14 | #include "DragAndDrop/DragDropHelper.h" | |
13 | #include "SqpApplication.h" |
|
15 | #include "SqpApplication.h" | |
14 |
|
16 | |||
15 | Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget") |
|
17 | Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget") | |
16 |
|
18 | |||
17 | namespace { |
|
19 | namespace { | |
18 |
|
20 | |||
19 | /// Generates a default name for a new zone, according to the number of zones already displayed in |
|
21 | /// Generates a default name for a new zone, according to the number of zones already displayed in | |
20 | /// the tab |
|
22 | /// the tab | |
21 | QString defaultZoneName(const QLayout &layout) |
|
23 | QString defaultZoneName(const QLayout &layout) | |
22 | { |
|
24 | { | |
23 | auto count = 0; |
|
25 | auto count = 0; | |
24 | for (auto i = 0; i < layout.count(); ++i) { |
|
26 | for (auto i = 0; i < layout.count(); ++i) { | |
25 | if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) { |
|
27 | if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) { | |
26 | count++; |
|
28 | count++; | |
27 | } |
|
29 | } | |
28 | } |
|
30 | } | |
29 |
|
31 | |||
30 | return QObject::tr("Zone %1").arg(count + 1); |
|
32 | return QObject::tr("Zone %1").arg(count + 1); | |
31 | } |
|
33 | } | |
32 |
|
34 | |||
33 | /** |
|
35 | /** | |
34 | * Applies a function to all zones of the tab represented by its layout |
|
36 | * Applies a function to all zones of the tab represented by its layout | |
35 | * @param layout the layout that contains zones |
|
37 | * @param layout the layout that contains zones | |
36 | * @param fun the function to apply to each zone |
|
38 | * @param fun the function to apply to each zone | |
37 | */ |
|
39 | */ | |
38 | template <typename Fun> |
|
40 | template <typename Fun> | |
39 | void processZones(QLayout &layout, Fun fun) |
|
41 | void processZones(QLayout &layout, Fun fun) | |
40 | { |
|
42 | { | |
41 | for (auto i = 0; i < layout.count(); ++i) { |
|
43 | for (auto i = 0; i < layout.count(); ++i) { | |
42 | if (auto item = layout.itemAt(i)) { |
|
44 | if (auto item = layout.itemAt(i)) { | |
43 | if (auto visualizationZoneWidget |
|
45 | if (auto visualizationZoneWidget | |
44 | = dynamic_cast<VisualizationZoneWidget *>(item->widget())) { |
|
46 | = dynamic_cast<VisualizationZoneWidget *>(item->widget())) { | |
45 | fun(*visualizationZoneWidget); |
|
47 | fun(*visualizationZoneWidget); | |
46 | } |
|
48 | } | |
47 | } |
|
49 | } | |
48 | } |
|
50 | } | |
49 | } |
|
51 | } | |
50 |
|
52 | |||
51 | } // namespace |
|
53 | } // namespace | |
52 |
|
54 | |||
53 | struct VisualizationTabWidget::VisualizationTabWidgetPrivate { |
|
55 | struct VisualizationTabWidget::VisualizationTabWidgetPrivate { | |
54 | explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {} |
|
56 | explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {} | |
55 |
|
57 | |||
56 | QString m_Name; |
|
58 | QString m_Name; | |
57 |
|
59 | |||
|
60 | #ifdef Q_OS_MAC | |||
|
61 | std::unique_ptr<MacScrollBarStyle> m_MacScrollBarStyle = std::make_unique<MacScrollBarStyle>(); | |||
|
62 | #endif | |||
|
63 | ||||
58 | void dropGraph(int index, VisualizationTabWidget *tabWidget); |
|
64 | void dropGraph(int index, VisualizationTabWidget *tabWidget); | |
59 | void dropZone(int index, VisualizationTabWidget *tabWidget); |
|
65 | void dropZone(int index, VisualizationTabWidget *tabWidget); | |
60 | void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index, |
|
66 | void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index, | |
61 | VisualizationTabWidget *tabWidget); |
|
67 | VisualizationTabWidget *tabWidget); | |
62 | }; |
|
68 | }; | |
63 |
|
69 | |||
64 | VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent) |
|
70 | VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent) | |
65 | : QWidget{parent}, |
|
71 | : QWidget{parent}, | |
66 | ui{new Ui::VisualizationTabWidget}, |
|
72 | ui{new Ui::VisualizationTabWidget}, | |
67 | impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)} |
|
73 | impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)} | |
68 | { |
|
74 | { | |
69 | ui->setupUi(this); |
|
75 | ui->setupUi(this); | |
70 |
|
76 | |||
|
77 | #ifdef Q_OS_MAC | |||
|
78 | impl->m_MacScrollBarStyle->selfInstallOn(ui->scrollArea, true); | |||
|
79 | #endif | |||
|
80 | ||||
71 | ui->dragDropContainer->setPlaceHolderType(DragDropHelper::PlaceHolderType::Zone, "Zone"); |
|
81 | ui->dragDropContainer->setPlaceHolderType(DragDropHelper::PlaceHolderType::Zone, "Zone"); | |
72 | ui->dragDropContainer->layout()->setContentsMargins(0, 0, 0, 5); |
|
82 | ui->dragDropContainer->layout()->setContentsMargins(0, 0, 0, 5); | |
73 | ui->dragDropContainer->addAcceptedMimeType( |
|
83 | ui->dragDropContainer->addAcceptedMimeType( | |
74 | MIME_TYPE_GRAPH, VisualizationDragDropContainer::DropBehavior::Inserted); |
|
84 | MIME_TYPE_GRAPH, VisualizationDragDropContainer::DropBehavior::Inserted); | |
75 | ui->dragDropContainer->addAcceptedMimeType( |
|
85 | ui->dragDropContainer->addAcceptedMimeType( | |
76 | MIME_TYPE_ZONE, VisualizationDragDropContainer::DropBehavior::Inserted); |
|
86 | MIME_TYPE_ZONE, VisualizationDragDropContainer::DropBehavior::Inserted); | |
77 | ui->dragDropContainer->addAcceptedMimeType( |
|
87 | ui->dragDropContainer->addAcceptedMimeType( | |
78 | MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::Inserted); |
|
88 | MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::Inserted); | |
79 |
|
89 | |||
80 | ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) { |
|
90 | ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) { | |
81 | return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData, |
|
91 | return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData, | |
82 | ui->dragDropContainer); |
|
92 | ui->dragDropContainer); | |
83 | }); |
|
93 | }); | |
84 |
|
94 | |||
85 | connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this, |
|
95 | connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this, | |
86 | &VisualizationTabWidget::dropMimeData); |
|
96 | &VisualizationTabWidget::dropMimeData); | |
87 |
|
97 | |||
88 | sqpApp->dragDropHelper().addDragDropScrollArea(ui->scrollArea); |
|
98 | sqpApp->dragDropHelper().addDragDropScrollArea(ui->scrollArea); | |
89 |
|
99 | |||
90 | // Widget is deleted when closed |
|
100 | // Widget is deleted when closed | |
91 | setAttribute(Qt::WA_DeleteOnClose); |
|
101 | setAttribute(Qt::WA_DeleteOnClose); | |
92 | } |
|
102 | } | |
93 |
|
103 | |||
94 | VisualizationTabWidget::~VisualizationTabWidget() |
|
104 | VisualizationTabWidget::~VisualizationTabWidget() | |
95 | { |
|
105 | { | |
96 | sqpApp->dragDropHelper().removeDragDropScrollArea(ui->scrollArea); |
|
106 | sqpApp->dragDropHelper().removeDragDropScrollArea(ui->scrollArea); | |
97 | delete ui; |
|
107 | delete ui; | |
98 | } |
|
108 | } | |
99 |
|
109 | |||
100 | void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget) |
|
110 | void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget) | |
101 | { |
|
111 | { | |
102 | ui->dragDropContainer->addDragWidget(zoneWidget); |
|
112 | ui->dragDropContainer->addDragWidget(zoneWidget); | |
103 | } |
|
113 | } | |
104 |
|
114 | |||
105 | void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zoneWidget) |
|
115 | void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zoneWidget) | |
106 | { |
|
116 | { | |
107 | ui->dragDropContainer->insertDragWidget(index, zoneWidget); |
|
117 | ui->dragDropContainer->insertDragWidget(index, zoneWidget); | |
108 | } |
|
118 | } | |
109 |
|
119 | |||
110 | VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable) |
|
120 | VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable) | |
111 | { |
|
121 | { | |
112 | return createZone({variable}, -1); |
|
122 | return createZone({variable}, -1); | |
113 | } |
|
123 | } | |
114 |
|
124 | |||
115 | VisualizationZoneWidget * |
|
125 | VisualizationZoneWidget * | |
116 | VisualizationTabWidget::createZone(const QList<std::shared_ptr<Variable> > &variables, int index) |
|
126 | VisualizationTabWidget::createZone(const QList<std::shared_ptr<Variable> > &variables, int index) | |
117 | { |
|
127 | { | |
118 | auto zoneWidget = createEmptyZone(index); |
|
128 | auto zoneWidget = createEmptyZone(index); | |
119 |
|
129 | |||
120 | // Creates a new graph into the zone |
|
130 | // Creates a new graph into the zone | |
121 | zoneWidget->createGraph(variables, index); |
|
131 | zoneWidget->createGraph(variables, index); | |
122 |
|
132 | |||
123 | return zoneWidget; |
|
133 | return zoneWidget; | |
124 | } |
|
134 | } | |
125 |
|
135 | |||
126 | VisualizationZoneWidget *VisualizationTabWidget::createEmptyZone(int index) |
|
136 | VisualizationZoneWidget *VisualizationTabWidget::createEmptyZone(int index) | |
127 | { |
|
137 | { | |
128 | auto zoneWidget |
|
138 | auto zoneWidget | |
129 | = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this}; |
|
139 | = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this}; | |
130 | this->insertZone(index, zoneWidget); |
|
140 | this->insertZone(index, zoneWidget); | |
131 |
|
141 | |||
132 | return zoneWidget; |
|
142 | return zoneWidget; | |
133 | } |
|
143 | } | |
134 |
|
144 | |||
135 | void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor) |
|
145 | void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor) | |
136 | { |
|
146 | { | |
137 | if (visitor) { |
|
147 | if (visitor) { | |
138 | visitor->visitEnter(this); |
|
148 | visitor->visitEnter(this); | |
139 |
|
149 | |||
140 | // Apply visitor to zone children: widgets different from zones are not visited (no action) |
|
150 | // Apply visitor to zone children: widgets different from zones are not visited (no action) | |
141 | processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) { |
|
151 | processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) { | |
142 | zoneWidget.accept(visitor); |
|
152 | zoneWidget.accept(visitor); | |
143 | }); |
|
153 | }); | |
144 |
|
154 | |||
145 | visitor->visitLeave(this); |
|
155 | visitor->visitLeave(this); | |
146 | } |
|
156 | } | |
147 | else { |
|
157 | else { | |
148 | qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null"); |
|
158 | qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null"); | |
149 | } |
|
159 | } | |
150 | } |
|
160 | } | |
151 |
|
161 | |||
152 | bool VisualizationTabWidget::canDrop(const Variable &variable) const |
|
162 | bool VisualizationTabWidget::canDrop(const Variable &variable) const | |
153 | { |
|
163 | { | |
154 | // A tab can always accomodate a variable |
|
164 | // A tab can always accomodate a variable | |
155 | Q_UNUSED(variable); |
|
165 | Q_UNUSED(variable); | |
156 | return true; |
|
166 | return true; | |
157 | } |
|
167 | } | |
158 |
|
168 | |||
159 | bool VisualizationTabWidget::contains(const Variable &variable) const |
|
169 | bool VisualizationTabWidget::contains(const Variable &variable) const | |
160 | { |
|
170 | { | |
161 | Q_UNUSED(variable); |
|
171 | Q_UNUSED(variable); | |
162 | return false; |
|
172 | return false; | |
163 | } |
|
173 | } | |
164 |
|
174 | |||
165 | QString VisualizationTabWidget::name() const |
|
175 | QString VisualizationTabWidget::name() const | |
166 | { |
|
176 | { | |
167 | return impl->m_Name; |
|
177 | return impl->m_Name; | |
168 | } |
|
178 | } | |
169 |
|
179 | |||
170 | void VisualizationTabWidget::closeEvent(QCloseEvent *event) |
|
180 | void VisualizationTabWidget::closeEvent(QCloseEvent *event) | |
171 | { |
|
181 | { | |
172 | // Closes zones in the tab |
|
182 | // Closes zones in the tab | |
173 | processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); }); |
|
183 | processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); }); | |
174 |
|
184 | |||
175 | QWidget::closeEvent(event); |
|
185 | QWidget::closeEvent(event); | |
176 | } |
|
186 | } | |
177 |
|
187 | |||
178 | QLayout &VisualizationTabWidget::tabLayout() const noexcept |
|
188 | QLayout &VisualizationTabWidget::tabLayout() const noexcept | |
179 | { |
|
189 | { | |
180 | return *ui->dragDropContainer->layout(); |
|
190 | return *ui->dragDropContainer->layout(); | |
181 | } |
|
191 | } | |
182 |
|
192 | |||
183 | void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData) |
|
193 | void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData) | |
184 | { |
|
194 | { | |
185 | if (mimeData->hasFormat(MIME_TYPE_GRAPH)) { |
|
195 | if (mimeData->hasFormat(MIME_TYPE_GRAPH)) { | |
186 | impl->dropGraph(index, this); |
|
196 | impl->dropGraph(index, this); | |
187 | } |
|
197 | } | |
188 | else if (mimeData->hasFormat(MIME_TYPE_ZONE)) { |
|
198 | else if (mimeData->hasFormat(MIME_TYPE_ZONE)) { | |
189 | impl->dropZone(index, this); |
|
199 | impl->dropZone(index, this); | |
190 | } |
|
200 | } | |
191 | else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) { |
|
201 | else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) { | |
192 | auto variables = sqpApp->variableController().variablesForMimeData( |
|
202 | auto variables = sqpApp->variableController().variablesForMimeData( | |
193 | mimeData->data(MIME_TYPE_VARIABLE_LIST)); |
|
203 | mimeData->data(MIME_TYPE_VARIABLE_LIST)); | |
194 | impl->dropVariables(variables, index, this); |
|
204 | impl->dropVariables(variables, index, this); | |
195 | } |
|
205 | } | |
196 | else { |
|
206 | else { | |
197 | qCWarning(LOG_VisualizationZoneWidget()) |
|
207 | qCWarning(LOG_VisualizationZoneWidget()) | |
198 | << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received."); |
|
208 | << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received."); | |
199 | } |
|
209 | } | |
200 | } |
|
210 | } | |
201 |
|
211 | |||
202 | void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph( |
|
212 | void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph( | |
203 | int index, VisualizationTabWidget *tabWidget) |
|
213 | int index, VisualizationTabWidget *tabWidget) | |
204 | { |
|
214 | { | |
205 | auto &helper = sqpApp->dragDropHelper(); |
|
215 | auto &helper = sqpApp->dragDropHelper(); | |
206 |
|
216 | |||
207 | auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget()); |
|
217 | auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget()); | |
208 | if (!graphWidget) { |
|
218 | if (!graphWidget) { | |
209 | qCWarning(LOG_VisualizationZoneWidget()) |
|
219 | qCWarning(LOG_VisualizationZoneWidget()) | |
210 | << tr("VisualizationTabWidget::dropGraph, drop aborted, the dropped graph is not " |
|
220 | << tr("VisualizationTabWidget::dropGraph, drop aborted, the dropped graph is not " | |
211 | "found or invalid."); |
|
221 | "found or invalid."); | |
212 | Q_ASSERT(false); |
|
222 | Q_ASSERT(false); | |
213 | return; |
|
223 | return; | |
214 | } |
|
224 | } | |
215 |
|
225 | |||
216 | auto parentDragDropContainer |
|
226 | auto parentDragDropContainer | |
217 | = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget()); |
|
227 | = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget()); | |
218 | if (!parentDragDropContainer) { |
|
228 | if (!parentDragDropContainer) { | |
219 | qCWarning(LOG_VisualizationZoneWidget()) |
|
229 | qCWarning(LOG_VisualizationZoneWidget()) | |
220 | << tr("VisualizationTabWidget::dropGraph, drop aborted, the parent container of " |
|
230 | << tr("VisualizationTabWidget::dropGraph, drop aborted, the parent container of " | |
221 | "the dropped graph is not found."); |
|
231 | "the dropped graph is not found."); | |
222 | Q_ASSERT(false); |
|
232 | Q_ASSERT(false); | |
223 | return; |
|
233 | return; | |
224 | } |
|
234 | } | |
225 |
|
235 | |||
226 | auto nbGraph = parentDragDropContainer->countDragWidget(); |
|
236 | auto nbGraph = parentDragDropContainer->countDragWidget(); | |
227 |
|
237 | |||
228 | const auto &variables = graphWidget->variables(); |
|
238 | const auto &variables = graphWidget->variables(); | |
229 |
|
239 | |||
230 | if (!variables.isEmpty()) { |
|
240 | if (!variables.isEmpty()) { | |
231 | // Abort the requests for the variables (if any) |
|
241 | // Abort the requests for the variables (if any) | |
232 | // Commented, because it's not sure if it's needed or not |
|
242 | // Commented, because it's not sure if it's needed or not | |
233 | // for (const auto& var : variables) |
|
243 | // for (const auto& var : variables) | |
234 | //{ |
|
244 | //{ | |
235 | // sqpApp->variableController().onAbortProgressRequested(var); |
|
245 | // sqpApp->variableController().onAbortProgressRequested(var); | |
236 | //} |
|
246 | //} | |
237 |
|
247 | |||
238 | if (nbGraph == 1) { |
|
248 | if (nbGraph == 1) { | |
239 | // This is the only graph in the previous zone, close the zone |
|
249 | // This is the only graph in the previous zone, close the zone | |
240 | helper.delayedCloseWidget(graphWidget->parentZoneWidget()); |
|
250 | helper.delayedCloseWidget(graphWidget->parentZoneWidget()); | |
241 | } |
|
251 | } | |
242 | else { |
|
252 | else { | |
243 | // Close the graph |
|
253 | // Close the graph | |
244 | helper.delayedCloseWidget(graphWidget); |
|
254 | helper.delayedCloseWidget(graphWidget); | |
245 | } |
|
255 | } | |
246 |
|
256 | |||
247 | tabWidget->createZone(variables, index); |
|
257 | tabWidget->createZone(variables, index); | |
248 | } |
|
258 | } | |
249 | else { |
|
259 | else { | |
250 | // The graph is empty, create an empty zone and move the graph inside |
|
260 | // The graph is empty, create an empty zone and move the graph inside | |
251 |
|
261 | |||
252 | auto parentZoneWidget = graphWidget->parentZoneWidget(); |
|
262 | auto parentZoneWidget = graphWidget->parentZoneWidget(); | |
253 |
|
263 | |||
254 | parentDragDropContainer->layout()->removeWidget(graphWidget); |
|
264 | parentDragDropContainer->layout()->removeWidget(graphWidget); | |
255 |
|
265 | |||
256 | auto zoneWidget = tabWidget->createEmptyZone(index); |
|
266 | auto zoneWidget = tabWidget->createEmptyZone(index); | |
257 | zoneWidget->addGraph(graphWidget); |
|
267 | zoneWidget->addGraph(graphWidget); | |
258 |
|
268 | |||
259 | // Close the old zone if it was the only graph inside |
|
269 | // Close the old zone if it was the only graph inside | |
260 | if (nbGraph == 1) { |
|
270 | if (nbGraph == 1) { | |
261 | helper.delayedCloseWidget(parentZoneWidget); |
|
271 | helper.delayedCloseWidget(parentZoneWidget); | |
262 | } |
|
272 | } | |
263 | } |
|
273 | } | |
264 | } |
|
274 | } | |
265 |
|
275 | |||
266 | void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone( |
|
276 | void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone( | |
267 | int index, VisualizationTabWidget *tabWidget) |
|
277 | int index, VisualizationTabWidget *tabWidget) | |
268 | { |
|
278 | { | |
269 | auto &helper = sqpApp->dragDropHelper(); |
|
279 | auto &helper = sqpApp->dragDropHelper(); | |
270 |
|
280 | |||
271 | auto zoneWidget = qobject_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget()); |
|
281 | auto zoneWidget = qobject_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget()); | |
272 | if (!zoneWidget) { |
|
282 | if (!zoneWidget) { | |
273 | qCWarning(LOG_VisualizationZoneWidget()) |
|
283 | qCWarning(LOG_VisualizationZoneWidget()) | |
274 | << tr("VisualizationTabWidget::dropZone, drop aborted, the dropped zone is not " |
|
284 | << tr("VisualizationTabWidget::dropZone, drop aborted, the dropped zone is not " | |
275 | "found or invalid."); |
|
285 | "found or invalid."); | |
276 | Q_ASSERT(false); |
|
286 | Q_ASSERT(false); | |
277 | return; |
|
287 | return; | |
278 | } |
|
288 | } | |
279 |
|
289 | |||
280 | auto parentDragDropContainer |
|
290 | auto parentDragDropContainer | |
281 | = qobject_cast<VisualizationDragDropContainer *>(zoneWidget->parentWidget()); |
|
291 | = qobject_cast<VisualizationDragDropContainer *>(zoneWidget->parentWidget()); | |
282 | if (!parentDragDropContainer) { |
|
292 | if (!parentDragDropContainer) { | |
283 | qCWarning(LOG_VisualizationZoneWidget()) |
|
293 | qCWarning(LOG_VisualizationZoneWidget()) | |
284 | << tr("VisualizationTabWidget::dropZone, drop aborted, the parent container of " |
|
294 | << tr("VisualizationTabWidget::dropZone, drop aborted, the parent container of " | |
285 | "the dropped zone is not found."); |
|
295 | "the dropped zone is not found."); | |
286 | Q_ASSERT(false); |
|
296 | Q_ASSERT(false); | |
287 | return; |
|
297 | return; | |
288 | } |
|
298 | } | |
289 |
|
299 | |||
290 | // Simple move of the zone, no variable operation associated |
|
300 | // Simple move of the zone, no variable operation associated | |
291 | parentDragDropContainer->layout()->removeWidget(zoneWidget); |
|
301 | parentDragDropContainer->layout()->removeWidget(zoneWidget); | |
292 | tabWidget->ui->dragDropContainer->insertDragWidget(index, zoneWidget); |
|
302 | tabWidget->ui->dragDropContainer->insertDragWidget(index, zoneWidget); | |
293 | } |
|
303 | } | |
294 |
|
304 | |||
295 | void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables( |
|
305 | void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables( | |
296 | const QList<std::shared_ptr<Variable> > &variables, int index, |
|
306 | const QList<std::shared_ptr<Variable> > &variables, int index, | |
297 | VisualizationTabWidget *tabWidget) |
|
307 | VisualizationTabWidget *tabWidget) | |
298 | { |
|
308 | { | |
299 | // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and |
|
309 | // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and | |
300 | // compatible variable here |
|
310 | // compatible variable here | |
301 | if (variables.count() > 1) { |
|
311 | if (variables.count() > 1) { | |
302 | qCWarning(LOG_VisualizationZoneWidget()) |
|
312 | qCWarning(LOG_VisualizationZoneWidget()) | |
303 | << tr("VisualizationTabWidget::dropVariables, dropping multiple variables, operation " |
|
313 | << tr("VisualizationTabWidget::dropVariables, dropping multiple variables, operation " | |
304 | "aborted."); |
|
314 | "aborted."); | |
305 | return; |
|
315 | return; | |
306 | } |
|
316 | } | |
307 |
|
317 | |||
308 | tabWidget->createZone(variables, index); |
|
318 | tabWidget->createZone(variables, index); | |
309 | } |
|
319 | } |
General Comments 0
You need to be logged in to leave comments.
Login now