##// END OF EJS Templates
Closed
Pull request !141 Created on Thu, 08 Jun 2017 10:17:28, by
- Merge pull request #140 from SCIQLOP-Initialisation feature/VisualizationWidget
- Widget of the tab widget are now of type VisualizationTabWidget
- Merge branch 'feature/PluginTreeItem' into develop
- Adds vera exclusions
- Loads SciQlop plugins
Pull request versions not available.
ver Time Author Commit Description
17 commits hidden, click expand to show them.
@@ -0,0 +1,1
1 TODO
@@ -0,0 +1,21
1 <ui version="4.0">
2 <author/>
3 <comment/>
4 <exportmacro/>
5 <class>SqpSidePane</class>
6 <widget name="SqpSidePane" class="QWidget">
7 <property name="geometry">
8 <rect>
9 <x>0</x>
10 <y>0</y>
11 <width>400</width>
12 <height>300</height>
13 </rect>
14 </property>
15 <property name="windowTitle">
16 <string>Form</string>
17 </property>
18 </widget>
19 <pixmapfunction/>
20 <connections/>
21 </ui>
@@ -0,0 +1,21
1 <ui version="4.0">
2 <author/>
3 <comment/>
4 <exportmacro/>
5 <class>VisualizationGraphWidget</class>
6 <widget name="VisualizationGraphWidget" class="QWidget">
7 <property name="geometry">
8 <rect>
9 <x>0</x>
10 <y>0</y>
11 <width>400</width>
12 <height>300</height>
13 </rect>
14 </property>
15 <property name="windowTitle">
16 <string>Form</string>
17 </property>
18 </widget>
19 <pixmapfunction/>
20 <connections/>
21 </ui>
@@ -0,0 +1,21
1 <ui version="4.0">
2 <author/>
3 <comment/>
4 <exportmacro/>
5 <class>VisualizationTabWidget</class>
6 <widget name="VisualizationTabWidget" class="QWidget">
7 <property name="geometry">
8 <rect>
9 <x>0</x>
10 <y>0</y>
11 <width>400</width>
12 <height>300</height>
13 </rect>
14 </property>
15 <property name="windowTitle">
16 <string>Form</string>
17 </property>
18 </widget>
19 <pixmapfunction/>
20 <connections/>
21 </ui>
@@ -1,31 +1,1
1 ![](gui/resources/icones/sciqlop2PNG_1024.png){:.some-css-class style="width: 20%"}
1 TODO No newline at end of file
2
3
4 # Overview
5
6 ** SciQLOP ** (**SCI**entific **Q**t application for **L**earning from **O**bservations of **P**lasmas) aims to be an ergonomic
7 and powerful tool enabling visualization and analysis of in-situ space plasma data. This goal rises some
8 challenges either technical and in the conception and the design.
9 The time resolution allowed by nowadays measurements imply the ability to plot millions of points just for
10 one sensor with no compromise on interactivity. Plots may stay responsive even with millions of points.
11 Being able to scroll, zoom, move and export the plots with the mouse are the minimal interactions expected by the user.
12 SciQLOP may also abstract the manipulation of physic data while providing contextual features such as
13 coordinate transform, physical quantity extraction from data.
14 That said increasing graphical features usually lead to slower software and more complex GUI. Keeping
15 SciQLOP lightweight and intuitive is one of the priorities to make it usable and competitive.
16
17
18 ## How to build
19
20 ```
21 git clone https://hephaistos.lpp.polytechnique.fr/rhodecode/HG_REPOSITORIES/LPP/SciQLOP_Repos/SciQLop
22 cd SciQLop
23 mkdir build && cd build
24 cmake ../
25 make
26
27 ```
28
29 ## How to contribute
30
31 Contact sciqlop@lpp.polytechnique.fr
@@ -14,7 +14,6 include_directories("${INCLUDES_DIR}")
14 # Find Qt modules
14 # Find Qt modules
15 #
15 #
16 SCIQLOP_FIND_QT(Core Widgets)
16 SCIQLOP_FIND_QT(Core Widgets)
17
18
17
19 #
18 #
20 # Find dependent libraries
19 # Find dependent libraries
@@ -66,18 +65,9 set_property(TARGET ${EXECUTABLE_NAME} PROPERTY CXX_STANDARD 14)
66 set_property(TARGET ${EXECUTABLE_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
65 set_property(TARGET ${EXECUTABLE_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
67 target_link_libraries(${EXECUTABLE_NAME}
66 target_link_libraries(${EXECUTABLE_NAME}
68 ${LIBRARIES})
67 ${LIBRARIES})
69
68
70 INSTALL(TARGETS ${EXECUTABLE_NAME}
71 RUNTIME DESTINATION ${INSTALL_BINARY_DIR}
72 LIBRARY DESTINATION ${INSTALL_BINARY_DIR}
73 ARCHIVE DESTINATION ${INSTALL_BINARY_DIR}
74 )
75 # Link with Qt5 modules
69 # Link with Qt5 modules
76 qt5_use_modules(${EXECUTABLE_NAME} Core Widgets)
70 qt5_use_modules(${EXECUTABLE_NAME} Core Widgets)
77
78
79 add_dependencies(${EXECUTABLE_NAME} ${SQPGUI_LIBRARY_NAME} ${SQPCORE_LIBRARY_NAME})
80
81
71
82
72
83 # Add the files to the list of files to be analyzed
73 # Add the files to the list of files to be analyzed
@@ -23,20 +23,17
23 #define SCIQLOP_MAINWINDOW_H
23 #define SCIQLOP_MAINWINDOW_H
24
24
25 #include <QListWidgetItem>
25 #include <QListWidgetItem>
26 #include <QLoggingCategory>
27 #include <QMainWindow>
26 #include <QMainWindow>
28 #include <QProgressBar>
27 #include <QProgressBar>
29 #include <QProgressDialog>
28 #include <QProgressDialog>
30 #include <QThread>
29 #include <QThread>
31 #include <QVBoxLayout>
30 #include <QVBoxLayout>
32 #include <QWidget>
31 #include <QWidget>
33
32 //#include "../Core/qlopservice.h"
34 #include <Common/spimpl.h>
33 //#include "../Core/qlopgui.h"
35
34
36 #include <memory>
35 #include <memory>
37
36
38 Q_DECLARE_LOGGING_CATEGORY(LOG_MainWindow)
39
40 namespace Ui {
37 namespace Ui {
41 class MainWindow;
38 class MainWindow;
42 } // namespace Ui
39 } // namespace Ui
@@ -58,8 +55,6 private:
58 // QWidget *m_progressWidget;
55 // QWidget *m_progressWidget;
59 // QVBoxLayout *m_progressLayout;
56 // QVBoxLayout *m_progressLayout;
60 // QList<QLopService*> m_qlopServices;
57 // QList<QLopService*> m_qlopServices;
61 class MainWindowPrivate;
62 spimpl::unique_impl_ptr<MainWindowPrivate> impl;
63 };
58 };
64
59
65 #endif // SCIQLOP_MAINWINDOW_H
60 #endif // SCIQLOP_MAINWINDOW_H
@@ -28,15 +28,11
28 #include <Plugin/PluginManager.h>
28 #include <Plugin/PluginManager.h>
29 #include <QDir>
29 #include <QDir>
30
30
31 #include <QLoggingCategory>
32
33 Q_LOGGING_CATEGORY(LOG_Main, "Main")
34
35 namespace {
31 namespace {
36
32
33 /// Name of the directory containing the plugins
37 const auto PLUGIN_DIRECTORY_NAME = QStringLiteral("plugins");
34 const auto PLUGIN_DIRECTORY_NAME = QStringLiteral("plugins");
38
35
39
40 } // namespace
36 } // namespace
41
37
42 int main(int argc, char *argv[])
38 int main(int argc, char *argv[])
@@ -49,32 +45,15 int main(int argc, char *argv[])
49 w.show();
45 w.show();
50
46
51 // Loads plugins
47 // Loads plugins
52 auto pluginDir = QDir{a.applicationDirPath()};
48 auto pluginDir = QDir{sqpApp->applicationDirPath()};
53 auto pluginLookupPath = {
54 a.applicationDirPath(),
55 a.applicationDirPath() + "/" + PLUGIN_DIRECTORY_NAME,
56 a.applicationDirPath() + "/../lib64/SciQlop",
57 a.applicationDirPath() + "/../lib64/sciqlop",
58 a.applicationDirPath() + "/../lib/SciQlop",
59 a.applicationDirPath() + "/../lib/sciqlop",
60 a.applicationDirPath() + "/../plugins",
61 };
62
63 #if _WIN32 || _WIN64
64 pluginDir.mkdir(PLUGIN_DIRECTORY_NAME);
49 pluginDir.mkdir(PLUGIN_DIRECTORY_NAME);
65 pluginDir.cd(PLUGIN_DIRECTORY_NAME);
50 pluginDir.cd(PLUGIN_DIRECTORY_NAME);
66 #endif
67
51
68 PluginManager pluginManager{};
52 qCDebug(LOG_PluginManager())
53 << QObject::tr("Plugin directory: %1").arg(pluginDir.absolutePath());
69
54
70 for (auto &&path : pluginLookupPath) {
55 PluginManager pluginManager{};
71 QDir directory{path};
56 pluginManager.loadPlugins(pluginDir);
72 if (directory.exists()) {
73 qCDebug(LOG_Main())
74 << QObject::tr("Plugin directory: %1").arg(directory.absolutePath());
75 pluginManager.loadPlugins(directory);
76 }
77 }
78
57
79 return a.exec();
58 return a.exec();
80 }
59 }
@@ -24,223 +24,97
24
24
25 #include <DataSource/DataSourceController.h>
25 #include <DataSource/DataSourceController.h>
26 #include <DataSource/DataSourceWidget.h>
26 #include <DataSource/DataSourceWidget.h>
27 #include <Settings/SqpSettingsDialog.h>
28 #include <Settings/SqpSettingsGeneralWidget.h>
29 #include <SidePane/SqpSidePane.h>
30 #include <SqpApplication.h>
27 #include <SqpApplication.h>
31 #include <Time/TimeController.h>
32 #include <TimeWidget/TimeWidget.h>
33 #include <Variable/Variable.h>
34 #include <Variable/VariableController.h>
35 #include <Visualization/VisualizationController.h>
36
28
37 #include <QAction>
29 #include <QAction>
38 #include <QDate>
30 #include <QDate>
31 #include <QDateTime>
39 #include <QDir>
32 #include <QDir>
40 #include <QFileDialog>
33 #include <QFileDialog>
34 //#include <omp.h>
35 //#include <network/filedownloader.h>
36 //#include <qlopdatabase.h>
37 //#include <qlopsettings.h>
38 //#include <qlopgui.h>
39 //#include <spacedata.h>
40 //#include "qlopcore.h"
41 //#include "qlopcodecmanager.h"
42 //#include "cdfcodec.h"
43 //#include "amdatxtcodec.h"
44 //#include <qlopplotmanager.h>
45 #include <QAction>
41 #include <QToolBar>
46 #include <QToolBar>
42 #include <QToolButton>
43 #include <memory.h>
47 #include <memory.h>
44
48 MainWindow::MainWindow(QWidget *parent) : QMainWindow{parent}, m_Ui{new Ui::MainWindow}
45 #include "iostream"
46
47 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
48
49 namespace {
50 const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0;
51 const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1;
52 const auto VIEWPLITTERINDEX = 2;
53 const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3;
54 const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4;
55 }
56
57 class MainWindow::MainWindowPrivate {
58 public:
59 explicit MainWindowPrivate(MainWindow *mainWindow)
60 : m_LastOpenLeftInspectorSize{},
61 m_LastOpenRightInspectorSize{},
62 m_GeneralSettingsWidget{new SqpSettingsGeneralWidget{mainWindow}},
63 m_SettingsDialog{new SqpSettingsDialog{mainWindow}}
64 {
65 }
66
67 QSize m_LastOpenLeftInspectorSize;
68 QSize m_LastOpenRightInspectorSize;
69 /// General settings widget. MainWindow has the ownership
70 SqpSettingsGeneralWidget *m_GeneralSettingsWidget;
71 /// Settings dialog. MainWindow has the ownership
72 SqpSettingsDialog *m_SettingsDialog;
73 };
74
75 MainWindow::MainWindow(QWidget *parent)
76 : QMainWindow{parent},
77 m_Ui{new Ui::MainWindow},
78 impl{spimpl::make_unique_impl<MainWindowPrivate>(this)}
79 {
49 {
80 m_Ui->setupUi(this);
50 m_Ui->setupUi(this);
81
51
82 m_Ui->splitter->setCollapsible(LEFTINSPECTORSIDEPANESPLITTERINDEX, false);
83 m_Ui->splitter->setCollapsible(RIGHTINSPECTORSIDEPANESPLITTERINDEX, false);
84
85
86 auto leftSidePane = m_Ui->leftInspectorSidePane->sidePane();
52 auto leftSidePane = m_Ui->leftInspectorSidePane->sidePane();
87 auto openLeftInspectorAction = new QAction{QIcon{
53 leftSidePane->addAction("ACTION L1");
88 ":/icones/previous.png",
54 leftSidePane->addAction("ACTION L2");
89 },
55 leftSidePane->addAction("ACTION L3");
90 tr("Show/hide the left inspector"), this};
91
92
93 auto spacerLeftTop = new QWidget{};
94 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
95
96 auto spacerLeftBottom = new QWidget{};
97 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
98
99 leftSidePane->addWidget(spacerLeftTop);
100 leftSidePane->addAction(openLeftInspectorAction);
101 leftSidePane->addWidget(spacerLeftBottom);
102
103
56
104 auto rightSidePane = m_Ui->rightInspectorSidePane->sidePane();
57 auto rightSidePane = m_Ui->rightInspectorSidePane->sidePane();
105 auto openRightInspectorAction = new QAction{QIcon{
58 rightSidePane->addAction("ACTION R1");
106 ":/icones/next.png",
59 rightSidePane->addAction("ACTION R2");
107 },
60 rightSidePane->addAction("ACTION R3");
108 tr("Show/hide the right inspector"), this};
109
110 auto spacerRightTop = new QWidget{};
111 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
112
113 auto spacerRightBottom = new QWidget{};
114 spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
115
116 rightSidePane->addWidget(spacerRightTop);
117 rightSidePane->addAction(openRightInspectorAction);
118 rightSidePane->addWidget(spacerRightBottom);
119
120 openLeftInspectorAction->setCheckable(true);
121 openRightInspectorAction->setCheckable(true);
122
123 auto openInspector = [this](bool checked, bool right, auto action) {
124
125 action->setIcon(QIcon{(checked xor right) ? ":/icones/next.png" : ":/icones/previous.png"});
126
127 auto &lastInspectorSize
128 = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize;
129
130 auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size()
131 : m_Ui->leftMainInspectorWidget->size();
132
133 // Update of the last opened geometry
134 if (checked) {
135 lastInspectorSize = nextInspectorSize;
136 }
137
138 auto startSize = lastInspectorSize;
139 auto endSize = startSize;
140 endSize.setWidth(0);
141
142 auto splitterInspectorIndex
143 = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX;
144
145 auto currentSizes = m_Ui->splitter->sizes();
146 if (checked) {
147 // adjust sizes individually here, e.g.
148 currentSizes[splitterInspectorIndex] -= lastInspectorSize.width();
149 currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width();
150 m_Ui->splitter->setSizes(currentSizes);
151 }
152 else {
153 // adjust sizes individually here, e.g.
154 currentSizes[splitterInspectorIndex] += lastInspectorSize.width();
155 currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width();
156 m_Ui->splitter->setSizes(currentSizes);
157 }
158
159 };
160
161
162 connect(openLeftInspectorAction, &QAction::triggered,
163 [openInspector, openLeftInspectorAction](bool checked) {
164 openInspector(checked, false, openLeftInspectorAction);
165 });
166 connect(openRightInspectorAction, &QAction::triggered,
167 [openInspector, openRightInspectorAction](bool checked) {
168 openInspector(checked, true, openRightInspectorAction);
169 });
170
171 // //// //
172 // Menu //
173 // //// //
174 this->menuBar()->addAction(tr("File"));
175 auto toolsMenu = this->menuBar()->addMenu(tr("Tools"));
176 toolsMenu->addAction(tr("Settings..."), [this]() {
177 // Loads settings
178 impl->m_SettingsDialog->loadSettings();
179
180 // Open settings dialog and save settings if the dialog is accepted
181 if (impl->m_SettingsDialog->exec() == QDialog::Accepted) {
182 impl->m_SettingsDialog->saveSettings();
183 }
184
185 });
186
61
187 auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar"));
62 this->menuBar()->addAction("File");
188
63 auto mainToolBar = this->addToolBar("MainToolBar");
189 auto timeWidget = new TimeWidget{};
64 mainToolBar->addAction("A1");
190 mainToolBar->addWidget(timeWidget);
191
192 // //////// //
193 // Settings //
194 // //////// //
195
196 // Registers "general settings" widget to the settings dialog
197 impl->m_SettingsDialog->registerWidget(QStringLiteral("General"),
198 impl->m_GeneralSettingsWidget);
199
200 // /////////// //
201 // Connections //
202 // /////////// //
203
204 // Controllers / controllers connections
205 connect(&sqpApp->timeController(), SIGNAL(timeUpdated(SqpRange)), &sqpApp->variableController(),
206 SLOT(onDateTimeOnSelection(SqpRange)));
207
65
208 // Widgets / controllers connections
66 // Widgets / controllers connections
209
210 // DataSource
211 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)),
67 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)),
212 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *)));
68 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *)));
213
69
214 // Time
70 /* QLopGUI::registerMenuBar(menuBar());
215 connect(timeWidget, SIGNAL(timeUpdated(SqpRange)), &sqpApp->timeController(),
71 this->setWindowIcon(QIcon(":/sciqlopLOGO.svg"));
216 SLOT(onTimeToUpdate(SqpRange)));
72 this->m_progressWidget = new QWidget();
217
73 this->m_progressLayout = new QVBoxLayout(this->m_progressWidget);
218 // Visualization
74 this->m_progressWidget->setLayout(this->m_progressLayout);
219 connect(&sqpApp->visualizationController(),
75 this->m_progressWidget->setWindowModality(Qt::WindowModal);
220 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
76 m_progressThreadIds = (int*) malloc(OMP_THREADS*sizeof(int));
221 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
77 for(int i=0;i<OMP_THREADS;i++)
222
78 {
223 connect(&sqpApp->visualizationController(),
79 this->m_progress.append(new QProgressBar(this->m_progressWidget));
224 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpRange &)), m_Ui->view,
80 this->m_progress.last()->setMinimum(0);
225 SLOT(onRangeChanged(std::shared_ptr<Variable>, const SqpRange &)));
81 this->m_progress.last()->setMaximum(100);
226
82 this->m_progressLayout->addWidget(this->m_progress.last());
227 // Widgets / widgets connections
83 this->m_progressWidget->hide();
228
84 this->m_progressThreadIds[i] = -1;
229 // For the following connections, we use DirectConnection to allow each widget that can
85 }
230 // potentially attach a menu to the variable's menu to do so before this menu is displayed.
86 this->m_progressWidget->setWindowTitle("Loading File");
231 // The order of connections is also important, since it determines the order in which each
87 const QList<QLopService*>ServicesToLoad=QList<QLopService*>()
232 // widget will attach its menu
88 << QLopCore::self()
233 connect(
89 << QLopPlotManager::self()
234 m_Ui->variableInspectorWidget,
90 << QLopCodecManager::self()
235 SIGNAL(tableMenuAboutToBeDisplayed(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
91 << FileDownloader::self()
236 m_Ui->view, SLOT(attachVariableMenu(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
92 << QLopDataBase::self()
237 Qt::DirectConnection);
93 << SpaceData::self();
94
95 CDFCodec::registerToManager();
96 AMDATXTCodec::registerToManager();
97
98
99 for(int i=0;i<ServicesToLoad.count();i++)
100 {
101 qDebug()<<ServicesToLoad.at(i)->serviceName();
102 ServicesToLoad.at(i)->initialize(); //must be called before getGUI
103 QDockWidget* wdgt=ServicesToLoad.at(i)->getGUI();
104 if(wdgt)
105 {
106 wdgt->setAllowedAreas(Qt::AllDockWidgetAreas);
107 this->addDockWidget(Qt::TopDockWidgetArea,wdgt);
108 }
109 PythonQt::self()->getMainModule().addObject(ServicesToLoad.at(i)->serviceName(),(QObject*)ServicesToLoad.at(i));
110 }*/
238 }
111 }
239
112
240 MainWindow::~MainWindow()
113 MainWindow::~MainWindow()
241 {
114 {
242 }
115 }
243
116
117
244 void MainWindow::changeEvent(QEvent *e)
118 void MainWindow::changeEvent(QEvent *e)
245 {
119 {
246 QMainWindow::changeEvent(e);
120 QMainWindow::changeEvent(e);
@@ -11,7 +11,7
11 </rect>
11 </rect>
12 </property>
12 </property>
13 <property name="windowTitle">
13 <property name="windowTitle">
14 <string>SciQlop v0.0.1</string>
14 <string>QLop</string>
15 </property>
15 </property>
16 <property name="dockNestingEnabled">
16 <property name="dockNestingEnabled">
17 <bool>true</bool>
17 <bool>true</bool>
@@ -34,7 +34,7
34 </property>
34 </property>
35 <layout class="QHBoxLayout" name="horizontalLayout">
35 <layout class="QHBoxLayout" name="horizontalLayout">
36 <property name="spacing">
36 <property name="spacing">
37 <number>0</number>
37 <number>3</number>
38 </property>
38 </property>
39 <property name="leftMargin">
39 <property name="leftMargin">
40 <number>0</number>
40 <number>0</number>
@@ -49,73 +49,129
49 <number>0</number>
49 <number>0</number>
50 </property>
50 </property>
51 <item>
51 <item>
52 <widget class="QSplitter" name="splitter">
52 <widget class="QWidget" name="leftInspectorWidget" native="true">
53 <property name="orientation">
53 <layout class="QHBoxLayout" name="horizontalLayout_2">
54 <enum>Qt::Horizontal</enum>
54 <property name="spacing">
55 </property>
55 <number>3</number>
56 <widget class="QWidget" name="leftMainInspectorWidget" native="true">
56 </property>
57 <layout class="QVBoxLayout" name="verticalLayout">
57 <property name="leftMargin">
58 <property name="spacing">
58 <number>0</number>
59 <number>0</number>
59 </property>
60 </property>
60 <property name="topMargin">
61 <property name="leftMargin">
61 <number>0</number>
62 <number>0</number>
62 </property>
63 </property>
63 <property name="rightMargin">
64 <property name="topMargin">
64 <number>0</number>
65 <number>0</number>
65 </property>
66 </property>
66 <property name="bottomMargin">
67 <property name="rightMargin">
67 <number>0</number>
68 <number>0</number>
69 </property>
70 <property name="bottomMargin">
71 <number>0</number>
72 </property>
73 <item>
74 <widget class="DataSourceWidget" name="dataSourceWidget" native="true"/>
75 </item>
76 <item>
77 <widget class="QWidget" name="dateTimeWidget" native="true"/>
78 </item>
79 <item>
80 <widget class="VariableInspectorWidget" name="variableInspectorWidget" native="true"/>
81 </item>
82 </layout>
83 </widget>
84 <widget class="SqpSidePane" name="leftInspectorSidePane" native="true"/>
85 <widget class="VisualizationWidget" name="view" native="true">
86 <property name="sizePolicy">
87 <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
88 <horstretch>0</horstretch>
89 <verstretch>0</verstretch>
90 </sizepolicy>
91 </property>
68 </property>
92 </widget>
69 <item>
93 <widget class="SqpSidePane" name="rightInspectorSidePane" native="true"/>
70 <widget class="QWidget" name="widget" native="true">
94 <widget class="QWidget" name="rightMainInspectorWidget" native="true">
71 <layout class="QVBoxLayout" name="verticalLayout">
95 <layout class="QVBoxLayout" name="verticalLayout_3">
72 <property name="spacing">
96 <property name="spacing">
73 <number>3</number>
97 <number>0</number>
74 </property>
98 </property>
75 <property name="leftMargin">
99 <property name="leftMargin">
76 <number>0</number>
100 <number>0</number>
77 </property>
101 </property>
78 <property name="topMargin">
102 <property name="topMargin">
79 <number>0</number>
103 <number>0</number>
80 </property>
104 </property>
81 <property name="rightMargin">
105 <property name="rightMargin">
82 <number>0</number>
106 <number>0</number>
83 </property>
107 </property>
84 <property name="bottomMargin">
108 <property name="bottomMargin">
85 <number>0</number>
109 <number>0</number>
86 </property>
110 </property>
87 <item>
111 <item>
88 <widget class="DataSourceWidget" name="dataSourceWidget" native="true"/>
112 <widget class="QWidget" name="commonPropertyInspectorWidget" native="true"/>
89 </item>
113 </item>
90 <item>
114 <item>
91 <widget class="QWidget" name="dateTimeWidget" native="true"/>
115 <widget class="DataSourceWidget" name="catalogWidget" native="true"/>
92 </item>
116 </item>
93 <item>
117 </layout>
94 <widget class="QWidget" name="variableInspectorWidget" native="true"/>
118 </widget>
95 </item>
96 </layout>
97 </widget>
98 </item>
99 <item>
100 <widget class="SqpSidePane" name="leftInspectorSidePane" native="true">
101 <layout class="QVBoxLayout" name="verticalLayout_2">
102 <property name="spacing">
103 <number>3</number>
104 </property>
105 <property name="leftMargin">
106 <number>0</number>
107 </property>
108 <property name="topMargin">
109 <number>0</number>
110 </property>
111 <property name="rightMargin">
112 <number>0</number>
113 </property>
114 <property name="bottomMargin">
115 <number>0</number>
116 </property>
117 </layout>
118 </widget>
119 </item>
120 </layout>
121 </widget>
122 </item>
123 <item>
124 <widget class="VisualizationWidget" name="view" native="true"/>
125 </item>
126 <item>
127 <widget class="QWidget" name="rightInspectorWidget" native="true">
128 <layout class="QHBoxLayout" name="horizontalLayout_3">
129 <property name="spacing">
130 <number>3</number>
131 </property>
132 <property name="leftMargin">
133 <number>0</number>
134 </property>
135 <property name="topMargin">
136 <number>0</number>
137 </property>
138 <property name="rightMargin">
139 <number>0</number>
140 </property>
141 <property name="bottomMargin">
142 <number>0</number>
143 </property>
144 <item>
145 <widget class="SqpSidePane" name="rightInspectorSidePane" native="true"/>
146 </item>
147 <item>
148 <widget class="QWidget" name="widget_2" native="true">
149 <layout class="QVBoxLayout" name="verticalLayout_3">
150 <property name="spacing">
151 <number>3</number>
152 </property>
153 <property name="leftMargin">
154 <number>0</number>
155 </property>
156 <property name="topMargin">
157 <number>0</number>
158 </property>
159 <property name="rightMargin">
160 <number>0</number>
161 </property>
162 <property name="bottomMargin">
163 <number>0</number>
164 </property>
165 <item>
166 <widget class="QWidget" name="commonPropertyInspectorWidget" native="true"/>
167 </item>
168 <item>
169 <widget class="QWidget" name="catalogWidget" native="true"/>
170 </item>
171 </layout>
172 </widget>
173 </item>
174 </layout>
119 </widget>
175 </widget>
120 </item>
176 </item>
121 </layout>
177 </layout>
@@ -126,7 +182,7
126 <x>0</x>
182 <x>0</x>
127 <y>0</y>
183 <y>0</y>
128 <width>800</width>
184 <width>800</width>
129 <height>28</height>
185 <height>26</height>
130 </rect>
186 </rect>
131 </property>
187 </property>
132 </widget>
188 </widget>
@@ -152,12 +208,6
152 <header location="global">DataSource/DataSourceWidget.h</header>
208 <header location="global">DataSource/DataSourceWidget.h</header>
153 <container>1</container>
209 <container>1</container>
154 </customwidget>
210 </customwidget>
155 <customwidget>
156 <class>VariableInspectorWidget</class>
157 <extends>QWidget</extends>
158 <header location="global">Variable/VariableInspectorWidget.h</header>
159 <container>1</container>
160 </customwidget>
161 </customwidgets>
211 </customwidgets>
162 <resources/>
212 <resources/>
163 <connections/>
213 <connections/>
@@ -1,5 +1,3
1 # Ignore false positive relative to App macro
1 # Ignore false positive relative to App macro
2 \.h:\d+:.IPSIS_S04.*found: Ui
2 \.h:\d+:.IPSIS_S04.*found: Ui
3
3
4 # Ignore false positive relative to macros
5 Main\.cpp:\d+:.*IPSIS_S04_VARIABLE.*found: (__ppc64__) No newline at end of file
@@ -21,7 +21,7 INCLUDE("cmake/sciqlop_params.cmake")
21 #
21 #
22 # Configure the compiler
22 # Configure the compiler
23 #
23 #
24 #INCLUDE("cmake/compiler/compiler.cmake")
24 INCLUDE("cmake/compiler/compiler.cmake")
25
25
26 #
26 #
27 # Find all necessary dependencies
27 # Find all necessary dependencies
@@ -1,3 +1,17
1 #
2 # Sciqlop_modules.cmake
3 #
4 # Set ouptut directories
5 #
6 SET (EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/dist)
7 SET (LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/dist)
8 IF (UNIX)
9 SET (CONFIG_OUTPUT_PATH $ENV{HOME}/.config/QtProject)
10 ELSEIF(WIN32)
11 SET (CONFIG_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/dist/app/QtProject)
12 ELSE()
13 SET (CONFIG_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/dist)
14 ENDIF()
1
15
2 if(BUILD_TESTS)
16 if(BUILD_TESTS)
3 INCLUDE ("cmake/sciqlop_code_coverage.cmake")
17 INCLUDE ("cmake/sciqlop_code_coverage.cmake")
@@ -21,25 +35,6 ADD_SUBDIRECTORY("${CMAKE_SOURCE_DIR}/gui")
21
35
22 ADD_SUBDIRECTORY("${CMAKE_SOURCE_DIR}/app")
36 ADD_SUBDIRECTORY("${CMAKE_SOURCE_DIR}/app")
23
37
24 OPTION (BUILD_PLUGINS "Build the plugins" OFF)
25 IF(BUILD_PLUGINS)
26 set(sciqlop-mockplugin_DIR "${CMAKE_SOURCE_DIR}/plugins/mockplugin/cmake")
27 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${sciqlop-mockplugin_DIR}")
28 ADD_SUBDIRECTORY("${CMAKE_SOURCE_DIR}/plugins/mockplugin")
29
30 set(sciqlop-amda_DIR "${CMAKE_SOURCE_DIR}/plugins/amda/cmake")
31 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${sciqlop-amda_DIR}")
32 ADD_SUBDIRECTORY("${CMAKE_SOURCE_DIR}/plugins/amda")
33
34 # Temporary target to copy to plugins dir
35 find_package(sciqlop-mockplugin)
36 find_package(sciqlop-amda)
37 ADD_CUSTOM_TARGET(plugins
38 COMMAND ${CMAKE_COMMAND} -E copy ${SCIQLOP-MOCKPLUGIN_LIBRARIES} "${LIBRARY_OUTPUT_PATH}/plugins/${SCIQLOP-MOCKPLUGIN_LIBRARIES_NAME}"
39 COMMAND ${CMAKE_COMMAND} -E copy ${SCIQLOP-AMDA_LIBRARIES} "${LIBRARY_OUTPUT_PATH}/plugins/${SCIQLOP-AMDA_LIBRARIES_NAME}"
40 )
41 ENDIF(BUILD_PLUGINS)
42
43 # LOGGER
38 # LOGGER
44 set(QTLOGGING_INI_FILE "${CMAKE_SOURCE_DIR}/config/QtProject/qtlogging.ini")
39 set(QTLOGGING_INI_FILE "${CMAKE_SOURCE_DIR}/config/QtProject/qtlogging.ini")
45 FILE(COPY ${QTLOGGING_INI_FILE} DESTINATION ${CONFIG_OUTPUT_PATH})
40 FILE(COPY ${QTLOGGING_INI_FILE} DESTINATION ${CONFIG_OUTPUT_PATH})
@@ -26,11 +26,11 SET (CPACK_PACKAGE_VERSION_MAJOR "${SCIQLOP_VERSION_MAJOR}")
26 SET (CPACK_PACKAGE_VERSION_MINOR "${SCIQLOP_VERSION_MINOR}")
26 SET (CPACK_PACKAGE_VERSION_MINOR "${SCIQLOP_VERSION_MINOR}")
27 SET (CPACK_PACKAGE_VERSION_PATCH "${SCIQLOP_VERSION_PATCH}${SCIQLOP_VERSION_SUFFIX}")
27 SET (CPACK_PACKAGE_VERSION_PATCH "${SCIQLOP_VERSION_PATCH}${SCIQLOP_VERSION_SUFFIX}")
28 SET (CPACK_PACKAGE_VERSION "${SCIQLOP_VERSION}")
28 SET (CPACK_PACKAGE_VERSION "${SCIQLOP_VERSION}")
29 SET (CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/COPYING)
29 SET (CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE)
30 SET (CPACK_PACKAGE_CONTACT "nicolas.aunai@lpp.polytechnique.fr")
30 SET (CPACK_PACKAGE_CONTACT "nicolas.aunai@lpp.polytechnique.fr")
31 SET(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/README.md)
31 SET(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/README.md)
32 # SET(CPACK_RESOURCE_FILE_WELCOME ${CMAKE_CURRENT_SOURCE_DIR}/WARN.txt)
32 # SET(CPACK_RESOURCE_FILE_WELCOME ${CMAKE_CURRENT_SOURCE_DIR}/WARN.txt)
33 SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/COPYING)
33 SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE)
34 # SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_NAME}-${PROJECT_VERSION})
34 # SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_NAME}-${PROJECT_VERSION})
35 SET(FULLBUILD ON)
35 SET(FULLBUILD ON)
36
36
@@ -42,6 +42,7 SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-Setu
42 SET(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_NAME})
42 SET(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_NAME})
43
43
44 set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
44 set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
45 message("exepath" ${CPACK_PACKAGE_INSTALL_DIRECTORY})
45
46
46 if (WIN32)
47 if (WIN32)
47 SET(CPACK_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
48 SET(CPACK_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
@@ -7,7 +7,7 SET(WINDEPLOYQT_ARGS --${CMAKE_BUILD_TYPE_TO_LOWER} --list mapping --no-system-d
7 #ENDFOREACH()
7 #ENDFOREACH()
8
8
9 EXECUTE_PROCESS(
9 EXECUTE_PROCESS(
10 COMMAND windeployqt ${WINDEPLOYQT_ARGS} -printsupport ${SCIQLOP_EXE_LOCATION}
10 COMMAND windeployqt ${WINDEPLOYQT_ARGS} ${SCIQLOP_EXE_LOCATION}
11 OUTPUT_VARIABLE QT_FILES
11 OUTPUT_VARIABLE QT_FILES
12 )
12 )
13
13
@@ -44,30 +44,6 else()
44 set(libRootDirForceValue)
44 set(libRootDirForceValue)
45 endif()
45 endif()
46
46
47 #
48 # Sciqlop_modules.cmake
49 #
50 # Set ouptut directories
51 #
52 IF (UNIX)
53 # 32 or 64 bits compiler
54 IF( CMAKE_SIZEOF_VOID_P EQUAL 8 )
55 SET(defaultLib "lib64/sciqlop")
56 ELSE()
57 SET(defaultLib "lib/sciqlop")
58 ENDIF()
59 SET (EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/bin)
60 SET (CONFIG_OUTPUT_PATH $ENV{HOME}/.config/QtProject)
61 SET (LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${defaultLib})
62 ELSEIF(WIN32)
63 SET (EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/dist)
64 SET (LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/dist)
65 SET (CONFIG_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/dist/app/QtProject)
66 ELSE()
67 SET (EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/dist)
68 SET (CONFIG_OUTPUT_PATH $ENV{HOME}/.config/QtProject)
69 SET (LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/dist)
70 ENDIF()
71
47
72
48
73 #
49 #
@@ -78,51 +54,33 OPTION (BUILD_SHARED_LIBS "Build the shared libraries" ON)
78 # Generate position independant code (-fPIC)
54 # Generate position independant code (-fPIC)
79 SET(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
55 SET(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
80
56
81
57 #
82
58 # Configure installation directories
83 # Configuration for make install
59 #
84
85 set(PROJECT_PLUGIN_PREFIX "SciQlop")
86
87 IF (UNIX)
60 IF (UNIX)
88 SET(CMAKE_INSTALL_PREFIX "/usr/local/${PROJECT_PLUGIN_PREFIX}")
89 SET(defaultBin "bin")
61 SET(defaultBin "bin")
90 SET(defaultInc "include/sciqlop")
62 SET(defaultInc "include/sciqlop")
91
63
92 # 32 or 64 bits compiler
64 # 32 or 64 bits compiler
93 IF( CMAKE_SIZEOF_VOID_P EQUAL 8 )
65 IF( CMAKE_SIZEOF_VOID_P EQUAL 8 )
94 SET(defaultLib "lib64")
66 SET(defaultLib "lib64/sciqlop")
95 SET(defaultPluginsLib "lib64/${PROJECT_PLUGIN_PREFIX}")
96 ELSE()
67 ELSE()
97 SET(defaultLib "lib/")
68 SET(defaultLib "lib/sciqlop")
98 SET(defaultPluginsLib "lib/${PROJECT_PLUGIN_PREFIX}")
99 ENDIF()
69 ENDIF()
100
70
101 SET(defaultDoc "share/docs/${PROJECT_PLUGIN_PREFIX}")
71 SET(defaultDoc "share/docs/sciqlop")
102 ELSE()
72 ELSE()
103 SET(defaultBin "bin")
73 SET(defaultBin "bin")
104 SET(defaultInc "include/${PROJECT_PLUGIN_PREFIX}")
74 SET(defaultInc "include/sciqlop")
105 SET(defaultLib "lib")
75 SET(defaultLib "lib/sciqlop")
106 SET(defaultPluginsLib "lib/${PROJECT_PLUGIN_PREFIX}")
76 SET(defaultDoc "docs/sciqlop")
107 SET(defaultDoc "docs/${PROJECT_PLUGIN_PREFIX}")
108 ENDIF()
77 ENDIF()
109
78
110 SET(INSTALL_BINARY_DIR "${defaultBin}" CACHE STRING
79 SET(INSTALL_BINARY_DIR "${defaultBin}" CACHE STRING
111 "Installation directory for binaries")
80 "Installation directory for binaries")
112 SET(INSTALL_LIBRARY_DIR "${defaultLib}" CACHE STRING
81 SET(INSTALL_LIBRARY_DIR "${defaultLib}" CACHE STRING
113 "Installation directory for libraries")
82 "Installation directory for libraries")
114 SET(INSTALL_PLUGINS_LIBRARY_DIR "${defaultPluginsLib}" CACHE STRING
115 "Installation directory for libraries")
116 SET(INSTALL_INCLUDE_DIR "${defaultInc}" CACHE STRING
83 SET(INSTALL_INCLUDE_DIR "${defaultInc}" CACHE STRING
117 "Installation directory for headers")
84 "Installation directory for headers")
118 SET(INSTALL_DOCUMENTATION_DIR "${defaultDoc}" CACHE STRING
85 SET(INSTALL_DOCUMENTATION_DIR "${defaultDoc}" CACHE STRING
119 "Installation directory for documentations")
86 "Installation directory for documentations")
120
121
122 # Set the rpath when installing
123 SET(CMAKE_SKIP_BUILD_RPATH FALSE)
124 SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
125 SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBRARY_DIR}")
126 SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
127
128 message("Install RPATH: ${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBRARY_DIR}")
@@ -24,14 +24,11 INCLUDE_DIRECTORIES(${SCIQLOP-PLUGIN_INCLUDE_DIR})
24 #
24 #
25 # Find Qt modules
25 # Find Qt modules
26 #
26 #
27 SCIQLOP_FIND_QT(Core Network)
27 SCIQLOP_FIND_QT(Core)
28
28
29 #
29 #
30 # Compile the library library
30 # Compile the library library
31 #
31 #
32
33 ADD_DEFINITIONS(-DCORE_LIB)
34
35 FILE (GLOB_RECURSE MODULE_SOURCES
32 FILE (GLOB_RECURSE MODULE_SOURCES
36 ${INCLUDES_DIR}/*.h
33 ${INCLUDES_DIR}/*.h
37 ${SOURCES_DIR}/*.c
34 ${SOURCES_DIR}/*.c
@@ -42,14 +39,8 ADD_LIBRARY(${SQPCORE_LIBRARY_NAME} ${MODULE_SOURCES})
42 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD 14)
39 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD 14)
43 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
40 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
44 TARGET_LINK_LIBRARIES(${SQPCORE_LIBRARY_NAME})
41 TARGET_LINK_LIBRARIES(${SQPCORE_LIBRARY_NAME})
45 qt5_use_modules(${SQPCORE_LIBRARY_NAME} Core Network)
42 qt5_use_modules(${SQPCORE_LIBRARY_NAME} Core)
46
43
47 INSTALL(TARGETS ${SQPCORE_LIBRARY_NAME}
48 RUNTIME DESTINATION ${INSTALL_BINARY_DIR}
49 LIBRARY DESTINATION ${INSTALL_LIBRARY_DIR}
50 ARCHIVE DESTINATION ${INSTALL_LIBRARY_DIR}
51 )
52
53 # From cmake documentation: http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
44 # From cmake documentation: http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
54 # Entries in the COMPILE_DEFINITIONS are prefixed with -D or /D and added to the compile line in an unspecified order.
45 # Entries in the COMPILE_DEFINITIONS are prefixed with -D or /D and added to the compile line in an unspecified order.
55 # The DEFINE_SYMBOL target property is also added as a compile definition as a special convenience case for SHARED and MODULE library targets
46 # The DEFINE_SYMBOL target property is also added as a compile definition as a special convenience case for SHARED and MODULE library targets
@@ -1,8 +1,6
1 #ifndef SCIQLOP_DATASOURCECONTROLLER_H
1 #ifndef SCIQLOP_DATASOURCECONTROLLER_H
2 #define SCIQLOP_DATASOURCECONTROLLER_H
2 #define SCIQLOP_DATASOURCECONTROLLER_H
3
3
4 #include "CoreGlobal.h"
5
6 #include <QLoggingCategory>
4 #include <QLoggingCategory>
7 #include <QObject>
5 #include <QObject>
8 #include <QUuid>
6 #include <QUuid>
@@ -12,7 +10,6
12 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSourceController)
10 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSourceController)
13
11
14 class DataSourceItem;
12 class DataSourceItem;
15 class IDataProvider;
16
13
17 /**
14 /**
18 * @brief The DataSourceController class aims to make the link between SciQlop and its plugins. This
15 * @brief The DataSourceController class aims to make the link between SciQlop and its plugins. This
@@ -21,7 +18,7 class IDataProvider;
21 * source) then others specifics method will be able to access it. You can load a data source driver
18 * source) then others specifics method will be able to access it. You can load a data source driver
22 * plugin then create a data source.
19 * plugin then create a data source.
23 */
20 */
24 class SCIQLOP_CORE_EXPORT DataSourceController : public QObject {
21 class DataSourceController : public QObject {
25 Q_OBJECT
22 Q_OBJECT
26 public:
23 public:
27 explicit DataSourceController(QObject *parent = 0);
24 explicit DataSourceController(QObject *parent = 0);
@@ -39,31 +36,12 public:
39 * Sets the structure of a data source. The controller takes ownership of the structure.
36 * Sets the structure of a data source. The controller takes ownership of the structure.
40 * @param dataSourceUid the unique id with which the data source has been registered into the
37 * @param dataSourceUid the unique id with which the data source has been registered into the
41 * controller. If it is invalid, the method has no effect.
38 * controller. If it is invalid, the method has no effect.
42 * @param dataSourceItem the structure of the data source. It must be not null to be registered
39 * @param dataSourceItem the structure of the data source
43 * @sa registerDataSource()
40 * @sa registerDataSource()
44 */
41 */
45 void setDataSourceItem(const QUuid &dataSourceUid,
42 void setDataSourceItem(const QUuid &dataSourceUid,
46 std::unique_ptr<DataSourceItem> dataSourceItem) noexcept;
43 std::unique_ptr<DataSourceItem> dataSourceItem) noexcept;
47
44
48 /**
49 * Sets the data provider used to retrieve data from of a data source. The controller takes
50 * ownership of the provider.
51 * @param dataSourceUid the unique id with which the data source has been registered into the
52 * controller. If it is invalid, the method has no effect.
53 * @param dataProvider the provider of the data source
54 * @sa registerDataSource()
55 */
56 void setDataProvider(const QUuid &dataSourceUid,
57 std::unique_ptr<IDataProvider> dataProvider) noexcept;
58
59 /**
60 * Loads an item (product) as a variable in SciQlop
61 * @param dataSourceUid the unique id of the data source containing the item. It is used to get
62 * the data provider associated to the data source, and pass it to for the variable creation
63 * @param productItem the item to load
64 */
65 void loadProductItem(const QUuid &dataSourceUid, const DataSourceItem &productItem) noexcept;
66
67 public slots:
45 public slots:
68 /// Manage init/end of the controller
46 /// Manage init/end of the controller
69 void initialize();
47 void initialize();
@@ -73,17 +51,6 signals:
73 /// Signal emitted when a structure has been set for a data source
51 /// Signal emitted when a structure has been set for a data source
74 void dataSourceItemSet(DataSourceItem *dataSourceItem);
52 void dataSourceItemSet(DataSourceItem *dataSourceItem);
75
53
76 /**
77 * Signal emitted when a variable creation is asked for a product
78 * @param variableName the name of the variable
79 * @param variableMetadata the metadata of the variable
80 * @param variableProvider the provider that will be used to retrieve the data of the variable
81 * (can be null)
82 */
83 void variableCreationRequested(const QString &variableName,
84 const QVariantHash &variableMetadata,
85 std::shared_ptr<IDataProvider> variableProvider);
86
87 private:
54 private:
88 void waitForFinish();
55 void waitForFinish();
89
56
@@ -1,19 +1,15
1 #ifndef SCIQLOP_DATASOURCEITEM_H
1 #ifndef SCIQLOP_DATASOURCEITEM_H
2 #define SCIQLOP_DATASOURCEITEM_H
2 #define SCIQLOP_DATASOURCEITEM_H
3
3
4 #include "CoreGlobal.h"
5
6 #include <Common/spimpl.h>
4 #include <Common/spimpl.h>
7
5
8 #include <QVariant>
6 #include <QVariant>
9 #include <QVector>
7 #include <QVector>
10
8
11 class DataSourceItemAction;
12
13 /**
9 /**
14 * Possible types of an item
10 * Possible types of an item
15 */
11 */
16 enum class DataSourceItemType { NODE, PRODUCT, COMPONENT };
12 enum class DataSourceItemType { NODE, PRODUCT };
17
13
18 /**
14 /**
19 * @brief The DataSourceItem class aims to represent a structure element of a data source.
15 * @brief The DataSourceItem class aims to represent a structure element of a data source.
@@ -21,23 +17,9 enum class DataSourceItemType { NODE, PRODUCT, COMPONENT };
21 * containing other DataSourceItem objects (children).
17 * containing other DataSourceItem objects (children).
22 * For each DataSourceItem can be associated a set of data representing it.
18 * For each DataSourceItem can be associated a set of data representing it.
23 */
19 */
24 class SCIQLOP_CORE_EXPORT DataSourceItem {
20 class DataSourceItem {
25 public:
21 public:
26 /// Key associated with the name of the item
22 explicit DataSourceItem(DataSourceItemType type, QVector<QVariant> data = {});
27 static const QString NAME_DATA_KEY;
28
29 explicit DataSourceItem(DataSourceItemType type, const QString &name);
30 explicit DataSourceItem(DataSourceItemType type, QVariantHash data = {});
31
32 /// @return the actions of the item as a vector
33 QVector<DataSourceItemAction *> actions() const noexcept;
34
35 /**
36 * Adds an action to the item. The item takes ownership of the action, and the action is
37 * automatically associated to the item
38 * @param action the action to add
39 */
40 void addAction(std::unique_ptr<DataSourceItemAction> action) noexcept;
41
23
42 /**
24 /**
43 * Adds a child to the item. The item takes ownership of the child.
25 * Adds a child to the item. The item takes ownership of the child.
@@ -55,18 +37,11 public:
55 int childCount() const noexcept;
37 int childCount() const noexcept;
56
38
57 /**
39 /**
58 * Get the data associated to a key
40 * Get the data associated to an index
59 * @param key the key to search
41 * @param dataIndex the index to search
60 * @return the data found if key is valid, default QVariant otherwise
42 * @return the data found if index is valid, default QVariant otherwise
61 */
43 */
62 QVariant data(const QString &key) const noexcept;
44 QVariant data(int dataIndex) const noexcept;
63
64 /// Gets all data
65 QVariantHash data() const noexcept;
66
67 bool isRoot() const noexcept;
68
69 QString name() const noexcept;
70
45
71 /**
46 /**
72 * Get the item's parent
47 * Get the item's parent
@@ -74,26 +49,8 public:
74 */
49 */
75 DataSourceItem *parentItem() const noexcept;
50 DataSourceItem *parentItem() const noexcept;
76
51
77 /**
78 * Gets the item's root
79 * @return the top parent, the item itself if it's the root item
80 */
81 const DataSourceItem &rootItem() const noexcept;
82
83 /**
84 * Sets or appends a value to a key
85 * @param key the key
86 * @param value the value
87 * @param append if true, the value is added to the values already existing for the key,
88 * otherwise it replaces the existing values
89 */
90 void setData(const QString &key, const QVariant &value, bool append = false) noexcept;
91
92 DataSourceItemType type() const noexcept;
52 DataSourceItemType type() const noexcept;
93
53
94 bool operator==(const DataSourceItem &other);
95 bool operator!=(const DataSourceItem &other);
96
97 private:
54 private:
98 class DataSourceItemPrivate;
55 class DataSourceItemPrivate;
99 spimpl::unique_impl_ptr<DataSourceItemPrivate> impl;
56 spimpl::unique_impl_ptr<DataSourceItemPrivate> impl;
@@ -1,8 +1,6
1 #ifndef SCIQLOP_PLUGINMANAGER_H
1 #ifndef SCIQLOP_PLUGINMANAGER_H
2 #define SCIQLOP_PLUGINMANAGER_H
2 #define SCIQLOP_PLUGINMANAGER_H
3
3
4 #include "CoreGlobal.h"
5
6 #include <Common/spimpl.h>
4 #include <Common/spimpl.h>
7
5
8 #include <QLoggingCategory>
6 #include <QLoggingCategory>
@@ -14,7 +12,7 Q_DECLARE_LOGGING_CATEGORY(LOG_PluginManager)
14 /**
12 /**
15 * @brief The PluginManager class aims to handle the plugins loaded dynamically into SciQLop.
13 * @brief The PluginManager class aims to handle the plugins loaded dynamically into SciQLop.
16 */
14 */
17 class SCIQLOP_CORE_EXPORT PluginManager {
15 class PluginManager {
18 public:
16 public:
19 explicit PluginManager();
17 explicit PluginManager();
20
18
@@ -1,10 +1,6
1 #ifndef SCIQLOP_VISUALIZATIONCONTROLLER_H
1 #ifndef SCIQLOP_VISUALIZATIONCONTROLLER_H
2 #define SCIQLOP_VISUALIZATIONCONTROLLER_H
2 #define SCIQLOP_VISUALIZATIONCONTROLLER_H
3
3
4 #include "CoreGlobal.h"
5
6 #include <Data/SqpRange.h>
7
8 #include <QLoggingCategory>
4 #include <QLoggingCategory>
9 #include <QObject>
5 #include <QObject>
10 #include <QUuid>
6 #include <QUuid>
@@ -14,7 +10,6
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationController)
10 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationController)
15
11
16 class DataSourceItem;
12 class DataSourceItem;
17 class Variable;
18
13
19 /**
14 /**
20 * @brief The VisualizationController class aims to make the link between SciQlop and its plugins.
15 * @brief The VisualizationController class aims to make the link between SciQlop and its plugins.
@@ -23,19 +18,12 class Variable;
23 * plugin source) then others specifics method will be able to access it. You can load a data source
18 * plugin source) then others specifics method will be able to access it. You can load a data source
24 * driver plugin then create a data source.
19 * driver plugin then create a data source.
25 */
20 */
26 class SCIQLOP_CORE_EXPORT VisualizationController : public QObject {
21 class VisualizationController : public QObject {
27 Q_OBJECT
22 Q_OBJECT
28 public:
23 public:
29 explicit VisualizationController(QObject *parent = 0);
24 explicit VisualizationController(QObject *parent = 0);
30 virtual ~VisualizationController();
25 virtual ~VisualizationController();
31
26
32 signals:
33 /// Signal emitted when a variable is about to be deleted from SciQlop
34 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
35
36 /// Signal emitted when a data acquisition is requested on a range for a variable
37 void rangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range);
38
39 public slots:
27 public slots:
40 /// Manage init/end of the controller
28 /// Manage init/end of the controller
41 void initialize();
29 void initialize();
@@ -1,7 +1,5
1 #include "DataSource/DataSourceController.h"
1 #include <DataSource/DataSourceController.h>
2 #include "DataSource/DataSourceItem.h"
2 #include <DataSource/DataSourceItem.h>
3
4 #include <Data/IDataProvider.h>
5
3
6 #include <QMutex>
4 #include <QMutex>
7 #include <QThread>
5 #include <QThread>
@@ -11,28 +9,6
11
9
12 Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController")
10 Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController")
13
11
14 namespace {
15
16 /**
17 * Builds the metadata of the variable that will be generated from the loading of an item
18 * @param dataSourceItem the data source item from which to generate the metadata
19 * @return the metadata of the variable
20 */
21 QVariantHash variableMetadata(const DataSourceItem &dataSourceItem)
22 {
23 // Variable metadata contains...
24
25 // ... all metadata of the item
26 auto result = dataSourceItem.data();
27
28 // ... and the name of the plugin, recovered from root item
29 result.insert(QStringLiteral("plugin"), dataSourceItem.rootItem().name());
30
31 return result;
32 }
33
34 } // namespace
35
36 class DataSourceController::DataSourceControllerPrivate {
12 class DataSourceController::DataSourceControllerPrivate {
37 public:
13 public:
38 QMutex m_WorkingMutex;
14 QMutex m_WorkingMutex;
@@ -40,10 +16,6 public:
40 QHash<QUuid, QString> m_DataSources;
16 QHash<QUuid, QString> m_DataSources;
41 /// Data sources structures
17 /// Data sources structures
42 std::map<QUuid, std::unique_ptr<DataSourceItem> > m_DataSourceItems;
18 std::map<QUuid, std::unique_ptr<DataSourceItem> > m_DataSourceItems;
43 /// Data providers registered
44 /// @remarks Data providers are stored as shared_ptr as they can be sent to a variable and
45 /// continue to live without necessarily the data source controller
46 std::map<QUuid, std::shared_ptr<IDataProvider> > m_DataProviders;
47 };
19 };
48
20
49 DataSourceController::DataSourceController(QObject *parent)
21 DataSourceController::DataSourceController(QObject *parent)
@@ -71,14 +43,7 QUuid DataSourceController::registerDataSource(const QString &dataSourceName) no
71 void DataSourceController::setDataSourceItem(
43 void DataSourceController::setDataSourceItem(
72 const QUuid &dataSourceUid, std::unique_ptr<DataSourceItem> dataSourceItem) noexcept
44 const QUuid &dataSourceUid, std::unique_ptr<DataSourceItem> dataSourceItem) noexcept
73 {
45 {
74 if (!dataSourceItem) {
75 qCWarning(LOG_DataSourceController())
76 << tr("Data source item can't be registered (null item)");
77 return;
78 }
79
80 if (impl->m_DataSources.contains(dataSourceUid)) {
46 if (impl->m_DataSources.contains(dataSourceUid)) {
81 // The data provider is implicitly converted to a shared_ptr
82 impl->m_DataSourceItems.insert(std::make_pair(dataSourceUid, std::move(dataSourceItem)));
47 impl->m_DataSourceItems.insert(std::make_pair(dataSourceUid, std::move(dataSourceItem)));
83
48
84 // Retrieves the data source item to emit the signal with it
49 // Retrieves the data source item to emit the signal with it
@@ -94,36 +59,6 void DataSourceController::setDataSourceItem(
94 }
59 }
95 }
60 }
96
61
97 void DataSourceController::setDataProvider(const QUuid &dataSourceUid,
98 std::unique_ptr<IDataProvider> dataProvider) noexcept
99 {
100 if (impl->m_DataSources.contains(dataSourceUid)) {
101 impl->m_DataProviders.insert(std::make_pair(dataSourceUid, std::move(dataProvider)));
102 }
103 else {
104 qCWarning(LOG_DataSourceController()) << tr("Can't set data provider for uid %1 : no data "
105 "source has been registered with the uid")
106 .arg(dataSourceUid.toString());
107 }
108 }
109
110 void DataSourceController::loadProductItem(const QUuid &dataSourceUid,
111 const DataSourceItem &productItem) noexcept
112 {
113 if (productItem.type() == DataSourceItemType::PRODUCT
114 || productItem.type() == DataSourceItemType::COMPONENT) {
115 /// Retrieves the data provider of the data source (if any)
116 auto it = impl->m_DataProviders.find(dataSourceUid);
117 auto dataProvider = (it != impl->m_DataProviders.end()) ? it->second : nullptr;
118
119 emit variableCreationRequested(productItem.name(), variableMetadata(productItem),
120 dataProvider);
121 }
122 else {
123 qCWarning(LOG_DataSourceController()) << tr("Can't load an item that is not a product");
124 }
125 }
126
127 void DataSourceController::initialize()
62 void DataSourceController::initialize()
128 {
63 {
129 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init")
64 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init")
@@ -1,49 +1,24
1 #include <DataSource/DataSourceItem.h>
1 #include <DataSource/DataSourceItem.h>
2 #include <DataSource/DataSourceItemAction.h>
3
2
4 #include <QVector>
3 #include <QVector>
5
4
6 const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name");
7
8 struct DataSourceItem::DataSourceItemPrivate {
5 struct DataSourceItem::DataSourceItemPrivate {
9 explicit DataSourceItemPrivate(DataSourceItemType type, QVariantHash data)
6 explicit DataSourceItemPrivate(DataSourceItemType type, QVector<QVariant> data)
10 : m_Parent{nullptr}, m_Children{}, m_Type{type}, m_Data{std::move(data)}, m_Actions{}
7 : m_Parent{nullptr}, m_Children{}, m_Type{type}, m_Data{std::move(data)}
11 {
8 {
12 }
9 }
13
10
14 DataSourceItem *m_Parent;
11 DataSourceItem *m_Parent;
15 std::vector<std::unique_ptr<DataSourceItem> > m_Children;
12 std::vector<std::unique_ptr<DataSourceItem> > m_Children;
16 DataSourceItemType m_Type;
13 DataSourceItemType m_Type;
17 QVariantHash m_Data;
14 QVector<QVariant> m_Data;
18 std::vector<std::unique_ptr<DataSourceItemAction> > m_Actions;
19 };
15 };
20
16
21 DataSourceItem::DataSourceItem(DataSourceItemType type, const QString &name)
17 DataSourceItem::DataSourceItem(DataSourceItemType type, QVector<QVariant> data)
22 : DataSourceItem{type, QVariantHash{{NAME_DATA_KEY, name}}}
23 {
24 }
25
26 DataSourceItem::DataSourceItem(DataSourceItemType type, QVariantHash data)
27 : impl{spimpl::make_unique_impl<DataSourceItemPrivate>(type, std::move(data))}
18 : impl{spimpl::make_unique_impl<DataSourceItemPrivate>(type, std::move(data))}
28 {
19 {
29 }
20 }
30
21
31 QVector<DataSourceItemAction *> DataSourceItem::actions() const noexcept
32 {
33 auto result = QVector<DataSourceItemAction *>{};
34
35 std::transform(std::cbegin(impl->m_Actions), std::cend(impl->m_Actions),
36 std::back_inserter(result), [](const auto &action) { return action.get(); });
37
38 return result;
39 }
40
41 void DataSourceItem::addAction(std::unique_ptr<DataSourceItemAction> action) noexcept
42 {
43 action->setDataSourceItem(this);
44 impl->m_Actions.push_back(std::move(action));
45 }
46
47 void DataSourceItem::appendChild(std::unique_ptr<DataSourceItem> child) noexcept
22 void DataSourceItem::appendChild(std::unique_ptr<DataSourceItem> child) noexcept
48 {
23 {
49 child->impl->m_Parent = this;
24 child->impl->m_Parent = this;
@@ -65,24 +40,9 int DataSourceItem::childCount() const noexcept
65 return impl->m_Children.size();
40 return impl->m_Children.size();
66 }
41 }
67
42
68 QVariant DataSourceItem::data(const QString &key) const noexcept
43 QVariant DataSourceItem::data(int dataIndex) const noexcept
69 {
70 return impl->m_Data.value(key);
71 }
72
73 QVariantHash DataSourceItem::data() const noexcept
74 {
75 return impl->m_Data;
76 }
77
78 bool DataSourceItem::isRoot() const noexcept
79 {
80 return impl->m_Parent == nullptr;
81 }
82
83 QString DataSourceItem::name() const noexcept
84 {
44 {
85 return data(NAME_DATA_KEY).toString();
45 return impl->m_Data.value(dataIndex);
86 }
46 }
87
47
88 DataSourceItem *DataSourceItem::parentItem() const noexcept
48 DataSourceItem *DataSourceItem::parentItem() const noexcept
@@ -90,56 +50,7 DataSourceItem *DataSourceItem::parentItem() const noexcept
90 return impl->m_Parent;
50 return impl->m_Parent;
91 }
51 }
92
52
93 const DataSourceItem &DataSourceItem::rootItem() const noexcept
94 {
95 return isRoot() ? *this : parentItem()->rootItem();
96 }
97
98 void DataSourceItem::setData(const QString &key, const QVariant &value, bool append) noexcept
99 {
100 auto it = impl->m_Data.constFind(key);
101 if (append && it != impl->m_Data.constEnd()) {
102 // Case of an existing value to which we want to add to the new value
103 if (it->canConvert<QVariantList>()) {
104 auto variantList = it->value<QVariantList>();
105 variantList.append(value);
106
107 impl->m_Data.insert(key, variantList);
108 }
109 else {
110 impl->m_Data.insert(key, QVariantList{*it, value});
111 }
112 }
113 else {
114 // Other cases :
115 // - new value in map OR
116 // - replacement of an existing value (not appending)
117 impl->m_Data.insert(key, value);
118 }
119 }
120
121 DataSourceItemType DataSourceItem::type() const noexcept
53 DataSourceItemType DataSourceItem::type() const noexcept
122 {
54 {
123 return impl->m_Type;
55 return impl->m_Type;
124 }
56 }
125
126 bool DataSourceItem::operator==(const DataSourceItem &other)
127 {
128 // Compares items' attributes
129 if (std::tie(impl->m_Type, impl->m_Data) == std::tie(other.impl->m_Type, other.impl->m_Data)) {
130 // Compares contents of items' children
131 return std::equal(std::cbegin(impl->m_Children), std::cend(impl->m_Children),
132 std::cbegin(other.impl->m_Children),
133 [](const auto &itemChild, const auto &otherChild) {
134 return *itemChild == *otherChild;
135 });
136 }
137 else {
138 return false;
139 }
140 }
141
142 bool DataSourceItem::operator!=(const DataSourceItem &other)
143 {
144 return !(*this == other);
145 }
@@ -106,15 +106,9 PluginManager::PluginManager() : impl{spimpl::make_unique_impl<PluginManagerPriv
106 void PluginManager::loadPlugins(const QDir &pluginDir)
106 void PluginManager::loadPlugins(const QDir &pluginDir)
107 {
107 {
108 // Load plugins
108 // Load plugins
109 auto pluginInfoList
109 auto pluginInfoList = pluginDir.entryInfoList(QDir::Files, QDir::Name);
110 = pluginDir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
110 for (auto pluginInfo : qAsConst(pluginInfoList)) {
111 for (auto entryInfo : qAsConst(pluginInfoList)) {
111 impl->loadPlugin(pluginInfo.absoluteFilePath());
112 if (entryInfo.isDir()) {
113 this->loadPlugins(QDir{entryInfo.absoluteFilePath()});
114 }
115 else if (QLibrary::isLibrary(entryInfo.absoluteFilePath())) {
116 impl->loadPlugin(entryInfo.absoluteFilePath());
117 }
118 }
112 }
119 }
113 }
120
114
@@ -1,7 +1,5
1 #include <Visualization/VisualizationController.h>
1 #include <Visualization/VisualizationController.h>
2
2
3 #include <Variable/Variable.h>
4
5 #include <QMutex>
3 #include <QMutex>
6 #include <QThread>
4 #include <QThread>
7
5
@@ -30,7 +30,9 void TestDataSourceController::testSetDataSourceItem()
30
30
31 // Create a data source item
31 // Create a data source item
32 auto source1Name = QStringLiteral("Source1");
32 auto source1Name = QStringLiteral("Source1");
33 auto source1Item = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, source1Name);
33 auto source1Values = QVector<QVariant>{source1Name};
34 auto source1Item
35 = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, std::move(source1Values));
34
36
35 // Add data source item to the controller and check that a signal has been emitted after setting
37 // Add data source item to the controller and check that a signal has been emitted after setting
36 // data source item in the controller
38 // data source item in the controller
@@ -2,51 +2,5
2 Common/spimpl\.h:\d+:.*
2 Common/spimpl\.h:\d+:.*
3
3
4 # Ignore false positive relative to two class definitions in a same file
4 # Ignore false positive relative to two class definitions in a same file
5 ArrayData\.h:\d+:.*IPSIS_S01.*
6 ArrayDataIterator\.h:\d+:.*IPSIS_S01.*
7 DataSourceItem\.h:\d+:.*IPSIS_S01.*
5 DataSourceItem\.h:\d+:.*IPSIS_S01.*
8 DataSeries\.h:\d+:.*IPSIS_S01.*
9 DataSeriesIterator\.h:\d+:.*IPSIS_S01.*
10 DataSeriesMergeHelper\.h:\d+:.*IPSIS_S01.*
11
6
12 # Ignore false positive relative to a template class
13 ArrayData\.h:\d+:.*IPSIS_S04_METHOD.*found: push_back
14 ArrayData\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (const_iterator)
15 ArrayData\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (D)
16 ArrayData\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (IC)
17 ArrayData\.h:\d+:.*IPSIS_S04_NAMESPACE.*found: (arraydata_detail)
18 ArrayData\.h:\d+:.*IPSIS_S06.*found: (D)
19 ArrayData\.h:\d+:.*IPSIS_S06.*found: (Dim)
20 ArrayData\.h:\d+:.*IPSIS_S06.*found: (IC)
21 ArrayData\.h:\d+:.*IPSIS_S06.*found: (IsConst)
22 DataSeries\.h:\d+:.*IPSIS_S04_METHOD.*found: LOG_DataSeries
23 DataSeries\.h:\d+:.*IPSIS_S04_METHOD.*found: push_back
24 DataSeries\.h:\d+:.*IPSIS_S04_VARIABLE.*
25 DataSeries\.h:\d+:.*IPSIS_S04_NAMESPACE.*found: (dataseries_detail)
26 DataSeries\.h:\d+:.*IPSIS_S05.*
27 DataSeries\.h:\d+:.*IPSIS_S06.*found: (value_type)
28 DataSeries\.h:\d+:.*IPSIS_S06.*found: (DataSeriesIteratorValue)
29 DataSeries\.h:\d+:.*IPSIS_S06.*found: (Dim)
30 DataSeries\.h:\d+:.*IPSIS_S06.*found: (IC)
31 DataSeries\.h:\d+:.*IPSIS_S06.*found: (IsConst)
32
33 # Ignore false positive relative to iterators
34 SqpIterator\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (random_access_iterator_tag)
35 SqpIterator\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (T)
36 SqpIterator\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (ptrdiff_t)
37 SqpIterator\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (value_type)
38 SqpIterator\.h:\d+:.*IPSIS_S06.*found: (iterator_category)
39 SqpIterator\.h:\d+:.*IPSIS_S06.*found: (random_access_iterator_tag)
40 SqpIterator\.h:\d+:.*IPSIS_S06.*found: (value_type)
41 SqpIterator\.h:\d+:.*IPSIS_S06.*found: (T)
42 SqpIterator\.h:\d+:.*IPSIS_S06.*found: (difference_type)
43 SqpIterator\.h:\d+:.*IPSIS_S06.*found: (ptrdiff_t)
44 SqpIterator\.h:\d+:.*IPSIS_S06.*found: (pointer)
45 SqpIterator\.h:\d+:.*IPSIS_S06.*found: (reference)
46 SqpIterator\.h:\d+:.*IPSIS_S06.*found: (value_type)
47
48 # Ignore false positive relative to an alias
49 DataSourceItemAction\.h:\d+:.*IPSIS_S06.*found: (ExecuteFunction)
50
51 # Ignore false positive relative to unnamed namespace
52 VariableController\.cpp:\d+:.*IPSIS_F13.*
@@ -63,7 +63,6 FUNCTION(ADD_CLANGFORMAT_TARGETS)
63 clangformat_incr(i)
63 clangformat_incr(i)
64 ENDWHILE()
64 ENDWHILE()
65
65
66
67 # Retrieve source files to format
66 # Retrieve source files to format
68 IF(recurse)
67 IF(recurse)
69 FILE(GLOB_RECURSE srcs ${globs})
68 FILE(GLOB_RECURSE srcs ${globs})
@@ -82,15 +81,6 FUNCTION(ADD_CLANGFORMAT_TARGETS)
82 # Create the directory where the touched files will be saved
81 # Create the directory where the touched files will be saved
83 SET(formatDirectory "${CMAKE_CURRENT_BINARY_DIR}/format")
82 SET(formatDirectory "${CMAKE_CURRENT_BINARY_DIR}/format")
84 FILE(MAKE_DIRECTORY ${formatDirectory})
83 FILE(MAKE_DIRECTORY ${formatDirectory})
85 # STRING(REPLACE "*.ui" "" srcs ${srcs})
86 FOREACH(item ${globs})
87 STRING(REGEX MATCH ".*\.ui$" item ${item})
88 IF(item)
89 LIST(APPEND UIS ${item})
90 ENDIF(item)
91 ENDFOREACH(item ${globs})
92
93 LIST(REMOVE_ITEM srcs ${UIS})
94 FOREACH (s ${srcs})
84 FOREACH (s ${srcs})
95 SET(touchedFile ${formatDirectory}/format_touchedfile_${reportNb})
85 SET(touchedFile ${formatDirectory}/format_touchedfile_${reportNb})
96 IF(addToAll)
86 IF(addToAll)
@@ -10,10 +10,3
10 # Ignore false positive relative to 'override' keyword
10 # Ignore false positive relative to 'override' keyword
11 .*IPSIS_S04_VARIABLE.*found: override
11 .*IPSIS_S04_VARIABLE.*found: override
12 .*IPSIS_S06.*found: override
12 .*IPSIS_S06.*found: override
13
14 # Ignore false positive relative to 'final' keyword
15 .*IPSIS_S04_VARIABLE.*found: final
16 .*IPSIS_S06.*found: final
17
18 # Ignore false positive relative to unnamed namespace
19 .*IPSIS_F13.*
@@ -67,15 +67,6 set_property(TARGET ${SQPGUI_LIBRARY_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
67 TARGET_LINK_LIBRARIES(${SQPGUI_LIBRARY_NAME} ${LIBRARIES})
67 TARGET_LINK_LIBRARIES(${SQPGUI_LIBRARY_NAME} ${LIBRARIES})
68 qt5_use_modules(${SQPGUI_LIBRARY_NAME} Core Widgets PrintSupport)
68 qt5_use_modules(${SQPGUI_LIBRARY_NAME} Core Widgets PrintSupport)
69
69
70
71 INSTALL(TARGETS ${SQPGUI_LIBRARY_NAME}
72 RUNTIME DESTINATION ${INSTALL_BINARY_DIR}
73 LIBRARY DESTINATION ${INSTALL_LIBRARY_DIR}
74 ARCHIVE DESTINATION ${INSTALL_LIBRARY_DIR}
75 )
76 add_dependencies(${SQPGUI_LIBRARY_NAME} ${SQPCORE_LIBRARY_NAME})
77
78
79 # From cmake documentation: http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
70 # From cmake documentation: http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
80 # Entries in the COMPILE_DEFINITIONS are prefixed with -D or /D and added to the compile line in an unspecified order.
71 # Entries in the COMPILE_DEFINITIONS are prefixed with -D or /D and added to the compile line in an unspecified order.
81 # The DEFINE_SYMBOL target property is also added as a compile definition as a special convenience case for SHARED and MODULE library targets
72 # The DEFINE_SYMBOL target property is also added as a compile definition as a special convenience case for SHARED and MODULE library targets
@@ -21,14 +21,9 public:
21 explicit DataSourceTreeWidgetItem(QTreeWidget *parent, const DataSourceItem *data,
21 explicit DataSourceTreeWidgetItem(QTreeWidget *parent, const DataSourceItem *data,
22 int type = Type);
22 int type = Type);
23
23
24 const DataSourceItem *data() const;
25
26 virtual QVariant data(int column, int role) const override;
24 virtual QVariant data(int column, int role) const override;
27 virtual void setData(int column, int role, const QVariant &value) override;
25 virtual void setData(int column, int role, const QVariant &value) override;
28
26
29 /// @return the actions associated to the item
30 QList<QAction *> actions() const noexcept;
31
32 private:
27 private:
33 class DataSourceTreeWidgetItemPrivate;
28 class DataSourceTreeWidgetItemPrivate;
34 spimpl::unique_impl_ptr<DataSourceTreeWidgetItemPrivate> impl;
29 spimpl::unique_impl_ptr<DataSourceTreeWidgetItemPrivate> impl;
@@ -1,11 +1,9
1 #ifndef SCIQLOP_DATASOURCEWIDGET_H
1 #ifndef SCIQLOP_DATASOURCEWIDGET_H
2 #define SCIQLOP_DATASOURCEWIDGET_H
2 #define SCIQLOP_DATASOURCEWIDGET_H
3
3
4 #include <QWidget>
4 #include <Common/spimpl.h>
5
5
6 namespace Ui {
6 #include <QWidget>
7 class DataSourceWidget;
8 } // Ui
9
7
10 class DataSourceItem;
8 class DataSourceItem;
11
9
@@ -18,7 +16,6 class DataSourceWidget : public QWidget {
18
16
19 public:
17 public:
20 explicit DataSourceWidget(QWidget *parent = 0);
18 explicit DataSourceWidget(QWidget *parent = 0);
21 virtual ~DataSourceWidget() noexcept;
22
19
23 public slots:
20 public slots:
24 /**
21 /**
@@ -29,14 +26,8 public slots:
29 void addDataSource(DataSourceItem *dataSource) noexcept;
26 void addDataSource(DataSourceItem *dataSource) noexcept;
30
27
31 private:
28 private:
32 Ui::DataSourceWidget *ui;
29 class DataSourceWidgetPrivate;
33
30 spimpl::unique_impl_ptr<DataSourceWidgetPrivate> impl;
34 private slots:
35 /// Slot called when the filtering text has changed
36 void filterChanged(const QString &text) noexcept;
37
38 /// Slot called when right clicking on an item in the tree (displays a menu)
39 void onTreeMenuRequested(const QPoint &pos) noexcept;
40 };
31 };
41
32
42 #endif // SCIQLOP_DATASOURCEWIDGET_H
33 #endif // SCIQLOP_DATASOURCEWIDGET_H
@@ -16,9 +16,6 Q_DECLARE_LOGGING_CATEGORY(LOG_SqpApplication)
16 #define sqpApp (static_cast<SqpApplication *>(QCoreApplication::instance()))
16 #define sqpApp (static_cast<SqpApplication *>(QCoreApplication::instance()))
17
17
18 class DataSourceController;
18 class DataSourceController;
19 class NetworkController;
20 class TimeController;
21 class VariableController;
22 class VisualizationController;
19 class VisualizationController;
23
20
24 /**
21 /**
@@ -38,11 +35,8 public:
38 void initialize();
35 void initialize();
39
36
40 /// Accessors for the differents sciqlop controllers
37 /// Accessors for the differents sciqlop controllers
41 DataSourceController &dataSourceController() noexcept;
38 DataSourceController &dataSourceController() const noexcept;
42 NetworkController &networkController() noexcept;
39 VisualizationController &visualizationController() const noexcept;
43 TimeController &timeController() noexcept;
44 VariableController &variableController() noexcept;
45 VisualizationController &visualizationController() noexcept;
46
40
47 private:
41 private:
48 class SqpApplicationPrivate;
42 class SqpApplicationPrivate;
@@ -1,98 +1,21
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
5
6 #include <QLoggingCategory>
7 #include <QWidget>
4 #include <QWidget>
8
5
9 #include <memory>
10
11 #include <Common/spimpl.h>
12
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
14
15 class QCPRange;
16 class QCustomPlot;
17 class SqpRange;
18 class Variable;
19
20 namespace Ui {
6 namespace Ui {
21 class VisualizationGraphWidget;
7 class VisualizationGraphWidget;
22 } // namespace Ui
8 } // namespace Ui
23
9
24 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
10 class VisualizationGraphWidget : public QWidget {
25 Q_OBJECT
11 Q_OBJECT
26
12
27 friend class QCustomPlotSynchronizer;
28 friend class VisualizationGraphRenderingDelegate;
29
30 public:
13 public:
31 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
14 explicit VisualizationGraphWidget(QWidget *parent = 0);
32 virtual ~VisualizationGraphWidget();
15 virtual ~VisualizationGraphWidget();
33
16
34 /// If acquisition isn't enable, requestDataLoading signal cannot be emit
35 void enableAcquisition(bool enable);
36
37 void addVariable(std::shared_ptr<Variable> variable, SqpRange range);
38
39 /// Removes a variable from the graph
40 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
41
42 void setRange(std::shared_ptr<Variable> variable, const SqpRange &range);
43 void setYRange(const SqpRange &range);
44 SqpRange graphRange() const noexcept;
45 void setGraphRange(const SqpRange &range);
46
47 // IVisualizationWidget interface
48 void accept(IVisualizationWidgetVisitor *visitor) override;
49 bool canDrop(const Variable &variable) const override;
50 bool contains(const Variable &variable) const override;
51 QString name() const override;
52
53
54 signals:
55 void synchronize(const SqpRange &range, const SqpRange &oldRange);
56 void requestDataLoading(QVector<std::shared_ptr<Variable> > variable, const SqpRange &range,
57 const SqpRange &oldRange, bool synchronise);
58
59 /// Signal emitted when the variable is about to be removed from the graph
60 void variableAboutToBeRemoved(std::shared_ptr<Variable> var);
61 /// Signal emitted when the variable has been added to the graph
62 void variableAdded(std::shared_ptr<Variable> var);
63
64 protected:
65 void closeEvent(QCloseEvent *event) override;
66 void enterEvent(QEvent *event) override;
67 void leaveEvent(QEvent *event) override;
68
69 QCustomPlot &plot() noexcept;
70
71 private:
17 private:
72 Ui::VisualizationGraphWidget *ui;
18 Ui::VisualizationGraphWidget *ui;
73
74 class VisualizationGraphWidgetPrivate;
75 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
76
77 private slots:
78 /// Slot called when right clicking on the graph (displays a menu)
79 void onGraphMenuRequested(const QPoint &pos) noexcept;
80
81 /// Rescale the X axe to range parameter
82 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
83
84 /// Slot called when a mouse move was made
85 void onMouseMove(QMouseEvent *event) noexcept;
86 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
87 void onMouseWheel(QWheelEvent *event) noexcept;
88 /// Slot called when a mouse press was made, to activate the calibration of a graph
89 void onMousePress(QMouseEvent *event) noexcept;
90 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
91 void onMouseRelease(QMouseEvent *event) noexcept;
92
93 void onDataCacheVariableUpdated();
94
95 void onUpdateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
96 };
19 };
97
20
98 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
21 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -1,57 +1,21
1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
5
6 #include <Common/spimpl.h>
7
8 #include <QLoggingCategory>
9 #include <QWidget>
4 #include <QWidget>
10
5
11 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
12
13 class Variable;
14 class VisualizationZoneWidget;
15
16 namespace Ui {
6 namespace Ui {
17 class VisualizationTabWidget;
7 class VisualizationTabWidget;
18 } // namespace Ui
8 } // namespace Ui
19
9
20 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
10 class VisualizationTabWidget : public QWidget {
21 Q_OBJECT
11 Q_OBJECT
22
12
23 public:
13 public:
24 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
14 explicit VisualizationTabWidget(QWidget *parent = 0);
25 virtual ~VisualizationTabWidget();
15 virtual ~VisualizationTabWidget();
26
16
27 /// Add a zone widget
28 void addZone(VisualizationZoneWidget *zoneWidget);
29
30 /**
31 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
32 * zone.
33 * @param variable the variable for which to create the zone
34 * @return the pointer to the created zone
35 */
36 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
37
38 // IVisualizationWidget interface
39 void accept(IVisualizationWidgetVisitor *visitor) override;
40 bool canDrop(const Variable &variable) const override;
41 bool contains(const Variable &variable) const override;
42 QString name() const override;
43
44 protected:
45 void closeEvent(QCloseEvent *event) override;
46
47 private:
17 private:
48 /// @return the layout of tab in which zones are added
49 QLayout &tabLayout() const noexcept;
50
51 Ui::VisualizationTabWidget *ui;
18 Ui::VisualizationTabWidget *ui;
52
53 class VisualizationTabWidgetPrivate;
54 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
55 };
19 };
56
20
57 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
21 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
@@ -1,52 +1,22
1 #ifndef SCIQLOP_VISUALIZATIONWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONWIDGET_H
2 #define SCIQLOP_VISUALIZATIONWIDGET_H
2 #define SCIQLOP_VISUALIZATIONWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
5 #include <Data/SqpRange.h>
6
7 #include <QLoggingCategory>
4 #include <QLoggingCategory>
8 #include <QWidget>
5 #include <QWidget>
9
6
10 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
7 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
11
8
12 class QMenu;
13 class Variable;
14 class VisualizationTabWidget;
15
16 namespace Ui {
9 namespace Ui {
17 class VisualizationWidget;
10 class VisualizationWidget;
18 } // namespace Ui
11 } // namespace Ui
19
12
20 class VisualizationWidget : public QWidget, public IVisualizationWidget {
13 class VisualizationWidget : public QWidget {
21 Q_OBJECT
14 Q_OBJECT
22
15
23 public:
16 public:
24 explicit VisualizationWidget(QWidget *parent = 0);
17 explicit VisualizationWidget(QWidget *parent = 0);
25 virtual ~VisualizationWidget();
18 virtual ~VisualizationWidget();
26
19
27 // IVisualizationWidget interface
28 void accept(IVisualizationWidgetVisitor *visitor) override;
29 bool canDrop(const Variable &variable) const override;
30 bool contains(const Variable &variable) const override;
31 QString name() const override;
32
33 public slots:
34 /**
35 * Attaches to a menu the menu relative to the visualization of variables
36 * @param menu the parent menu of the generated menu
37 * @param variables the variables for which to generate the menu
38 */
39 void attachVariableMenu(QMenu *menu,
40 const QVector<std::shared_ptr<Variable> > &variables) noexcept;
41
42 /// Slot called when a variable is about to be deleted from SciQlop
43 void onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept;
44
45 void onRangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range) noexcept;
46
47 protected:
48 void closeEvent(QCloseEvent *event) override;
49
50 private:
20 private:
51 Ui::VisualizationWidget *ui;
21 Ui::VisualizationWidget *ui;
52 };
22 };
@@ -1,60 +1,21
1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
5
6 #include <QLoggingCategory>
7 #include <QWidget>
4 #include <QWidget>
8
5
9 #include <memory>
10
11 #include <Common/spimpl.h>
12
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
14
15 namespace Ui {
6 namespace Ui {
16 class VisualizationZoneWidget;
7 class VisualizationZoneWidget;
17 } // Ui
8 } // Ui
18
9
19 class Variable;
10 class VisualizationZoneWidget : public QWidget {
20 class VisualizationGraphWidget;
21
22 class VisualizationZoneWidget : public QWidget, public IVisualizationWidget {
23 Q_OBJECT
11 Q_OBJECT
24
12
25 public:
13 public:
26 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
14 explicit VisualizationZoneWidget(QWidget *parent = 0);
27 virtual ~VisualizationZoneWidget();
15 virtual ~VisualizationZoneWidget();
28
16
29 /// Add a graph widget
30 void addGraph(VisualizationGraphWidget *graphWidget);
31
32 /**
33 * Creates a graph using a variable. The variable will be displayed in the new graph.
34 * @param variable the variable for which to create the graph
35 * @return the pointer to the created graph
36 */
37 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
38
39 // IVisualizationWidget interface
40 void accept(IVisualizationWidgetVisitor *visitor) override;
41 bool canDrop(const Variable &variable) const override;
42 bool contains(const Variable &variable) const override;
43 QString name() const override;
44
45 protected:
46 void closeEvent(QCloseEvent *event) override;
47
48 private:
17 private:
49 Ui::VisualizationZoneWidget *ui;
18 Ui::VisualizationZoneWidget *ui;
50
51 class VisualizationZoneWidgetPrivate;
52 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
53
54 private slots:
55 void onVariableAdded(std::shared_ptr<Variable> variable);
56 /// Slot called when a variable is about to be removed from a graph contained in the zone
57 void onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable);
58 };
19 };
59
20
60 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
21 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -42,9 +42,6
42
42
43 #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
43 #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
44 #define QCP_DEVICEPIXELRATIO_SUPPORTED
44 #define QCP_DEVICEPIXELRATIO_SUPPORTED
45 #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
46 #define QCP_DEVICEPIXELRATIO_FLOAT
47 #endif
48 #endif
45 #endif
49
46
50 #include <QtCore/QCache>
47 #include <QtCore/QCache>
@@ -112,8 +109,8 class QCPColorMap;
112 class QCPColorScale;
109 class QCPColorScale;
113 class QCPBars;
110 class QCPBars;
114
111
115 /* including file 'src/global.h', size 16225 */
112 /* including file 'src/global.h', size 16131 */
116 /* commit e7c6a5540d344a96d107dce53f9d4414a09a7320 2017-07-25 00:52:29 +0200 */
113 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
117
114
118 // decl definitions for shared library compilation/usage:
115 // decl definitions for shared library compilation/usage:
119 #if defined(QCUSTOMPLOT_COMPILE_LIBRARY)
116 #if defined(QCUSTOMPLOT_COMPILE_LIBRARY)
@@ -1797,8 +1794,8 protected:
1797 /* end of 'src/axis/axistickerdatetime.h' */
1794 /* end of 'src/axis/axistickerdatetime.h' */
1798
1795
1799
1796
1800 /* including file 'src/axis/axistickertime.h', size 3542 */
1797 /* including file 'src/axis/axistickertime.h', size 3288 */
1801 /* commit c38adb94d83c6a752597a5d43d45c0561fbe1d4d 2017-08-13 17:37:53 +0200 */
1798 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
1802
1799
1803 class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker {
1800 class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker {
1804 Q_GADGET
1801 Q_GADGET
@@ -1808,17 +1805,7 public:
1808
1805
1809 \see setFieldWidth, setTimeFormat
1806 \see setFieldWidth, setTimeFormat
1810 */
1807 */
1811 enum TimeUnit {
1808 enum TimeUnit { tuMilliseconds, tuSeconds, tuMinutes, tuHours, tuDays };
1812 tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat)
1813 ,
1814 tuSeconds ///< Seconds (%%s in \ref setTimeFormat)
1815 ,
1816 tuMinutes ///< Minutes (%%m in \ref setTimeFormat)
1817 ,
1818 tuHours ///< Hours (%%h in \ref setTimeFormat)
1819 ,
1820 tuDays ///< Days (%%d in \ref setTimeFormat)
1821 };
1822 Q_ENUMS(TimeUnit)
1809 Q_ENUMS(TimeUnit)
1823
1810
1824 QCPAxisTickerTime();
1811 QCPAxisTickerTime();
@@ -2039,8 +2026,8 protected:
2039 /* end of 'src/axis/axistickerlog.h' */
2026 /* end of 'src/axis/axistickerlog.h' */
2040
2027
2041
2028
2042 /* including file 'src/axis/axis.h', size 20634 */
2029 /* including file 'src/axis/axis.h', size 20230 */
2043 /* commit 0cc4d9f61f7bf45321a88fec89d909b020ffa26f 2017-08-14 00:43:29 +0200 */
2030 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
2044
2031
2045 class QCP_LIB_DECL QCPGrid : public QCPLayerable {
2032 class QCP_LIB_DECL QCPGrid : public QCPLayerable {
2046 Q_OBJECT
2033 Q_OBJECT
@@ -2377,9 +2364,6 protected:
2377 QVector<double> mSubTickVector;
2364 QVector<double> mSubTickVector;
2378 bool mCachedMarginValid;
2365 bool mCachedMarginValid;
2379 int mCachedMargin;
2366 int mCachedMargin;
2380 bool mDragging;
2381 QCPRange mDragStartRange;
2382 QCP::AntialiasedElements mAADragBackup, mNotAADragBackup;
2383
2367
2384 // introduced virtual methods:
2368 // introduced virtual methods:
2385 virtual int calculateMargin();
2369 virtual int calculateMargin();
@@ -2392,11 +2376,6 protected:
2392 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details,
2376 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details,
2393 bool *selectionStateChanged) Q_DECL_OVERRIDE;
2377 bool *selectionStateChanged) Q_DECL_OVERRIDE;
2394 virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE;
2378 virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE;
2395 // mouse events:
2396 virtual void mousePressEvent(QMouseEvent *event, const QVariant &details);
2397 virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos);
2398 virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos);
2399 virtual void wheelEvent(QWheelEvent *event);
2400
2379
2401 // non-virtual methods:
2380 // non-virtual methods:
2402 void setupTickVectors();
2381 void setupTickVectors();
@@ -2633,8 +2612,8 Q_DECLARE_METATYPE(QCPScatterStyle::ScatterShape)
2633 /* end of 'src/scatterstyle.h' */
2612 /* end of 'src/scatterstyle.h' */
2634
2613
2635
2614
2636 /* including file 'src/datacontainer.h', size 4596 */
2615 /* including file 'src/datacontainer.h', size 4535 */
2637 /* commit bee82298bd87b91a50093fb0b81cd7c734724a6f 2017-08-13 16:10:24 +0200 */
2616 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
2638
2617
2639 /*! \relates QCPDataContainer
2618 /*! \relates QCPDataContainer
2640 Returns whether the sort key of \a a is less than the sort key of \a b.
2619 Returns whether the sort key of \a a is less than the sort key of \a b.
@@ -2648,8 +2627,7 inline bool qcpLessThanSortKey(const DataType &a, const DataType &b)
2648 }
2627 }
2649
2628
2650 template <class DataType>
2629 template <class DataType>
2651 class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below)
2630 class QCP_LIB_DECL QCPDataContainer {
2652 {
2653 public:
2631 public:
2654 typedef typename QVector<DataType>::const_iterator const_iterator;
2632 typedef typename QVector<DataType>::const_iterator const_iterator;
2655 typedef typename QVector<DataType>::iterator iterator;
2633 typedef typename QVector<DataType>::iterator iterator;
@@ -2708,8 +2686,8 protected:
2708
2686
2709 // include implementation in header since it is a class template:
2687 // include implementation in header since it is a class template:
2710
2688
2711 /* including file 'src/datacontainer.cpp', size 31349 */
2689 /* including file 'src/datacontainer.cpp', size 31224 */
2712 /* commit 820d2282db70144c358c13433cd74b4175f9252b 2017-07-24 00:24:17 +0200 */
2690 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
2713
2691
2714 ////////////////////////////////////////////////////////////////////////////////////////////////////
2692 ////////////////////////////////////////////////////////////////////////////////////////////////////
2715 //////////////////// QCPDataContainer
2693 //////////////////// QCPDataContainer
@@ -3425,8 +3403,7 QCPRange QCPDataContainer<DataType>::valueRange(bool &foundRange, QCP::SignDomai
3425
3403
3426 /*!
3404 /*!
3427 Makes sure \a begin and \a end mark a data range that is both within the bounds of this data
3405 Makes sure \a begin and \a end mark a data range that is both within the bounds of this data
3428 container's data, as well as within the specified \a dataRange. The initial range described by
3406 container's data, as well as within the specified \a dataRange.
3429 the passed iterators \a begin and \a end is never expanded, only contracted if necessary.
3430
3407
3431 This function doesn't require for \a dataRange to be within the bounds of this data container's
3408 This function doesn't require for \a dataRange to be within the bounds of this data container's
3432 valid range.
3409 valid range.
@@ -3683,8 +3660,8 private:
3683 /* end of 'src/plottable.h' */
3660 /* end of 'src/plottable.h' */
3684
3661
3685
3662
3686 /* including file 'src/item.h', size 9384 */
3663 /* including file 'src/item.h', size 9368 */
3687 /* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */
3664 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
3688
3665
3689 class QCP_LIB_DECL QCPItemAnchor {
3666 class QCP_LIB_DECL QCPItemAnchor {
3690 Q_GADGET
3667 Q_GADGET
@@ -3773,7 +3750,7 public:
3773 QCPAxis *keyAxis() const { return mKeyAxis.data(); }
3750 QCPAxis *keyAxis() const { return mKeyAxis.data(); }
3774 QCPAxis *valueAxis() const { return mValueAxis.data(); }
3751 QCPAxis *valueAxis() const { return mValueAxis.data(); }
3775 QCPAxisRect *axisRect() const;
3752 QCPAxisRect *axisRect() const;
3776 virtual QPointF pixelPosition() const Q_DECL_OVERRIDE;
3753 virtual QPointF pixelPosition() const;
3777
3754
3778 // setters:
3755 // setters:
3779 void setType(PositionType type);
3756 void setType(PositionType type);
@@ -3880,8 +3857,8 private:
3880 /* end of 'src/item.h' */
3857 /* end of 'src/item.h' */
3881
3858
3882
3859
3883 /* including file 'src/core.h', size 14886 */
3860 /* including file 'src/core.h', size 14797 */
3884 /* commit 29aafbce469a36d175d4fb32cbfd1f50a6072890 2016-10-12 19:21:24 +0200 */
3861 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
3885
3862
3886 class QCP_LIB_DECL QCustomPlot : public QWidget {
3863 class QCP_LIB_DECL QCustomPlot : public QWidget {
3887 Q_OBJECT
3864 Q_OBJECT
@@ -4114,9 +4091,7 protected:
4114 QPoint mMousePressPos;
4091 QPoint mMousePressPos;
4115 bool mMouseHasMoved;
4092 bool mMouseHasMoved;
4116 QPointer<QCPLayerable> mMouseEventLayerable;
4093 QPointer<QCPLayerable> mMouseEventLayerable;
4117 QPointer<QCPLayerable> mMouseSignalLayerable;
4118 QVariant mMouseEventLayerableDetails;
4094 QVariant mMouseEventLayerableDetails;
4119 QVariant mMouseSignalLayerableDetails;
4120 bool mReplotting;
4095 bool mReplotting;
4121 bool mReplotQueued;
4096 bool mReplotQueued;
4122 int mOpenGlMultisamples;
4097 int mOpenGlMultisamples;
@@ -4178,12 +4153,11 Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority)
4178 /* end of 'src/core.h' */
4153 /* end of 'src/core.h' */
4179
4154
4180
4155
4181 /* including file 'src/plottable1d.h', size 4544 */
4156 /* including file 'src/plottable1d.h', size 4250 */
4182 /* commit bee82298bd87b91a50093fb0b81cd7c734724a6f 2017-08-13 16:10:24 +0200 */
4157 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
4183
4158
4184 class QCPPlottableInterface1D {
4159 class QCP_LIB_DECL QCPPlottableInterface1D {
4185 public:
4160 public:
4186 virtual ~QCPPlottableInterface1D() {}
4187 // introduced pure virtual methods:
4161 // introduced pure virtual methods:
4188 virtual int dataCount() const = 0;
4162 virtual int dataCount() const = 0;
4189 virtual double dataMainKey(int index) const = 0;
4163 virtual double dataMainKey(int index) const = 0;
@@ -4198,11 +4172,8 public:
4198 };
4172 };
4199
4173
4200 template <class DataType>
4174 template <class DataType>
4201 class QCPAbstractPlottable1D : public QCPAbstractPlottable,
4175 class QCP_LIB_DECL QCPAbstractPlottable1D : public QCPAbstractPlottable,
4202 public QCPPlottableInterface1D // no QCP_LIB_DECL, template class
4176 public QCPPlottableInterface1D {
4203 // ends up in header (cpp included
4204 // below)
4205 {
4206 // No Q_OBJECT macro due to template class
4177 // No Q_OBJECT macro due to template class
4207
4178
4208 public:
4179 public:
@@ -4210,22 +4181,20 public:
4210 virtual ~QCPAbstractPlottable1D();
4181 virtual ~QCPAbstractPlottable1D();
4211
4182
4212 // virtual methods of 1d plottable interface:
4183 // virtual methods of 1d plottable interface:
4213 virtual int dataCount() const Q_DECL_OVERRIDE;
4184 virtual int dataCount() const;
4214 virtual double dataMainKey(int index) const Q_DECL_OVERRIDE;
4185 virtual double dataMainKey(int index) const;
4215 virtual double dataSortKey(int index) const Q_DECL_OVERRIDE;
4186 virtual double dataSortKey(int index) const;
4216 virtual double dataMainValue(int index) const Q_DECL_OVERRIDE;
4187 virtual double dataMainValue(int index) const;
4217 virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE;
4188 virtual QCPRange dataValueRange(int index) const;
4218 virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE;
4189 virtual QPointF dataPixelPosition(int index) const;
4219 virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE;
4190 virtual bool sortKeyIsMainKey() const;
4220 virtual QCPDataSelection selectTestRect(const QRectF &rect,
4191 virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const;
4221 bool onlySelectable) const Q_DECL_OVERRIDE;
4192 virtual int findBegin(double sortKey, bool expandedRange = true) const;
4222 virtual int findBegin(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE;
4193 virtual int findEnd(double sortKey, bool expandedRange = true) const;
4223 virtual int findEnd(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE;
4224
4194
4225 // reimplemented virtual methods:
4195 // virtual methods:
4226 virtual double selectTest(const QPointF &pos, bool onlySelectable,
4196 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details = 0) const;
4227 QVariant *details = 0) const Q_DECL_OVERRIDE;
4197 virtual QCPPlottableInterface1D *interface1D() { return this; }
4228 virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; }
4229
4198
4230 protected:
4199 protected:
4231 // property members:
4200 // property members:
@@ -4894,8 +4863,8 Q_DECLARE_METATYPE(QCPColorGradient::GradientPreset)
4894 /* end of 'src/colorgradient.h' */
4863 /* end of 'src/colorgradient.h' */
4895
4864
4896
4865
4897 /* including file 'src/selectiondecorator-bracket.h', size 4442 */
4866 /* including file 'src/selectiondecorator-bracket.h', size 4426 */
4898 /* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */
4867 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
4899
4868
4900 class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator {
4869 class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator {
4901 Q_GADGET
4870 Q_GADGET
@@ -4947,7 +4916,7 public:
4947 virtual void drawBracket(QCPPainter *painter, int direction) const;
4916 virtual void drawBracket(QCPPainter *painter, int direction) const;
4948
4917
4949 // virtual methods:
4918 // virtual methods:
4950 virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection) Q_DECL_OVERRIDE;
4919 virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection);
4951
4920
4952 protected:
4921 protected:
4953 // property members:
4922 // property members:
@@ -4969,8 +4938,8 Q_DECLARE_METATYPE(QCPSelectionDecoratorBracket::BracketStyle)
4969 /* end of 'src/selectiondecorator-bracket.h' */
4938 /* end of 'src/selectiondecorator-bracket.h' */
4970
4939
4971
4940
4972 /* including file 'src/layoutelements/layoutelement-axisrect.h', size 7507 */
4941 /* including file 'src/layoutelements/layoutelement-axisrect.h', size 7528 */
4973 /* commit 77ba168312f935543fc31d1ae9b4cdcf34aae4f9 2017-08-13 18:29:48 +0200 */
4942 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
4974
4943
4975 class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement {
4944 class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement {
4976 Q_OBJECT
4945 Q_OBJECT
@@ -5068,6 +5037,7 protected:
5068 // non-property members:
5037 // non-property members:
5069 QList<QCPRange> mDragStartHorzRange, mDragStartVertRange;
5038 QList<QCPRange> mDragStartHorzRange, mDragStartVertRange;
5070 QCP::AntialiasedElements mAADragBackup, mNotAADragBackup;
5039 QCP::AntialiasedElements mAADragBackup, mNotAADragBackup;
5040 QPoint mDragStart;
5071 bool mDragging;
5041 bool mDragging;
5072 QHash<QCPAxis::AxisType, QList<QCPAxis *> > mAxes;
5042 QHash<QCPAxis::AxisType, QList<QCPAxis *> > mAxes;
5073
5043
@@ -5408,8 +5378,8 private:
5408 /* end of 'src/layoutelements/layoutelement-textelement.h' */
5378 /* end of 'src/layoutelements/layoutelement-textelement.h' */
5409
5379
5410
5380
5411 /* including file 'src/layoutelements/layoutelement-colorscale.h', size 5923 */
5381 /* including file 'src/layoutelements/layoutelement-colorscale.h', size 5907 */
5412 /* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */
5382 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
5413
5383
5414
5384
5415 class QCPColorScaleAxisRectPrivate : public QCPAxisRect {
5385 class QCPColorScaleAxisRectPrivate : public QCPAxisRect {
@@ -5428,7 +5398,7 protected:
5428 using QCPAxisRect::mouseReleaseEvent;
5398 using QCPAxisRect::mouseReleaseEvent;
5429 using QCPAxisRect::wheelEvent;
5399 using QCPAxisRect::wheelEvent;
5430 using QCPAxisRect::update;
5400 using QCPAxisRect::update;
5431 virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
5401 virtual void draw(QCPPainter *painter);
5432 void updateGradientImage();
5402 void updateGradientImage();
5433 Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts);
5403 Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts);
5434 Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts);
5404 Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts);
@@ -5516,8 +5486,8 private:
5516 /* end of 'src/layoutelements/layoutelement-colorscale.h' */
5486 /* end of 'src/layoutelements/layoutelement-colorscale.h' */
5517
5487
5518
5488
5519 /* including file 'src/plottables/plottable-graph.h', size 9294 */
5489 /* including file 'src/plottables/plottable-graph.h', size 8826 */
5520 /* commit f3881770eaf7366171012ad01cad2aaf5f61dd27 2017-06-23 02:48:21 +0200 */
5490 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
5521
5491
5522 class QCP_LIB_DECL QCPGraphData {
5492 class QCP_LIB_DECL QCPGraphData {
5523 public:
5493 public:
@@ -5654,20 +5624,11 protected:
5654 QVector<QPointF> dataToStepRightLines(const QVector<QCPGraphData> &data) const;
5624 QVector<QPointF> dataToStepRightLines(const QVector<QCPGraphData> &data) const;
5655 QVector<QPointF> dataToStepCenterLines(const QVector<QCPGraphData> &data) const;
5625 QVector<QPointF> dataToStepCenterLines(const QVector<QCPGraphData> &data) const;
5656 QVector<QPointF> dataToImpulseLines(const QVector<QCPGraphData> &data) const;
5626 QVector<QPointF> dataToImpulseLines(const QVector<QCPGraphData> &data) const;
5657 QVector<QCPDataRange> getNonNanSegments(const QVector<QPointF> *lineData,
5627 void addFillBasePoints(QVector<QPointF> *lines) const;
5658 Qt::Orientation keyOrientation) const;
5628 void removeFillBasePoints(QVector<QPointF> *lines) const;
5659 QVector<QPair<QCPDataRange, QCPDataRange> >
5629 QPointF lowerFillBasePoint(double lowerKey) const;
5660 getOverlappingSegments(QVector<QCPDataRange> thisSegments, const QVector<QPointF> *thisData,
5630 QPointF upperFillBasePoint(double upperKey) const;
5661 QVector<QCPDataRange> otherSegments,
5631 const QPolygonF getChannelFillPolygon(const QVector<QPointF> *lines) const;
5662 const QVector<QPointF> *otherData) const;
5663 bool segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper,
5664 int &bPrecedence) const;
5665 QPointF getFillBasePoint(QPointF matchingDataPoint) const;
5666 const QPolygonF getFillPolygon(const QVector<QPointF> *lineData, QCPDataRange segment) const;
5667 const QPolygonF getChannelFillPolygon(const QVector<QPointF> *lineData,
5668 QCPDataRange thisSegment,
5669 const QVector<QPointF> *otherData,
5670 QCPDataRange otherSegment) const;
5671 int findIndexBelowX(const QVector<QPointF> *data, double x) const;
5632 int findIndexBelowX(const QVector<QPointF> *data, double x) const;
5672 int findIndexAboveX(const QVector<QPointF> *data, double x) const;
5633 int findIndexAboveX(const QVector<QPointF> *data, double x) const;
5673 int findIndexBelowY(const QVector<QPointF> *data, double y) const;
5634 int findIndexBelowY(const QVector<QPointF> *data, double y) const;
@@ -6464,8 +6425,8 Q_DECLARE_METATYPE(QCPFinancial::ChartStyle)
6464 /* end of 'src/plottables/plottable-financial.h' */
6425 /* end of 'src/plottables/plottable-financial.h' */
6465
6426
6466
6427
6467 /* including file 'src/plottables/plottable-errorbar.h', size 7727 */
6428 /* including file 'src/plottables/plottable-errorbar.h', size 7567 */
6468 /* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */
6429 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
6469
6430
6470 class QCP_LIB_DECL QCPErrorBarsData {
6431 class QCP_LIB_DECL QCPErrorBarsData {
6471 public:
6432 public:
@@ -6544,17 +6505,16 public:
6544 void addData(double errorMinus, double errorPlus);
6505 void addData(double errorMinus, double errorPlus);
6545
6506
6546 // virtual methods of 1d plottable interface:
6507 // virtual methods of 1d plottable interface:
6547 virtual int dataCount() const Q_DECL_OVERRIDE;
6508 virtual int dataCount() const;
6548 virtual double dataMainKey(int index) const Q_DECL_OVERRIDE;
6509 virtual double dataMainKey(int index) const;
6549 virtual double dataSortKey(int index) const Q_DECL_OVERRIDE;
6510 virtual double dataSortKey(int index) const;
6550 virtual double dataMainValue(int index) const Q_DECL_OVERRIDE;
6511 virtual double dataMainValue(int index) const;
6551 virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE;
6512 virtual QCPRange dataValueRange(int index) const;
6552 virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE;
6513 virtual QPointF dataPixelPosition(int index) const;
6553 virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE;
6514 virtual bool sortKeyIsMainKey() const;
6554 virtual QCPDataSelection selectTestRect(const QRectF &rect,
6515 virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const;
6555 bool onlySelectable) const Q_DECL_OVERRIDE;
6516 virtual int findBegin(double sortKey, bool expandedRange = true) const;
6556 virtual int findBegin(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE;
6517 virtual int findEnd(double sortKey, bool expandedRange = true) const;
6557 virtual int findEnd(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE;
6558
6518
6559 // reimplemented virtual methods:
6519 // reimplemented virtual methods:
6560 virtual double selectTest(const QPointF &pos, bool onlySelectable,
6520 virtual double selectTest(const QPointF &pos, bool onlySelectable,
@@ -1,29 +1,21
1 #include <DataSource/DataSourceItem.h>
1 #include <DataSource/DataSourceItem.h>
2 #include <DataSource/DataSourceItemAction.h>
3 #include <DataSource/DataSourceTreeWidgetItem.h>
2 #include <DataSource/DataSourceTreeWidgetItem.h>
4
3
5 #include <QAction>
4 #include <SqpApplication.h>
6
5
7 Q_LOGGING_CATEGORY(LOG_DataSourceTreeWidgetItem, "DataSourceTreeWidgetItem")
6 Q_LOGGING_CATEGORY(LOG_DataSourceTreeWidgetItem, "DataSourceTreeWidgetItem")
8
7
9 namespace {
8 namespace {
10
9
11 // Column indexes
12 const auto NAME_COLUMN = 0;
13
14 QIcon itemIcon(const DataSourceItem *dataSource)
10 QIcon itemIcon(const DataSourceItem *dataSource)
15 {
11 {
16 if (dataSource) {
12 if (dataSource) {
17 auto dataSourceType = dataSource->type();
13 auto dataSourceType = dataSource->type();
18 switch (dataSourceType) {
14 switch (dataSourceType) {
19 case DataSourceItemType::NODE: {
15 case DataSourceItemType::NODE:
20 return dataSource->isRoot() ? QIcon{":/icones/dataSourceRoot.png"}
16 return sqpApp->style()->standardIcon(QStyle::SP_DirIcon);
21 : QIcon{":/icones/dataSourceNode.png"};
22 }
23 case DataSourceItemType::PRODUCT:
17 case DataSourceItemType::PRODUCT:
24 return QIcon{":/icones/dataSourceProduct.png"};
18 return sqpApp->style()->standardIcon(QStyle::SP_FileIcon);
25 case DataSourceItemType::COMPONENT:
26 return QIcon{":/icones/dataSourceComponent.png"};
27 default:
19 default:
28 // No action
20 // No action
29 break;
21 break;
@@ -33,7 +25,7 QIcon itemIcon(const DataSourceItem *dataSource)
33 << QObject::tr("Can't set data source icon : unknown data source type");
25 << QObject::tr("Can't set data source icon : unknown data source type");
34 }
26 }
35 else {
27 else {
36 qCCritical(LOG_DataSourceTreeWidgetItem())
28 qCWarning(LOG_DataSourceTreeWidgetItem())
37 << QObject::tr("Can't set data source icon : the data source is null");
29 << QObject::tr("Can't set data source icon : the data source is null");
38 }
30 }
39
31
@@ -41,54 +33,6 QIcon itemIcon(const DataSourceItem *dataSource)
41 return QIcon{};
33 return QIcon{};
42 }
34 }
43
35
44 /// @return the tooltip text for a variant. The text depends on whether the data is a simple variant
45 /// or a list of variants
46 QString tooltipValue(const QVariant &variant) noexcept
47 {
48 // If the variant is a list of variants, the text of the tooltip is of the form: {val1, val2,
49 // ...}
50 if (variant.canConvert<QVariantList>()) {
51 auto valueString = QStringLiteral("{");
52
53 auto variantList = variant.value<QVariantList>();
54 for (auto it = variantList.cbegin(), end = variantList.cend(); it != end; ++it) {
55 valueString.append(it->toString());
56
57 if (std::distance(it, end) != 1) {
58 valueString.append(", ");
59 }
60 }
61
62 valueString.append(QStringLiteral("}"));
63
64 return valueString;
65 }
66 else {
67 return variant.toString();
68 }
69 }
70
71 QString itemTooltip(const DataSourceItem *dataSource) noexcept
72 {
73 // The tooltip displays all item's data
74 if (dataSource) {
75 auto result = QString{};
76
77 const auto &data = dataSource->data();
78 for (auto it = data.cbegin(), end = data.cend(); it != end; ++it) {
79 result.append(QString{"<b>%1:</b> %2<br/>"}.arg(it.key(), tooltipValue(it.value())));
80 }
81
82 return result;
83 }
84 else {
85 qCCritical(LOG_DataSourceTreeWidgetItem())
86 << QObject::tr("Can't set data source tooltip : the data source is null");
87
88 return QString{};
89 }
90 }
91
92 } // namespace
36 } // namespace
93
37
94 struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
38 struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
@@ -96,9 +40,6 struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
96
40
97 /// Model used to retrieve data source information
41 /// Model used to retrieve data source information
98 const DataSourceItem *m_Data;
42 const DataSourceItem *m_Data;
99 /// Actions associated to the item. The parent of the item (QTreeWidget) takes the ownership of
100 /// the actions
101 QList<QAction *> m_Actions;
102 };
43 };
103
44
104 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(const DataSourceItem *data, int type)
45 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(const DataSourceItem *data, int type)
@@ -111,51 +52,14 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(QTreeWidget *parent, const Da
111 : QTreeWidgetItem{parent, type},
52 : QTreeWidgetItem{parent, type},
112 impl{spimpl::make_unique_impl<DataSourceTreeWidgetItemPrivate>(data)}
53 impl{spimpl::make_unique_impl<DataSourceTreeWidgetItemPrivate>(data)}
113 {
54 {
114 // Sets the icon and the tooltip depending on the data source
55 // Sets the icon depending on the data source
115 setIcon(0, itemIcon(impl->m_Data));
56 setIcon(0, itemIcon(impl->m_Data));
116 setToolTip(0, itemTooltip(impl->m_Data));
117
118 // Generates tree actions based on the item actions
119 auto createTreeAction = [this, &parent](const auto &itemAction) {
120 auto treeAction = new QAction{itemAction->name(), parent};
121
122 // Executes item action when tree action is triggered
123 QObject::connect(treeAction, &QAction::triggered, itemAction,
124 &DataSourceItemAction::execute);
125
126 return treeAction;
127 };
128
129 auto itemActions = impl->m_Data->actions();
130 std::transform(std::cbegin(itemActions), std::cend(itemActions),
131 std::back_inserter(impl->m_Actions), createTreeAction);
132 }
133
134 const DataSourceItem *DataSourceTreeWidgetItem::data() const
135 {
136 return impl->m_Data;
137 }
57 }
138
58
139 QVariant DataSourceTreeWidgetItem::data(int column, int role) const
59 QVariant DataSourceTreeWidgetItem::data(int column, int role) const
140 {
60 {
141 if (role == Qt::DisplayRole) {
61 if (role == Qt::DisplayRole) {
142 if (impl->m_Data) {
62 return (impl->m_Data) ? impl->m_Data->data(column) : QVariant{};
143 switch (column) {
144 case NAME_COLUMN:
145 return impl->m_Data->name();
146 default:
147 // No action
148 break;
149 }
150
151 qCWarning(LOG_DataSourceTreeWidgetItem())
152 << QObject::tr("Can't get data (unknown column %1)").arg(column);
153 }
154 else {
155 qCCritical(LOG_DataSourceTreeWidgetItem()) << QObject::tr("Can't get data (null item)");
156 }
157
158 return QVariant{};
159 }
63 }
160 else {
64 else {
161 return QTreeWidgetItem::data(column, role);
65 return QTreeWidgetItem::data(column, role);
@@ -169,8 +73,3 void DataSourceTreeWidgetItem::setData(int column, int role, const QVariant &val
169 QTreeWidgetItem::setData(column, role, value);
73 QTreeWidgetItem::setData(column, role, value);
170 }
74 }
171 }
75 }
172
173 QList<QAction *> DataSourceTreeWidgetItem::actions() const noexcept
174 {
175 return impl->m_Actions;
176 }
@@ -3,11 +3,8
3 #include <ui_DataSourceWidget.h>
3 #include <ui_DataSourceWidget.h>
4
4
5 #include <DataSource/DataSourceItem.h>
5 #include <DataSource/DataSourceItem.h>
6 #include <DataSource/DataSourceTreeWidgetHelper.h>
7 #include <DataSource/DataSourceTreeWidgetItem.h>
6 #include <DataSource/DataSourceTreeWidgetItem.h>
8
7
9 #include <QMenu>
10
11 namespace {
8 namespace {
12
9
13 /// Number of columns displayed in the tree
10 /// Number of columns displayed in the tree
@@ -36,26 +33,24 DataSourceTreeWidgetItem *createTreeWidgetItem(DataSourceItem *dataSource)
36
33
37 } // namespace
34 } // namespace
38
35
39 DataSourceWidget::DataSourceWidget(QWidget *parent) : QWidget{parent}, ui{new Ui::DataSourceWidget}
36 class DataSourceWidget::DataSourceWidgetPrivate {
40 {
37 public:
41 ui->setupUi(this);
38 explicit DataSourceWidgetPrivate(DataSourceWidget &widget)
42
39 : m_Ui{std::make_unique<Ui::DataSourceWidget>()}
43 // Set tree properties
40 {
44 ui->treeWidget->setColumnCount(TREE_NB_COLUMNS);
41 m_Ui->setupUi(&widget);
45 ui->treeWidget->setHeaderLabels(TREE_HEADER_LABELS);
46 ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
47
42
48 // Connection to show a menu when right clicking on the tree
43 // Set tree properties
49 connect(ui->treeWidget, &QTreeWidget::customContextMenuRequested, this,
44 m_Ui->treeWidget->setColumnCount(TREE_NB_COLUMNS);
50 &DataSourceWidget::onTreeMenuRequested);
45 m_Ui->treeWidget->setHeaderLabels(TREE_HEADER_LABELS);
46 }
51
47
52 // Connection to filter tree
48 std::unique_ptr<Ui::DataSourceWidget> m_Ui;
53 connect(ui->filterLineEdit, &QLineEdit::textChanged, this, &DataSourceWidget::filterChanged);
49 };
54 }
55
50
56 DataSourceWidget::~DataSourceWidget() noexcept
51 DataSourceWidget::DataSourceWidget(QWidget *parent)
52 : QWidget{parent}, impl{spimpl::make_unique_impl<DataSourceWidgetPrivate>(*this)}
57 {
53 {
58 delete ui;
59 }
54 }
60
55
61 void DataSourceWidget::addDataSource(DataSourceItem *dataSource) noexcept
56 void DataSourceWidget::addDataSource(DataSourceItem *dataSource) noexcept
@@ -63,38 +58,6 void DataSourceWidget::addDataSource(DataSourceItem *dataSource) noexcept
63 // Creates the item associated to the source and adds it to the tree widget. The tree widget
58 // Creates the item associated to the source and adds it to the tree widget. The tree widget
64 // takes the ownership of the item
59 // takes the ownership of the item
65 if (dataSource) {
60 if (dataSource) {
66 ui->treeWidget->addTopLevelItem(createTreeWidgetItem(dataSource));
61 impl->m_Ui->treeWidget->addTopLevelItem(createTreeWidgetItem(dataSource));
67 }
68 }
69
70 void DataSourceWidget::filterChanged(const QString &text) noexcept
71 {
72 auto validateItem = [&text](const DataSourceTreeWidgetItem &item) {
73 auto regExp = QRegExp{text, Qt::CaseInsensitive, QRegExp::Wildcard};
74
75 // An item is valid if any of its metadata validates the text filter
76 auto itemMetadata = item.data()->data();
77 auto itemMetadataEnd = itemMetadata.cend();
78 auto acceptFilter
79 = [&regExp](const auto &variant) { return variant.toString().contains(regExp); };
80
81 return std::find_if(itemMetadata.cbegin(), itemMetadataEnd, acceptFilter)
82 != itemMetadataEnd;
83 };
84
85 // Applies filter on tree widget
86 DataSourceTreeWidgetHelper::filter(*ui->treeWidget, validateItem);
87 }
88
89 void DataSourceWidget::onTreeMenuRequested(const QPoint &pos) noexcept
90 {
91 // Retrieves the selected item in the tree, and build the menu from its actions
92 if (auto selectedItem = dynamic_cast<DataSourceTreeWidgetItem *>(ui->treeWidget->itemAt(pos))) {
93 QMenu treeMenu{};
94 treeMenu.addActions(selectedItem->actions());
95
96 if (!treeMenu.isEmpty()) {
97 treeMenu.exec(QCursor::pos());
98 }
99 }
62 }
100 }
63 }
@@ -24,14 +24,14 static const QString SQPSIDEPANESTYLESHEET
24
24
25 SqpSidePane::SqpSidePane(QWidget *parent) : QWidget{parent}, ui{new Ui::SqpSidePane}
25 SqpSidePane::SqpSidePane(QWidget *parent) : QWidget{parent}, ui{new Ui::SqpSidePane}
26 {
26 {
27 // QVBoxLayout *sidePaneLayout = new QVBoxLayout(this);
27 QVBoxLayout *sidePaneLayout = new QVBoxLayout(this);
28 // sidePaneLayout->setContentsMargins(0, 0, 0, 0);
28 sidePaneLayout->setContentsMargins(0, 0, 0, 0);
29 // this->setLayout(sidePaneLayout);
29 this->setLayout(sidePaneLayout);
30
30
31 ui->setupUi(this);
31 ui->setupUi(this);
32 m_SidePaneToolbar = new QToolBar();
32 m_SidePaneToolbar = new QToolBar(this);
33 m_SidePaneToolbar->setOrientation(Qt::Vertical);
33 m_SidePaneToolbar->setOrientation(Qt::Vertical);
34 this->layout()->addWidget(m_SidePaneToolbar);
34 sidePaneLayout->addWidget(m_SidePaneToolbar);
35
35
36 m_SidePaneToolbar->setStyleSheet(SQPSIDEPANESTYLESHEET);
36 m_SidePaneToolbar->setStyleSheet(SQPSIDEPANESTYLESHEET);
37 }
37 }
@@ -1,12 +1,7
1 #include "SqpApplication.h"
1 #include "SqpApplication.h"
2
2
3 #include <Data/IDataProvider.h>
4 #include <DataSource/DataSourceController.h>
3 #include <DataSource/DataSourceController.h>
5 #include <Network/NetworkController.h>
6 #include <QThread>
4 #include <QThread>
7 #include <Time/TimeController.h>
8 #include <Variable/Variable.h>
9 #include <Variable/VariableController.h>
10 #include <Visualization/VisualizationController.h>
5 #include <Visualization/VisualizationController.h>
11
6
12 Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication")
7 Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication")
@@ -15,72 +10,25 class SqpApplication::SqpApplicationPrivate {
15 public:
10 public:
16 SqpApplicationPrivate()
11 SqpApplicationPrivate()
17 : m_DataSourceController{std::make_unique<DataSourceController>()},
12 : m_DataSourceController{std::make_unique<DataSourceController>()},
18 m_NetworkController{std::make_unique<NetworkController>()},
19 m_TimeController{std::make_unique<TimeController>()},
20 m_VariableController{std::make_unique<VariableController>()},
21 m_VisualizationController{std::make_unique<VisualizationController>()}
13 m_VisualizationController{std::make_unique<VisualizationController>()}
22 {
14 {
23 // /////////////////////////////// //
24 // Connections between controllers //
25 // /////////////////////////////// //
26
27 // VariableController <-> DataSourceController
28 connect(m_DataSourceController.get(),
29 SIGNAL(variableCreationRequested(const QString &, const QVariantHash &,
30 std::shared_ptr<IDataProvider>)),
31 m_VariableController.get(),
32 SLOT(createVariable(const QString &, const QVariantHash &,
33 std::shared_ptr<IDataProvider>)));
34
35 // VariableController <-> VisualizationController
36 connect(m_VariableController.get(),
37 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)),
38 m_VisualizationController.get(),
39 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), Qt::DirectConnection);
40
41 connect(m_VariableController.get(),
42 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpRange &)),
43 m_VisualizationController.get(),
44 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpRange &)));
45
46
47 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
15 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
48 m_DataSourceControllerThread.setObjectName("DataSourceControllerThread");
49 m_NetworkController->moveToThread(&m_NetworkControllerThread);
50 m_NetworkControllerThread.setObjectName("NetworkControllerThread");
51 m_VariableController->moveToThread(&m_VariableControllerThread);
52 m_VariableControllerThread.setObjectName("VariableControllerThread");
53 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
16 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
54 m_VisualizationControllerThread.setObjectName("VsualizationControllerThread");
55
56
57 // Additionnal init
58 m_VariableController->setTimeController(m_TimeController.get());
59 }
17 }
60
18
61 virtual ~SqpApplicationPrivate()
19 virtual ~SqpApplicationPrivate()
62 {
20 {
21 qCInfo(LOG_SqpApplication()) << tr("SqpApplicationPrivate destruction");
63 m_DataSourceControllerThread.quit();
22 m_DataSourceControllerThread.quit();
64 m_DataSourceControllerThread.wait();
23 m_DataSourceControllerThread.wait();
65
24
66 m_NetworkControllerThread.quit();
67 m_NetworkControllerThread.wait();
68
69 m_VariableControllerThread.quit();
70 m_VariableControllerThread.wait();
71
72 m_VisualizationControllerThread.quit();
25 m_VisualizationControllerThread.quit();
73 m_VisualizationControllerThread.wait();
26 m_VisualizationControllerThread.wait();
74 }
27 }
75
28
76 std::unique_ptr<DataSourceController> m_DataSourceController;
29 std::unique_ptr<DataSourceController> m_DataSourceController;
77 std::unique_ptr<VariableController> m_VariableController;
78 std::unique_ptr<TimeController> m_TimeController;
79 std::unique_ptr<NetworkController> m_NetworkController;
80 std::unique_ptr<VisualizationController> m_VisualizationController;
30 std::unique_ptr<VisualizationController> m_VisualizationController;
81 QThread m_DataSourceControllerThread;
31 QThread m_DataSourceControllerThread;
82 QThread m_NetworkControllerThread;
83 QThread m_VariableControllerThread;
84 QThread m_VisualizationControllerThread;
32 QThread m_VisualizationControllerThread;
85 };
33 };
86
34
@@ -88,31 +36,20 public:
88 SqpApplication::SqpApplication(int &argc, char **argv)
36 SqpApplication::SqpApplication(int &argc, char **argv)
89 : QApplication{argc, argv}, impl{spimpl::make_unique_impl<SqpApplicationPrivate>()}
37 : QApplication{argc, argv}, impl{spimpl::make_unique_impl<SqpApplicationPrivate>()}
90 {
38 {
91 qCDebug(LOG_SqpApplication()) << tr("SqpApplication construction") << QThread::currentThread();
39 qCInfo(LOG_SqpApplication()) << tr("SqpApplication construction");
92
40
93 connect(&impl->m_DataSourceControllerThread, &QThread::started,
41 connect(&impl->m_DataSourceControllerThread, &QThread::started,
94 impl->m_DataSourceController.get(), &DataSourceController::initialize);
42 impl->m_DataSourceController.get(), &DataSourceController::initialize);
95 connect(&impl->m_DataSourceControllerThread, &QThread::finished,
43 connect(&impl->m_DataSourceControllerThread, &QThread::finished,
96 impl->m_DataSourceController.get(), &DataSourceController::finalize);
44 impl->m_DataSourceController.get(), &DataSourceController::finalize);
97
45
98 connect(&impl->m_NetworkControllerThread, &QThread::started, impl->m_NetworkController.get(),
99 &NetworkController::initialize);
100 connect(&impl->m_NetworkControllerThread, &QThread::finished, impl->m_NetworkController.get(),
101 &NetworkController::finalize);
102
103 connect(&impl->m_VariableControllerThread, &QThread::started, impl->m_VariableController.get(),
104 &VariableController::initialize);
105 connect(&impl->m_VariableControllerThread, &QThread::finished, impl->m_VariableController.get(),
106 &VariableController::finalize);
107
108 connect(&impl->m_VisualizationControllerThread, &QThread::started,
46 connect(&impl->m_VisualizationControllerThread, &QThread::started,
109 impl->m_VisualizationController.get(), &VisualizationController::initialize);
47 impl->m_VisualizationController.get(), &VisualizationController::initialize);
110 connect(&impl->m_VisualizationControllerThread, &QThread::finished,
48 connect(&impl->m_VisualizationControllerThread, &QThread::finished,
111 impl->m_VisualizationController.get(), &VisualizationController::finalize);
49 impl->m_VisualizationController.get(), &VisualizationController::finalize);
112
50
51
113 impl->m_DataSourceControllerThread.start();
52 impl->m_DataSourceControllerThread.start();
114 impl->m_NetworkControllerThread.start();
115 impl->m_VariableControllerThread.start();
116 impl->m_VisualizationControllerThread.start();
53 impl->m_VisualizationControllerThread.start();
117 }
54 }
118
55
@@ -124,27 +61,12 void SqpApplication::initialize()
124 {
61 {
125 }
62 }
126
63
127 DataSourceController &SqpApplication::dataSourceController() noexcept
64 DataSourceController &SqpApplication::dataSourceController() const noexcept
128 {
65 {
129 return *impl->m_DataSourceController;
66 return *impl->m_DataSourceController;
130 }
67 }
131
68
132 NetworkController &SqpApplication::networkController() noexcept
69 VisualizationController &SqpApplication::visualizationController() const noexcept
133 {
134 return *impl->m_NetworkController;
135 }
136
137 TimeController &SqpApplication::timeController() noexcept
138 {
139 return *impl->m_TimeController;
140 }
141
142 VariableController &SqpApplication::variableController() noexcept
143 {
144 return *impl->m_VariableController;
145 }
146
147 VisualizationController &SqpApplication::visualizationController() noexcept
148 {
70 {
149 return *impl->m_VisualizationController;
71 return *impl->m_VisualizationController;
150 }
72 }
@@ -1,356 +1,13
1 #include "Visualization/VisualizationGraphWidget.h"
1 #include "Visualization/VisualizationGraphWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationDefs.h"
4 #include "Visualization/VisualizationGraphHelper.h"
5 #include "Visualization/VisualizationGraphRenderingDelegate.h"
6 #include "ui_VisualizationGraphWidget.h"
2 #include "ui_VisualizationGraphWidget.h"
7
3
8 #include <Data/ArrayData.h>
4 VisualizationGraphWidget::VisualizationGraphWidget(QWidget *parent)
9 #include <Data/IDataSeries.h>
5 : QWidget(parent), ui(new Ui::VisualizationGraphWidget)
10 #include <Settings/SqpSettingsDefs.h>
11 #include <SqpApplication.h>
12 #include <Variable/Variable.h>
13 #include <Variable/VariableController.h>
14
15 #include <unordered_map>
16
17 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
18
19 namespace {
20
21 /// Key pressed to enable zoom on horizontal axis
22 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
23
24 /// Key pressed to enable zoom on vertical axis
25 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
26
27 } // namespace
28
29 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
30
31 explicit VisualizationGraphWidgetPrivate(const QString &name)
32 : m_Name{name},
33 m_DoAcquisition{true},
34 m_IsCalibration{false},
35 m_RenderingDelegate{nullptr}
36 {
37 }
38
39 QString m_Name;
40 // 1 variable -> n qcpplot
41 std::map<std::shared_ptr<Variable>, PlottablesMap> m_VariableToPlotMultiMap;
42 bool m_DoAcquisition;
43 bool m_IsCalibration;
44 QCPItemTracer *m_TextTracer;
45 /// Delegate used to attach rendering features to the plot
46 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
47 };
48
49 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
50 : QWidget{parent},
51 ui{new Ui::VisualizationGraphWidget},
52 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>(name)}
53 {
6 {
54 ui->setupUi(this);
7 ui->setupUi(this);
55
56 // 'Close' options : widget is deleted when closed
57 setAttribute(Qt::WA_DeleteOnClose);
58
59 // Set qcpplot properties :
60 // - Drag (on x-axis) and zoom are enabled
61 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
62 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectItems);
63 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
64
65 // The delegate must be initialized after the ui as it uses the plot
66 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*this);
67
68 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
69 connect(ui->widget, &QCustomPlot::mouseRelease, this,
70 &VisualizationGraphWidget::onMouseRelease);
71 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
72 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
73 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
74 &QCPAxis::rangeChanged),
75 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
76
77 // Activates menu when right clicking on the graph
78 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
79 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
80 &VisualizationGraphWidget::onGraphMenuRequested);
81
82 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
83 &VariableController::onRequestDataLoading);
84
85 connect(&sqpApp->variableController(), &VariableController::updateVarDisplaying, this,
86 &VisualizationGraphWidget::onUpdateVarDisplaying);
87 }
8 }
88
9
89
90 VisualizationGraphWidget::~VisualizationGraphWidget()
10 VisualizationGraphWidget::~VisualizationGraphWidget()
91 {
11 {
92 delete ui;
12 delete ui;
93 }
13 }
94
95 void VisualizationGraphWidget::enableAcquisition(bool enable)
96 {
97 impl->m_DoAcquisition = enable;
98 }
99
100 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
101 {
102 // Uses delegate to create the qcpplot components according to the variable
103 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
104 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
105
106 // Set axes properties according to the units of the data series
107 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
108 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
109 auto xAxisUnit = Unit{};
110 auto valuesUnit = Unit{};
111
112 if (auto dataSeries = variable->dataSeries()) {
113 dataSeries->lockRead();
114 xAxisUnit = dataSeries->xAxisUnit();
115 valuesUnit = dataSeries->valuesUnit();
116 dataSeries->unlock();
117 }
118 impl->m_RenderingDelegate->setAxesProperties(xAxisUnit, valuesUnit);
119
120 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
121
122 auto varRange = variable->range();
123
124 this->enableAcquisition(false);
125 this->setGraphRange(range);
126 this->enableAcquisition(true);
127
128 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, varRange,
129 false);
130
131 emit variableAdded(variable);
132 }
133
134 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
135 {
136 // Each component associated to the variable :
137 // - is removed from qcpplot (which deletes it)
138 // - is no longer referenced in the map
139 auto variableIt = impl->m_VariableToPlotMultiMap.find(variable);
140 if (variableIt != impl->m_VariableToPlotMultiMap.cend()) {
141 emit variableAboutToBeRemoved(variable);
142
143 auto &plottablesMap = variableIt->second;
144
145 for (auto plottableIt = plottablesMap.cbegin(), plottableEnd = plottablesMap.cend();
146 plottableIt != plottableEnd;) {
147 ui->widget->removePlottable(plottableIt->second);
148 plottableIt = plottablesMap.erase(plottableIt);
149 }
150
151 impl->m_VariableToPlotMultiMap.erase(variableIt);
152 }
153
154 // Updates graph
155 ui->widget->replot();
156 }
157
158 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable, const SqpRange &range)
159 {
160 // Note: in case of different axes that depends on variable, we could start with a code like
161 // that:
162 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
163 // for (auto it = componentsIt.first; it != componentsIt.second;) {
164 // }
165 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
166 ui->widget->replot();
167 }
168
169 void VisualizationGraphWidget::setYRange(const SqpRange &range)
170 {
171 ui->widget->yAxis->setRange(range.m_TStart, range.m_TEnd);
172 }
173
174 SqpRange VisualizationGraphWidget::graphRange() const noexcept
175 {
176 auto graphRange = ui->widget->xAxis->range();
177 return SqpRange{graphRange.lower, graphRange.upper};
178 }
179
180 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
181 {
182 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
183 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
184 ui->widget->replot();
185 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
186 }
187
188 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
189 {
190 if (visitor) {
191 visitor->visit(this);
192 }
193 else {
194 qCCritical(LOG_VisualizationGraphWidget())
195 << tr("Can't visit widget : the visitor is null");
196 }
197 }
198
199 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
200 {
201 /// @todo : for the moment, a graph can always accomodate a variable
202 Q_UNUSED(variable);
203 return true;
204 }
205
206 bool VisualizationGraphWidget::contains(const Variable &variable) const
207 {
208 // Finds the variable among the keys of the map
209 auto variablePtr = &variable;
210 auto findVariable
211 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
212
213 auto end = impl->m_VariableToPlotMultiMap.cend();
214 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
215 return it != end;
216 }
217
218 QString VisualizationGraphWidget::name() const
219 {
220 return impl->m_Name;
221 }
222
223 void VisualizationGraphWidget::closeEvent(QCloseEvent *event)
224 {
225 Q_UNUSED(event);
226
227 // Prevents that all variables will be removed from graph when it will be closed
228 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
229 emit variableAboutToBeRemoved(variableEntry.first);
230 }
231 }
232
233 void VisualizationGraphWidget::enterEvent(QEvent *event)
234 {
235 Q_UNUSED(event);
236 impl->m_RenderingDelegate->showGraphOverlay(true);
237 }
238
239 void VisualizationGraphWidget::leaveEvent(QEvent *event)
240 {
241 Q_UNUSED(event);
242 impl->m_RenderingDelegate->showGraphOverlay(false);
243 }
244
245 QCustomPlot &VisualizationGraphWidget::plot() noexcept
246 {
247 return *ui->widget;
248 }
249
250 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
251 {
252 QMenu graphMenu{};
253
254 // Iterates on variables (unique keys)
255 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
256 end = impl->m_VariableToPlotMultiMap.cend();
257 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
258 // 'Remove variable' action
259 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
260 [ this, var = it->first ]() { removeVariable(var); });
261 }
262
263 if (!graphMenu.isEmpty()) {
264 graphMenu.exec(QCursor::pos());
265 }
266 }
267
268 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
269 {
270 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
271 << QThread::currentThread()->objectName() << "DoAcqui"
272 << impl->m_DoAcquisition;
273
274 auto graphRange = SqpRange{t1.lower, t1.upper};
275 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
276
277 if (impl->m_DoAcquisition) {
278 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
279
280 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
281 end = impl->m_VariableToPlotMultiMap.end();
282 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
283 variableUnderGraphVector.push_back(it->first);
284 }
285 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, oldGraphRange,
286 !impl->m_IsCalibration);
287
288 if (!impl->m_IsCalibration) {
289 qCDebug(LOG_VisualizationGraphWidget())
290 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
291 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
292 emit synchronize(graphRange, oldGraphRange);
293 }
294 }
295 }
296
297 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
298 {
299 // Handles plot rendering when mouse is moving
300 impl->m_RenderingDelegate->onMouseMove(event);
301 }
302
303 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
304 {
305 auto zoomOrientations = QFlags<Qt::Orientation>{};
306
307 // Lambda that enables a zoom orientation if the key modifier related to this orientation
308 // has
309 // been pressed
310 auto enableOrientation
311 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
312 auto orientationEnabled = event->modifiers().testFlag(modifier);
313 zoomOrientations.setFlag(orientation, orientationEnabled);
314 };
315 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
316 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
317
318 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
319 }
320
321 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
322 {
323 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
324 }
325
326 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
327 {
328 impl->m_IsCalibration = false;
329 }
330
331 void VisualizationGraphWidget::onDataCacheVariableUpdated()
332 {
333 auto graphRange = ui->widget->xAxis->range();
334 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
335
336 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
337 auto variable = variableEntry.first;
338 qCDebug(LOG_VisualizationGraphWidget())
339 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
340 qCDebug(LOG_VisualizationGraphWidget())
341 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
342 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
343 VisualizationGraphHelper::updateData(variableEntry.second, variable->dataSeries(),
344 variable->range());
345 }
346 }
347 }
348
349 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
350 const SqpRange &range)
351 {
352 auto it = impl->m_VariableToPlotMultiMap.find(variable);
353 if (it != impl->m_VariableToPlotMultiMap.end()) {
354 VisualizationGraphHelper::updateData(it->second, variable->dataSeries(), range);
355 }
356 }
@@ -1,129 +1,13
1 #include "Visualization/VisualizationTabWidget.h"
1 #include "Visualization/VisualizationTabWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "ui_VisualizationTabWidget.h"
2 #include "ui_VisualizationTabWidget.h"
4
3
5 #include "Visualization/VisualizationZoneWidget.h"
4 VisualizationTabWidget::VisualizationTabWidget(QWidget *parent)
6
5 : QWidget{parent}, ui{new Ui::VisualizationTabWidget}
7 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
8
9 namespace {
10
11 /// Generates a default name for a new zone, according to the number of zones already displayed in
12 /// the tab
13 QString defaultZoneName(const QLayout &layout)
14 {
15 auto count = 0;
16 for (auto i = 0; i < layout.count(); ++i) {
17 if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) {
18 count++;
19 }
20 }
21
22 return QObject::tr("Zone %1").arg(count + 1);
23 }
24
25 /**
26 * Applies a function to all zones of the tab represented by its layout
27 * @param layout the layout that contains zones
28 * @param fun the function to apply to each zone
29 */
30 template <typename Fun>
31 void processZones(QLayout &layout, Fun fun)
32 {
33 for (auto i = 0; i < layout.count(); ++i) {
34 if (auto item = layout.itemAt(i)) {
35 if (auto visualizationZoneWidget
36 = dynamic_cast<VisualizationZoneWidget *>(item->widget())) {
37 fun(*visualizationZoneWidget);
38 }
39 }
40 }
41 }
42
43 } // namespace
44
45 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
46 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
47
48 QString m_Name;
49 };
50
51 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
52 : QWidget{parent},
53 ui{new Ui::VisualizationTabWidget},
54 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
55 {
6 {
56 ui->setupUi(this);
7 ui->setupUi(this);
57
58 // Widget is deleted when closed
59 setAttribute(Qt::WA_DeleteOnClose);
60 }
8 }
61
9
62 VisualizationTabWidget::~VisualizationTabWidget()
10 VisualizationTabWidget::~VisualizationTabWidget()
63 {
11 {
64 delete ui;
12 delete ui;
65 }
13 }
66
67 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
68 {
69 tabLayout().addWidget(zoneWidget);
70 }
71
72 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
73 {
74 auto zoneWidget = new VisualizationZoneWidget{defaultZoneName(tabLayout()), this};
75 this->addZone(zoneWidget);
76
77 // Creates a new graph into the zone
78 zoneWidget->createGraph(variable);
79
80 return zoneWidget;
81 }
82
83 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
84 {
85 if (visitor) {
86 visitor->visitEnter(this);
87
88 // Apply visitor to zone children: widgets different from zones are not visited (no action)
89 processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) {
90 zoneWidget.accept(visitor);
91 });
92
93 visitor->visitLeave(this);
94 }
95 else {
96 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
97 }
98 }
99
100 bool VisualizationTabWidget::canDrop(const Variable &variable) const
101 {
102 // A tab can always accomodate a variable
103 Q_UNUSED(variable);
104 return true;
105 }
106
107 bool VisualizationTabWidget::contains(const Variable &variable) const
108 {
109 Q_UNUSED(variable);
110 return false;
111 }
112
113 QString VisualizationTabWidget::name() const
114 {
115 return impl->m_Name;
116 }
117
118 void VisualizationTabWidget::closeEvent(QCloseEvent *event)
119 {
120 // Closes zones in the tab
121 processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); });
122
123 QWidget::closeEvent(event);
124 }
125
126 QLayout &VisualizationTabWidget::tabLayout() const noexcept
127 {
128 return *ui->scrollAreaWidgetContents->layout();
129 }
@@ -1,18 +1,12
1 #include "Visualization/VisualizationWidget.h"
1 #include "Visualization/VisualizationWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationGraphWidget.h"
4 #include "Visualization/VisualizationTabWidget.h"
2 #include "Visualization/VisualizationTabWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/operations/FindVariableOperation.h"
7 #include "Visualization/operations/GenerateVariableMenuOperation.h"
8 #include "Visualization/operations/RemoveVariableOperation.h"
9 #include "Visualization/operations/RescaleAxeOperation.h"
10 #include "Visualization/qcustomplot.h"
11
12 #include "ui_VisualizationWidget.h"
3 #include "ui_VisualizationWidget.h"
13
4
5 #include <QDebug>
14 #include <QToolButton>
6 #include <QToolButton>
15
7
8 #include "iostream"
9
16 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
10 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
17
11
18 VisualizationWidget::VisualizationWidget(QWidget *parent)
12 VisualizationWidget::VisualizationWidget(QWidget *parent)
@@ -23,150 +17,27 VisualizationWidget::VisualizationWidget(QWidget *parent)
23 auto addTabViewButton = new QToolButton{ui->tabWidget};
17 auto addTabViewButton = new QToolButton{ui->tabWidget};
24 addTabViewButton->setText(tr("Add View"));
18 addTabViewButton->setText(tr("Add View"));
25 addTabViewButton->setCursor(Qt::ArrowCursor);
19 addTabViewButton->setCursor(Qt::ArrowCursor);
20 addTabViewButton->setAutoRaise(true);
26 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
21 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
27
22
28 auto enableMinimumCornerWidgetSize = [this](bool enable) {
23 auto addTabView = [&](bool checked) {
29
24 auto index = ui->tabWidget->addTab(new VisualizationTabWidget(ui->tabWidget),
30 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
25 QString("View %1").arg(ui->tabWidget->count() + 1));
31 auto width = enable ? tabViewCornerWidget->width() : 0;
32 auto height = enable ? tabViewCornerWidget->height() : 0;
33 tabViewCornerWidget->setMinimumHeight(height);
34 tabViewCornerWidget->setMinimumWidth(width);
35 ui->tabWidget->setMinimumHeight(height);
36 ui->tabWidget->setMinimumWidth(width);
37 };
38
39 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
40 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
41 ui->tabWidget};
42 auto index = ui->tabWidget->addTab(widget, widget->name());
43 if (ui->tabWidget->count() > 0) {
44 enableMinimumCornerWidgetSize(false);
45 }
46 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
26 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
47 };
27 };
48
28
49 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
29 auto removeTabView = [&](int index) {
50 if (ui->tabWidget->count() == 1) {
51 enableMinimumCornerWidgetSize(true);
52 }
53
54 // Removes widget from tab and closes it
55 auto widget = ui->tabWidget->widget(index);
56 ui->tabWidget->removeTab(index);
30 ui->tabWidget->removeTab(index);
57 if (widget) {
58 widget->close();
59 }
60
61 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
31 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
62
63 };
32 };
64
33
65 ui->tabWidget->setTabsClosable(true);
34 ui->tabWidget->setTabsClosable(true);
66
35
67 connect(addTabViewButton, &QToolButton::clicked, addTabView);
36 connect(addTabViewButton, &QToolButton::clicked, addTabView);
68 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
37 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
69
70 // Adds default tab
71 addTabView();
72 }
38 }
73
39
74 VisualizationWidget::~VisualizationWidget()
40 VisualizationWidget::~VisualizationWidget()
75 {
41 {
76 delete ui;
42 delete ui;
77 }
43 }
78
79 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
80 {
81 if (visitor) {
82 visitor->visitEnter(this);
83
84 // Apply visitor for tab children
85 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
86 // Widgets different from tabs are not visited (no action)
87 if (auto visualizationTabWidget
88 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
89 visualizationTabWidget->accept(visitor);
90 }
91 }
92
93 visitor->visitLeave(this);
94 }
95 else {
96 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
97 }
98 }
99
100 bool VisualizationWidget::canDrop(const Variable &variable) const
101 {
102 // The main widget can never accomodate a variable
103 Q_UNUSED(variable);
104 return false;
105 }
106
107 bool VisualizationWidget::contains(const Variable &variable) const
108 {
109 Q_UNUSED(variable);
110 return false;
111 }
112
113 QString VisualizationWidget::name() const
114 {
115 return QStringLiteral("MainView");
116 }
117
118 void VisualizationWidget::attachVariableMenu(
119 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
120 {
121 // Menu is generated only if there is a single variable
122 if (variables.size() == 1) {
123 if (auto variable = variables.first()) {
124 // Gets the containers of the variable
125 FindVariableOperation findVariableOperation{variable};
126 accept(&findVariableOperation);
127 auto variableContainers = findVariableOperation.result();
128
129 // Generates the actions that make it possible to visualize the variable
130 GenerateVariableMenuOperation generateVariableMenuOperation{
131 menu, variable, std::move(variableContainers)};
132 accept(&generateVariableMenuOperation);
133 }
134 else {
135 qCCritical(LOG_VisualizationWidget()) << tr(
136 "Can't generate the menu relative to the visualization: the variable is null");
137 }
138 }
139 else {
140 qCDebug(LOG_VisualizationWidget())
141 << tr("No generation of the menu related to the visualization: several variables are "
142 "selected");
143 }
144 }
145
146 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept
147 {
148 // Calls the operation of removing all references to the variable in the visualization
149 auto removeVariableOperation = RemoveVariableOperation{variable};
150 accept(&removeVariableOperation);
151 }
152
153 void VisualizationWidget::onRangeChanged(std::shared_ptr<Variable> variable,
154 const SqpRange &range) noexcept
155 {
156 // Calls the operation of rescaling all graph that contrains variable in the visualization
157 auto rescaleVariableOperation = RescaleAxeOperation{variable, range};
158 accept(&rescaleVariableOperation);
159 }
160
161 void VisualizationWidget::closeEvent(QCloseEvent *event)
162 {
163 // Closes tabs in the widget
164 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
165 if (auto visualizationTabWidget
166 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
167 visualizationTabWidget->close();
168 }
169 }
170
171 QWidget::closeEvent(event);
172 }
@@ -1,302 +1,13
1 #include "Visualization/VisualizationZoneWidget.h"
1 #include "Visualization/VisualizationZoneWidget.h"
2
3 #include "Visualization/IVisualizationWidgetVisitor.h"
4 #include "Visualization/QCustomPlotSynchronizer.h"
5 #include "Visualization/VisualizationGraphWidget.h"
6 #include "ui_VisualizationZoneWidget.h"
2 #include "ui_VisualizationZoneWidget.h"
7
3
8 #include <Data/SqpRange.h>
4 VisualizationZoneWidget::VisualizationZoneWidget(QWidget *parent)
9 #include <Variable/Variable.h>
5 : QWidget{parent}, ui{new Ui::VisualizationZoneWidget}
10 #include <Variable/VariableController.h>
11
12 #include <QUuid>
13 #include <SqpApplication.h>
14 #include <cmath>
15
16 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
17
18 namespace {
19
20 /// Minimum height for graph added in zones (in pixels)
21 const auto GRAPH_MINIMUM_HEIGHT = 300;
22
23 /// Generates a default name for a new graph, according to the number of graphs already displayed in
24 /// the zone
25 QString defaultGraphName(const QLayout &layout)
26 {
27 auto count = 0;
28 for (auto i = 0; i < layout.count(); ++i) {
29 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
30 count++;
31 }
32 }
33
34 return QObject::tr("Graph %1").arg(count + 1);
35 }
36
37 /**
38 * Applies a function to all graphs of the zone represented by its layout
39 * @param layout the layout that contains graphs
40 * @param fun the function to apply to each graph
41 */
42 template <typename Fun>
43 void processGraphs(QLayout &layout, Fun fun)
44 {
45 for (auto i = 0; i < layout.count(); ++i) {
46 if (auto item = layout.itemAt(i)) {
47 if (auto visualizationGraphWidget
48 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
49 fun(*visualizationGraphWidget);
50 }
51 }
52 }
53 }
54
55 } // namespace
56
57 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
58
59 explicit VisualizationZoneWidgetPrivate()
60 : m_SynchronisationGroupId{QUuid::createUuid()},
61 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
62 {
63 }
64 QUuid m_SynchronisationGroupId;
65 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
66 };
67
68 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
69 : QWidget{parent},
70 ui{new Ui::VisualizationZoneWidget},
71 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
72 {
6 {
73 ui->setupUi(this);
7 ui->setupUi(this);
74
75 ui->zoneNameLabel->setText(name);
76
77 // 'Close' options : widget is deleted when closed
78 setAttribute(Qt::WA_DeleteOnClose);
79 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
80 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
81
82 // Synchronisation id
83 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
84 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
85 }
8 }
86
9
87 VisualizationZoneWidget::~VisualizationZoneWidget()
10 VisualizationZoneWidget::~VisualizationZoneWidget()
88 {
11 {
89 delete ui;
12 delete ui;
90 }
13 }
91
92 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
93 {
94 // Synchronize new graph with others in the zone
95 impl->m_Synchronizer->addGraph(*graphWidget);
96
97 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
98 }
99
100 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
101 {
102 auto graphWidget = new VisualizationGraphWidget{
103 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
104
105
106 // Set graph properties
107 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
108 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
109
110
111 // Lambda to synchronize zone widget
112 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
113 const SqpRange &oldGraphRange) {
114
115 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
116 auto frameLayout = ui->visualizationZoneFrame->layout();
117 for (auto i = 0; i < frameLayout->count(); ++i) {
118 auto graphChild
119 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
120 if (graphChild && (graphChild != graphWidget)) {
121
122 auto graphChildRange = graphChild->graphRange();
123 switch (zoomType) {
124 case AcquisitionZoomType::ZoomIn: {
125 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
126 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
127 graphChildRange.m_TStart += deltaLeft;
128 graphChildRange.m_TEnd -= deltaRight;
129 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
130 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
131 << deltaLeft;
132 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
133 << deltaRight;
134 qCDebug(LOG_VisualizationZoneWidget())
135 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
136
137 break;
138 }
139
140 case AcquisitionZoomType::ZoomOut: {
141 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
142 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
143 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
144 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
145 << deltaLeft;
146 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
147 << deltaRight;
148 qCDebug(LOG_VisualizationZoneWidget())
149 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
150 graphChildRange.m_TStart -= deltaLeft;
151 graphChildRange.m_TEnd += deltaRight;
152 break;
153 }
154 case AcquisitionZoomType::PanRight: {
155 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
156 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
157 graphChildRange.m_TStart += deltaRight;
158 graphChildRange.m_TEnd += deltaRight;
159 qCDebug(LOG_VisualizationZoneWidget())
160 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
161 break;
162 }
163 case AcquisitionZoomType::PanLeft: {
164 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
165 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
166 graphChildRange.m_TStart -= deltaLeft;
167 graphChildRange.m_TEnd -= deltaLeft;
168 break;
169 }
170 case AcquisitionZoomType::Unknown: {
171 qCDebug(LOG_VisualizationZoneWidget())
172 << tr("Impossible to synchronize: zoom type unknown");
173 break;
174 }
175 default:
176 qCCritical(LOG_VisualizationZoneWidget())
177 << tr("Impossible to synchronize: zoom type not take into account");
178 // No action
179 break;
180 }
181 graphChild->enableAcquisition(false);
182 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
183 << graphChild->graphRange();
184 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
185 << graphChildRange;
186 qCDebug(LOG_VisualizationZoneWidget())
187 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
188 graphChild->setGraphRange(graphChildRange);
189 graphChild->enableAcquisition(true);
190 }
191 }
192 };
193
194 // connection for synchronization
195 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
196 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
197 &VisualizationZoneWidget::onVariableAdded);
198 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
199 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
200
201 auto range = SqpRange{};
202
203 // Apply visitor to graph children
204 auto layout = ui->visualizationZoneFrame->layout();
205 if (layout->count() > 0) {
206 // Case of a new graph in a existant zone
207 if (auto visualizationGraphWidget
208 = dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
209 range = visualizationGraphWidget->graphRange();
210 }
211 }
212 else {
213 // Case of a new graph as the first of the zone
214 range = variable->range();
215 }
216
217 this->addGraph(graphWidget);
218
219 graphWidget->addVariable(variable, range);
220
221 // get y using variable range
222 if (auto dataSeries = variable->dataSeries()) {
223 dataSeries->lockRead();
224 auto valuesBounds
225 = dataSeries->valuesBounds(variable->range().m_TStart, variable->range().m_TEnd);
226 auto end = dataSeries->cend();
227 if (valuesBounds.first != end && valuesBounds.second != end) {
228 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
229
230 auto minValue = rangeValue(valuesBounds.first->minValue());
231 auto maxValue = rangeValue(valuesBounds.second->maxValue());
232
233 graphWidget->setYRange(SqpRange{minValue, maxValue});
234 }
235 dataSeries->unlock();
236 }
237
238 return graphWidget;
239 }
240
241 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
242 {
243 if (visitor) {
244 visitor->visitEnter(this);
245
246 // Apply visitor to graph children: widgets different from graphs are not visited (no
247 // action)
248 processGraphs(
249 *ui->visualizationZoneFrame->layout(),
250 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
251
252 visitor->visitLeave(this);
253 }
254 else {
255 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
256 }
257 }
258
259 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
260 {
261 // A tab can always accomodate a variable
262 Q_UNUSED(variable);
263 return true;
264 }
265
266 bool VisualizationZoneWidget::contains(const Variable &variable) const
267 {
268 Q_UNUSED(variable);
269 return false;
270 }
271
272 QString VisualizationZoneWidget::name() const
273 {
274 return ui->zoneNameLabel->text();
275 }
276
277 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
278 {
279 // Closes graphs in the zone
280 processGraphs(*ui->visualizationZoneFrame->layout(),
281 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
282
283 // Delete synchronization group from variable controller
284 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
285 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
286
287 QWidget::closeEvent(event);
288 }
289
290 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
291 {
292 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
293 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
294 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
295 }
296
297 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
298 {
299 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
300 Q_ARG(std::shared_ptr<Variable>, variable),
301 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
302 }
This diff has been collapsed as it changes many lines, (1350 lines changed) Show them Hide them
@@ -2102,8 +2102,8 bool QCPRange::validRange(const QCPRange &range)
2102 /* end of 'src/axis/range.cpp' */
2102 /* end of 'src/axis/range.cpp' */
2103
2103
2104
2104
2105 /* including file 'src/selection.cpp', size 21906 */
2105 /* including file 'src/selection.cpp', size 21898 */
2106 /* commit 820d2282db70144c358c13433cd74b4175f9252b 2017-07-24 00:24:17 +0200 */
2106 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
2107
2107
2108 ////////////////////////////////////////////////////////////////////////////////////////////////////
2108 ////////////////////////////////////////////////////////////////////////////////////////////////////
2109 //////////////////// QCPDataRange
2109 //////////////////// QCPDataRange
@@ -2406,7 +2406,7 QCPDataSelection &QCPDataSelection::operator+=(const QCPDataRange &other)
2406 }
2406 }
2407
2407
2408 /*!
2408 /*!
2409 Removes all data point indices that are described by \a other from this data selection.
2409 Removes all data point indices that are described by \a other from this data range.
2410 */
2410 */
2411 QCPDataSelection &QCPDataSelection::operator-=(const QCPDataSelection &other)
2411 QCPDataSelection &QCPDataSelection::operator-=(const QCPDataSelection &other)
2412 {
2412 {
@@ -2417,7 +2417,7 QCPDataSelection &QCPDataSelection::operator-=(const QCPDataSelection &other)
2417 }
2417 }
2418
2418
2419 /*!
2419 /*!
2420 Removes all data point indices that are described by \a other from this data selection.
2420 Removes all data point indices that are described by \a other from this data range.
2421 */
2421 */
2422 QCPDataSelection &QCPDataSelection::operator-=(const QCPDataRange &other)
2422 QCPDataSelection &QCPDataSelection::operator-=(const QCPDataRange &other)
2423 {
2423 {
@@ -2930,8 +2930,8 void QCPSelectionRect::draw(QCPPainter *painter)
2930 /* end of 'src/selectionrect.cpp' */
2930 /* end of 'src/selectionrect.cpp' */
2931
2931
2932
2932
2933 /* including file 'src/layout.cpp', size 74663 */
2933 /* including file 'src/layout.cpp', size 74302 */
2934 /* commit a872eb91ec087561efd83dd9cb041a26ab95ce55 2017-07-31 00:21:41 +0200 */
2934 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
2935
2935
2936 ////////////////////////////////////////////////////////////////////////////////////////////////////
2936 ////////////////////////////////////////////////////////////////////////////////////////////////////
2937 //////////////////// QCPMarginGroup
2937 //////////////////// QCPMarginGroup
@@ -3572,13 +3572,12 QCPLayout::QCPLayout()
3572 }
3572 }
3573
3573
3574 /*!
3574 /*!
3575 If \a phase is \ref upLayout, calls \ref updateLayout, which subclasses may reimplement to
3575 First calls the QCPLayoutElement::update base class implementation to update the margins on this
3576 reposition and resize their cells.
3576 layout.
3577
3577
3578 Finally, the call is propagated down to all child \ref QCPLayoutElement "QCPLayoutElements".
3578 Then calls \ref updateLayout which subclasses reimplement to reposition and resize their cells.
3579
3579
3580 For details about this method and the update phases, see the documentation of \ref
3580 Finally, \ref update is called on all child elements.
3581 QCPLayoutElement::update.
3582 */
3581 */
3583 void QCPLayout::update(UpdatePhase phase)
3582 void QCPLayout::update(UpdatePhase phase)
3584 {
3583 {
@@ -4243,7 +4242,7 void QCPLayoutGrid::setWrap(int count)
4243
4242
4244 If you want to have all current elements arranged in the new order, set \a rearrange to true. The
4243 If you want to have all current elements arranged in the new order, set \a rearrange to true. The
4245 elements will be rearranged in a way that tries to preserve their linear index. However, empty
4244 elements will be rearranged in a way that tries to preserve their linear index. However, empty
4246 cells are skipped during build-up of the new cell order, which shifts the succeeding element's
4245 cells are skipped during build-up of the new cell order, which shifts the succeding element's
4247 index. The rearranging is performed even if the specified \a order is already the current fill
4246 index. The rearranging is performed even if the specified \a order is already the current fill
4248 order. Thus this method can be used to re-wrap the current elements.
4247 order. Thus this method can be used to re-wrap the current elements.
4249
4248
@@ -4338,8 +4337,7 void QCPLayoutGrid::insertRow(int newIndex)
4338
4337
4339 /*!
4338 /*!
4340 Inserts a new column with empty cells at the column index \a newIndex. Valid values for \a
4339 Inserts a new column with empty cells at the column index \a newIndex. Valid values for \a
4341 newIndex range from 0 (inserts a column at the left) to \a columnCount (appends a column at the
4340 newIndex range from 0 (inserts a row at the left) to \a rowCount (appends a row at the right).
4342 right).
4343
4341
4344 \see insertRow
4342 \see insertRow
4345 */
4343 */
@@ -4413,9 +4411,7 void QCPLayoutGrid::indexToRowCol(int index, int &row, int &column) const
4413 {
4411 {
4414 row = -1;
4412 row = -1;
4415 column = -1;
4413 column = -1;
4416 const int nCols = columnCount();
4414 if (columnCount() == 0 || rowCount() == 0)
4417 const int nRows = rowCount();
4418 if (nCols == 0 || nRows == 0)
4419 return;
4415 return;
4420 if (index < 0 || index >= elementCount()) {
4416 if (index < 0 || index >= elementCount()) {
4421 qDebug() << Q_FUNC_INFO << "index out of bounds:" << index;
4417 qDebug() << Q_FUNC_INFO << "index out of bounds:" << index;
@@ -4424,13 +4420,13 void QCPLayoutGrid::indexToRowCol(int index, int &row, int &column) const
4424
4420
4425 switch (mFillOrder) {
4421 switch (mFillOrder) {
4426 case foRowsFirst: {
4422 case foRowsFirst: {
4427 column = index / nRows;
4423 column = index / rowCount();
4428 row = index % nRows;
4424 row = index % rowCount();
4429 break;
4425 break;
4430 }
4426 }
4431 case foColumnsFirst: {
4427 case foColumnsFirst: {
4432 row = index / nCols;
4428 row = index / columnCount();
4433 column = index % nCols;
4429 column = index % columnCount();
4434 break;
4430 break;
4435 }
4431 }
4436 }
4432 }
@@ -4596,8 +4592,9 QSize QCPLayoutGrid::minimumSizeHint() const
4596 result.rwidth() += minColWidths.at(i);
4592 result.rwidth() += minColWidths.at(i);
4597 for (int i = 0; i < minRowHeights.size(); ++i)
4593 for (int i = 0; i < minRowHeights.size(); ++i)
4598 result.rheight() += minRowHeights.at(i);
4594 result.rheight() += minRowHeights.at(i);
4599 result.rwidth() += qMax(0, columnCount() - 1) * mColumnSpacing;
4595 result.rwidth()
4600 result.rheight() += qMax(0, rowCount() - 1) * mRowSpacing;
4596 += qMax(0, columnCount() - 1) * mColumnSpacing + mMargins.left() + mMargins.right();
4597 result.rheight() += qMax(0, rowCount() - 1) * mRowSpacing + mMargins.top() + mMargins.bottom();
4601 return result;
4598 return result;
4602 }
4599 }
4603
4600
@@ -4612,8 +4609,9 QSize QCPLayoutGrid::maximumSizeHint() const
4612 result.setWidth(qMin(result.width() + maxColWidths.at(i), QWIDGETSIZE_MAX));
4609 result.setWidth(qMin(result.width() + maxColWidths.at(i), QWIDGETSIZE_MAX));
4613 for (int i = 0; i < maxRowHeights.size(); ++i)
4610 for (int i = 0; i < maxRowHeights.size(); ++i)
4614 result.setHeight(qMin(result.height() + maxRowHeights.at(i), QWIDGETSIZE_MAX));
4611 result.setHeight(qMin(result.height() + maxRowHeights.at(i), QWIDGETSIZE_MAX));
4615 result.rwidth() += qMax(0, columnCount() - 1) * mColumnSpacing;
4612 result.rwidth()
4616 result.rheight() += qMax(0, rowCount() - 1) * mRowSpacing;
4613 += qMax(0, columnCount() - 1) * mColumnSpacing + mMargins.left() + mMargins.right();
4614 result.rheight() += qMax(0, rowCount() - 1) * mRowSpacing + mMargins.top() + mMargins.bottom();
4617 return result;
4615 return result;
4618 }
4616 }
4619
4617
@@ -4622,9 +4620,8 QSize QCPLayoutGrid::maximumSizeHint() const
4622 Places the minimum column widths and row heights into \a minColWidths and \a minRowHeights
4620 Places the minimum column widths and row heights into \a minColWidths and \a minRowHeights
4623 respectively.
4621 respectively.
4624
4622
4625 The minimum height of a row is the largest minimum height of any element's outer rect in that
4623 The minimum height of a row is the largest minimum height of any element in that row. The minimum
4626 row. The minimum width of a column is the largest minimum width of any element's outer rect in
4624 width of a column is the largest minimum width of any element in that column.
4627 that column.
4628
4625
4629 This is a helper function for \ref updateLayout.
4626 This is a helper function for \ref updateLayout.
4630
4627
@@ -4637,13 +4634,11 void QCPLayoutGrid::getMinimumRowColSizes(QVector<int> *minColWidths,
4637 *minRowHeights = QVector<int>(rowCount(), 0);
4634 *minRowHeights = QVector<int>(rowCount(), 0);
4638 for (int row = 0; row < rowCount(); ++row) {
4635 for (int row = 0; row < rowCount(); ++row) {
4639 for (int col = 0; col < columnCount(); ++col) {
4636 for (int col = 0; col < columnCount(); ++col) {
4640 if (QCPLayoutElement *el = mElements.at(row).at(col)) {
4637 if (mElements.at(row).at(col)) {
4641 QSize minHint = el->minimumSizeHint();
4638 QSize minHint = mElements.at(row).at(col)->minimumSizeHint();
4642 QSize min = el->minimumSize();
4639 QSize min = mElements.at(row).at(col)->minimumSize();
4643 QSize final(min.width() > 0 ? min.width() : minHint.width(),
4640 QSize final(min.width() > 0 ? min.width() : minHint.width(),
4644 min.height() > 0 ? min.height() : minHint.height());
4641 min.height() > 0 ? min.height() : minHint.height());
4645 final += QSize(el->margins().left() + el->margins().right(),
4646 el->margins().top() + el->margins().bottom());
4647 if (minColWidths->at(col) < final.width())
4642 if (minColWidths->at(col) < final.width())
4648 (*minColWidths)[col] = final.width();
4643 (*minColWidths)[col] = final.width();
4649 if (minRowHeights->at(row) < final.height())
4644 if (minRowHeights->at(row) < final.height())
@@ -4658,9 +4653,8 void QCPLayoutGrid::getMinimumRowColSizes(QVector<int> *minColWidths,
4658 Places the maximum column widths and row heights into \a maxColWidths and \a maxRowHeights
4653 Places the maximum column widths and row heights into \a maxColWidths and \a maxRowHeights
4659 respectively.
4654 respectively.
4660
4655
4661 The maximum height of a row is the smallest maximum height of any element's outer rect in that
4656 The maximum height of a row is the smallest maximum height of any element in that row. The
4662 row. The maximum width of a column is the smallest maximum width of any element's outer rect in
4657 maximum width of a column is the smallest maximum width of any element in that column.
4663 that column.
4664
4658
4665 This is a helper function for \ref updateLayout.
4659 This is a helper function for \ref updateLayout.
4666
4660
@@ -4673,13 +4667,11 void QCPLayoutGrid::getMaximumRowColSizes(QVector<int> *maxColWidths,
4673 *maxRowHeights = QVector<int>(rowCount(), QWIDGETSIZE_MAX);
4667 *maxRowHeights = QVector<int>(rowCount(), QWIDGETSIZE_MAX);
4674 for (int row = 0; row < rowCount(); ++row) {
4668 for (int row = 0; row < rowCount(); ++row) {
4675 for (int col = 0; col < columnCount(); ++col) {
4669 for (int col = 0; col < columnCount(); ++col) {
4676 if (QCPLayoutElement *el = mElements.at(row).at(col)) {
4670 if (mElements.at(row).at(col)) {
4677 QSize maxHint = el->maximumSizeHint();
4671 QSize maxHint = mElements.at(row).at(col)->maximumSizeHint();
4678 QSize max = el->maximumSize();
4672 QSize max = mElements.at(row).at(col)->maximumSize();
4679 QSize final(max.width() < QWIDGETSIZE_MAX ? max.width() : maxHint.width(),
4673 QSize final(max.width() < QWIDGETSIZE_MAX ? max.width() : maxHint.width(),
4680 max.height() < QWIDGETSIZE_MAX ? max.height() : maxHint.height());
4674 max.height() < QWIDGETSIZE_MAX ? max.height() : maxHint.height());
4681 final += QSize(el->margins().left() + el->margins().right(),
4682 el->margins().top() + el->margins().bottom());
4683 if (maxColWidths->at(col) > final.width())
4675 if (maxColWidths->at(col) > final.width())
4684 (*maxColWidths)[col] = final.width();
4676 (*maxColWidths)[col] = final.width();
4685 if (maxRowHeights->at(row) > final.height())
4677 if (maxRowHeights->at(row) > final.height())
@@ -4828,25 +4820,22 void QCPLayoutInset::setInsetRect(int index, const QRectF &rect)
4828 void QCPLayoutInset::updateLayout()
4820 void QCPLayoutInset::updateLayout()
4829 {
4821 {
4830 for (int i = 0; i < mElements.size(); ++i) {
4822 for (int i = 0; i < mElements.size(); ++i) {
4831 QCPLayoutElement *el = mElements.at(i);
4832 QRect insetRect;
4823 QRect insetRect;
4833 QSize finalMinSize, finalMaxSize;
4824 QSize finalMinSize, finalMaxSize;
4834 QSize minSizeHint = el->minimumSizeHint();
4825 QSize minSizeHint = mElements.at(i)->minimumSizeHint();
4835 QSize maxSizeHint = el->maximumSizeHint();
4826 QSize maxSizeHint = mElements.at(i)->maximumSizeHint();
4836 finalMinSize.setWidth(el->minimumSize().width() > 0 ? el->minimumSize().width()
4827 finalMinSize.setWidth(mElements.at(i)->minimumSize().width() > 0
4837 : minSizeHint.width());
4828 ? mElements.at(i)->minimumSize().width()
4838 finalMinSize.setHeight(el->minimumSize().height() > 0 ? el->minimumSize().height()
4829 : minSizeHint.width());
4839 : minSizeHint.height());
4830 finalMinSize.setHeight(mElements.at(i)->minimumSize().height() > 0
4840 finalMaxSize.setWidth(el->maximumSize().width() < QWIDGETSIZE_MAX
4831 ? mElements.at(i)->minimumSize().height()
4841 ? el->maximumSize().width()
4832 : minSizeHint.height());
4833 finalMaxSize.setWidth(mElements.at(i)->maximumSize().width() < QWIDGETSIZE_MAX
4834 ? mElements.at(i)->maximumSize().width()
4842 : maxSizeHint.width());
4835 : maxSizeHint.width());
4843 finalMaxSize.setHeight(el->maximumSize().height() < QWIDGETSIZE_MAX
4836 finalMaxSize.setHeight(mElements.at(i)->maximumSize().height() < QWIDGETSIZE_MAX
4844 ? el->maximumSize().height()
4837 ? mElements.at(i)->maximumSize().height()
4845 : maxSizeHint.height());
4838 : maxSizeHint.height());
4846 finalMinSize += QSize(el->margins().left() + el->margins().right(),
4847 el->margins().top() + el->margins().bottom());
4848 finalMaxSize += QSize(el->margins().left() + el->margins().right(),
4849 el->margins().top() + el->margins().bottom());
4850 if (mInsetPlacement.at(i) == ipFree) {
4839 if (mInsetPlacement.at(i) == ipFree) {
4851 insetRect = QRect(rect().x() + rect().width() * mInsetRect.at(i).x(),
4840 insetRect = QRect(rect().x() + rect().width() * mInsetRect.at(i).x(),
4852 rect().y() + rect().height() * mInsetRect.at(i).y(),
4841 rect().y() + rect().height() * mInsetRect.at(i).y(),
@@ -7161,8 +7150,8 QVector<double> QCPAxisTickerLog::createTickVector(double tickStep, const QCPRan
7161 /* end of 'src/axis/axistickerlog.cpp' */
7150 /* end of 'src/axis/axistickerlog.cpp' */
7162
7151
7163
7152
7164 /* including file 'src/axis/axis.cpp', size 99397 */
7153 /* including file 'src/axis/axis.cpp', size 94458 */
7165 /* commit 0cc4d9f61f7bf45321a88fec89d909b020ffa26f 2017-08-14 00:43:29 +0200 */
7154 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
7166
7155
7167
7156
7168 ////////////////////////////////////////////////////////////////////////////////////////////////////
7157 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -8654,11 +8643,11 double QCPAxis::coordToPixel(double value) const
8654 }
8643 }
8655 else // mScaleType == stLogarithmic
8644 else // mScaleType == stLogarithmic
8656 {
8645 {
8657 if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just
8646 if (value >= 0 && mRange.upper < 0) // invalid value for logarithmic scale, just draw it
8658 // draw it outside visible range
8647 // outside visible range
8659 return !mRangeReversed ? mAxisRect->right() + 200 : mAxisRect->left() - 200;
8648 return !mRangeReversed ? mAxisRect->right() + 200 : mAxisRect->left() - 200;
8660 else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale,
8649 else if (value <= 0 && mRange.upper > 0) // invalid value for logarithmic scale, just
8661 // just draw it outside visible range
8650 // draw it outside visible range
8662 return !mRangeReversed ? mAxisRect->left() - 200 : mAxisRect->right() + 200;
8651 return !mRangeReversed ? mAxisRect->left() - 200 : mAxisRect->right() + 200;
8663 else {
8652 else {
8664 if (!mRangeReversed)
8653 if (!mRangeReversed)
@@ -8684,11 +8673,11 double QCPAxis::coordToPixel(double value) const
8684 }
8673 }
8685 else // mScaleType == stLogarithmic
8674 else // mScaleType == stLogarithmic
8686 {
8675 {
8687 if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just
8676 if (value >= 0 && mRange.upper < 0) // invalid value for logarithmic scale, just draw it
8688 // draw it outside visible range
8677 // outside visible range
8689 return !mRangeReversed ? mAxisRect->top() - 200 : mAxisRect->bottom() + 200;
8678 return !mRangeReversed ? mAxisRect->top() - 200 : mAxisRect->bottom() + 200;
8690 else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale,
8679 else if (value <= 0 && mRange.upper > 0) // invalid value for logarithmic scale, just
8691 // just draw it outside visible range
8680 // draw it outside visible range
8692 return !mRangeReversed ? mAxisRect->bottom() + 200 : mAxisRect->top() - 200;
8681 return !mRangeReversed ? mAxisRect->bottom() + 200 : mAxisRect->top() - 200;
8693 else {
8682 else {
8694 if (!mRangeReversed)
8683 if (!mRangeReversed)
@@ -8879,132 +8868,6 void QCPAxis::deselectEvent(bool *selectionStateChanged)
8879
8868
8880 /*! \internal
8869 /*! \internal
8881
8870
8882 This mouse event reimplementation provides the functionality to let the user drag individual axes
8883 exclusively, by startig the drag on top of the axis.
8884
8885 For the axis to accept this event and perform the single axis drag, the parent \ref QCPAxisRect
8886 must be configured accordingly, i.e. it must allow range dragging in the orientation of this axis
8887 (\ref QCPAxisRect::setRangeDrag) and this axis must be a draggable axis (\ref
8888 QCPAxisRect::setRangeDragAxes)
8889
8890 \seebaseclassmethod
8891
8892 \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis
8893 rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent.
8894 */
8895 void QCPAxis::mousePressEvent(QMouseEvent *event, const QVariant &details)
8896 {
8897 Q_UNUSED(details)
8898 if (!mParentPlot->interactions().testFlag(QCP::iRangeDrag)
8899 || !mAxisRect->rangeDrag().testFlag(orientation())
8900 || !mAxisRect->rangeDragAxes(orientation()).contains(this)) {
8901 event->ignore();
8902 return;
8903 }
8904
8905 if (event->buttons() & Qt::LeftButton) {
8906 mDragging = true;
8907 // initialize antialiasing backup in case we start dragging:
8908 if (mParentPlot->noAntialiasingOnDrag()) {
8909 mAADragBackup = mParentPlot->antialiasedElements();
8910 mNotAADragBackup = mParentPlot->notAntialiasedElements();
8911 }
8912 // Mouse range dragging interaction:
8913 if (mParentPlot->interactions().testFlag(QCP::iRangeDrag))
8914 mDragStartRange = mRange;
8915 }
8916 }
8917
8918 /*! \internal
8919
8920 This mouse event reimplementation provides the functionality to let the user drag individual axes
8921 exclusively, by startig the drag on top of the axis.
8922
8923 \seebaseclassmethod
8924
8925 \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis
8926 rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent.
8927
8928 \see QCPAxis::mousePressEvent
8929 */
8930 void QCPAxis::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
8931 {
8932 if (mDragging) {
8933 const double startPixel = orientation() == Qt::Horizontal ? startPos.x() : startPos.y();
8934 const double currentPixel
8935 = orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y();
8936 if (mScaleType == QCPAxis::stLinear) {
8937 const double diff = pixelToCoord(startPixel) - pixelToCoord(currentPixel);
8938 setRange(mDragStartRange.lower + diff, mDragStartRange.upper + diff);
8939 }
8940 else if (mScaleType == QCPAxis::stLogarithmic) {
8941 const double diff = pixelToCoord(startPixel) / pixelToCoord(currentPixel);
8942 setRange(mDragStartRange.lower * diff, mDragStartRange.upper * diff);
8943 }
8944
8945 if (mParentPlot->noAntialiasingOnDrag())
8946 mParentPlot->setNotAntialiasedElements(QCP::aeAll);
8947 mParentPlot->replot(QCustomPlot::rpQueuedReplot);
8948 }
8949 }
8950
8951 /*! \internal
8952
8953 This mouse event reimplementation provides the functionality to let the user drag individual axes
8954 exclusively, by startig the drag on top of the axis.
8955
8956 \seebaseclassmethod
8957
8958 \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis
8959 rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent.
8960
8961 \see QCPAxis::mousePressEvent
8962 */
8963 void QCPAxis::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos)
8964 {
8965 Q_UNUSED(event)
8966 Q_UNUSED(startPos)
8967 mDragging = false;
8968 if (mParentPlot->noAntialiasingOnDrag()) {
8969 mParentPlot->setAntialiasedElements(mAADragBackup);
8970 mParentPlot->setNotAntialiasedElements(mNotAADragBackup);
8971 }
8972 }
8973
8974 /*! \internal
8975
8976 This mouse event reimplementation provides the functionality to let the user zoom individual axes
8977 exclusively, by performing the wheel event on top of the axis.
8978
8979 For the axis to accept this event and perform the single axis zoom, the parent \ref QCPAxisRect
8980 must be configured accordingly, i.e. it must allow range zooming in the orientation of this axis
8981 (\ref QCPAxisRect::setRangeZoom) and this axis must be a zoomable axis (\ref
8982 QCPAxisRect::setRangeZoomAxes)
8983
8984 \seebaseclassmethod
8985
8986 \note The zooming of possibly multiple axes at once by performing the wheel event anywhere in the
8987 axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::wheelEvent.
8988 */
8989 void QCPAxis::wheelEvent(QWheelEvent *event)
8990 {
8991 // Mouse range zooming interaction:
8992 if (!mParentPlot->interactions().testFlag(QCP::iRangeZoom)
8993 || !mAxisRect->rangeZoom().testFlag(orientation())
8994 || !mAxisRect->rangeZoomAxes(orientation()).contains(this)) {
8995 event->ignore();
8996 return;
8997 }
8998
8999 const double wheelSteps = event->delta() / 120.0; // a single step delta is +/-120 usually
9000 const double factor = qPow(mAxisRect->rangeZoomFactor(orientation()), wheelSteps);
9001 scaleRange(factor,
9002 pixelToCoord(orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y()));
9003 mParentPlot->replot();
9004 }
9005
9006 /*! \internal
9007
9008 A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter
8871 A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter
9009 before drawing axis lines.
8872 before drawing axis lines.
9010
8873
@@ -9661,15 +9524,12 void QCPAxisPainterPrivate::placeTickLabel(QCPPainter *painter, double position,
9661 cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()
9524 cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()
9662 * mParentPlot->bufferDevicePixelRatio());
9525 * mParentPlot->bufferDevicePixelRatio());
9663 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
9526 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
9664 #ifdef QCP_DEVICEPIXELRATIO_FLOAT
9665 cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatioF());
9666 #else
9667 cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatio());
9527 cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatio());
9668 #endif
9528 #endif
9669 #endif
9670 }
9529 }
9671 else
9530 else
9672 cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size());
9531 cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size());
9532 cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size());
9673 cachedLabel->pixmap.fill(Qt::transparent);
9533 cachedLabel->pixmap.fill(Qt::transparent);
9674 QCPPainter cachePainter(&cachedLabel->pixmap);
9534 QCPPainter cachePainter(&cachedLabel->pixmap);
9675 cachePainter.setPen(painter->pen());
9535 cachePainter.setPen(painter->pen());
@@ -10034,8 +9894,8 void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString
10034 /* end of 'src/axis/axis.cpp' */
9894 /* end of 'src/axis/axis.cpp' */
10035
9895
10036
9896
10037 /* including file 'src/scatterstyle.cpp', size 17450 */
9897 /* including file 'src/scatterstyle.cpp', size 17420 */
10038 /* commit 820d2282db70144c358c13433cd74b4175f9252b 2017-07-24 00:24:17 +0200 */
9898 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
10039
9899
10040 ////////////////////////////////////////////////////////////////////////////////////////////////////
9900 ////////////////////////////////////////////////////////////////////////////////////////////////////
10041 //////////////////// QCPScatterStyle
9901 //////////////////// QCPScatterStyle
@@ -10205,8 +10065,8 QCPScatterStyle::QCPScatterStyle(const QPixmap &pixmap)
10205
10065
10206 The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly
10066 The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly
10207 different meaning than for built-in scatter points: The custom path will be drawn scaled by a
10067 different meaning than for built-in scatter points: The custom path will be drawn scaled by a
10208 factor of \a size/6.0. Since the default \a size is 6, the custom path will appear in its
10068 factor of \a size/6.0. Since the default \a size is 6, the custom path will appear at a its
10209 original size by default. To for example double the size of the path, set \a size to 12.
10069 natural size by default. To double the size of the path for example, set \a size to 12.
10210 */
10070 */
10211 QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen,
10071 QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen,
10212 const QBrush &brush, double size)
10072 const QBrush &brush, double size)
@@ -10393,9 +10253,10 void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const
10393 break;
10253 break;
10394 }
10254 }
10395 case ssDiamond: {
10255 case ssDiamond: {
10396 QPointF lineArray[4]
10256 painter->drawLine(QLineF(x - w, y, x, y - w));
10397 = {QPointF(x - w, y), QPointF(x, y - w), QPointF(x + w, y), QPointF(x, y + w)};
10257 painter->drawLine(QLineF(x, y - w, x + w, y));
10398 painter->drawPolygon(lineArray, 4);
10258 painter->drawLine(QLineF(x + w, y, x, y + w));
10259 painter->drawLine(QLineF(x, y + w, x - w, y));
10399 break;
10260 break;
10400 }
10261 }
10401 case ssStar: {
10262 case ssStar: {
@@ -10406,46 +10267,46 void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const
10406 break;
10267 break;
10407 }
10268 }
10408 case ssTriangle: {
10269 case ssTriangle: {
10409 QPointF lineArray[3] = {QPointF(x - w, y + 0.755 * w), QPointF(x + w, y + 0.755 * w),
10270 painter->drawLine(QLineF(x - w, y + 0.755 * w, x + w, y + 0.755 * w));
10410 QPointF(x, y - 0.977 * w)};
10271 painter->drawLine(QLineF(x + w, y + 0.755 * w, x, y - 0.977 * w));
10411 painter->drawPolygon(lineArray, 3);
10272 painter->drawLine(QLineF(x, y - 0.977 * w, x - w, y + 0.755 * w));
10412 break;
10273 break;
10413 }
10274 }
10414 case ssTriangleInverted: {
10275 case ssTriangleInverted: {
10415 QPointF lineArray[3] = {QPointF(x - w, y - 0.755 * w), QPointF(x + w, y - 0.755 * w),
10276 painter->drawLine(QLineF(x - w, y - 0.755 * w, x + w, y - 0.755 * w));
10416 QPointF(x, y + 0.977 * w)};
10277 painter->drawLine(QLineF(x + w, y - 0.755 * w, x, y + 0.977 * w));
10417 painter->drawPolygon(lineArray, 3);
10278 painter->drawLine(QLineF(x, y + 0.977 * w, x - w, y - 0.755 * w));
10418 break;
10279 break;
10419 }
10280 }
10420 case ssCrossSquare: {
10281 case ssCrossSquare: {
10421 painter->drawRect(QRectF(x - w, y - w, mSize, mSize));
10422 painter->drawLine(QLineF(x - w, y - w, x + w * 0.95, y + w * 0.95));
10282 painter->drawLine(QLineF(x - w, y - w, x + w * 0.95, y + w * 0.95));
10423 painter->drawLine(QLineF(x - w, y + w * 0.95, x + w * 0.95, y - w));
10283 painter->drawLine(QLineF(x - w, y + w * 0.95, x + w * 0.95, y - w));
10284 painter->drawRect(QRectF(x - w, y - w, mSize, mSize));
10424 break;
10285 break;
10425 }
10286 }
10426 case ssPlusSquare: {
10287 case ssPlusSquare: {
10427 painter->drawRect(QRectF(x - w, y - w, mSize, mSize));
10428 painter->drawLine(QLineF(x - w, y, x + w * 0.95, y));
10288 painter->drawLine(QLineF(x - w, y, x + w * 0.95, y));
10429 painter->drawLine(QLineF(x, y + w, x, y - w));
10289 painter->drawLine(QLineF(x, y + w, x, y - w));
10290 painter->drawRect(QRectF(x - w, y - w, mSize, mSize));
10430 break;
10291 break;
10431 }
10292 }
10432 case ssCrossCircle: {
10293 case ssCrossCircle: {
10433 painter->drawEllipse(QPointF(x, y), w, w);
10434 painter->drawLine(QLineF(x - w * 0.707, y - w * 0.707, x + w * 0.670, y + w * 0.670));
10294 painter->drawLine(QLineF(x - w * 0.707, y - w * 0.707, x + w * 0.670, y + w * 0.670));
10435 painter->drawLine(QLineF(x - w * 0.707, y + w * 0.670, x + w * 0.670, y - w * 0.707));
10295 painter->drawLine(QLineF(x - w * 0.707, y + w * 0.670, x + w * 0.670, y - w * 0.707));
10296 painter->drawEllipse(QPointF(x, y), w, w);
10436 break;
10297 break;
10437 }
10298 }
10438 case ssPlusCircle: {
10299 case ssPlusCircle: {
10439 painter->drawEllipse(QPointF(x, y), w, w);
10440 painter->drawLine(QLineF(x - w, y, x + w, y));
10300 painter->drawLine(QLineF(x - w, y, x + w, y));
10441 painter->drawLine(QLineF(x, y + w, x, y - w));
10301 painter->drawLine(QLineF(x, y + w, x, y - w));
10302 painter->drawEllipse(QPointF(x, y), w, w);
10442 break;
10303 break;
10443 }
10304 }
10444 case ssPeace: {
10305 case ssPeace: {
10445 painter->drawEllipse(QPointF(x, y), w, w);
10446 painter->drawLine(QLineF(x, y - w, x, y + w));
10306 painter->drawLine(QLineF(x, y - w, x, y + w));
10447 painter->drawLine(QLineF(x, y, x - w * 0.707, y + w * 0.707));
10307 painter->drawLine(QLineF(x, y, x - w * 0.707, y + w * 0.707));
10448 painter->drawLine(QLineF(x, y, x + w * 0.707, y + w * 0.707));
10308 painter->drawLine(QLineF(x, y, x + w * 0.707, y + w * 0.707));
10309 painter->drawEllipse(QPointF(x, y), w, w);
10449 break;
10310 break;
10450 }
10311 }
10451 case ssPixmap: {
10312 case ssPixmap: {
@@ -10476,8 +10337,8 void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const
10476
10337
10477 // amalgamation: add datacontainer.cpp
10338 // amalgamation: add datacontainer.cpp
10478
10339
10479 /* including file 'src/plottable.cpp', size 38845 */
10340 /* including file 'src/plottable.cpp', size 38861 */
10480 /* commit b0bed12626f942821097f43091126b6fb7163122 2017-08-13 17:17:33 +0200 */
10341 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
10481
10342
10482 ////////////////////////////////////////////////////////////////////////////////////////////////////
10343 ////////////////////////////////////////////////////////////////////////////////////////////////////
10483 //////////////////// QCPSelectionDecorator
10344 //////////////////// QCPSelectionDecorator
@@ -10515,8 +10376,8 void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const
10515 QCPSelectionDecorator::QCPSelectionDecorator()
10376 QCPSelectionDecorator::QCPSelectionDecorator()
10516 : mPen(QColor(80, 80, 255), 2.5),
10377 : mPen(QColor(80, 80, 255), 2.5),
10517 mBrush(Qt::NoBrush),
10378 mBrush(Qt::NoBrush),
10518 mScatterStyle(),
10379 mScatterStyle(QCPScatterStyle::ssNone, QPen(Qt::blue, 2), Qt::NoBrush, 6.0),
10519 mUsedScatterProperties(QCPScatterStyle::spNone),
10380 mUsedScatterProperties(QCPScatterStyle::spPen),
10520 mPlottable(0)
10381 mPlottable(0)
10521 {
10382 {
10522 }
10383 }
@@ -10559,8 +10420,6 void QCPSelectionDecorator::setScatterStyle(const QCPScatterStyle &scatterStyle,
10559 Use this method to define which properties of the scatter style (set via \ref setScatterStyle)
10420 Use this method to define which properties of the scatter style (set via \ref setScatterStyle)
10560 will be used for selected data segments. All properties of the scatter style that are not
10421 will be used for selected data segments. All properties of the scatter style that are not
10561 specified in \a properties will remain as specified in the plottable's original scatter style.
10422 specified in \a properties will remain as specified in the plottable's original scatter style.
10562
10563 \see QCPScatterStyle::ScatterProperty
10564 */
10423 */
10565 void QCPSelectionDecorator::setUsedScatterProperties(
10424 void QCPSelectionDecorator::setUsedScatterProperties(
10566 const QCPScatterStyle::ScatterProperties &properties)
10425 const QCPScatterStyle::ScatterProperties &properties)
@@ -12765,8 +12624,8 QCP::Interaction QCPAbstractItem::selectionCategory() const
12765 /* end of 'src/item.cpp' */
12624 /* end of 'src/item.cpp' */
12766
12625
12767
12626
12768 /* including file 'src/core.cpp', size 125027 */
12627 /* including file 'src/core.cpp', size 124243 */
12769 /* commit 9ede7553208db59867d1ea9f1988cd90e3c7ffed 2017-08-13 17:25:24 +0200 */
12628 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
12770
12629
12771 ////////////////////////////////////////////////////////////////////////////////////////////////////
12630 ////////////////////////////////////////////////////////////////////////////////////////////////////
12772 //////////////////// QCustomPlot
12631 //////////////////// QCustomPlot
@@ -13110,7 +12969,6 QCustomPlot::QCustomPlot(QWidget *parent)
13110 mOpenGl(false),
12969 mOpenGl(false),
13111 mMouseHasMoved(false),
12970 mMouseHasMoved(false),
13112 mMouseEventLayerable(0),
12971 mMouseEventLayerable(0),
13113 mMouseSignalLayerable(0),
13114 mReplotting(false),
12972 mReplotting(false),
13115 mReplotQueued(false),
12973 mReplotQueued(false),
13116 mOpenGlMultisamples(16),
12974 mOpenGlMultisamples(16),
@@ -13125,12 +12983,8 QCustomPlot::QCustomPlot(QWidget *parent)
13125 currentLocale.setNumberOptions(QLocale::OmitGroupSeparator);
12983 currentLocale.setNumberOptions(QLocale::OmitGroupSeparator);
13126 setLocale(currentLocale);
12984 setLocale(currentLocale);
13127 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
12985 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
13128 #ifdef QCP_DEVICEPIXELRATIO_FLOAT
13129 setBufferDevicePixelRatio(QWidget::devicePixelRatioF());
13130 #else
13131 setBufferDevicePixelRatio(QWidget::devicePixelRatio());
12986 setBufferDevicePixelRatio(QWidget::devicePixelRatio());
13132 #endif
12987 #endif
13133 #endif
13134
12988
13135 mOpenGlAntialiasedElementsBackup = mAntialiasedElements;
12989 mOpenGlAntialiasedElementsBackup = mAntialiasedElements;
13136 mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels);
12990 mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels);
@@ -13532,10 +13386,6 void QCustomPlot::setSelectionRect(QCPSelectionRect *selectionRect)
13532 }
13386 }
13533
13387
13534 /*!
13388 /*!
13535 \warning This is still an experimental feature and its performance depends on the system that it
13536 runs on. Having multiple QCustomPlot widgets in one application with enabled OpenGL rendering
13537 might cause context conflicts on some systems.
13538
13539 This method allows to enable OpenGL plot rendering, for increased plotting performance of
13389 This method allows to enable OpenGL plot rendering, for increased plotting performance of
13540 graphically demanding plots (thick lines, translucent fills, etc.).
13390 graphically demanding plots (thick lines, translucent fills, etc.).
13541
13391
@@ -15084,20 +14934,12 void QCustomPlot::mousePressEvent(QMouseEvent *event)
15084 mSelectionRect->startSelection(event);
14934 mSelectionRect->startSelection(event);
15085 }
14935 }
15086 else {
14936 else {
15087 // no selection rect interaction, prepare for click signal emission and forward event to
14937 // no selection rect interaction, so forward event to layerable under the cursor:
15088 // layerable under the cursor:
15089 QList<QVariant> details;
14938 QList<QVariant> details;
15090 QList<QCPLayerable *> candidates = layerableListAt(mMousePressPos, false, &details);
14939 QList<QCPLayerable *> candidates = layerableListAt(mMousePressPos, false, &details);
15091 if (!candidates.isEmpty()) {
15092 mMouseSignalLayerable = candidates.first(); // candidate for signal emission is always
15093 // topmost hit layerable (signal emitted in
15094 // release event)
15095 mMouseSignalLayerableDetails = details.first();
15096 }
15097 // forward event to topmost candidate which accepts the event:
15098 for (int i = 0; i < candidates.size(); ++i) {
14940 for (int i = 0; i < candidates.size(); ++i) {
15099 event->accept(); // default impl of QCPLayerable's mouse events call ignore() on the
14941 event->accept(); // default impl of QCPLayerable's mouse events ignore the event, in
15100 // event, in that case propagate to next candidate in list
14942 // that case propagate to next candidate in list
15101 candidates.at(i)->mousePressEvent(event, details.at(i));
14943 candidates.at(i)->mousePressEvent(event, details.at(i));
15102 if (event->isAccepted()) {
14944 if (event->isAccepted()) {
15103 mMouseEventLayerable = candidates.at(i);
14945 mMouseEventLayerable = candidates.at(i);
@@ -15168,25 +15010,22 void QCustomPlot::mouseReleaseEvent(QMouseEvent *event)
15168 processPointSelection(event);
15010 processPointSelection(event);
15169
15011
15170 // emit specialized click signals of QCustomPlot instance:
15012 // emit specialized click signals of QCustomPlot instance:
15171 if (QCPAbstractPlottable *ap
15013 if (QCPAbstractPlottable *ap = qobject_cast<QCPAbstractPlottable *>(mMouseEventLayerable)) {
15172 = qobject_cast<QCPAbstractPlottable *>(mMouseSignalLayerable)) {
15173 int dataIndex = 0;
15014 int dataIndex = 0;
15174 if (!mMouseSignalLayerableDetails.value<QCPDataSelection>().isEmpty())
15015 if (!mMouseEventLayerableDetails.value<QCPDataSelection>().isEmpty())
15175 dataIndex
15016 dataIndex
15176 = mMouseSignalLayerableDetails.value<QCPDataSelection>().dataRange().begin();
15017 = mMouseEventLayerableDetails.value<QCPDataSelection>().dataRange().begin();
15177 emit plottableClick(ap, dataIndex, event);
15018 emit plottableClick(ap, dataIndex, event);
15178 }
15019 }
15179 else if (QCPAxis *ax = qobject_cast<QCPAxis *>(mMouseSignalLayerable))
15020 else if (QCPAxis *ax = qobject_cast<QCPAxis *>(mMouseEventLayerable))
15180 emit axisClick(ax, mMouseSignalLayerableDetails.value<QCPAxis::SelectablePart>(),
15021 emit axisClick(ax, mMouseEventLayerableDetails.value<QCPAxis::SelectablePart>(), event);
15181 event);
15022 else if (QCPAbstractItem *ai = qobject_cast<QCPAbstractItem *>(mMouseEventLayerable))
15182 else if (QCPAbstractItem *ai = qobject_cast<QCPAbstractItem *>(mMouseSignalLayerable))
15183 emit itemClick(ai, event);
15023 emit itemClick(ai, event);
15184 else if (QCPLegend *lg = qobject_cast<QCPLegend *>(mMouseSignalLayerable))
15024 else if (QCPLegend *lg = qobject_cast<QCPLegend *>(mMouseEventLayerable))
15185 emit legendClick(lg, 0, event);
15025 emit legendClick(lg, 0, event);
15186 else if (QCPAbstractLegendItem *li
15026 else if (QCPAbstractLegendItem *li
15187 = qobject_cast<QCPAbstractLegendItem *>(mMouseSignalLayerable))
15027 = qobject_cast<QCPAbstractLegendItem *>(mMouseEventLayerable))
15188 emit legendClick(li->parentLegend(), li, event);
15028 emit legendClick(li->parentLegend(), li, event);
15189 mMouseSignalLayerable = 0;
15190 }
15029 }
15191
15030
15192 if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the
15031 if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the
@@ -16958,8 +16797,8 QCPSelectionDecoratorBracket::getPixelCoordinates(const QCPPlottableInterface1D
16958 /* end of 'src/selectiondecorator-bracket.cpp' */
16797 /* end of 'src/selectiondecorator-bracket.cpp' */
16959
16798
16960
16799
16961 /* including file 'src/layoutelements/layoutelement-axisrect.cpp', size 47584 */
16800 /* including file 'src/layoutelements/layoutelement-axisrect.cpp', size 47509 */
16962 /* commit 77ba168312f935543fc31d1ae9b4cdcf34aae4f9 2017-08-13 18:29:48 +0200 */
16801 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
16963
16802
16964
16803
16965 ////////////////////////////////////////////////////////////////////////////////////////////////////
16804 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -17213,7 +17052,7 QList<QCPAxis *> QCPAxisRect::axes() const
17213 new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to
17052 new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to
17214 remove an axis, use \ref removeAxis instead of deleting it manually.
17053 remove an axis, use \ref removeAxis instead of deleting it manually.
17215
17054
17216 You may inject QCPAxis instances (or subclasses of QCPAxis) by setting \a axis to an axis that was
17055 You may inject QCPAxis instances (or sublasses of QCPAxis) by setting \a axis to an axis that was
17217 previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership
17056 previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership
17218 of the axis, so you may not delete it afterwards. Further, the \a axis must have been created
17057 of the axis, so you may not delete it afterwards. Further, the \a axis must have been created
17219 with this axis rect as parent and with the same axis type as specified in \a type. If this is not
17058 with this axis rect as parent and with the same axis type as specified in \a type. If this is not
@@ -17326,12 +17165,6 bool QCPAxisRect::removeAxis(QCPAxis *axis)
17326 while (it.hasNext()) {
17165 while (it.hasNext()) {
17327 it.next();
17166 it.next();
17328 if (it.value().contains(axis)) {
17167 if (it.value().contains(axis)) {
17329 if (it.value().first() == axis && it.value().size() > 1) // if removing first axis,
17330 // transfer axis offset to the
17331 // new first axis (which at
17332 // this point is the second
17333 // axis, if it exists)
17334 it.value()[1]->setOffset(axis->offset());
17335 mAxes[it.key()].removeOne(axis);
17168 mAxes[it.key()].removeOne(axis);
17336 if (qobject_cast<QCustomPlot *>(parentPlot())) // make sure this isn't called from
17169 if (qobject_cast<QCustomPlot *>(parentPlot())) // make sure this isn't called from
17337 // QObject dtor when QCustomPlot is
17170 // QObject dtor when QCustomPlot is
@@ -18101,6 +17934,9 void QCPAxisRect::layoutChanged()
18101 void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details)
17934 void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details)
18102 {
17935 {
18103 Q_UNUSED(details)
17936 Q_UNUSED(details)
17937 mDragStart = event->pos(); // need this even when not LeftButton is pressed, to determine in
17938 // releaseEvent whether it was a full click (no position change
17939 // between press and release)
18104 if (event->buttons() & Qt::LeftButton) {
17940 if (event->buttons() & Qt::LeftButton) {
18105 mDragging = true;
17941 mDragging = true;
18106 // initialize antialiasing backup in case we start dragging:
17942 // initialize antialiasing backup in case we start dragging:
@@ -18146,13 +17982,13 void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
18146 break;
17982 break;
18147 if (ax->mScaleType == QCPAxis::stLinear) {
17983 if (ax->mScaleType == QCPAxis::stLinear) {
18148 double diff
17984 double diff
18149 = ax->pixelToCoord(startPos.x()) - ax->pixelToCoord(event->pos().x());
17985 = ax->pixelToCoord(mDragStart.x()) - ax->pixelToCoord(event->pos().x());
18150 ax->setRange(mDragStartHorzRange.at(i).lower + diff,
17986 ax->setRange(mDragStartHorzRange.at(i).lower + diff,
18151 mDragStartHorzRange.at(i).upper + diff);
17987 mDragStartHorzRange.at(i).upper + diff);
18152 }
17988 }
18153 else if (ax->mScaleType == QCPAxis::stLogarithmic) {
17989 else if (ax->mScaleType == QCPAxis::stLogarithmic) {
18154 double diff
17990 double diff
18155 = ax->pixelToCoord(startPos.x()) / ax->pixelToCoord(event->pos().x());
17991 = ax->pixelToCoord(mDragStart.x()) / ax->pixelToCoord(event->pos().x());
18156 ax->setRange(mDragStartHorzRange.at(i).lower * diff,
17992 ax->setRange(mDragStartHorzRange.at(i).lower * diff,
18157 mDragStartHorzRange.at(i).upper * diff);
17993 mDragStartHorzRange.at(i).upper * diff);
18158 }
17994 }
@@ -18168,13 +18004,13 void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
18168 break;
18004 break;
18169 if (ax->mScaleType == QCPAxis::stLinear) {
18005 if (ax->mScaleType == QCPAxis::stLinear) {
18170 double diff
18006 double diff
18171 = ax->pixelToCoord(startPos.y()) - ax->pixelToCoord(event->pos().y());
18007 = ax->pixelToCoord(mDragStart.y()) - ax->pixelToCoord(event->pos().y());
18172 ax->setRange(mDragStartVertRange.at(i).lower + diff,
18008 ax->setRange(mDragStartVertRange.at(i).lower + diff,
18173 mDragStartVertRange.at(i).upper + diff);
18009 mDragStartVertRange.at(i).upper + diff);
18174 }
18010 }
18175 else if (ax->mScaleType == QCPAxis::stLogarithmic) {
18011 else if (ax->mScaleType == QCPAxis::stLogarithmic) {
18176 double diff
18012 double diff
18177 = ax->pixelToCoord(startPos.y()) / ax->pixelToCoord(event->pos().y());
18013 = ax->pixelToCoord(mDragStart.y()) / ax->pixelToCoord(event->pos().y());
18178 ax->setRange(mDragStartVertRange.at(i).lower * diff,
18014 ax->setRange(mDragStartVertRange.at(i).lower * diff,
18179 mDragStartVertRange.at(i).upper * diff);
18015 mDragStartVertRange.at(i).upper * diff);
18180 }
18016 }
@@ -18185,7 +18021,7 void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
18185 {
18021 {
18186 if (mParentPlot->noAntialiasingOnDrag())
18022 if (mParentPlot->noAntialiasingOnDrag())
18187 mParentPlot->setNotAntialiasedElements(QCP::aeAll);
18023 mParentPlot->setNotAntialiasedElements(QCP::aeAll);
18188 mParentPlot->replot(QCustomPlot::rpQueuedReplot);
18024 mParentPlot->replot();
18189 }
18025 }
18190 }
18026 }
18191 }
18027 }
@@ -18246,8 +18082,8 void QCPAxisRect::wheelEvent(QWheelEvent *event)
18246 /* end of 'src/layoutelements/layoutelement-axisrect.cpp' */
18082 /* end of 'src/layoutelements/layoutelement-axisrect.cpp' */
18247
18083
18248
18084
18249 /* including file 'src/layoutelements/layoutelement-legend.cpp', size 30971 */
18085 /* including file 'src/layoutelements/layoutelement-legend.cpp', size 30933 */
18250 /* commit 305808813c9c6451dca8399c2fc66d68ebd24b5e 2017-08-15 23:03:07 +0200 */
18086 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
18251
18087
18252 ////////////////////////////////////////////////////////////////////////////////////////////////////
18088 ////////////////////////////////////////////////////////////////////////////////////////////////////
18253 //////////////////// QCPAbstractLegendItem
18089 //////////////////// QCPAbstractLegendItem
@@ -18450,7 +18286,9 void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged)
18450 QCPLegend::setIconBorderPen and \ref QCPLegend::setIconTextPadding.
18286 QCPLegend::setIconBorderPen and \ref QCPLegend::setIconTextPadding.
18451
18287
18452 The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend
18288 The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend
18453 creates/removes legend items of this type.
18289 creates/removes legend items of this type in the default implementation. However, these functions
18290 may be reimplemented such that a different kind of legend item (e.g a direct subclass of
18291 QCPAbstractLegendItem) is used for that plottable.
18454
18292
18455 Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of
18293 Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of
18456 QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout
18294 QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout
@@ -18557,8 +18395,10 QSize QCPPlottableLegendItem::minimumSizeHint() const
18557 QSize iconSize = mParentLegend->iconSize();
18395 QSize iconSize = mParentLegend->iconSize();
18558 textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip,
18396 textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip,
18559 mPlottable->name());
18397 mPlottable->name());
18560 result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width());
18398 result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width()
18561 result.setHeight(qMax(textRect.height(), iconSize.height()));
18399 + mMargins.left() + mMargins.right());
18400 result.setHeight(qMax(textRect.height(), iconSize.height()) + mMargins.top()
18401 + mMargins.bottom());
18562 return result;
18402 return result;
18563 }
18403 }
18564
18404
@@ -18572,14 +18412,10 QSize QCPPlottableLegendItem::minimumSizeHint() const
18572
18412
18573 A legend is a small box somewhere in the plot which lists plottables with their name and icon.
18413 A legend is a small box somewhere in the plot which lists plottables with their name and icon.
18574
18414
18575 A legend is populated with legend items by calling \ref QCPAbstractPlottable::addToLegend on the
18415 Normally, the legend is populated by calling \ref QCPAbstractPlottable::addToLegend. The
18576 plottable, for which a legend item shall be created. In the case of the main legend (\ref
18416 respective legend item can be removed with \ref QCPAbstractPlottable::removeFromLegend. However,
18577 QCustomPlot::legend), simply adding plottables to the plot while \ref
18417 QCPLegend also offers an interface to add and manipulate legend items directly: \ref item, \ref
18578 QCustomPlot::setAutoAddPlottableToLegend is set to true (the default) creates corresponding
18418 itemWithPlottable, \ref itemCount, \ref addItem, \ref removeItem, etc.
18579 legend items. The legend item associated with a certain plottable can be removed with \ref
18580 QCPAbstractPlottable::removeFromLegend. However, QCPLegend also offers an interface to add and
18581 manipulate legend items directly: \ref item, \ref itemWithPlottable, \ref itemCount, \ref
18582 addItem, \ref removeItem, etc.
18583
18419
18584 Since \ref QCPLegend derives from \ref QCPLayoutGrid, it can be placed in any position a \ref
18420 Since \ref QCPLegend derives from \ref QCPLayoutGrid, it can be placed in any position a \ref
18585 QCPLayoutElement may be positioned. The legend items are themselves \ref QCPLayoutElement
18421 QCPLayoutElement may be positioned. The legend items are themselves \ref QCPLayoutElement
@@ -19176,8 +19012,8 void QCPLegend::parentPlotInitialized(QCustomPlot *parentPlot)
19176 /* end of 'src/layoutelements/layoutelement-legend.cpp' */
19012 /* end of 'src/layoutelements/layoutelement-legend.cpp' */
19177
19013
19178
19014
19179 /* including file 'src/layoutelements/layoutelement-textelement.cpp', size 12561 */
19015 /* including file 'src/layoutelements/layoutelement-textelement.cpp', size 12759 */
19180 /* commit a872eb91ec087561efd83dd9cb041a26ab95ce55 2017-07-31 00:21:41 +0200 */
19016 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
19181
19017
19182 ////////////////////////////////////////////////////////////////////////////////////////////////////
19018 ////////////////////////////////////////////////////////////////////////////////////////////////////
19183 //////////////////// QCPTextElement
19019 //////////////////// QCPTextElement
@@ -19463,7 +19299,10 void QCPTextElement::draw(QCPPainter *painter)
19463 QSize QCPTextElement::minimumSizeHint() const
19299 QSize QCPTextElement::minimumSizeHint() const
19464 {
19300 {
19465 QFontMetrics metrics(mFont);
19301 QFontMetrics metrics(mFont);
19466 return metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size();
19302 QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size();
19303 result.rwidth() += mMargins.left() + mMargins.right();
19304 result.rheight() += mMargins.top() + mMargins.bottom();
19305 return result;
19467 }
19306 }
19468
19307
19469 /* inherits documentation from base class */
19308 /* inherits documentation from base class */
@@ -19471,6 +19310,7 QSize QCPTextElement::maximumSizeHint() const
19471 {
19310 {
19472 QFontMetrics metrics(mFont);
19311 QFontMetrics metrics(mFont);
19473 QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size();
19312 QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size();
19313 result.rheight() += mMargins.top() + mMargins.bottom();
19474 result.setWidth(QWIDGETSIZE_MAX);
19314 result.setWidth(QWIDGETSIZE_MAX);
19475 return result;
19315 return result;
19476 }
19316 }
@@ -20260,8 +20100,8 void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectablePart
20260 /* end of 'src/layoutelements/layoutelement-colorscale.cpp' */
20100 /* end of 'src/layoutelements/layoutelement-colorscale.cpp' */
20261
20101
20262
20102
20263 /* including file 'src/plottables/plottable-graph.cpp', size 73960 */
20103 /* including file 'src/plottables/plottable-graph.cpp', size 72363 */
20264 /* commit 7e7381ef4f218e004d72a218820634fff0959d1b 2017-08-02 00:02:36 +0200 */
20104 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
20265
20105
20266 ////////////////////////////////////////////////////////////////////////////////////////////////////
20106 ////////////////////////////////////////////////////////////////////////////////////////////////////
20267 //////////////////// QCPGraphData
20107 //////////////////// QCPGraphData
@@ -20809,12 +20649,6 void QCPGraph::getLines(QVector<QPointF> *lines, const QCPDataRange &dataRange)
20809 if (mLineStyle != lsNone)
20649 if (mLineStyle != lsNone)
20810 getOptimizedLineData(&lineData, begin, end);
20650 getOptimizedLineData(&lineData, begin, end);
20811
20651
20812 if (mKeyAxis->rangeReversed()
20813 != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending
20814 // in lineData (significantly simplifies
20815 // following processing)
20816 std::reverse(lineData.begin(), lineData.end());
20817
20818 switch (mLineStyle) {
20652 switch (mLineStyle) {
20819 case lsNone:
20653 case lsNone:
20820 lines->clear();
20654 lines->clear();
@@ -20870,13 +20704,6 void QCPGraph::getScatters(QVector<QPointF> *scatters, const QCPDataRange &dataR
20870
20704
20871 QVector<QCPGraphData> data;
20705 QVector<QCPGraphData> data;
20872 getOptimizedScatterData(&data, begin, end);
20706 getOptimizedScatterData(&data, begin, end);
20873
20874 if (mKeyAxis->rangeReversed()
20875 != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending
20876 // in data (significantly simplifies following
20877 // processing)
20878 std::reverse(data.begin(), data.end());
20879
20880 scatters->resize(data.size());
20707 scatters->resize(data.size());
20881 if (keyAxis->orientation() == Qt::Vertical) {
20708 if (keyAxis->orientation() == Qt::Vertical) {
20882 for (int i = 0; i < data.size(); ++i) {
20709 for (int i = 0; i < data.size(); ++i) {
@@ -20917,6 +20744,8 QVector<QPointF> QCPGraph::dataToLines(const QVector<QCPGraphData> &data) const
20917 return result;
20744 return result;
20918 }
20745 }
20919
20746
20747 result.reserve(data.size() + 2); // added 2 to reserve memory for lower/upper fill base points
20748 // that might be needed for fill
20920 result.resize(data.size());
20749 result.resize(data.size());
20921
20750
20922 // transform data points to pixels:
20751 // transform data points to pixels:
@@ -20957,6 +20786,8 QVector<QPointF> QCPGraph::dataToStepLeftLines(const QVector<QCPGraphData> &data
20957 return result;
20786 return result;
20958 }
20787 }
20959
20788
20789 result.reserve(data.size() * 2 + 2); // added 2 to reserve memory for lower/upper fill base
20790 // points that might be needed for fill
20960 result.resize(data.size() * 2);
20791 result.resize(data.size() * 2);
20961
20792
20962 // calculate steps from data and transform to pixel coordinates:
20793 // calculate steps from data and transform to pixel coordinates:
@@ -21007,6 +20838,8 QVector<QPointF> QCPGraph::dataToStepRightLines(const QVector<QCPGraphData> &dat
21007 return result;
20838 return result;
21008 }
20839 }
21009
20840
20841 result.reserve(data.size() * 2 + 2); // added 2 to reserve memory for lower/upper fill base
20842 // points that might be needed for fill
21010 result.resize(data.size() * 2);
20843 result.resize(data.size() * 2);
21011
20844
21012 // calculate steps from data and transform to pixel coordinates:
20845 // calculate steps from data and transform to pixel coordinates:
@@ -21057,6 +20890,8 QVector<QPointF> QCPGraph::dataToStepCenterLines(const QVector<QCPGraphData> &da
21057 return result;
20890 return result;
21058 }
20891 }
21059
20892
20893 result.reserve(data.size() * 2 + 2); // added 2 to reserve memory for lower/upper fill base
20894 // points that might be needed for fill
21060 result.resize(data.size() * 2);
20895 result.resize(data.size() * 2);
21061
20896
21062 // calculate steps from data and transform to pixel coordinates:
20897 // calculate steps from data and transform to pixel coordinates:
@@ -21119,7 +20954,8 QVector<QPointF> QCPGraph::dataToImpulseLines(const QVector<QCPGraphData> &data)
21119 return result;
20954 return result;
21120 }
20955 }
21121
20956
21122 result.resize(data.size() * 2);
20957 result.resize(data.size()
20958 * 2); // no need to reserve 2 extra points because impulse plot has no fill
21123
20959
21124 // transform data points to pixels:
20960 // transform data points to pixels:
21125 if (keyAxis->orientation() == Qt::Vertical) {
20961 if (keyAxis->orientation() == Qt::Vertical) {
@@ -21148,16 +20984,15 QVector<QPointF> QCPGraph::dataToImpulseLines(const QVector<QCPGraphData> &data)
21148
20984
21149 Draws the fill of the graph using the specified \a painter, with the currently set brush.
20985 Draws the fill of the graph using the specified \a painter, with the currently set brush.
21150
20986
21151 Depending on whether a normal fill or a channel fill (\ref setChannelFillGraph) is needed, \ref
20987 \a lines contains the points of the graph line, in pixel coordinates.
21152 getFillPolygon or \ref getChannelFillPolygon are used to find the according fill polygons.
21153
20988
21154 In order to handle NaN Data points correctly (the fill needs to be split into disjoint areas),
20989 If the fill is a normal fill towards the zero-value-line, only the points in \a lines are
21155 this method first determines a list of non-NaN segments with \ref getNonNanSegments, on which to
20990 required and two extra points at the zero-value-line, which are added by \ref addFillBasePoints
21156 operate. In the channel fill case, \ref getOverlappingSegments is used to consolidate the non-NaN
20991 and removed by \ref removeFillBasePoints after the fill drawing is done.
21157 segments of the two involved graphs, before passing the overlapping pairs to \ref
21158 getChannelFillPolygon.
21159
20992
21160 Pass the points of this graph's line as \a lines, in pixel coordinates.
20993 On the other hand if the fill is a channel fill between this QCPGraph and another QCPGraph (\a
20994 mChannelFillGraph), the more complex polygon is calculated with the \ref getChannelFillPolygon
20995 function, and then drawn.
21161
20996
21162 \see drawLinePlot, drawImpulsePlot, drawScatterPlot
20997 \see drawLinePlot, drawImpulsePlot, drawScatterPlot
21163 */
20998 */
@@ -21169,25 +21004,15 void QCPGraph::drawFill(QCPPainter *painter, QVector<QPointF> *lines) const
21169 return;
21004 return;
21170
21005
21171 applyFillAntialiasingHint(painter);
21006 applyFillAntialiasingHint(painter);
21172 QVector<QCPDataRange> segments = getNonNanSegments(lines, keyAxis()->orientation());
21173 if (!mChannelFillGraph) {
21007 if (!mChannelFillGraph) {
21174 // draw base fill under graph, fill goes all the way to the zero-value-line:
21008 // draw base fill under graph, fill goes all the way to the zero-value-line:
21175 for (int i = 0; i < segments.size(); ++i)
21009 addFillBasePoints(lines);
21176 painter->drawPolygon(getFillPolygon(lines, segments.at(i)));
21010 painter->drawPolygon(QPolygonF(*lines));
21011 removeFillBasePoints(lines);
21177 }
21012 }
21178 else {
21013 else {
21179 // draw fill between this graph and mChannelFillGraph:
21014 // draw channel fill between this graph and mChannelFillGraph:
21180 QVector<QPointF> otherLines;
21015 painter->drawPolygon(getChannelFillPolygon(lines));
21181 mChannelFillGraph->getLines(&otherLines, QCPDataRange(0, mChannelFillGraph->dataCount()));
21182 if (!otherLines.isEmpty()) {
21183 QVector<QCPDataRange> otherSegments
21184 = getNonNanSegments(&otherLines, mChannelFillGraph->keyAxis()->orientation());
21185 QVector<QPair<QCPDataRange, QCPDataRange> > segmentPairs
21186 = getOverlappingSegments(segments, lines, otherSegments, &otherLines);
21187 for (int i = 0; i < segmentPairs.size(); ++i)
21188 painter->drawPolygon(getChannelFillPolygon(lines, segmentPairs.at(i).first,
21189 &otherLines, segmentPairs.at(i).second));
21190 }
21191 }
21016 }
21192 }
21017 }
21193
21018
@@ -21380,8 +21205,12 void QCPGraph::getOptimizedLineData(QVector<QCPGraphData> *lineData,
21380 else // don't use adaptive sampling algorithm, transfer points one-to-one from the data
21205 else // don't use adaptive sampling algorithm, transfer points one-to-one from the data
21381 // container into the output
21206 // container into the output
21382 {
21207 {
21383 lineData->resize(dataCount);
21208 QCPGraphDataContainer::const_iterator it = begin;
21384 std::copy(begin, end, lineData->begin());
21209 lineData->reserve(dataCount + 2); // +2 for possible fill end points
21210 while (it != end) {
21211 lineData->append(*it);
21212 ++it;
21213 }
21385 }
21214 }
21386 }
21215 }
21387
21216
@@ -21650,177 +21479,151 void QCPGraph::getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin
21650 }
21479 }
21651 }
21480 }
21652
21481
21653 /*! \internal
21482 /*! \internal
21654
21483
21655 This method goes through the passed points in \a lineData and returns a list of the segments
21484 The line vector generated by e.g. \ref getLines describes only the line that connects the data
21656 which don't contain NaN data points.
21485 points. If the graph needs to be filled, two additional points need to be added at the
21486 value-zero-line in the lower and upper key positions of the graph. This function calculates these
21487 points and adds them to the end of \a lineData. Since the fill is typically drawn before the line
21488 stroke, these added points need to be removed again after the fill is done, with the
21489 removeFillBasePoints function.
21657
21490
21658 \a keyOrientation defines whether the \a x or \a y member of the passed QPointF is used to check
21491 The expanding of \a lines by two points will not cause unnecessary memory reallocations, because
21659 for NaN. If \a keyOrientation is \c Qt::Horizontal, the \a y member is checked, if it is \c
21492 the data vector generation functions (e.g. \ref getLines) reserve two extra points when they
21660 Qt::Vertical, the \a x member is checked.
21493 allocate memory for \a lines.
21661
21494
21662 \see getOverlappingSegments, drawFill
21495 \see removeFillBasePoints, lowerFillBasePoint, upperFillBasePoint
21663 */
21496 */
21664 QVector<QCPDataRange> QCPGraph::getNonNanSegments(const QVector<QPointF> *lineData,
21497 void QCPGraph::addFillBasePoints(QVector<QPointF> *lines) const
21665 Qt::Orientation keyOrientation) const
21666 {
21498 {
21667 QVector<QCPDataRange> result;
21499 if (!mKeyAxis) {
21668 const int n = lineData->size();
21500 qDebug() << Q_FUNC_INFO << "invalid key axis";
21669
21501 return;
21670 QCPDataRange currentSegment(-1, -1);
21502 }
21671 int i = 0;
21503 if (!lines) {
21504 qDebug() << Q_FUNC_INFO << "passed null as lineData";
21505 return;
21506 }
21507 if (lines->isEmpty())
21508 return;
21672
21509
21673 if (keyOrientation == Qt::Horizontal) {
21510 // append points that close the polygon fill at the key axis:
21674 while (i < n) {
21511 if (mKeyAxis.data()->orientation() == Qt::Vertical) {
21675 while (i < n && qIsNaN(lineData->at(i).y())) // seek next non-NaN data point
21512 *lines << upperFillBasePoint(lines->last().y());
21676 ++i;
21513 *lines << lowerFillBasePoint(lines->first().y());
21677 if (i == n)
21678 break;
21679 currentSegment.setBegin(i++);
21680 while (i < n && !qIsNaN(lineData->at(i).y())) // seek next NaN data point or end of data
21681 ++i;
21682 currentSegment.setEnd(i++);
21683 result.append(currentSegment);
21684 }
21685 }
21514 }
21686 else // keyOrientation == Qt::Vertical
21515 else {
21687 {
21516 *lines << upperFillBasePoint(lines->last().x());
21688 while (i < n) {
21517 *lines << lowerFillBasePoint(lines->first().x());
21689 while (i < n && qIsNaN(lineData->at(i).x())) // seek next non-NaN data point
21690 ++i;
21691 if (i == n)
21692 break;
21693 currentSegment.setBegin(i++);
21694 while (i < n && !qIsNaN(lineData->at(i).x())) // seek next NaN data point or end of data
21695 ++i;
21696 currentSegment.setEnd(i++);
21697 result.append(currentSegment);
21698 }
21699 }
21518 }
21700 return result;
21701 }
21519 }
21702
21520
21703 /*! \internal
21521 /*! \internal
21704
21705 This method takes two segment lists (e.g. created by \ref getNonNanSegments) \a thisSegments and
21706 \a otherSegments, and their associated point data \a thisData and \a otherData.
21707
21708 It returns all pairs of segments (the first from \a thisSegments, the second from \a
21709 otherSegments), which overlap in plot coordinates.
21710
21711 This method is useful in the case of a channel fill between two graphs, when only those non-NaN
21712 segments which actually overlap in their key coordinate shall be considered for drawing a channel
21713 fill polygon.
21714
21522
21715 It is assumed that the passed segments in \a thisSegments are ordered ascending by index, and
21523 removes the two points from \a lines that were added by \ref addFillBasePoints.
21716 that the segments don't overlap themselves. The same is assumed for the segments in \a
21717 otherSegments. This is fulfilled when the segments are obtained via \ref getNonNanSegments.
21718
21524
21719 \see getNonNanSegments, segmentsIntersect, drawFill, getChannelFillPolygon
21525 \see addFillBasePoints, lowerFillBasePoint, upperFillBasePoint
21720 */
21526 */
21721 QVector<QPair<QCPDataRange, QCPDataRange> > QCPGraph::getOverlappingSegments(
21527 void QCPGraph::removeFillBasePoints(QVector<QPointF> *lines) const
21722 QVector<QCPDataRange> thisSegments, const QVector<QPointF> *thisData,
21723 QVector<QCPDataRange> otherSegments, const QVector<QPointF> *otherData) const
21724 {
21528 {
21725 QVector<QPair<QCPDataRange, QCPDataRange> > result;
21529 if (!lines) {
21726 if (thisData->isEmpty() || otherData->isEmpty() || thisSegments.isEmpty()
21530 qDebug() << Q_FUNC_INFO << "passed null as lineData";
21727 || otherSegments.isEmpty())
21531 return;
21728 return result;
21729
21730 int thisIndex = 0;
21731 int otherIndex = 0;
21732 const bool verticalKey = mKeyAxis->orientation() == Qt::Vertical;
21733 while (thisIndex < thisSegments.size() && otherIndex < otherSegments.size()) {
21734 if (thisSegments.at(thisIndex).size()
21735 < 2) // segments with fewer than two points won't have a fill anyhow
21736 {
21737 ++thisIndex;
21738 continue;
21739 }
21740 if (otherSegments.at(otherIndex).size()
21741 < 2) // segments with fewer than two points won't have a fill anyhow
21742 {
21743 ++otherIndex;
21744 continue;
21745 }
21746 double thisLower, thisUpper, otherLower, otherUpper;
21747 if (!verticalKey) {
21748 thisLower = thisData->at(thisSegments.at(thisIndex).begin()).x();
21749 thisUpper = thisData->at(thisSegments.at(thisIndex).end() - 1).x();
21750 otherLower = otherData->at(otherSegments.at(otherIndex).begin()).x();
21751 otherUpper = otherData->at(otherSegments.at(otherIndex).end() - 1).x();
21752 }
21753 else {
21754 thisLower = thisData->at(thisSegments.at(thisIndex).begin()).y();
21755 thisUpper = thisData->at(thisSegments.at(thisIndex).end() - 1).y();
21756 otherLower = otherData->at(otherSegments.at(otherIndex).begin()).y();
21757 otherUpper = otherData->at(otherSegments.at(otherIndex).end() - 1).y();
21758 }
21759
21760 int bPrecedence;
21761 if (segmentsIntersect(thisLower, thisUpper, otherLower, otherUpper, bPrecedence))
21762 result.append(QPair<QCPDataRange, QCPDataRange>(thisSegments.at(thisIndex),
21763 otherSegments.at(otherIndex)));
21764
21765 if (bPrecedence <= 0) // otherSegment doesn't reach as far as thisSegment, so continue with
21766 // next otherSegment, keeping current thisSegment
21767 ++otherIndex;
21768 else // otherSegment reaches further than thisSegment, so continue with next thisSegment,
21769 // keeping current otherSegment
21770 ++thisIndex;
21771 }
21532 }
21533 if (lines->isEmpty())
21534 return;
21772
21535
21773 return result;
21536 lines->remove(lines->size() - 2, 2);
21774 }
21537 }
21775
21538
21776 /*! \internal
21539 /*! \internal
21777
21778 Returns whether the segments defined by the coordinates (aLower, aUpper) and (bLower, bUpper)
21779 have overlap.
21780
21540
21781 The output parameter \a bPrecedence indicates whether the \a b segment reaches farther than the
21541 called by \ref addFillBasePoints to conveniently assign the point which closes the fill polygon
21782 \a a segment or not. If \a bPrecedence returns 1, segment \a b reaches the farthest to higher
21542 on the lower side of the zero-value-line parallel to the key axis. The logarithmic axis scale
21783 coordinates (i.e. bUpper > aUpper). If it returns -1, segment \a a reaches the farthest. Only if
21543 case is a bit special, since the zero-value-line in pixel coordinates is in positive or negative
21784 both segment's upper bounds are identical, 0 is returned as \a bPrecedence.
21544 infinity. So this case is handled separately by just closing the fill polygon on the axis which
21545 lies in the direction towards the zero value.
21785
21546
21786 It is assumed that the lower bounds always have smaller or equal values than the upper bounds.
21547 \a lowerKey will be the the key (in pixels) of the returned point. Depending on whether the key
21548 axis is horizontal or vertical, \a lowerKey will end up as the x or y value of the returned
21549 point, respectively.
21787
21550
21788 \see getOverlappingSegments
21551 \see upperFillBasePoint, addFillBasePoints
21789 */
21552 */
21790 bool QCPGraph::segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper,
21553 QPointF QCPGraph::lowerFillBasePoint(double lowerKey) const
21791 int &bPrecedence) const
21792 {
21554 {
21793 bPrecedence = 0;
21555 QCPAxis *keyAxis = mKeyAxis.data();
21794 if (aLower > bUpper) {
21556 QCPAxis *valueAxis = mValueAxis.data();
21795 bPrecedence = -1;
21557 if (!keyAxis || !valueAxis) {
21796 return false;
21558 qDebug() << Q_FUNC_INFO << "invalid key or value axis";
21797 }
21559 return QPointF();
21798 else if (bLower > aUpper) {
21799 bPrecedence = 1;
21800 return false;
21801 }
21560 }
21802 else {
21803 if (aUpper > bUpper)
21804 bPrecedence = -1;
21805 else if (aUpper < bUpper)
21806 bPrecedence = 1;
21807
21561
21808 return true;
21562 QPointF point;
21563 if (valueAxis->scaleType() == QCPAxis::stLinear) {
21564 if (keyAxis->axisType() == QCPAxis::atLeft) {
21565 point.setX(valueAxis->coordToPixel(0));
21566 point.setY(lowerKey);
21567 }
21568 else if (keyAxis->axisType() == QCPAxis::atRight) {
21569 point.setX(valueAxis->coordToPixel(0));
21570 point.setY(lowerKey);
21571 }
21572 else if (keyAxis->axisType() == QCPAxis::atTop) {
21573 point.setX(lowerKey);
21574 point.setY(valueAxis->coordToPixel(0));
21575 }
21576 else if (keyAxis->axisType() == QCPAxis::atBottom) {
21577 point.setX(lowerKey);
21578 point.setY(valueAxis->coordToPixel(0));
21579 }
21809 }
21580 }
21581 else // valueAxis->mScaleType == QCPAxis::stLogarithmic
21582 {
21583 // In logarithmic scaling we can't just draw to value zero so we just fill all the way
21584 // to the axis which is in the direction towards zero
21585 if (keyAxis->orientation() == Qt::Vertical) {
21586 if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed())
21587 || (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is
21588 // negative, zero
21589 // is on opposite
21590 // side of key axis
21591 point.setX(keyAxis->axisRect()->right());
21592 else
21593 point.setX(keyAxis->axisRect()->left());
21594 point.setY(lowerKey);
21595 }
21596 else if (keyAxis->axisType() == QCPAxis::atTop
21597 || keyAxis->axisType() == QCPAxis::atBottom) {
21598 point.setX(lowerKey);
21599 if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed())
21600 || (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is
21601 // negative, zero
21602 // is on opposite
21603 // side of key axis
21604 point.setY(keyAxis->axisRect()->top());
21605 else
21606 point.setY(keyAxis->axisRect()->bottom());
21607 }
21608 }
21609 return point;
21810 }
21610 }
21811
21611
21812 /*! \internal
21612 /*! \internal
21813
21613
21814 Returns the point which closes the fill polygon on the zero-value-line parallel to the key axis.
21614 called by \ref addFillBasePoints to conveniently assign the point which closes the fill
21815 The logarithmic axis scale case is a bit special, since the zero-value-line in pixel coordinates
21615 polygon on the upper side of the zero-value-line parallel to the key axis. The logarithmic axis
21816 is in positive or negative infinity. So this case is handled separately by just closing the fill
21616 scale case is a bit special, since the zero-value-line in pixel coordinates is in positive or
21817 polygon on the axis which lies in the direction towards the zero value.
21617 negative infinity. So this case is handled separately by just closing the fill polygon on the
21618 axis which lies in the direction towards the zero value.
21619
21620 \a upperKey will be the the key (in pixels) of the returned point. Depending on whether the key
21621 axis is horizontal or vertical, \a upperKey will end up as the x or y value of the returned
21622 point, respectively.
21818
21623
21819 \a matchingDataPoint will provide the key (in pixels) of the returned point. Depending on whether
21624 \see lowerFillBasePoint, addFillBasePoints
21820 the key axis of this graph is horizontal or vertical, \a matchingDataPoint will provide the x or
21821 y value of the returned point, respectively.
21822 */
21625 */
21823 QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const
21626 QPointF QCPGraph::upperFillBasePoint(double upperKey) const
21824 {
21627 {
21825 QCPAxis *keyAxis = mKeyAxis.data();
21628 QCPAxis *keyAxis = mKeyAxis.data();
21826 QCPAxis *valueAxis = mValueAxis.data();
21629 QCPAxis *valueAxis = mValueAxis.data();
@@ -21829,16 +21632,23 QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const
21829 return QPointF();
21632 return QPointF();
21830 }
21633 }
21831
21634
21832 QPointF result;
21635 QPointF point;
21833 if (valueAxis->scaleType() == QCPAxis::stLinear) {
21636 if (valueAxis->scaleType() == QCPAxis::stLinear) {
21834 if (keyAxis->orientation() == Qt::Horizontal) {
21637 if (keyAxis->axisType() == QCPAxis::atLeft) {
21835 result.setX(matchingDataPoint.x());
21638 point.setX(valueAxis->coordToPixel(0));
21836 result.setY(valueAxis->coordToPixel(0));
21639 point.setY(upperKey);
21837 }
21640 }
21838 else // keyAxis->orientation() == Qt::Vertical
21641 else if (keyAxis->axisType() == QCPAxis::atRight) {
21839 {
21642 point.setX(valueAxis->coordToPixel(0));
21840 result.setX(valueAxis->coordToPixel(0));
21643 point.setY(upperKey);
21841 result.setY(matchingDataPoint.y());
21644 }
21645 else if (keyAxis->axisType() == QCPAxis::atTop) {
21646 point.setX(upperKey);
21647 point.setY(valueAxis->coordToPixel(0));
21648 }
21649 else if (keyAxis->axisType() == QCPAxis::atBottom) {
21650 point.setX(upperKey);
21651 point.setY(valueAxis->coordToPixel(0));
21842 }
21652 }
21843 }
21653 }
21844 else // valueAxis->mScaleType == QCPAxis::stLogarithmic
21654 else // valueAxis->mScaleType == QCPAxis::stLogarithmic
@@ -21851,80 +21661,40 QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const
21851 // negative, zero
21661 // negative, zero
21852 // is on opposite
21662 // is on opposite
21853 // side of key axis
21663 // side of key axis
21854 result.setX(keyAxis->axisRect()->right());
21664 point.setX(keyAxis->axisRect()->right());
21855 else
21665 else
21856 result.setX(keyAxis->axisRect()->left());
21666 point.setX(keyAxis->axisRect()->left());
21857 result.setY(matchingDataPoint.y());
21667 point.setY(upperKey);
21858 }
21668 }
21859 else if (keyAxis->axisType() == QCPAxis::atTop
21669 else if (keyAxis->axisType() == QCPAxis::atTop
21860 || keyAxis->axisType() == QCPAxis::atBottom) {
21670 || keyAxis->axisType() == QCPAxis::atBottom) {
21861 result.setX(matchingDataPoint.x());
21671 point.setX(upperKey);
21862 if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed())
21672 if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed())
21863 || (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is
21673 || (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is
21864 // negative, zero
21674 // negative, zero
21865 // is on opposite
21675 // is on opposite
21866 // side of key axis
21676 // side of key axis
21867 result.setY(keyAxis->axisRect()->top());
21677 point.setY(keyAxis->axisRect()->top());
21868 else
21678 else
21869 result.setY(keyAxis->axisRect()->bottom());
21679 point.setY(keyAxis->axisRect()->bottom());
21870 }
21680 }
21871 }
21681 }
21872 return result;
21682 return point;
21873 }
21683 }
21874
21684
21875 /*! \internal
21685 /*! \internal
21876
21686
21877 Returns the polygon needed for drawing normal fills between this graph and the key axis.
21687 Generates the polygon needed for drawing channel fills between this graph and the graph specified
21878
21688 in \a mChannelFillGraph (see \ref setChannelFillGraph). The data points representing the line of
21879 Pass the graph's data points (in pixel coordinates) as \a lineData, and specify the \a segment
21689 this graph in pixel coordinates must be passed in \a lines, the corresponding points of the other
21880 which shall be used for the fill. The collection of \a lineData points described by \a segment
21690 graph are generated by calling its \ref getLines method.
21881 must not contain NaN data points (see \ref getNonNanSegments).
21882
21691
21883 The returned fill polygon will be closed at the key axis (the zero-value line) for linear value
21692 This method may return an empty polygon if the key ranges of the two graphs have no overlap of if
21884 axes. For logarithmic value axes the polygon will reach just beyond the corresponding axis rect
21693 they don't have the same orientation (e.g. one key axis vertical, the other horizontal). For
21885 side (see \ref getFillBasePoint).
21694 increased performance (due to implicit sharing), it is recommended to keep the returned QPolygonF
21886
21695 const.
21887 For increased performance (due to implicit sharing), keep the returned QPolygonF const.
21888
21889 \see drawFill, getNonNanSegments
21890 */
21696 */
21891 const QPolygonF QCPGraph::getFillPolygon(const QVector<QPointF> *lineData,
21697 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *lines) const
21892 QCPDataRange segment) const
21893 {
21894 if (segment.size() < 2)
21895 return QPolygonF();
21896 QPolygonF result(segment.size() + 2);
21897
21898 result[0] = getFillBasePoint(lineData->at(segment.begin()));
21899 std::copy(lineData->constBegin() + segment.begin(), lineData->constBegin() + segment.end(),
21900 result.begin() + 1);
21901 result[result.size() - 1] = getFillBasePoint(lineData->at(segment.end() - 1));
21902
21903 return result;
21904 }
21905
21906 /*! \internal
21907
21908 Returns the polygon needed for drawing (partial) channel fills between this graph and the graph
21909 specified by \ref setChannelFillGraph.
21910
21911 The data points of this graph are passed as pixel coordinates via \a thisData, the data of the
21912 other graph as \a otherData. The returned polygon will be calculated for the specified data
21913 segments \a thisSegment and \a otherSegment, pertaining to the respective \a thisData and \a
21914 otherData, respectively.
21915
21916 The passed \a thisSegment and \a otherSegment should correspond to the segment pairs returned by
21917 \ref getOverlappingSegments, to make sure only segments that actually have key coordinate overlap
21918 need to be processed here.
21919
21920 For increased performance due to implicit sharing, keep the returned QPolygonF const.
21921
21922 \see drawFill, getOverlappingSegments, getNonNanSegments
21923 */
21924 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData,
21925 QCPDataRange thisSegment,
21926 const QVector<QPointF> *otherData,
21927 QCPDataRange otherSegment) const
21928 {
21698 {
21929 if (!mChannelFillGraph)
21699 if (!mChannelFillGraph)
21930 return QPolygonF();
21700 return QPolygonF();
@@ -21945,35 +21715,55 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData
21945 // fits, valueAxis will fit too, because it's always orthogonal to
21715 // fits, valueAxis will fit too, because it's always orthogonal to
21946 // keyAxis)
21716 // keyAxis)
21947
21717
21948 if (thisData->isEmpty())
21718 if (lines->isEmpty())
21719 return QPolygonF();
21720 QVector<QPointF> otherData;
21721 mChannelFillGraph.data()->getLines(&otherData,
21722 QCPDataRange(0, mChannelFillGraph.data()->dataCount()));
21723 if (otherData.isEmpty())
21949 return QPolygonF();
21724 return QPolygonF();
21950 QVector<QPointF> thisSegmentData(thisSegment.size());
21725 QVector<QPointF> thisData;
21951 QVector<QPointF> otherSegmentData(otherSegment.size());
21726 thisData.reserve(
21952 std::copy(thisData->constBegin() + thisSegment.begin(),
21727 lines->size()
21953 thisData->constBegin() + thisSegment.end(), thisSegmentData.begin());
21728 + otherData.size()); // because we will join both vectors at end of this function
21954 std::copy(otherData->constBegin() + otherSegment.begin(),
21729 for (int i = 0; i < lines->size(); ++i) // don't use the vector<<(vector), it squeezes
21955 otherData->constBegin() + otherSegment.end(), otherSegmentData.begin());
21730 // internally, which ruins the performance tuning with
21731 // reserve()
21732 thisData << lines->at(i);
21733
21956 // pointers to be able to swap them, depending which data range needs cropping:
21734 // pointers to be able to swap them, depending which data range needs cropping:
21957 QVector<QPointF> *staticData = &thisSegmentData;
21735 QVector<QPointF> *staticData = &thisData;
21958 QVector<QPointF> *croppedData = &otherSegmentData;
21736 QVector<QPointF> *croppedData = &otherData;
21959
21737
21960 // crop both vectors to ranges in which the keys overlap (which coord is key, depends on
21738 // crop both vectors to ranges in which the keys overlap (which coord is key, depends on
21961 // axisType):
21739 // axisType):
21962 if (keyAxis->orientation() == Qt::Horizontal) {
21740 if (keyAxis->orientation() == Qt::Horizontal) {
21963 // x is key
21741 // x is key
21742 // if an axis range is reversed, the data point keys will be descending. Reverse them, since
21743 // following algorithm assumes ascending keys:
21744 if (staticData->first().x() > staticData->last().x()) {
21745 int size = staticData->size();
21746 for (int i = 0; i < size / 2; ++i)
21747 qSwap((*staticData)[i], (*staticData)[size - 1 - i]);
21748 }
21749 if (croppedData->first().x() > croppedData->last().x()) {
21750 int size = croppedData->size();
21751 for (int i = 0; i < size / 2; ++i)
21752 qSwap((*croppedData)[i], (*croppedData)[size - 1 - i]);
21753 }
21964 // crop lower bound:
21754 // crop lower bound:
21965 if (staticData->first().x() < croppedData->first().x()) // other one must be cropped
21755 if (staticData->first().x() < croppedData->first().x()) // other one must be cropped
21966 qSwap(staticData, croppedData);
21756 qSwap(staticData, croppedData);
21967 const int lowBound = findIndexBelowX(croppedData, staticData->first().x());
21757 int lowBound = findIndexBelowX(croppedData, staticData->first().x());
21968 if (lowBound == -1)
21758 if (lowBound == -1)
21969 return QPolygonF(); // key ranges have no overlap
21759 return QPolygonF(); // key ranges have no overlap
21970 croppedData->remove(0, lowBound);
21760 croppedData->remove(0, lowBound);
21971 // set lowest point of cropped data to fit exactly key position of first static data point
21761 // set lowest point of cropped data to fit exactly key position of first static data
21972 // via linear interpolation:
21762 // point via linear interpolation:
21973 if (croppedData->size() < 2)
21763 if (croppedData->size() < 2)
21974 return QPolygonF(); // need at least two points for interpolation
21764 return QPolygonF(); // need at least two points for interpolation
21975 double slope;
21765 double slope;
21976 if (!qFuzzyCompare(croppedData->at(1).x(), croppedData->at(0).x()))
21766 if (croppedData->at(1).x() - croppedData->at(0).x() != 0)
21977 slope = (croppedData->at(1).y() - croppedData->at(0).y())
21767 slope = (croppedData->at(1).y() - croppedData->at(0).y())
21978 / (croppedData->at(1).x() - croppedData->at(0).x());
21768 / (croppedData->at(1).x() - croppedData->at(0).x());
21979 else
21769 else
@@ -21989,12 +21779,12 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData
21989 if (highBound == -1)
21779 if (highBound == -1)
21990 return QPolygonF(); // key ranges have no overlap
21780 return QPolygonF(); // key ranges have no overlap
21991 croppedData->remove(highBound + 1, croppedData->size() - (highBound + 1));
21781 croppedData->remove(highBound + 1, croppedData->size() - (highBound + 1));
21992 // set highest point of cropped data to fit exactly key position of last static data point
21782 // set highest point of cropped data to fit exactly key position of last static data
21993 // via linear interpolation:
21783 // point via linear interpolation:
21994 if (croppedData->size() < 2)
21784 if (croppedData->size() < 2)
21995 return QPolygonF(); // need at least two points for interpolation
21785 return QPolygonF(); // need at least two points for interpolation
21996 const int li = croppedData->size() - 1; // last index
21786 int li = croppedData->size() - 1; // last index
21997 if (!qFuzzyCompare(croppedData->at(li).x(), croppedData->at(li - 1).x()))
21787 if (croppedData->at(li).x() - croppedData->at(li - 1).x() != 0)
21998 slope = (croppedData->at(li).y() - croppedData->at(li - 1).y())
21788 slope = (croppedData->at(li).y() - croppedData->at(li - 1).y())
21999 / (croppedData->at(li).x() - croppedData->at(li - 1).x());
21789 / (croppedData->at(li).x() - croppedData->at(li - 1).x());
22000 else
21790 else
@@ -22006,20 +21796,36 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData
22006 else // mKeyAxis->orientation() == Qt::Vertical
21796 else // mKeyAxis->orientation() == Qt::Vertical
22007 {
21797 {
22008 // y is key
21798 // y is key
21799 // similar to "x is key" but switched x,y. Further, lower/upper meaning is inverted compared
21800 // to x,
21801 // because in pixel coordinates, y increases from top to bottom, not bottom to top like data
21802 // coordinate.
21803 // if an axis range is reversed, the data point keys will be descending. Reverse them, since
21804 // following algorithm assumes ascending keys:
21805 if (staticData->first().y() < staticData->last().y()) {
21806 int size = staticData->size();
21807 for (int i = 0; i < size / 2; ++i)
21808 qSwap((*staticData)[i], (*staticData)[size - 1 - i]);
21809 }
21810 if (croppedData->first().y() < croppedData->last().y()) {
21811 int size = croppedData->size();
21812 for (int i = 0; i < size / 2; ++i)
21813 qSwap((*croppedData)[i], (*croppedData)[size - 1 - i]);
21814 }
22009 // crop lower bound:
21815 // crop lower bound:
22010 if (staticData->first().y() < croppedData->first().y()) // other one must be cropped
21816 if (staticData->first().y() > croppedData->first().y()) // other one must be cropped
22011 qSwap(staticData, croppedData);
21817 qSwap(staticData, croppedData);
22012 int lowBound = findIndexBelowY(croppedData, staticData->first().y());
21818 int lowBound = findIndexAboveY(croppedData, staticData->first().y());
22013 if (lowBound == -1)
21819 if (lowBound == -1)
22014 return QPolygonF(); // key ranges have no overlap
21820 return QPolygonF(); // key ranges have no overlap
22015 croppedData->remove(0, lowBound);
21821 croppedData->remove(0, lowBound);
22016 // set lowest point of cropped data to fit exactly key position of first static data point
21822 // set lowest point of cropped data to fit exactly key position of first static data
22017 // via linear interpolation:
21823 // point via linear interpolation:
22018 if (croppedData->size() < 2)
21824 if (croppedData->size() < 2)
22019 return QPolygonF(); // need at least two points for interpolation
21825 return QPolygonF(); // need at least two points for interpolation
22020 double slope;
21826 double slope;
22021 if (!qFuzzyCompare(croppedData->at(1).y(),
21827 if (croppedData->at(1).y() - croppedData->at(0).y()
22022 croppedData->at(0).y())) // avoid division by zero in step plots
21828 != 0) // avoid division by zero in step plots
22023 slope = (croppedData->at(1).x() - croppedData->at(0).x())
21829 slope = (croppedData->at(1).x() - croppedData->at(0).x())
22024 / (croppedData->at(1).y() - croppedData->at(0).y());
21830 / (croppedData->at(1).y() - croppedData->at(0).y());
22025 else
21831 else
@@ -22029,19 +21835,19 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData
22029 (*croppedData)[0].setY(staticData->first().y());
21835 (*croppedData)[0].setY(staticData->first().y());
22030
21836
22031 // crop upper bound:
21837 // crop upper bound:
22032 if (staticData->last().y() > croppedData->last().y()) // other one must be cropped
21838 if (staticData->last().y() < croppedData->last().y()) // other one must be cropped
22033 qSwap(staticData, croppedData);
21839 qSwap(staticData, croppedData);
22034 int highBound = findIndexAboveY(croppedData, staticData->last().y());
21840 int highBound = findIndexBelowY(croppedData, staticData->last().y());
22035 if (highBound == -1)
21841 if (highBound == -1)
22036 return QPolygonF(); // key ranges have no overlap
21842 return QPolygonF(); // key ranges have no overlap
22037 croppedData->remove(highBound + 1, croppedData->size() - (highBound + 1));
21843 croppedData->remove(highBound + 1, croppedData->size() - (highBound + 1));
22038 // set highest point of cropped data to fit exactly key position of last static data point
21844 // set highest point of cropped data to fit exactly key position of last static data
22039 // via linear interpolation:
21845 // point via linear interpolation:
22040 if (croppedData->size() < 2)
21846 if (croppedData->size() < 2)
22041 return QPolygonF(); // need at least two points for interpolation
21847 return QPolygonF(); // need at least two points for interpolation
22042 int li = croppedData->size() - 1; // last index
21848 int li = croppedData->size() - 1; // last index
22043 if (!qFuzzyCompare(croppedData->at(li).y(),
21849 if (croppedData->at(li).y() - croppedData->at(li - 1).y()
22044 croppedData->at(li - 1).y())) // avoid division by zero in step plots
21850 != 0) // avoid division by zero in step plots
22045 slope = (croppedData->at(li).x() - croppedData->at(li - 1).x())
21851 slope = (croppedData->at(li).x() - croppedData->at(li - 1).x())
22046 / (croppedData->at(li).y() - croppedData->at(li - 1).y());
21852 / (croppedData->at(li).y() - croppedData->at(li - 1).y());
22047 else
21853 else
@@ -22052,17 +21858,16 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData
22052 }
21858 }
22053
21859
22054 // return joined:
21860 // return joined:
22055 for (int i = otherSegmentData.size() - 1; i >= 0;
21861 for (int i = otherData.size() - 1; i >= 0;
22056 --i) // insert reversed, otherwise the polygon will be twisted
21862 --i) // insert reversed, otherwise the polygon will be twisted
22057 thisSegmentData << otherSegmentData.at(i);
21863 thisData << otherData.at(i);
22058 return QPolygonF(thisSegmentData);
21864 return QPolygonF(thisData);
22059 }
21865 }
22060
21866
22061 /*! \internal
21867 /*! \internal
22062
21868
22063 Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in
21869 Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in
22064 \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key
21870 \a data points are ordered ascending, as is the case when plotting with horizontal key axis.
22065 axis is horizontal.
22066
21871
22067 Used to calculate the channel fill polygon, see \ref getChannelFillPolygon.
21872 Used to calculate the channel fill polygon, see \ref getChannelFillPolygon.
22068 */
21873 */
@@ -22082,8 +21887,7 int QCPGraph::findIndexAboveX(const QVector<QPointF> *data, double x) const
22082 /*! \internal
21887 /*! \internal
22083
21888
22084 Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in
21889 Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in
22085 \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key
21890 \a data points are ordered ascending, as is the case when plotting with horizontal key axis.
22086 axis is horizontal.
22087
21891
22088 Used to calculate the channel fill polygon, see \ref getChannelFillPolygon.
21892 Used to calculate the channel fill polygon, see \ref getChannelFillPolygon.
22089 */
21893 */
@@ -22103,19 +21907,18 int QCPGraph::findIndexBelowX(const QVector<QPointF> *data, double x) const
22103 /*! \internal
21907 /*! \internal
22104
21908
22105 Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in
21909 Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in
22106 \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key
21910 \a data points are ordered descending, as is the case when plotting with vertical key axis.
22107 axis is vertical.
22108
21911
22109 Used to calculate the channel fill polygon, see \ref getChannelFillPolygon.
21912 Used to calculate the channel fill polygon, see \ref getChannelFillPolygon.
22110 */
21913 */
22111 int QCPGraph::findIndexAboveY(const QVector<QPointF> *data, double y) const
21914 int QCPGraph::findIndexAboveY(const QVector<QPointF> *data, double y) const
22112 {
21915 {
22113 for (int i = data->size() - 1; i >= 0; --i) {
21916 for (int i = 0; i < data->size(); ++i) {
22114 if (data->at(i).y() < y) {
21917 if (data->at(i).y() < y) {
22115 if (i < data->size() - 1)
21918 if (i > 0)
22116 return i + 1;
21919 return i - 1;
22117 else
21920 else
22118 return data->size() - 1;
21921 return 0;
22119 }
21922 }
22120 }
21923 }
22121 return -1;
21924 return -1;
@@ -22191,19 +21994,19 double QCPGraph::pointDistance(const QPointF &pixelPoint,
22191 /*! \internal
21994 /*! \internal
22192
21995
22193 Finds the highest index of \a data, whose points y value is just below \a y. Assumes y values in
21996 Finds the highest index of \a data, whose points y value is just below \a y. Assumes y values in
22194 \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key
21997 \a data points are ordered descending, as is the case when plotting with vertical key axis (since
22195 axis is vertical.
21998 keys are ordered ascending).
22196
21999
22197 Used to calculate the channel fill polygon, see \ref getChannelFillPolygon.
22000 Used to calculate the channel fill polygon, see \ref getChannelFillPolygon.
22198 */
22001 */
22199 int QCPGraph::findIndexBelowY(const QVector<QPointF> *data, double y) const
22002 int QCPGraph::findIndexBelowY(const QVector<QPointF> *data, double y) const
22200 {
22003 {
22201 for (int i = 0; i < data->size(); ++i) {
22004 for (int i = data->size() - 1; i >= 0; --i) {
22202 if (data->at(i).y() > y) {
22005 if (data->at(i).y() > y) {
22203 if (i > 0)
22006 if (i < data->size() - 1)
22204 return i - 1;
22007 return i + 1;
22205 else
22008 else
22206 return 0;
22009 return data->size() - 1;
22207 }
22010 }
22208 }
22011 }
22209 return -1;
22012 return -1;
@@ -22211,8 +22014,8 int QCPGraph::findIndexBelowY(const QVector<QPointF> *data, double y) const
22211 /* end of 'src/plottables/plottable-graph.cpp' */
22014 /* end of 'src/plottables/plottable-graph.cpp' */
22212
22015
22213
22016
22214 /* including file 'src/plottables/plottable-curve.cpp', size 63527 */
22017 /* including file 'src/plottables/plottable-curve.cpp', size 60009 */
22215 /* commit 63bcca79007f7f56dce5dd035560f2e871d1dfc1 2017-07-20 18:02:21 +0200 */
22018 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
22216
22019
22217 ////////////////////////////////////////////////////////////////////////////////////////////////////
22020 ////////////////////////////////////////////////////////////////////////////////////////////////////
22218 //////////////////// QCPCurveData
22021 //////////////////// QCPCurveData
@@ -22376,7 +22179,6 QCPCurve::QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis)
22376
22179
22377 setScatterStyle(QCPScatterStyle());
22180 setScatterStyle(QCPScatterStyle());
22378 setLineStyle(lsLine);
22181 setLineStyle(lsLine);
22379 setScatterSkip(0);
22380 }
22182 }
22381
22183
22382 QCPCurve::~QCPCurve()
22184 QCPCurve::~QCPCurve()
@@ -23079,74 +22881,54 QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double oth
23079 double value, double keyMin, double valueMax, double keyMax,
22881 double value, double keyMin, double valueMax, double keyMax,
23080 double valueMin) const
22882 double valueMin) const
23081 {
22883 {
23082 // The intersection point interpolation here is done in pixel coordinates, so we don't need to
22884 double intersectKey = keyMin; // initial value is just fail-safe
23083 // differentiate between different axis scale types. Note that the nomenclature
22885 double intersectValue = valueMax; // initial value is just fail-safe
23084 // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be
23085 // different in pixel coordinates (horz/vert key axes, reversed ranges)
23086
23087 const double keyMinPx = mKeyAxis->coordToPixel(keyMin);
23088 const double keyMaxPx = mKeyAxis->coordToPixel(keyMax);
23089 const double valueMinPx = mValueAxis->coordToPixel(valueMin);
23090 const double valueMaxPx = mValueAxis->coordToPixel(valueMax);
23091 const double otherValuePx = mValueAxis->coordToPixel(otherValue);
23092 const double valuePx = mValueAxis->coordToPixel(value);
23093 const double otherKeyPx = mKeyAxis->coordToPixel(otherKey);
23094 const double keyPx = mKeyAxis->coordToPixel(key);
23095 double intersectKeyPx = keyMinPx; // initial key just a fail-safe
23096 double intersectValuePx = valueMinPx; // initial value just a fail-safe
23097 switch (otherRegion) {
22886 switch (otherRegion) {
23098 case 1: // top and left edge
22887 case 1: // top and left edge
23099 {
22888 {
23100 intersectValuePx = valueMaxPx;
22889 intersectValue = valueMax;
23101 intersectKeyPx = otherKeyPx
22890 intersectKey
23102 + (keyPx - otherKeyPx) / (valuePx - otherValuePx)
22891 = otherKey
23103 * (intersectValuePx - otherValuePx);
22892 + (key - otherKey) / (value - otherValue) * (intersectValue - otherValue);
23104 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx)
22893 if (intersectKey < keyMin
23105 || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not
22894 || intersectKey > keyMax) // doesn't intersect, so must intersect other:
23106 // intersected, then it must be left
23107 // edge (qMin/qMax necessary since
23108 // axes may be reversed)
23109 {
22895 {
23110 intersectKeyPx = keyMinPx;
22896 intersectKey = keyMin;
23111 intersectValuePx = otherValuePx
22897 intersectValue
23112 + (valuePx - otherValuePx) / (keyPx - otherKeyPx)
22898 = otherValue
23113 * (intersectKeyPx - otherKeyPx);
22899 + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey);
23114 }
22900 }
23115 break;
22901 break;
23116 }
22902 }
23117 case 2: // left edge
22903 case 2: // left edge
23118 {
22904 {
23119 intersectKeyPx = keyMinPx;
22905 intersectKey = keyMin;
23120 intersectValuePx
22906 intersectValue
23121 = otherValuePx
22907 = otherValue + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey);
23122 + (valuePx - otherValuePx) / (keyPx - otherKeyPx) * (intersectKeyPx - otherKeyPx);
23123 break;
22908 break;
23124 }
22909 }
23125 case 3: // bottom and left edge
22910 case 3: // bottom and left edge
23126 {
22911 {
23127 intersectValuePx = valueMinPx;
22912 intersectValue = valueMin;
23128 intersectKeyPx = otherKeyPx
22913 intersectKey
23129 + (keyPx - otherKeyPx) / (valuePx - otherValuePx)
22914 = otherKey
23130 * (intersectValuePx - otherValuePx);
22915 + (key - otherKey) / (value - otherValue) * (intersectValue - otherValue);
23131 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx)
22916 if (intersectKey < keyMin
23132 || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not
22917 || intersectKey > keyMax) // doesn't intersect, so must intersect other:
23133 // intersected, then it must be left
23134 // edge (qMin/qMax necessary since
23135 // axes may be reversed)
23136 {
22918 {
23137 intersectKeyPx = keyMinPx;
22919 intersectKey = keyMin;
23138 intersectValuePx = otherValuePx
22920 intersectValue
23139 + (valuePx - otherValuePx) / (keyPx - otherKeyPx)
22921 = otherValue
23140 * (intersectKeyPx - otherKeyPx);
22922 + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey);
23141 }
22923 }
23142 break;
22924 break;
23143 }
22925 }
23144 case 4: // top edge
22926 case 4: // top edge
23145 {
22927 {
23146 intersectValuePx = valueMaxPx;
22928 intersectValue = valueMax;
23147 intersectKeyPx = otherKeyPx
22929 intersectKey
23148 + (keyPx - otherKeyPx) / (valuePx - otherValuePx)
22930 = otherKey
23149 * (intersectValuePx - otherValuePx);
22931 + (key - otherKey) / (value - otherValue) * (intersectValue - otherValue);
23150 break;
22932 break;
23151 }
22933 }
23152 case 5: {
22934 case 5: {
@@ -23155,63 +22937,53 QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double oth
23155 }
22937 }
23156 case 6: // bottom edge
22938 case 6: // bottom edge
23157 {
22939 {
23158 intersectValuePx = valueMinPx;
22940 intersectValue = valueMin;
23159 intersectKeyPx = otherKeyPx
22941 intersectKey
23160 + (keyPx - otherKeyPx) / (valuePx - otherValuePx)
22942 = otherKey
23161 * (intersectValuePx - otherValuePx);
22943 + (key - otherKey) / (value - otherValue) * (intersectValue - otherValue);
23162 break;
22944 break;
23163 }
22945 }
23164 case 7: // top and right edge
22946 case 7: // top and right edge
23165 {
22947 {
23166 intersectValuePx = valueMaxPx;
22948 intersectValue = valueMax;
23167 intersectKeyPx = otherKeyPx
22949 intersectKey
23168 + (keyPx - otherKeyPx) / (valuePx - otherValuePx)
22950 = otherKey
23169 * (intersectValuePx - otherValuePx);
22951 + (key - otherKey) / (value - otherValue) * (intersectValue - otherValue);
23170 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx)
22952 if (intersectKey < keyMin
23171 || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not
22953 || intersectKey > keyMax) // doesn't intersect, so must intersect other:
23172 // intersected, then it must be right
23173 // edge (qMin/qMax necessary since
23174 // axes may be reversed)
23175 {
22954 {
23176 intersectKeyPx = keyMaxPx;
22955 intersectKey = keyMax;
23177 intersectValuePx = otherValuePx
22956 intersectValue
23178 + (valuePx - otherValuePx) / (keyPx - otherKeyPx)
22957 = otherValue
23179 * (intersectKeyPx - otherKeyPx);
22958 + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey);
23180 }
22959 }
23181 break;
22960 break;
23182 }
22961 }
23183 case 8: // right edge
22962 case 8: // right edge
23184 {
22963 {
23185 intersectKeyPx = keyMaxPx;
22964 intersectKey = keyMax;
23186 intersectValuePx
22965 intersectValue
23187 = otherValuePx
22966 = otherValue + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey);
23188 + (valuePx - otherValuePx) / (keyPx - otherKeyPx) * (intersectKeyPx - otherKeyPx);
23189 break;
22967 break;
23190 }
22968 }
23191 case 9: // bottom and right edge
22969 case 9: // bottom and right edge
23192 {
22970 {
23193 intersectValuePx = valueMinPx;
22971 intersectValue = valueMin;
23194 intersectKeyPx = otherKeyPx
22972 intersectKey
23195 + (keyPx - otherKeyPx) / (valuePx - otherValuePx)
22973 = otherKey
23196 * (intersectValuePx - otherValuePx);
22974 + (key - otherKey) / (value - otherValue) * (intersectValue - otherValue);
23197 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx)
22975 if (intersectKey < keyMin
23198 || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not
22976 || intersectKey > keyMax) // doesn't intersect, so must intersect other:
23199 // intersected, then it must be right
23200 // edge (qMin/qMax necessary since
23201 // axes may be reversed)
23202 {
22977 {
23203 intersectKeyPx = keyMaxPx;
22978 intersectKey = keyMax;
23204 intersectValuePx = otherValuePx
22979 intersectValue
23205 + (valuePx - otherValuePx) / (keyPx - otherKeyPx)
22980 = otherValue
23206 * (intersectKeyPx - otherKeyPx);
22981 + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey);
23207 }
22982 }
23208 break;
22983 break;
23209 }
22984 }
23210 }
22985 }
23211 if (mKeyAxis->orientation() == Qt::Horizontal)
22986 return coordsToPixels(intersectKey, intersectValue);
23212 return QPointF(intersectKeyPx, intersectValuePx);
23213 else
23214 return QPointF(intersectValuePx, intersectKeyPx);
23215 }
22987 }
23216
22988
23217 /*! \internal
22989 /*! \internal
@@ -23724,79 +23496,44 bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double
23724 double keyMin, double valueMax, double keyMax, double valueMin,
23496 double keyMin, double valueMax, double keyMax, double valueMin,
23725 QPointF &crossA, QPointF &crossB) const
23497 QPointF &crossA, QPointF &crossB) const
23726 {
23498 {
23727 // The intersection point interpolation here is done in pixel coordinates, so we don't need to
23499 QList<QPointF> intersections; // x of QPointF corresponds to key and y to value
23728 // differentiate between different axis scale types. Note that the nomenclature
23729 // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be
23730 // different in pixel coordinates (horz/vert key axes, reversed ranges)
23731
23732 QList<QPointF> intersections;
23733 const double valueMinPx = mValueAxis->coordToPixel(valueMin);
23734 const double valueMaxPx = mValueAxis->coordToPixel(valueMax);
23735 const double keyMinPx = mKeyAxis->coordToPixel(keyMin);
23736 const double keyMaxPx = mKeyAxis->coordToPixel(keyMax);
23737 const double keyPx = mKeyAxis->coordToPixel(key);
23738 const double valuePx = mValueAxis->coordToPixel(value);
23739 const double prevKeyPx = mKeyAxis->coordToPixel(prevKey);
23740 const double prevValuePx = mValueAxis->coordToPixel(prevValue);
23741 if (qFuzzyIsNull(key - prevKey)) // line is parallel to value axis
23500 if (qFuzzyIsNull(key - prevKey)) // line is parallel to value axis
23742 {
23501 {
23743 // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5
23502 // due to region filter in mayTraverseR(), if line is parallel to value or key axis, R is
23744 // is traversed here
23503 // traversed here
23745 intersections.append(
23504 intersections.append(
23746 mKeyAxis->orientation() == Qt::Horizontal
23505 QPointF(key, valueMin)); // direction will be taken care of at end of method
23747 ? QPointF(keyPx, valueMinPx)
23506 intersections.append(QPointF(key, valueMax));
23748 : QPointF(valueMinPx, keyPx)); // direction will be taken care of at end of method
23749 intersections.append(mKeyAxis->orientation() == Qt::Horizontal
23750 ? QPointF(keyPx, valueMaxPx)
23751 : QPointF(valueMaxPx, keyPx));
23752 }
23507 }
23753 else if (qFuzzyIsNull(value - prevValue)) // line is parallel to key axis
23508 else if (qFuzzyIsNull(value - prevValue)) // line is parallel to key axis
23754 {
23509 {
23755 // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5
23510 // due to region filter in mayTraverseR(), if line is parallel to value or key axis, R is
23756 // is traversed here
23511 // traversed here
23757 intersections.append(
23512 intersections.append(
23758 mKeyAxis->orientation() == Qt::Horizontal
23513 QPointF(keyMin, value)); // direction will be taken care of at end of method
23759 ? QPointF(keyMinPx, valuePx)
23514 intersections.append(QPointF(keyMax, value));
23760 : QPointF(valuePx, keyMinPx)); // direction will be taken care of at end of method
23761 intersections.append(mKeyAxis->orientation() == Qt::Horizontal
23762 ? QPointF(keyMaxPx, valuePx)
23763 : QPointF(valuePx, keyMaxPx));
23764 }
23515 }
23765 else // line is skewed
23516 else // line is skewed
23766 {
23517 {
23767 double gamma;
23518 double gamma;
23768 double keyPerValuePx = (keyPx - prevKeyPx) / (valuePx - prevValuePx);
23519 double keyPerValue = (key - prevKey) / (value - prevValue);
23769 // check top of rect:
23520 // check top of rect:
23770 gamma = prevKeyPx + (valueMaxPx - prevValuePx) * keyPerValuePx;
23521 gamma = prevKey + (valueMax - prevValue) * keyPerValue;
23771 if (gamma >= qMin(keyMinPx, keyMaxPx)
23522 if (gamma >= keyMin && gamma <= keyMax)
23772 && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed
23523 intersections.append(QPointF(gamma, valueMax));
23773 intersections.append(mKeyAxis->orientation() == Qt::Horizontal
23774 ? QPointF(gamma, valueMaxPx)
23775 : QPointF(valueMaxPx, gamma));
23776 // check bottom of rect:
23524 // check bottom of rect:
23777 gamma = prevKeyPx + (valueMinPx - prevValuePx) * keyPerValuePx;
23525 gamma = prevKey + (valueMin - prevValue) * keyPerValue;
23778 if (gamma >= qMin(keyMinPx, keyMaxPx)
23526 if (gamma >= keyMin && gamma <= keyMax)
23779 && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed
23527 intersections.append(QPointF(gamma, valueMin));
23780 intersections.append(mKeyAxis->orientation() == Qt::Horizontal
23528 double valuePerKey = 1.0 / keyPerValue;
23781 ? QPointF(gamma, valueMinPx)
23782 : QPointF(valueMinPx, gamma));
23783 const double valuePerKeyPx = 1.0 / keyPerValuePx;
23784 // check left of rect:
23529 // check left of rect:
23785 gamma = prevValuePx + (keyMinPx - prevKeyPx) * valuePerKeyPx;
23530 gamma = prevValue + (keyMin - prevKey) * valuePerKey;
23786 if (gamma >= qMin(valueMinPx, valueMaxPx)
23531 if (gamma >= valueMin && gamma <= valueMax)
23787 && gamma <= qMax(valueMinPx,
23532 intersections.append(QPointF(keyMin, gamma));
23788 valueMaxPx)) // qMin/qMax necessary since axes may be reversed
23789 intersections.append(mKeyAxis->orientation() == Qt::Horizontal
23790 ? QPointF(keyMinPx, gamma)
23791 : QPointF(gamma, keyMinPx));
23792 // check right of rect:
23533 // check right of rect:
23793 gamma = prevValuePx + (keyMaxPx - prevKeyPx) * valuePerKeyPx;
23534 gamma = prevValue + (keyMax - prevKey) * valuePerKey;
23794 if (gamma >= qMin(valueMinPx, valueMaxPx)
23535 if (gamma >= valueMin && gamma <= valueMax)
23795 && gamma <= qMax(valueMinPx,
23536 intersections.append(QPointF(keyMax, gamma));
23796 valueMaxPx)) // qMin/qMax necessary since axes may be reversed
23797 intersections.append(mKeyAxis->orientation() == Qt::Horizontal
23798 ? QPointF(keyMaxPx, gamma)
23799 : QPointF(gamma, keyMaxPx));
23800 }
23537 }
23801
23538
23802 // handle cases where found points isn't exactly 2:
23539 // handle cases where found points isn't exactly 2:
@@ -23825,16 +23562,12 bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double
23825 }
23562 }
23826
23563
23827 // possibly re-sort points so optimized point segment has same direction as original segment:
23564 // possibly re-sort points so optimized point segment has same direction as original segment:
23828 double xDelta = keyPx - prevKeyPx;
23565 if ((key - prevKey) * (intersections.at(1).x() - intersections.at(0).x())
23829 double yDelta = valuePx - prevValuePx;
23566 + (value - prevValue) * (intersections.at(1).y() - intersections.at(0).y())
23830 if (mKeyAxis->orientation() != Qt::Horizontal)
23831 qSwap(xDelta, yDelta);
23832 if (xDelta * (intersections.at(1).x() - intersections.at(0).x())
23833 + yDelta * (intersections.at(1).y() - intersections.at(0).y())
23834 < 0) // scalar product of both segments < 0 -> opposite direction
23567 < 0) // scalar product of both segments < 0 -> opposite direction
23835 intersections.move(0, 1);
23568 intersections.move(0, 1);
23836 crossA = intersections.at(0);
23569 crossA = coordsToPixels(intersections.at(0).x(), intersections.at(0).y());
23837 crossB = intersections.at(1);
23570 crossB = coordsToPixels(intersections.at(1).x(), intersections.at(1).y());
23838 return true;
23571 return true;
23839 }
23572 }
23840
23573
@@ -25945,8 +25678,8 QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iter
25945 /* end of 'src/plottables/plottable-statisticalbox.cpp' */
25678 /* end of 'src/plottables/plottable-statisticalbox.cpp' */
25946
25679
25947
25680
25948 /* including file 'src/plottables/plottable-colormap.cpp', size 47881 */
25681 /* including file 'src/plottables/plottable-colormap.cpp', size 47531 */
25949 /* commit 83a770151292397b3ba4984108d7ed167a9aec65 2017-08-13 16:22:21 +0200 */
25682 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
25950
25683
25951 ////////////////////////////////////////////////////////////////////////////////////////////////////
25684 ////////////////////////////////////////////////////////////////////////////////////////////////////
25952 //////////////////// QCPColorMapData
25685 //////////////////// QCPColorMapData
@@ -26617,7 +26350,6 QCPColorMap::QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis)
26617 : QCPAbstractPlottable(keyAxis, valueAxis),
26350 : QCPAbstractPlottable(keyAxis, valueAxis),
26618 mDataScaleType(QCPAxis::stLinear),
26351 mDataScaleType(QCPAxis::stLinear),
26619 mMapData(new QCPColorMapData(10, 10, QCPRange(0, 5), QCPRange(0, 5))),
26352 mMapData(new QCPColorMapData(10, 10, QCPRange(0, 5), QCPRange(0, 5))),
26620 mGradient(QCPColorGradient::gpCold),
26621 mInterpolate(true),
26353 mInterpolate(true),
26622 mTightBoundary(false),
26354 mTightBoundary(false),
26623 mMapImageInvalidated(true)
26355 mMapImageInvalidated(true)
@@ -26977,82 +26709,74 void QCPColorMap::updateMapImage()
26977 mMapImage = QImage(
26709 mMapImage = QImage(
26978 QSize(valueSize * valueOversamplingFactor, keySize * keyOversamplingFactor), format);
26710 QSize(valueSize * valueOversamplingFactor, keySize * keyOversamplingFactor), format);
26979
26711
26980 if (mMapImage.isNull()) {
26712 QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates.
26981 qDebug() << Q_FUNC_INFO << "Couldn't create map image (possibly too large for memory)";
26713 // Either the final mMapImage, or if we need oversampling,
26982 mMapImage = QImage(QSize(10, 10), format);
26714 // mUndersampledMapImage
26983 mMapImage.fill(Qt::black);
26715 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) {
26984 }
26716 // resize undersampled map image to actual key/value cell sizes:
26985 else {
26717 if (keyAxis->orientation() == Qt::Horizontal
26986 QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates.
26718 && (mUndersampledMapImage.width() != keySize
26987 // Either the final mMapImage, or if we need
26719 || mUndersampledMapImage.height() != valueSize))
26988 // oversampling, mUndersampledMapImage
26720 mUndersampledMapImage = QImage(QSize(keySize, valueSize), format);
26989 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) {
26721 else if (keyAxis->orientation() == Qt::Vertical
26990 // resize undersampled map image to actual key/value cell sizes:
26722 && (mUndersampledMapImage.width() != valueSize
26991 if (keyAxis->orientation() == Qt::Horizontal
26723 || mUndersampledMapImage.height() != keySize))
26992 && (mUndersampledMapImage.width() != keySize
26724 mUndersampledMapImage = QImage(QSize(valueSize, keySize), format);
26993 || mUndersampledMapImage.height() != valueSize))
26725 localMapImage
26994 mUndersampledMapImage = QImage(QSize(keySize, valueSize), format);
26726 = &mUndersampledMapImage; // make the colorization run on the undersampled image
26995 else if (keyAxis->orientation() == Qt::Vertical
26727 }
26996 && (mUndersampledMapImage.width() != valueSize
26728 else if (!mUndersampledMapImage.isNull())
26997 || mUndersampledMapImage.height() != keySize))
26729 mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has
26998 mUndersampledMapImage = QImage(QSize(valueSize, keySize), format);
26730 // changed) but mUndersampledMapImage still has nonzero
26999 localMapImage
26731 // size, free it
27000 = &mUndersampledMapImage; // make the colorization run on the undersampled image
26732
27001 }
26733 const double *rawData = mMapData->mData;
27002 else if (!mUndersampledMapImage.isNull())
26734 const unsigned char *rawAlpha = mMapData->mAlpha;
27003 mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size
26735 if (keyAxis->orientation() == Qt::Horizontal) {
27004 // has changed) but mUndersampledMapImage still has
26736 const int lineCount = valueSize;
27005 // nonzero size, free it
26737 const int rowCount = keySize;
27006
26738 for (int line = 0; line < lineCount; ++line) {
27007 const double *rawData = mMapData->mData;
26739 QRgb *pixels = reinterpret_cast<QRgb *>(localMapImage->scanLine(
27008 const unsigned char *rawAlpha = mMapData->mAlpha;
26740 lineCount - 1 - line)); // invert scanline index because QImage counts scanlines
27009 if (keyAxis->orientation() == Qt::Horizontal) {
26741 // from top, but our vertical index counts from bottom
27010 const int lineCount = valueSize;
26742 // (mathematical coordinate system)
27011 const int rowCount = keySize;
26743 if (rawAlpha)
27012 for (int line = 0; line < lineCount; ++line) {
26744 mGradient.colorize(rawData + line * rowCount, rawAlpha + line * rowCount,
27013 QRgb *pixels = reinterpret_cast<QRgb *>(localMapImage->scanLine(
26745 mDataRange, pixels, rowCount, 1,
27014 lineCount - 1 - line)); // invert scanline index because QImage counts scanlines
26746 mDataScaleType == QCPAxis::stLogarithmic);
27015 // from top, but our vertical index counts from bottom
26747 else
27016 // (mathematical coordinate system)
26748 mGradient.colorize(rawData + line * rowCount, mDataRange, pixels, rowCount, 1,
27017 if (rawAlpha)
26749 mDataScaleType == QCPAxis::stLogarithmic);
27018 mGradient.colorize(rawData + line * rowCount, rawAlpha + line * rowCount,
27019 mDataRange, pixels, rowCount, 1,
27020 mDataScaleType == QCPAxis::stLogarithmic);
27021 else
27022 mGradient.colorize(rawData + line * rowCount, mDataRange, pixels, rowCount, 1,
27023 mDataScaleType == QCPAxis::stLogarithmic);
27024 }
27025 }
27026 else // keyAxis->orientation() == Qt::Vertical
27027 {
27028 const int lineCount = keySize;
27029 const int rowCount = valueSize;
27030 for (int line = 0; line < lineCount; ++line) {
27031 QRgb *pixels = reinterpret_cast<QRgb *>(localMapImage->scanLine(
27032 lineCount - 1 - line)); // invert scanline index because QImage counts scanlines
27033 // from top, but our vertical index counts from bottom
27034 // (mathematical coordinate system)
27035 if (rawAlpha)
27036 mGradient.colorize(rawData + line, rawAlpha + line, mDataRange, pixels,
27037 rowCount, lineCount,
27038 mDataScaleType == QCPAxis::stLogarithmic);
27039 else
27040 mGradient.colorize(rawData + line, mDataRange, pixels, rowCount, lineCount,
27041 mDataScaleType == QCPAxis::stLogarithmic);
27042 }
27043 }
26750 }
27044
26751 }
27045 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) {
26752 else // keyAxis->orientation() == Qt::Vertical
27046 if (keyAxis->orientation() == Qt::Horizontal)
26753 {
27047 mMapImage = mUndersampledMapImage.scaled(
26754 const int lineCount = keySize;
27048 keySize * keyOversamplingFactor, valueSize * valueOversamplingFactor,
26755 const int rowCount = valueSize;
27049 Qt::IgnoreAspectRatio, Qt::FastTransformation);
26756 for (int line = 0; line < lineCount; ++line) {
26757 QRgb *pixels = reinterpret_cast<QRgb *>(localMapImage->scanLine(
26758 lineCount - 1 - line)); // invert scanline index because QImage counts scanlines
26759 // from top, but our vertical index counts from bottom
26760 // (mathematical coordinate system)
26761 if (rawAlpha)
26762 mGradient.colorize(rawData + line, rawAlpha + line, mDataRange, pixels, rowCount,
26763 lineCount, mDataScaleType == QCPAxis::stLogarithmic);
27050 else
26764 else
27051 mMapImage = mUndersampledMapImage.scaled(
26765 mGradient.colorize(rawData + line, mDataRange, pixels, rowCount, lineCount,
27052 valueSize * valueOversamplingFactor, keySize * keyOversamplingFactor,
26766 mDataScaleType == QCPAxis::stLogarithmic);
27053 Qt::IgnoreAspectRatio, Qt::FastTransformation);
27054 }
26767 }
27055 }
26768 }
26769
26770 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) {
26771 if (keyAxis->orientation() == Qt::Horizontal)
26772 mMapImage = mUndersampledMapImage.scaled(keySize * keyOversamplingFactor,
26773 valueSize * valueOversamplingFactor,
26774 Qt::IgnoreAspectRatio, Qt::FastTransformation);
26775 else
26776 mMapImage = mUndersampledMapImage.scaled(valueSize * valueOversamplingFactor,
26777 keySize * keyOversamplingFactor,
26778 Qt::IgnoreAspectRatio, Qt::FastTransformation);
26779 }
27056 mMapData->mDataModified = false;
26780 mMapData->mDataModified = false;
27057 mMapImageInvalidated = false;
26781 mMapImageInvalidated = false;
27058 }
26782 }
@@ -28215,8 +27939,8 QRectF QCPFinancial::selectionHitBox(QCPFinancialDataContainer::const_iterator i
28215 /* end of 'src/plottables/plottable-financial.cpp' */
27939 /* end of 'src/plottables/plottable-financial.cpp' */
28216
27940
28217
27941
28218 /* including file 'src/plottables/plottable-errorbar.cpp', size 37355 */
27942 /* including file 'src/plottables/plottable-errorbar.cpp', size 37210 */
28219 /* commit 6f159843e9ec9ea6431b26591937aea13a9f2751 2017-07-25 11:13:32 +0200 */
27943 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
28220
27944
28221 ////////////////////////////////////////////////////////////////////////////////////////////////////
27945 ////////////////////////////////////////////////////////////////////////////////////////////////////
28222 //////////////////// QCPErrorBarsData
27946 //////////////////// QCPErrorBarsData
@@ -28947,8 +28671,8 void QCPErrorBars::getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it
28947 QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index);
28671 QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index);
28948 if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y()))
28672 if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y()))
28949 return;
28673 return;
28950 QCPAxis *errorAxis = mErrorType == etValueError ? mValueAxis.data() : mKeyAxis.data();
28674 QCPAxis *errorAxis = mErrorType == etValueError ? mValueAxis : mKeyAxis;
28951 QCPAxis *orthoAxis = mErrorType == etValueError ? mKeyAxis.data() : mValueAxis.data();
28675 QCPAxis *orthoAxis = mErrorType == etValueError ? mKeyAxis : mValueAxis;
28952 const double centerErrorAxisPixel
28676 const double centerErrorAxisPixel
28953 = errorAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y();
28677 = errorAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y();
28954 const double centerOrthoAxisPixel
28678 const double centerOrthoAxisPixel
@@ -29082,10 +28806,6 double QCPErrorBars::pointDistance(const QPointF &pixelPoint,
29082 closestData = mDataContainer->constEnd();
28806 closestData = mDataContainer->constEnd();
29083 if (!mDataPlottable || mDataContainer->isEmpty())
28807 if (!mDataPlottable || mDataContainer->isEmpty())
29084 return -1.0;
28808 return -1.0;
29085 if (!mKeyAxis || !mValueAxis) {
29086 qDebug() << Q_FUNC_INFO << "invalid key or value axis";
29087 return -1.0;
29088 }
29089
28809
29090 QCPErrorBarsDataContainer::const_iterator begin, end;
28810 QCPErrorBarsDataContainer::const_iterator begin, end;
29091 getVisibleDataBounds(begin, end, QCPDataRange(0, dataCount()));
28811 getVisibleDataBounds(begin, end, QCPDataRange(0, dataCount()));
@@ -15,16 +15,7
15 </property>
15 </property>
16 <layout class="QGridLayout" name="gridLayout">
16 <layout class="QGridLayout" name="gridLayout">
17 <item row="0" column="0">
17 <item row="0" column="0">
18 <widget class="QLineEdit" name="filterLineEdit"/>
18 <widget class="QTreeWidget" name="treeWidget"/>
19 </item>
20 <item row="1" column="0">
21 <widget class="QTreeWidget" name="treeWidget">
22 <column>
23 <property name="text">
24 <string notr="true">1</string>
25 </property>
26 </column>
27 </widget>
28 </item>
19 </item>
29 </layout>
20 </layout>
30 </widget>
21 </widget>
@@ -14,27 +14,28
14 <string>Form</string>
14 <string>Form</string>
15 </property>
15 </property>
16 <layout class="QVBoxLayout" name="verticalLayout">
16 <layout class="QVBoxLayout" name="verticalLayout">
17 <property name="leftMargin">
18 <number>0</number>
19 </property>
20 <property name="topMargin">
21 <number>0</number>
22 </property>
23 <property name="rightMargin">
24 <number>0</number>
25 </property>
26 <property name="bottomMargin">
27 <number>0</number>
28 </property>
29 <item>
17 <item>
30 <widget class="QTabWidget" name="tabWidget">
18 <widget class="QTabWidget" name="tabWidget">
31 <property name="currentIndex">
19 <property name="currentIndex">
32 <number>-1</number>
20 <number>0</number>
33 </property>
21 </property>
22 <widget class="VisualizationTabWidget" name="firstView">
23 <attribute name="title">
24 <string>View 1</string>
25 </attribute>
26 </widget>
34 </widget>
27 </widget>
35 </item>
28 </item>
36 </layout>
29 </layout>
37 </widget>
30 </widget>
31 <customwidgets>
32 <customwidget>
33 <class>VisualizationTabWidget</class>
34 <extends>QWidget</extends>
35 <header location="global">Visualization/VisualizationTabWidget.h</header>
36 <container>1</container>
37 </customwidget>
38 </customwidgets>
38 <resources/>
39 <resources/>
39 <connections/>
40 <connections/>
40 </ui>
41 </ui>
@@ -1,7 +1,9
1 <?xml version="1.0" encoding="UTF-8"?>
2 <ui version="4.0">
1 <ui version="4.0">
3 <class>VariableInspectorWidget</class>
2 <author/>
4 <widget class="QWidget" name="VariableInspectorWidget">
3 <comment/>
4 <exportmacro/>
5 <class>VisualizationZoneWidget</class>
6 <widget name="VisualizationZoneWidget" class="QWidget">
5 <property name="geometry">
7 <property name="geometry">
6 <rect>
8 <rect>
7 <x>0</x>
9 <x>0</x>
@@ -11,21 +13,9
11 </rect>
13 </rect>
12 </property>
14 </property>
13 <property name="windowTitle">
15 <property name="windowTitle">
14 <string>Variables</string>
16 <string>Form</string>
15 </property>
17 </property>
16 <layout class="QGridLayout" name="gridLayout">
17 <item row="0" column="0">
18 <widget class="QTableView" name="tableView">
19 <property name="sortingEnabled">
20 <bool>true</bool>
21 </property>
22 <attribute name="horizontalHeaderStretchLastSection">
23 <bool>true</bool>
24 </attribute>
25 </widget>
26 </item>
27 </layout>
28 </widget>
18 </widget>
29 <resources/>
19 <pixmapfunction/>
30 <connections/>
20 <connections/>
31 </ui>
21 </ui>
@@ -6,4 +6,6 qcustomplot\.cpp:\d+:.IPSIS
6 SqpApplication\.h:\d+:.IPSIS_S03.*found: sqpApp
6 SqpApplication\.h:\d+:.IPSIS_S03.*found: sqpApp
7 SqpApplication\.h:\d+:.IPSIS_S04_VARIABLE.*found: sqpApp
7 SqpApplication\.h:\d+:.IPSIS_S04_VARIABLE.*found: sqpApp
8
8
9 # Ignore false positive relative to unnamed namespace
10 DataSourceTreeWidgetItem\.cpp:\d+:.*IPSIS_F13.*
9
11
@@ -17,14 +17,7 SCIQLOP_FIND_QT(Core)
17 FILE (GLOB_RECURSE MODULE_SOURCES
17 FILE (GLOB_RECURSE MODULE_SOURCES
18 ${INCLUDES_DIR}/*.h)
18 ${INCLUDES_DIR}/*.h)
19
19
20 ADD_LIBRARY(${SQPPLUGIN_LIBRARY_NAME} ${MODULE_SOURCES})
20 ADD_LIBRARY(${SQPPLUGIN_LIBRARY_NAME} ${MODULE_SOURCES})
21
22 INSTALL(TARGETS ${SQPPLUGIN_LIBRARY_NAME}
23 RUNTIME DESTINATION ${INSTALL_BINARY_DIR}
24 LIBRARY DESTINATION ${INSTALL_LIBRARY_DIR}
25 ARCHIVE DESTINATION ${INSTALL_LIBRARY_DIR}
26 )
27
28
21
29 # Add the files to the list of files to be analyzed
22 # Add the files to the list of files to be analyzed
30 LIST(APPEND CHECKSTYLE_INPUT_FILES ${MODULE_SOURCES})
23 LIST(APPEND CHECKSTYLE_INPUT_FILES ${MODULE_SOURCES})
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (674 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (842 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (636 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (22288 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (29129 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (10802 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (360000 lines changed) Show them Hide them
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 3
there is 1 general comment from older versions, show it
Under Review
author

Pull request updated. Auto status change to "Under Review"

Changed commits:
  * 6 added
  * 3 removed

Changed files:
  * A gui/src/Visualization/VisualizationWidget.cpp
  * A gui/include/SidePane/SqpSidePane.h
  * A gui/include/Visualization/VisualizationGraphWidget.h
  * A gui/include/Visualization/VisualizationTabWidget.h
  * A gui/include/Visualization/VisualizationWidget.h
  * A gui/include/Visualization/VisualizationZoneWidget.h
  * A gui/include/Visualization/qcustomplot.h
  * A gui/src/SidePane/SqpSidePane.cpp
  * A gui/src/Visualization/VisualizationGraphWidget.cpp
  * A gui/src/Visualization/VisualizationTabWidget.cpp
  * A gui/src/Visualization/VisualizationZoneWidget.cpp
  * A gui/src/Visualization/qcustomplot.cpp
  * M gui/include/DataSource/DataSourceWidget.h
  * M gui/src/DataSource/DataSourceTreeWidgetItem.cpp
  * M gui/src/DataSource/DataSourceWidget.cpp
  * M app/src/Main.cpp
  * M app/src/MainWindow.cpp
  * M app/ui/MainWindow.ui
  * M core/include/DataSource/DataSourceController.h
  * M core/src/DataSource/DataSourceController.cpp
  * M core/tests/DataSource/TestDataSourceController.cpp
  * M gui/ui/visualization/VisualizationWidget.ui
  * M gui/vera-exclusions/exclusions.txt
  * M gui/src/visualization/VisualizationWidget.cpp
  * R cmake/sciqlop_package_qt.cmake
  * R core/include/Plugin/PluginManager.h
  * R core/include/Visualization/VisualizationController.h
  * R core/src/Plugin/PluginManager.cpp
  * R core/src/Visualization/VisualizationController.cpp
  * R gui/include/sidepane/SqpSidePane.h
  * R gui/include/visualization/VisualizationGraphWidget.h
  * R gui/include/visualization/VisualizationTabWidget.h
  * R gui/include/visualization/VisualizationWidget.h
  * R gui/include/visualization/VisualizationZoneWidget.h
  * R gui/include/visualization/qcustomplot.h
  * R gui/src/sidepane/SqpSidePane.cpp
  * R gui/src/visualization/VisualizationGraphWidget.cpp
  * R gui/src/visualization/VisualizationTabWidget.cpp
  * R gui/src/visualization/VisualizationZoneWidget.cpp
  * R gui/src/visualization/qcustomplot.cpp
  * R gui/ui/sidepane/SqpSidePane.ui
  * R gui/ui/visualization/VisualizationGraphWidget.ui
  * R gui/ui/visualization/VisualizationTabWidget.ui
  * R gui/ui/visualization/VisualizationZoneWidget.ui
  * R plugin/CMakeLists.txt
  * R plugin/cmake/Findsciqlop-plugin.cmake
  * R plugin/include/Plugin/IPlugin.h
  * R app/CMakeLists.txt
  * R app/include/MainWindow.h
  * R app/vera-exclusions/exclusions.txt
  * R cmake/sciqlop_applications.cmake
  * R core/CMakeLists.txt
  * R core/include/Common/spimpl.h
  * R gui/CMakeLists.txt
  * R gui/include/SqpApplication.h
  * R gui/src/SqpApplication.cpp
  * R app/src/mainwindow.ui
Approved
author

Status change > Approved