##// END OF EJS Templates
Closed
Pull request !138 Created on Wed, 07 Jun 2017 16:33:09, by
- Merge branch 'feature/InitPlugin' into develop
- Unit tests for plugin loading (2)
- Unit tests for plugin loading (1)
- Implements method to get the number of plugins loaded
- Adds logs in plugin loading method
Pull request versions not available.
ver Time Author Commit Description
22 commits hidden, click expand to show them.
@@ -0,0 +1,1
1 TODO
@@ -0,0 +1,21
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
3
4 #include <QWidget>
5
6 namespace Ui {
7 class VisualizationGraphWidget;
8 } // namespace Ui
9
10 class VisualizationGraphWidget : public QWidget {
11 Q_OBJECT
12
13 public:
14 explicit VisualizationGraphWidget(QWidget *parent = 0);
15 virtual ~VisualizationGraphWidget();
16
17 private:
18 Ui::VisualizationGraphWidget *ui;
19 };
20
21 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -0,0 +1,21
1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
3
4 #include <QWidget>
5
6 namespace Ui {
7 class VisualizationTabWidget;
8 } // namespace Ui
9
10 class VisualizationTabWidget : public QWidget {
11 Q_OBJECT
12
13 public:
14 explicit VisualizationTabWidget(QWidget *parent = 0);
15 virtual ~VisualizationTabWidget();
16
17 private:
18 Ui::VisualizationTabWidget *ui;
19 };
20
21 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
@@ -0,0 +1,21
1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
3
4 #include <QWidget>
5
6 namespace Ui {
7 class VisualizationZoneWidget;
8 } // Ui
9
10 class VisualizationZoneWidget : public QWidget {
11 Q_OBJECT
12
13 public:
14 explicit VisualizationZoneWidget(QWidget *parent = 0);
15 virtual ~VisualizationZoneWidget();
16
17 private:
18 Ui::VisualizationZoneWidget *ui;
19 };
20
21 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -0,0 +1,13
1 #include "visualization\VisualizationGraphWidget.h"
2 #include "ui_VisualizationGraphWidget.h"
3
4 VisualizationGraphWidget::VisualizationGraphWidget(QWidget *parent)
5 : QWidget(parent), ui(new Ui::VisualizationGraphWidget)
6 {
7 ui->setupUi(this);
8 }
9
10 VisualizationGraphWidget::~VisualizationGraphWidget()
11 {
12 delete ui;
13 }
@@ -0,0 +1,13
1 #include "visualization\VisualizationTabWidget.h"
2 #include "ui_VisualizationTabWidget.h"
3
4 VisualizationTabWidget::VisualizationTabWidget(QWidget *parent)
5 : QWidget(parent), ui(new Ui::VisualizationTabWidget)
6 {
7 ui->setupUi(this);
8 }
9
10 VisualizationTabWidget::~VisualizationTabWidget()
11 {
12 delete ui;
13 }
@@ -0,0 +1,13
1 #include "visualization\VisualizationWidget.h"
2 #include "ui_VisualizationWidget.h"
3
4 VisualizationWidget::VisualizationWidget(QWidget *parent)
5 : QWidget(parent), ui(new Ui::VisualizationWidget)
6 {
7 ui->setupUi(this);
8 }
9
10 VisualizationWidget::~VisualizationWidget()
11 {
12 delete ui;
13 }
@@ -0,0 +1,13
1 #include "visualization\VisualizationZoneWidget.h"
2 #include "ui_VisualizationZoneWidget.h"
3
4 VisualizationZoneWidget::VisualizationZoneWidget(QWidget *parent)
5 : QWidget(parent), ui(new Ui::VisualizationZoneWidget)
6 {
7 ui->setupUi(this);
8 }
9
10 VisualizationZoneWidget::~VisualizationZoneWidget()
11 {
12 delete ui;
13 }
@@ -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%"}
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
1 TODO No newline at end of file
@@ -14,7 +14,6 include_directories("${INCLUDES_DIR}")
14 14 # Find Qt modules
15 15 #
16 16 SCIQLOP_FIND_QT(Core Widgets)
17
18 17
19 18 #
20 19 # Find dependent libraries
@@ -66,18 +65,9 set_property(TARGET ${EXECUTABLE_NAME} PROPERTY CXX_STANDARD 14)
66 65 set_property(TARGET ${EXECUTABLE_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
67 66 target_link_libraries(${EXECUTABLE_NAME}
68 67 ${LIBRARIES})
69
70 INSTALL(TARGETS ${EXECUTABLE_NAME}
71 RUNTIME DESTINATION ${INSTALL_BINARY_DIR}
72 LIBRARY DESTINATION ${INSTALL_BINARY_DIR}
73 ARCHIVE DESTINATION ${INSTALL_BINARY_DIR}
74 )
68
75 69 # Link with Qt5 modules
76 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 73 # Add the files to the list of files to be analyzed
@@ -23,20 +23,17
23 23 #define SCIQLOP_MAINWINDOW_H
24 24
25 25 #include <QListWidgetItem>
26 #include <QLoggingCategory>
27 26 #include <QMainWindow>
28 27 #include <QProgressBar>
29 28 #include <QProgressDialog>
30 29 #include <QThread>
31 30 #include <QVBoxLayout>
32 31 #include <QWidget>
33
34 #include <Common/spimpl.h>
32 //#include "../Core/qlopservice.h"
33 //#include "../Core/qlopgui.h"
35 34
36 35 #include <memory>
37 36
38 Q_DECLARE_LOGGING_CATEGORY(LOG_MainWindow)
39
40 37 namespace Ui {
41 38 class MainWindow;
42 39 } // namespace Ui
@@ -58,8 +55,6 private:
58 55 // QWidget *m_progressWidget;
59 56 // QVBoxLayout *m_progressLayout;
60 57 // QList<QLopService*> m_qlopServices;
61 class MainWindowPrivate;
62 spimpl::unique_impl_ptr<MainWindowPrivate> impl;
63 58 };
64 59
65 60 #endif // SCIQLOP_MAINWINDOW_H
@@ -21,226 +21,90
21 21 ----------------------------------------------------------------------------*/
22 22 #include "MainWindow.h"
23 23 #include "ui_MainWindow.h"
24
25 #include <DataSource/DataSourceController.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>
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
37 24 #include <QAction>
38 25 #include <QDate>
26 #include <QDateTime>
39 27 #include <QDir>
40 28 #include <QFileDialog>
29 //#include <omp.h>
30 //#include <network/filedownloader.h>
31 //#include <qlopdatabase.h>
32 //#include <qlopsettings.h>
33 //#include <qlopgui.h>
34 //#include <spacedata.h>
35 //#include "qlopcore.h"
36 //#include "qlopcodecmanager.h"
37 //#include "cdfcodec.h"
38 //#include "amdatxtcodec.h"
39 //#include <qlopplotmanager.h>
40 #include <QAction>
41 41 #include <QToolBar>
42 #include <QToolButton>
43 42 #include <memory.h>
44
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)}
43 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), m_Ui(new Ui::MainWindow)
79 44 {
80 45 m_Ui->setupUi(this);
81 46
82 m_Ui->splitter->setCollapsible(LEFTINSPECTORSIDEPANESPLITTERINDEX, false);
83 m_Ui->splitter->setCollapsible(RIGHTINSPECTORSIDEPANESPLITTERINDEX, false);
84
85
86 47 auto leftSidePane = m_Ui->leftInspectorSidePane->sidePane();
87 auto openLeftInspectorAction = new QAction{QIcon{
88 ":/icones/previous.png",
89 },
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
48 leftSidePane->addAction("ACTION L1");
49 leftSidePane->addAction("ACTION L2");
50 leftSidePane->addAction("ACTION L3");
103 51
104 52 auto rightSidePane = m_Ui->rightInspectorSidePane->sidePane();
105 auto openRightInspectorAction = new QAction{QIcon{
106 ":/icones/next.png",
107 },
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;
53 rightSidePane->addAction("ACTION R1");
54 rightSidePane->addAction("ACTION R2");
55 rightSidePane->addAction("ACTION R3");
56
57 this->menuBar()->addAction("File");
58 auto mainToolBar = this->addToolBar("MainToolBar");
59 mainToolBar->addAction("A1");
60 /* QLopGUI::registerMenuBar(menuBar());
61 this->setWindowIcon(QIcon(":/sciqlopLOGO.svg"));
62 this->m_progressWidget = new QWidget();
63 this->m_progressLayout = new QVBoxLayout(this->m_progressWidget);
64 this->m_progressWidget->setLayout(this->m_progressLayout);
65 this->m_progressWidget->setWindowModality(Qt::WindowModal);
66 m_progressThreadIds = (int*) malloc(OMP_THREADS*sizeof(int));
67 for(int i=0;i<OMP_THREADS;i++)
68 {
69 this->m_progress.append(new QProgressBar(this->m_progressWidget));
70 this->m_progress.last()->setMinimum(0);
71 this->m_progress.last()->setMaximum(100);
72 this->m_progressLayout->addWidget(this->m_progress.last());
73 this->m_progressWidget->hide();
74 this->m_progressThreadIds[i] = -1;
136 75 }
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
187 auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar"));
188
189 auto timeWidget = new TimeWidget{};
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
208 // Widgets / controllers connections
209
210 // DataSource
211 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)),
212 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *)));
213
214 // Time
215 connect(timeWidget, SIGNAL(timeUpdated(SqpRange)), &sqpApp->timeController(),
216 SLOT(onTimeToUpdate(SqpRange)));
217
218 // Visualization
219 connect(&sqpApp->visualizationController(),
220 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
221 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
222
223 connect(&sqpApp->visualizationController(),
224 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpRange &)), m_Ui->view,
225 SLOT(onRangeChanged(std::shared_ptr<Variable>, const SqpRange &)));
226
227 // Widgets / widgets connections
228
229 // For the following connections, we use DirectConnection to allow each widget that can
230 // potentially attach a menu to the variable's menu to do so before this menu is displayed.
231 // The order of connections is also important, since it determines the order in which each
232 // widget will attach its menu
233 connect(
234 m_Ui->variableInspectorWidget,
235 SIGNAL(tableMenuAboutToBeDisplayed(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
236 m_Ui->view, SLOT(attachVariableMenu(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
237 Qt::DirectConnection);
76 this->m_progressWidget->setWindowTitle("Loading File");
77 const QList<QLopService*>ServicesToLoad=QList<QLopService*>()
78 << QLopCore::self()
79 << QLopPlotManager::self()
80 << QLopCodecManager::self()
81 << FileDownloader::self()
82 << QLopDataBase::self()
83 << SpaceData::self();
84
85 CDFCodec::registerToManager();
86 AMDATXTCodec::registerToManager();
87
88
89 for(int i=0;i<ServicesToLoad.count();i++)
90 {
91 qDebug()<<ServicesToLoad.at(i)->serviceName();
92 ServicesToLoad.at(i)->initialize(); //must be called before getGUI
93 QDockWidget* wdgt=ServicesToLoad.at(i)->getGUI();
94 if(wdgt)
95 {
96 wdgt->setAllowedAreas(Qt::AllDockWidgetAreas);
97 this->addDockWidget(Qt::TopDockWidgetArea,wdgt);
98 }
99 PythonQt::self()->getMainModule().addObject(ServicesToLoad.at(i)->serviceName(),(QObject*)ServicesToLoad.at(i));
100 }*/
238 101 }
239 102
240 103 MainWindow::~MainWindow()
241 104 {
242 105 }
243 106
107
244 108 void MainWindow::changeEvent(QEvent *e)
245 109 {
246 110 QMainWindow::changeEvent(e);
@@ -19,26 +19,12
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 #include "MainWindow.h"
22 #include "mainwindow.h"
23 23 #include <QProcessEnvironment>
24 24 #include <QThread>
25 25 #include <SqpApplication.h>
26 26 #include <qglobal.h>
27 27
28 #include <Plugin/PluginManager.h>
29 #include <QDir>
30
31 #include <QLoggingCategory>
32
33 Q_LOGGING_CATEGORY(LOG_Main, "Main")
34
35 namespace {
36
37 const auto PLUGIN_DIRECTORY_NAME = QStringLiteral("plugins");
38
39
40 } // namespace
41
42 28 int main(int argc, char *argv[])
43 29 {
44 30 SqpApplication a{argc, argv};
@@ -48,33 +34,5 int main(int argc, char *argv[])
48 34 MainWindow w;
49 35 w.show();
50 36
51 // Loads plugins
52 auto pluginDir = QDir{a.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);
65 pluginDir.cd(PLUGIN_DIRECTORY_NAME);
66 #endif
67
68 PluginManager pluginManager{};
69
70 for (auto &&path : pluginLookupPath) {
71 QDir directory{path};
72 if (directory.exists()) {
73 qCDebug(LOG_Main())
74 << QObject::tr("Plugin directory: %1").arg(directory.absolutePath());
75 pluginManager.loadPlugins(directory);
76 }
77 }
78
79 37 return a.exec();
80 38 }
@@ -11,7 +11,7
11 11 </rect>
12 12 </property>
13 13 <property name="windowTitle">
14 <string>SciQlop v0.0.1</string>
14 <string>QLop</string>
15 15 </property>
16 16 <property name="dockNestingEnabled">
17 17 <bool>true</bool>
@@ -34,7 +34,7
34 34 </property>
35 35 <layout class="QHBoxLayout" name="horizontalLayout">
36 36 <property name="spacing">
37 <number>0</number>
37 <number>3</number>
38 38 </property>
39 39 <property name="leftMargin">
40 40 <number>0</number>
@@ -49,73 +49,129
49 49 <number>0</number>
50 50 </property>
51 51 <item>
52 <widget class="QSplitter" name="splitter">
53 <property name="orientation">
54 <enum>Qt::Horizontal</enum>
55 </property>
56 <widget class="QWidget" name="leftMainInspectorWidget" native="true">
57 <layout class="QVBoxLayout" name="verticalLayout">
58 <property name="spacing">
59 <number>0</number>
60 </property>
61 <property name="leftMargin">
62 <number>0</number>
63 </property>
64 <property name="topMargin">
65 <number>0</number>
66 </property>
67 <property name="rightMargin">
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>
52 <widget class="QWidget" name="leftInspectorWidget" native="true">
53 <layout class="QHBoxLayout" name="horizontalLayout_2">
54 <property name="spacing">
55 <number>3</number>
56 </property>
57 <property name="leftMargin">
58 <number>0</number>
59 </property>
60 <property name="topMargin">
61 <number>0</number>
91 62 </property>
92 </widget>
93 <widget class="SqpSidePane" name="rightInspectorSidePane" native="true"/>
94 <widget class="QWidget" name="rightMainInspectorWidget" native="true">
95 <layout class="QVBoxLayout" name="verticalLayout_3">
96 <property name="spacing">
97 <number>0</number>
98 </property>
99 <property name="leftMargin">
100 <number>0</number>
101 </property>
102 <property name="topMargin">
103 <number>0</number>
104 </property>
105 <property name="rightMargin">
106 <number>0</number>
107 </property>
108 <property name="bottomMargin">
109 <number>0</number>
110 </property>
111 <item>
112 <widget class="QWidget" name="commonPropertyInspectorWidget" native="true"/>
113 </item>
114 <item>
115 <widget class="DataSourceWidget" name="catalogWidget" native="true"/>
116 </item>
117 </layout>
118 </widget>
63 <property name="rightMargin">
64 <number>0</number>
65 </property>
66 <property name="bottomMargin">
67 <number>0</number>
68 </property>
69 <item>
70 <widget class="QWidget" name="widget" native="true">
71 <layout class="QVBoxLayout" name="verticalLayout">
72 <property name="spacing">
73 <number>3</number>
74 </property>
75 <property name="leftMargin">
76 <number>0</number>
77 </property>
78 <property name="topMargin">
79 <number>0</number>
80 </property>
81 <property name="rightMargin">
82 <number>0</number>
83 </property>
84 <property name="bottomMargin">
85 <number>0</number>
86 </property>
87 <item>
88 <widget class="QWidget" name="dateSourceWidget" native="true"/>
89 </item>
90 <item>
91 <widget class="QWidget" name="dateTimeWidget" native="true"/>
92 </item>
93 <item>
94 <widget class="QWidget" name="variableInspectorWidget" native="true"/>
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 175 </widget>
120 176 </item>
121 177 </layout>
@@ -126,7 +182,7
126 182 <x>0</x>
127 183 <y>0</y>
128 184 <width>800</width>
129 <height>28</height>
185 <height>26</height>
130 186 </rect>
131 187 </property>
132 188 </widget>
@@ -137,25 +193,13
137 193 <customwidget>
138 194 <class>VisualizationWidget</class>
139 195 <extends>QWidget</extends>
140 <header location="global">Visualization/VisualizationWidget.h</header>
196 <header location="global">visualization/VisualizationWidget.h</header>
141 197 <container>1</container>
142 198 </customwidget>
143 199 <customwidget>
144 200 <class>SqpSidePane</class>
145 201 <extends>QWidget</extends>
146 <header location="global">SidePane/SqpSidePane.h</header>
147 <container>1</container>
148 </customwidget>
149 <customwidget>
150 <class>DataSourceWidget</class>
151 <extends>QWidget</extends>
152 <header location="global">DataSource/DataSourceWidget.h</header>
153 <container>1</container>
154 </customwidget>
155 <customwidget>
156 <class>VariableInspectorWidget</class>
157 <extends>QWidget</extends>
158 <header location="global">Variable/VariableInspectorWidget.h</header>
202 <header location="global">sidepane/SqpSidePane.h</header>
159 203 <container>1</container>
160 204 </customwidget>
161 205 </customwidgets>
@@ -1,5 +1,3
1 1 # Ignore false positive relative to App macro
2 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 22 # Configure the compiler
23 23 #
24 #INCLUDE("cmake/compiler/compiler.cmake")
24 INCLUDE("cmake/compiler/compiler.cmake")
25 25
26 26 #
27 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 16 if(BUILD_TESTS)
3 17 INCLUDE ("cmake/sciqlop_code_coverage.cmake")
@@ -21,25 +35,6 ADD_SUBDIRECTORY("${CMAKE_SOURCE_DIR}/gui")
21 35
22 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 38 # LOGGER
44 39 set(QTLOGGING_INI_FILE "${CMAKE_SOURCE_DIR}/config/QtProject/qtlogging.ini")
45 40 FILE(COPY ${QTLOGGING_INI_FILE} DESTINATION ${CONFIG_OUTPUT_PATH})
@@ -26,11 +26,11 SET (CPACK_PACKAGE_VERSION_MAJOR "${SCIQLOP_VERSION_MAJOR}")
26 26 SET (CPACK_PACKAGE_VERSION_MINOR "${SCIQLOP_VERSION_MINOR}")
27 27 SET (CPACK_PACKAGE_VERSION_PATCH "${SCIQLOP_VERSION_PATCH}${SCIQLOP_VERSION_SUFFIX}")
28 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 30 SET (CPACK_PACKAGE_CONTACT "nicolas.aunai@lpp.polytechnique.fr")
31 31 SET(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/README.md)
32 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 34 # SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_NAME}-${PROJECT_VERSION})
35 35 SET(FULLBUILD ON)
36 36
@@ -42,6 +42,7 SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-Setu
42 42 SET(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_NAME})
43 43
44 44 set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
45 message("exepath" ${CPACK_PACKAGE_INSTALL_DIRECTORY})
45 46
46 47 if (WIN32)
47 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 7 #ENDFOREACH()
8 8
9 9 EXECUTE_PROCESS(
10 COMMAND windeployqt ${WINDEPLOYQT_ARGS} -printsupport ${SCIQLOP_EXE_LOCATION}
10 COMMAND windeployqt ${WINDEPLOYQT_ARGS} ${SCIQLOP_EXE_LOCATION}
11 11 OUTPUT_VARIABLE QT_FILES
12 12 )
13 13
@@ -44,30 +44,6 else()
44 44 set(libRootDirForceValue)
45 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 54 # Generate position independant code (-fPIC)
79 55 SET(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
80 56
81
82
83 # Configuration for make install
84
85 set(PROJECT_PLUGIN_PREFIX "SciQlop")
86
57 #
58 # Configure installation directories
59 #
87 60 IF (UNIX)
88 SET(CMAKE_INSTALL_PREFIX "/usr/local/${PROJECT_PLUGIN_PREFIX}")
89 61 SET(defaultBin "bin")
90 62 SET(defaultInc "include/sciqlop")
91 63
92 64 # 32 or 64 bits compiler
93 65 IF( CMAKE_SIZEOF_VOID_P EQUAL 8 )
94 SET(defaultLib "lib64")
95 SET(defaultPluginsLib "lib64/${PROJECT_PLUGIN_PREFIX}")
66 SET(defaultLib "lib64/sciqlop")
96 67 ELSE()
97 SET(defaultLib "lib/")
98 SET(defaultPluginsLib "lib/${PROJECT_PLUGIN_PREFIX}")
68 SET(defaultLib "lib/sciqlop")
99 69 ENDIF()
100 70
101 SET(defaultDoc "share/docs/${PROJECT_PLUGIN_PREFIX}")
71 SET(defaultDoc "share/docs/sciqlop")
102 72 ELSE()
103 73 SET(defaultBin "bin")
104 SET(defaultInc "include/${PROJECT_PLUGIN_PREFIX}")
105 SET(defaultLib "lib")
106 SET(defaultPluginsLib "lib/${PROJECT_PLUGIN_PREFIX}")
107 SET(defaultDoc "docs/${PROJECT_PLUGIN_PREFIX}")
74 SET(defaultInc "include/sciqlop")
75 SET(defaultLib "lib/sciqlop")
76 SET(defaultDoc "docs/sciqlop")
108 77 ENDIF()
109 78
110 79 SET(INSTALL_BINARY_DIR "${defaultBin}" CACHE STRING
111 80 "Installation directory for binaries")
112 81 SET(INSTALL_LIBRARY_DIR "${defaultLib}" CACHE STRING
113 82 "Installation directory for libraries")
114 SET(INSTALL_PLUGINS_LIBRARY_DIR "${defaultPluginsLib}" CACHE STRING
115 "Installation directory for libraries")
116 83 SET(INSTALL_INCLUDE_DIR "${defaultInc}" CACHE STRING
117 84 "Installation directory for headers")
118 85 SET(INSTALL_DOCUMENTATION_DIR "${defaultDoc}" CACHE STRING
119 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 25 # Find Qt modules
26 26 #
27 SCIQLOP_FIND_QT(Core Network)
27 SCIQLOP_FIND_QT(Core)
28 28
29 29 #
30 30 # Compile the library library
31 31 #
32
33 ADD_DEFINITIONS(-DCORE_LIB)
34
35 32 FILE (GLOB_RECURSE MODULE_SOURCES
36 33 ${INCLUDES_DIR}/*.h
37 34 ${SOURCES_DIR}/*.c
@@ -42,14 +39,8 ADD_LIBRARY(${SQPCORE_LIBRARY_NAME} ${MODULE_SOURCES})
42 39 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD 14)
43 40 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
44 41 TARGET_LINK_LIBRARIES(${SQPCORE_LIBRARY_NAME})
45 qt5_use_modules(${SQPCORE_LIBRARY_NAME} Core Network)
46
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
42 qt5_use_modules(${SQPCORE_LIBRARY_NAME} Core)
43
53 44 # From cmake documentation: http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
54 45 # Entries in the COMPILE_DEFINITIONS are prefixed with -D or /D and added to the compile line in an unspecified order.
55 46 # The DEFINE_SYMBOL target property is also added as a compile definition as a special convenience case for SHARED and MODULE library targets
@@ -89,8 +89,9 using default_copier_t = typename default_copier<T>::type;
89 89
90 90 template <class T, class D, class C>
91 91 struct is_default_manageable
92 : public std::integral_constant<bool, std::is_same<D, default_deleter_t<T> >::value
93 && std::is_same<C, default_copier_t<T> >::value> {
92 : public std::integral_constant<bool,
93 std::is_same<D, default_deleter_t<T> >::value
94 && std::is_same<C, default_copier_t<T> >::value> {
94 95 };
95 96 }
96 97
@@ -131,10 +132,11 public:
131 132 }
132 133
133 134 template <class U>
134 impl_ptr(U *u, typename std::enable_if<std::is_convertible<U *, pointer>::value
135 && is_default_manageable::value,
136 dummy_t_>::type
137 = dummy_t_()) SPIMPL_NOEXCEPT
135 impl_ptr(U *u,
136 typename std::enable_if<std::is_convertible<U *, pointer>::value
137 && is_default_manageable::value,
138 dummy_t_>::type
139 = dummy_t_()) SPIMPL_NOEXCEPT
138 140 : impl_ptr(u, &details::default_delete<T>, &details::default_copy<T>)
139 141 {
140 142 }
@@ -151,12 +153,12 public:
151 153
152 154 #ifdef SPIMPL_HAS_AUTO_PTR
153 155 template <class U>
154 impl_ptr(std::auto_ptr<U> &&u, typename std::enable_if<std::is_convertible<U *, pointer>::value
155 && is_default_manageable::value,
156 dummy_t_>::type
157 = dummy_t_()) SPIMPL_NOEXCEPT
158 : ptr_(u.release(), &details::default_delete<T>),
159 copier_(&details::default_copy<T>)
156 impl_ptr(std::auto_ptr<U> &&u,
157 typename std::enable_if<std::is_convertible<U *, pointer>::value
158 && is_default_manageable::value,
159 dummy_t_>::type
160 = dummy_t_()) SPIMPL_NOEXCEPT : ptr_(u.release(), &details::default_delete<T>),
161 copier_(&details::default_copy<T>)
160 162 {
161 163 }
162 164 #endif
@@ -1,8 +1,6
1 1 #ifndef SCIQLOP_DATASOURCECONTROLLER_H
2 2 #define SCIQLOP_DATASOURCECONTROLLER_H
3 3
4 #include "CoreGlobal.h"
5
6 4 #include <QLoggingCategory>
7 5 #include <QObject>
8 6 #include <QUuid>
@@ -12,7 +10,6
12 10 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSourceController)
13 11
14 12 class DataSourceItem;
15 class IDataProvider;
16 13
17 14 /**
18 15 * @brief The DataSourceController class aims to make the link between SciQlop and its plugins. This
@@ -21,7 +18,7 class IDataProvider;
21 18 * source) then others specifics method will be able to access it. You can load a data source driver
22 19 * plugin then create a data source.
23 20 */
24 class SCIQLOP_CORE_EXPORT DataSourceController : public QObject {
21 class DataSourceController : public QObject {
25 22 Q_OBJECT
26 23 public:
27 24 explicit DataSourceController(QObject *parent = 0);
@@ -39,31 +36,12 public:
39 36 * Sets the structure of a data source. The controller takes ownership of the structure.
40 37 * @param dataSourceUid the unique id with which the data source has been registered into the
41 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 40 * @sa registerDataSource()
44 41 */
45 42 void setDataSourceItem(const QUuid &dataSourceUid,
46 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 45 public slots:
68 46 /// Manage init/end of the controller
69 47 void initialize();
@@ -71,18 +49,7 public slots:
71 49
72 50 signals:
73 51 /// Signal emitted when a structure has been set for a data source
74 void dataSourceItemSet(DataSourceItem *dataSourceItem);
75
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);
52 void dataSourceItemSet(const DataSourceItem &dataSourceItem);
86 53
87 54 private:
88 55 void waitForFinish();
@@ -1,43 +1,20
1 1 #ifndef SCIQLOP_DATASOURCEITEM_H
2 2 #define SCIQLOP_DATASOURCEITEM_H
3 3
4 #include "CoreGlobal.h"
5
6 4 #include <Common/spimpl.h>
7 5
8 6 #include <QVariant>
9 7 #include <QVector>
10 8
11 class DataSourceItemAction;
12
13 /**
14 * Possible types of an item
15 */
16 enum class DataSourceItemType { NODE, PRODUCT, COMPONENT };
17
18 9 /**
19 10 * @brief The DataSourceItem class aims to represent a structure element of a data source.
20 11 * A data source has a tree structure that is made up of a main DataSourceItem object (root)
21 12 * containing other DataSourceItem objects (children).
22 13 * For each DataSourceItem can be associated a set of data representing it.
23 14 */
24 class SCIQLOP_CORE_EXPORT DataSourceItem {
15 class DataSourceItem {
25 16 public:
26 /// Key associated with the name of the item
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;
17 explicit DataSourceItem(QVector<QVariant> data = {});
41 18
42 19 /**
43 20 * Adds a child to the item. The item takes ownership of the child.
@@ -55,18 +32,11 public:
55 32 int childCount() const noexcept;
56 33
57 34 /**
58 * Get the data associated to a key
59 * @param key the key to search
60 * @return the data found if key is valid, default QVariant otherwise
35 * Get the data associated to an index
36 * @param dataIndex the index to search
37 * @return the data found if index is valid, default QVariant otherwise
61 38 */
62 QVariant data(const QString &key) const noexcept;
63
64 /// Gets all data
65 QVariantHash data() const noexcept;
66
67 bool isRoot() const noexcept;
68
69 QString name() const noexcept;
39 QVariant data(int dataIndex) const noexcept;
70 40
71 41 /**
72 42 * Get the item's parent
@@ -74,26 +44,6 public:
74 44 */
75 45 DataSourceItem *parentItem() const noexcept;
76 46
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;
93
94 bool operator==(const DataSourceItem &other);
95 bool operator!=(const DataSourceItem &other);
96
97 47 private:
98 48 class DataSourceItemPrivate;
99 49 spimpl::unique_impl_ptr<DataSourceItemPrivate> impl;
@@ -1,8 +1,6
1 1 #ifndef SCIQLOP_PLUGINMANAGER_H
2 2 #define SCIQLOP_PLUGINMANAGER_H
3 3
4 #include "CoreGlobal.h"
5
6 4 #include <Common/spimpl.h>
7 5
8 6 #include <QLoggingCategory>
@@ -14,7 +12,7 Q_DECLARE_LOGGING_CATEGORY(LOG_PluginManager)
14 12 /**
15 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 16 public:
19 17 explicit PluginManager();
20 18
@@ -1,10 +1,6
1 1 #ifndef SCIQLOP_VISUALIZATIONCONTROLLER_H
2 2 #define SCIQLOP_VISUALIZATIONCONTROLLER_H
3 3
4 #include "CoreGlobal.h"
5
6 #include <Data/SqpRange.h>
7
8 4 #include <QLoggingCategory>
9 5 #include <QObject>
10 6 #include <QUuid>
@@ -14,7 +10,6
14 10 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationController)
15 11
16 12 class DataSourceItem;
17 class Variable;
18 13
19 14 /**
20 15 * @brief The VisualizationController class aims to make the link between SciQlop and its plugins.
@@ -23,19 +18,12 class Variable;
23 18 * plugin source) then others specifics method will be able to access it. You can load a data source
24 19 * driver plugin then create a data source.
25 20 */
26 class SCIQLOP_CORE_EXPORT VisualizationController : public QObject {
21 class VisualizationController : public QObject {
27 22 Q_OBJECT
28 23 public:
29 24 explicit VisualizationController(QObject *parent = 0);
30 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 27 public slots:
40 28 /// Manage init/end of the controller
41 29 void initialize();
@@ -1,7 +1,5
1 #include "DataSource/DataSourceController.h"
2 #include "DataSource/DataSourceItem.h"
3
4 #include <Data/IDataProvider.h>
1 #include <DataSource/DataSourceController.h>
2 #include <DataSource/DataSourceItem.h>
5 3
6 4 #include <QMutex>
7 5 #include <QThread>
@@ -11,28 +9,6
11 9
12 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 12 class DataSourceController::DataSourceControllerPrivate {
37 13 public:
38 14 QMutex m_WorkingMutex;
@@ -40,23 +16,19 public:
40 16 QHash<QUuid, QString> m_DataSources;
41 17 /// Data sources structures
42 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 21 DataSourceController::DataSourceController(QObject *parent)
50 22 : impl{spimpl::make_unique_impl<DataSourceControllerPrivate>()}
51 23 {
52 qCDebug(LOG_DataSourceController()) << tr("DataSourceController construction")
53 << QThread::currentThread();
24 qCDebug(LOG_DataSourceController())
25 << tr("DataSourceController construction") << QThread::currentThread();
54 26 }
55 27
56 28 DataSourceController::~DataSourceController()
57 29 {
58 qCDebug(LOG_DataSourceController()) << tr("DataSourceController destruction")
59 << QThread::currentThread();
30 qCDebug(LOG_DataSourceController())
31 << tr("DataSourceController destruction") << QThread::currentThread();
60 32 this->waitForFinish();
61 33 }
62 34
@@ -71,20 +43,13 QUuid DataSourceController::registerDataSource(const QString &dataSourceName) no
71 43 void DataSourceController::setDataSourceItem(
72 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 46 if (impl->m_DataSources.contains(dataSourceUid)) {
81 // The data provider is implicitly converted to a shared_ptr
82 47 impl->m_DataSourceItems.insert(std::make_pair(dataSourceUid, std::move(dataSourceItem)));
83 48
84 49 // Retrieves the data source item to emit the signal with it
85 50 auto it = impl->m_DataSourceItems.find(dataSourceUid);
86 51 if (it != impl->m_DataSourceItems.end()) {
87 emit dataSourceItemSet(it->second.get());
52 emit dataSourceItemSet(*it->second);
88 53 }
89 54 }
90 55 else {
@@ -94,40 +59,10 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 62 void DataSourceController::initialize()
128 63 {
129 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init")
130 << QThread::currentThread();
64 qCDebug(LOG_DataSourceController())
65 << tr("DataSourceController init") << QThread::currentThread();
131 66 impl->m_WorkingMutex.lock();
132 67 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init END");
133 68 }
@@ -1,47 +1,21
1 1 #include <DataSource/DataSourceItem.h>
2 #include <DataSource/DataSourceItemAction.h>
3 2
4 3 #include <QVector>
5 4
6 const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name");
7
8 5 struct DataSourceItem::DataSourceItemPrivate {
9 explicit DataSourceItemPrivate(DataSourceItemType type, QVariantHash data)
10 : m_Parent{nullptr}, m_Children{}, m_Type{type}, m_Data{std::move(data)}, m_Actions{}
6 explicit DataSourceItemPrivate(QVector<QVariant> data)
7 : m_Parent{nullptr}, m_Children{}, m_Data{std::move(data)}
11 8 {
12 9 }
13 10
14 11 DataSourceItem *m_Parent;
15 12 std::vector<std::unique_ptr<DataSourceItem> > m_Children;
16 DataSourceItemType m_Type;
17 QVariantHash m_Data;
18 std::vector<std::unique_ptr<DataSourceItemAction> > m_Actions;
13 QVector<QVariant> m_Data;
19 14 };
20 15
21 DataSourceItem::DataSourceItem(DataSourceItemType type, const QString &name)
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))}
28 {
29 }
30
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
16 DataSourceItem::DataSourceItem(QVector<QVariant> data)
17 : impl{spimpl::make_unique_impl<DataSourceItemPrivate>(data)}
42 18 {
43 action->setDataSourceItem(this);
44 impl->m_Actions.push_back(std::move(action));
45 19 }
46 20
47 21 void DataSourceItem::appendChild(std::unique_ptr<DataSourceItem> child) noexcept
@@ -65,81 +39,12 int DataSourceItem::childCount() const noexcept
65 39 return impl->m_Children.size();
66 40 }
67 41
68 QVariant DataSourceItem::data(const QString &key) const noexcept
69 {
70 return impl->m_Data.value(key);
71 }
72
73 QVariantHash DataSourceItem::data() const noexcept
42 QVariant DataSourceItem::data(int dataIndex) const noexcept
74 43 {
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 {
85 return data(NAME_DATA_KEY).toString();
44 return impl->m_Data.value(dataIndex);
86 45 }
87 46
88 47 DataSourceItem *DataSourceItem::parentItem() const noexcept
89 48 {
90 49 return impl->m_Parent;
91 50 }
92
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
122 {
123 return impl->m_Type;
124 }
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 106 void PluginManager::loadPlugins(const QDir &pluginDir)
107 107 {
108 108 // Load plugins
109 auto pluginInfoList
110 = pluginDir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
111 for (auto entryInfo : qAsConst(pluginInfoList)) {
112 if (entryInfo.isDir()) {
113 this->loadPlugins(QDir{entryInfo.absoluteFilePath()});
114 }
115 else if (QLibrary::isLibrary(entryInfo.absoluteFilePath())) {
116 impl->loadPlugin(entryInfo.absoluteFilePath());
117 }
109 auto pluginInfoList = pluginDir.entryInfoList(QDir::Files, QDir::Name);
110 for (auto pluginInfo : qAsConst(pluginInfoList)) {
111 impl->loadPlugin(pluginInfo.absoluteFilePath());
118 112 }
119 113 }
120 114
@@ -1,7 +1,5
1 1 #include <Visualization/VisualizationController.h>
2 2
3 #include <Variable/Variable.h>
4
5 3 #include <QMutex>
6 4 #include <QThread>
7 5
@@ -18,21 +16,21 public:
18 16 VisualizationController::VisualizationController(QObject *parent)
19 17 : impl{spimpl::make_unique_impl<VisualizationControllerPrivate>()}
20 18 {
21 qCDebug(LOG_VisualizationController()) << tr("VisualizationController construction")
22 << QThread::currentThread();
19 qCDebug(LOG_VisualizationController())
20 << tr("VisualizationController construction") << QThread::currentThread();
23 21 }
24 22
25 23 VisualizationController::~VisualizationController()
26 24 {
27 qCDebug(LOG_VisualizationController()) << tr("VisualizationController destruction")
28 << QThread::currentThread();
25 qCDebug(LOG_VisualizationController())
26 << tr("VisualizationController destruction") << QThread::currentThread();
29 27 this->waitForFinish();
30 28 }
31 29
32 30 void VisualizationController::initialize()
33 31 {
34 qCDebug(LOG_VisualizationController()) << tr("VisualizationController init")
35 << QThread::currentThread();
32 qCDebug(LOG_VisualizationController())
33 << tr("VisualizationController init") << QThread::currentThread();
36 34 impl->m_WorkingMutex.lock();
37 35 qCDebug(LOG_VisualizationController()) << tr("VisualizationController init END");
38 36 }
@@ -26,11 +26,12 void TestDataSourceController::testSetDataSourceItem()
26 26 DataSourceController dataSourceController{};
27 27
28 28 // Spy to test controllers' signals
29 QSignalSpy signalSpy{&dataSourceController, SIGNAL(dataSourceItemSet(DataSourceItem *))};
29 QSignalSpy signalSpy{&dataSourceController, SIGNAL(dataSourceItemSet(const DataSourceItem &))};
30 30
31 31 // Create a data source item
32 32 auto source1Name = QStringLiteral("Source1");
33 auto source1Item = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, source1Name);
33 auto source1Values = QVector<QVariant>{source1Name};
34 auto source1Item = std::make_unique<DataSourceItem>(std::move(source1Values));
34 35
35 36 // Add data source item to the controller and check that a signal has been emitted after setting
36 37 // data source item in the controller
@@ -40,8 +41,7 void TestDataSourceController::testSetDataSourceItem()
40 41
41 42 // Try to a data source item with an unregistered uid and check that no signal has been emitted
42 43 auto unregisteredUid = QUuid::createUuid();
43 dataSourceController.setDataSourceItem(
44 unregisteredUid, std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT));
44 dataSourceController.setDataSourceItem(unregisteredUid, std::make_unique<DataSourceItem>());
45 45 QCOMPARE(signalSpy.count(), 1);
46 46 }
47 47
@@ -1,52 +1,3
1 1 # On ignore toutes les règles vera++ pour le fichier spimpl
2 2 Common/spimpl\.h:\d+:.*
3 3
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.*
8 DataSeries\.h:\d+:.*IPSIS_S01.*
9 DataSeriesIterator\.h:\d+:.*IPSIS_S01.*
10 DataSeriesMergeHelper\.h:\d+:.*IPSIS_S01.*
11
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 63 clangformat_incr(i)
64 64 ENDWHILE()
65 65
66
67 66 # Retrieve source files to format
68 67 IF(recurse)
69 68 FILE(GLOB_RECURSE srcs ${globs})
@@ -82,15 +81,6 FUNCTION(ADD_CLANGFORMAT_TARGETS)
82 81 # Create the directory where the touched files will be saved
83 82 SET(formatDirectory "${CMAKE_CURRENT_BINARY_DIR}/format")
84 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 84 FOREACH (s ${srcs})
95 85 SET(touchedFile ${formatDirectory}/format_touchedfile_${reportNb})
96 86 IF(addToAll)
@@ -6,14 +6,3
6 6 # Ignore false positive relative to 'noexcept' keyword
7 7 .*IPSIS_S04_VARIABLE.*found: noexcept
8 8 .*IPSIS_S06.*found: noexcept
9
10 # Ignore false positive relative to 'override' keyword
11 .*IPSIS_S04_VARIABLE.*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 67 TARGET_LINK_LIBRARIES(${SQPGUI_LIBRARY_NAME} ${LIBRARIES})
68 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 70 # From cmake documentation: http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
80 71 # Entries in the COMPILE_DEFINITIONS are prefixed with -D or /D and added to the compile line in an unspecified order.
81 72 # The DEFINE_SYMBOL target property is also added as a compile definition as a special convenience case for SHARED and MODULE library targets
@@ -16,9 +16,6 Q_DECLARE_LOGGING_CATEGORY(LOG_SqpApplication)
16 16 #define sqpApp (static_cast<SqpApplication *>(QCoreApplication::instance()))
17 17
18 18 class DataSourceController;
19 class NetworkController;
20 class TimeController;
21 class VariableController;
22 19 class VisualizationController;
23 20
24 21 /**
@@ -38,11 +35,8 public:
38 35 void initialize();
39 36
40 37 /// Accessors for the differents sciqlop controllers
41 DataSourceController &dataSourceController() noexcept;
42 NetworkController &networkController() noexcept;
43 TimeController &timeController() noexcept;
44 VariableController &variableController() noexcept;
45 VisualizationController &visualizationController() noexcept;
38 DataSourceController &dataSourceController() const noexcept;
39 VisualizationController &visualizationController() const noexcept;
46 40
47 41 private:
48 42 class SqpApplicationPrivate;
1 NO CONTENT: file renamed from gui/include/SidePane/SqpSidePane.h to gui/include/sidepane/SqpSidePane.h
@@ -1,52 +1,19
1 1 #ifndef SCIQLOP_VISUALIZATIONWIDGET_H
2 2 #define SCIQLOP_VISUALIZATIONWIDGET_H
3 3
4 #include "Visualization/IVisualizationWidget.h"
5 #include <Data/SqpRange.h>
6
7 #include <QLoggingCategory>
8 4 #include <QWidget>
9 5
10 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
11
12 class QMenu;
13 class Variable;
14 class VisualizationTabWidget;
15
16 6 namespace Ui {
17 7 class VisualizationWidget;
18 8 } // namespace Ui
19 9
20 class VisualizationWidget : public QWidget, public IVisualizationWidget {
10 class VisualizationWidget : public QWidget {
21 11 Q_OBJECT
22 12
23 13 public:
24 14 explicit VisualizationWidget(QWidget *parent = 0);
25 15 virtual ~VisualizationWidget();
26 16
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 17 private:
51 18 Ui::VisualizationWidget *ui;
52 19 };
@@ -42,9 +42,6
42 42
43 43 #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
44 44 #define QCP_DEVICEPIXELRATIO_SUPPORTED
45 #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
46 #define QCP_DEVICEPIXELRATIO_FLOAT
47 #endif
48 45 #endif
49 46
50 47 #include <QtCore/QCache>
@@ -112,8 +109,8 class QCPColorMap;
112 109 class QCPColorScale;
113 110 class QCPBars;
114 111
115 /* including file 'src/global.h', size 16225 */
116 /* commit e7c6a5540d344a96d107dce53f9d4414a09a7320 2017-07-25 00:52:29 +0200 */
112 /* including file 'src/global.h', size 16131 */
113 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
117 114
118 115 // decl definitions for shared library compilation/usage:
119 116 #if defined(QCUSTOMPLOT_COMPILE_LIBRARY)
@@ -1797,8 +1794,8 protected:
1797 1794 /* end of 'src/axis/axistickerdatetime.h' */
1798 1795
1799 1796
1800 /* including file 'src/axis/axistickertime.h', size 3542 */
1801 /* commit c38adb94d83c6a752597a5d43d45c0561fbe1d4d 2017-08-13 17:37:53 +0200 */
1797 /* including file 'src/axis/axistickertime.h', size 3288 */
1798 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
1802 1799
1803 1800 class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker {
1804 1801 Q_GADGET
@@ -1808,17 +1805,7 public:
1808 1805
1809 1806 \see setFieldWidth, setTimeFormat
1810 1807 */
1811 enum TimeUnit {
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 };
1808 enum TimeUnit { tuMilliseconds, tuSeconds, tuMinutes, tuHours, tuDays };
1822 1809 Q_ENUMS(TimeUnit)
1823 1810
1824 1811 QCPAxisTickerTime();
@@ -2039,8 +2026,8 protected:
2039 2026 /* end of 'src/axis/axistickerlog.h' */
2040 2027
2041 2028
2042 /* including file 'src/axis/axis.h', size 20634 */
2043 /* commit 0cc4d9f61f7bf45321a88fec89d909b020ffa26f 2017-08-14 00:43:29 +0200 */
2029 /* including file 'src/axis/axis.h', size 20230 */
2030 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
2044 2031
2045 2032 class QCP_LIB_DECL QCPGrid : public QCPLayerable {
2046 2033 Q_OBJECT
@@ -2377,9 +2364,6 protected:
2377 2364 QVector<double> mSubTickVector;
2378 2365 bool mCachedMarginValid;
2379 2366 int mCachedMargin;
2380 bool mDragging;
2381 QCPRange mDragStartRange;
2382 QCP::AntialiasedElements mAADragBackup, mNotAADragBackup;
2383 2367
2384 2368 // introduced virtual methods:
2385 2369 virtual int calculateMargin();
@@ -2392,11 +2376,6 protected:
2392 2376 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details,
2393 2377 bool *selectionStateChanged) Q_DECL_OVERRIDE;
2394 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 2380 // non-virtual methods:
2402 2381 void setupTickVectors();
@@ -2633,8 +2612,8 Q_DECLARE_METATYPE(QCPScatterStyle::ScatterShape)
2633 2612 /* end of 'src/scatterstyle.h' */
2634 2613
2635 2614
2636 /* including file 'src/datacontainer.h', size 4596 */
2637 /* commit bee82298bd87b91a50093fb0b81cd7c734724a6f 2017-08-13 16:10:24 +0200 */
2615 /* including file 'src/datacontainer.h', size 4535 */
2616 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
2638 2617
2639 2618 /*! \relates QCPDataContainer
2640 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 2629 template <class DataType>
2651 class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below)
2652 {
2630 class QCP_LIB_DECL QCPDataContainer {
2653 2631 public:
2654 2632 typedef typename QVector<DataType>::const_iterator const_iterator;
2655 2633 typedef typename QVector<DataType>::iterator iterator;
@@ -2708,8 +2686,8 protected:
2708 2686
2709 2687 // include implementation in header since it is a class template:
2710 2688
2711 /* including file 'src/datacontainer.cpp', size 31349 */
2712 /* commit 820d2282db70144c358c13433cd74b4175f9252b 2017-07-24 00:24:17 +0200 */
2689 /* including file 'src/datacontainer.cpp', size 31224 */
2690 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
2713 2691
2714 2692 ////////////////////////////////////////////////////////////////////////////////////////////////////
2715 2693 //////////////////// QCPDataContainer
@@ -3425,8 +3403,7 QCPRange QCPDataContainer<DataType>::valueRange(bool &foundRange, QCP::SignDomai
3425 3403
3426 3404 /*!
3427 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
3429 the passed iterators \a begin and \a end is never expanded, only contracted if necessary.
3406 container's data, as well as within the specified \a dataRange.
3430 3407
3431 3408 This function doesn't require for \a dataRange to be within the bounds of this data container's
3432 3409 valid range.
@@ -3683,8 +3660,8 private:
3683 3660 /* end of 'src/plottable.h' */
3684 3661
3685 3662
3686 /* including file 'src/item.h', size 9384 */
3687 /* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */
3663 /* including file 'src/item.h', size 9368 */
3664 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
3688 3665
3689 3666 class QCP_LIB_DECL QCPItemAnchor {
3690 3667 Q_GADGET
@@ -3773,7 +3750,7 public:
3773 3750 QCPAxis *keyAxis() const { return mKeyAxis.data(); }
3774 3751 QCPAxis *valueAxis() const { return mValueAxis.data(); }
3775 3752 QCPAxisRect *axisRect() const;
3776 virtual QPointF pixelPosition() const Q_DECL_OVERRIDE;
3753 virtual QPointF pixelPosition() const;
3777 3754
3778 3755 // setters:
3779 3756 void setType(PositionType type);
@@ -3880,8 +3857,8 private:
3880 3857 /* end of 'src/item.h' */
3881 3858
3882 3859
3883 /* including file 'src/core.h', size 14886 */
3884 /* commit 29aafbce469a36d175d4fb32cbfd1f50a6072890 2016-10-12 19:21:24 +0200 */
3860 /* including file 'src/core.h', size 14797 */
3861 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
3885 3862
3886 3863 class QCP_LIB_DECL QCustomPlot : public QWidget {
3887 3864 Q_OBJECT
@@ -4114,9 +4091,7 protected:
4114 4091 QPoint mMousePressPos;
4115 4092 bool mMouseHasMoved;
4116 4093 QPointer<QCPLayerable> mMouseEventLayerable;
4117 QPointer<QCPLayerable> mMouseSignalLayerable;
4118 4094 QVariant mMouseEventLayerableDetails;
4119 QVariant mMouseSignalLayerableDetails;
4120 4095 bool mReplotting;
4121 4096 bool mReplotQueued;
4122 4097 int mOpenGlMultisamples;
@@ -4178,12 +4153,11 Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority)
4178 4153 /* end of 'src/core.h' */
4179 4154
4180 4155
4181 /* including file 'src/plottable1d.h', size 4544 */
4182 /* commit bee82298bd87b91a50093fb0b81cd7c734724a6f 2017-08-13 16:10:24 +0200 */
4156 /* including file 'src/plottable1d.h', size 4250 */
4157 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
4183 4158
4184 class QCPPlottableInterface1D {
4159 class QCP_LIB_DECL QCPPlottableInterface1D {
4185 4160 public:
4186 virtual ~QCPPlottableInterface1D() {}
4187 4161 // introduced pure virtual methods:
4188 4162 virtual int dataCount() const = 0;
4189 4163 virtual double dataMainKey(int index) const = 0;
@@ -4198,11 +4172,8 public:
4198 4172 };
4199 4173
4200 4174 template <class DataType>
4201 class QCPAbstractPlottable1D : public QCPAbstractPlottable,
4202 public QCPPlottableInterface1D // no QCP_LIB_DECL, template class
4203 // ends up in header (cpp included
4204 // below)
4205 {
4175 class QCP_LIB_DECL QCPAbstractPlottable1D : public QCPAbstractPlottable,
4176 public QCPPlottableInterface1D {
4206 4177 // No Q_OBJECT macro due to template class
4207 4178
4208 4179 public:
@@ -4210,22 +4181,20 public:
4210 4181 virtual ~QCPAbstractPlottable1D();
4211 4182
4212 4183 // virtual methods of 1d plottable interface:
4213 virtual int dataCount() const Q_DECL_OVERRIDE;
4214 virtual double dataMainKey(int index) const Q_DECL_OVERRIDE;
4215 virtual double dataSortKey(int index) const Q_DECL_OVERRIDE;
4216 virtual double dataMainValue(int index) const Q_DECL_OVERRIDE;
4217 virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE;
4218 virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE;
4219 virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE;
4220 virtual QCPDataSelection selectTestRect(const QRectF &rect,
4221 bool onlySelectable) const Q_DECL_OVERRIDE;
4222 virtual int findBegin(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE;
4223 virtual int findEnd(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE;
4184 virtual int dataCount() const;
4185 virtual double dataMainKey(int index) const;
4186 virtual double dataSortKey(int index) const;
4187 virtual double dataMainValue(int index) const;
4188 virtual QCPRange dataValueRange(int index) const;
4189 virtual QPointF dataPixelPosition(int index) const;
4190 virtual bool sortKeyIsMainKey() const;
4191 virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const;
4192 virtual int findBegin(double sortKey, bool expandedRange = true) const;
4193 virtual int findEnd(double sortKey, bool expandedRange = true) const;
4224 4194
4225 // reimplemented virtual methods:
4226 virtual double selectTest(const QPointF &pos, bool onlySelectable,
4227 QVariant *details = 0) const Q_DECL_OVERRIDE;
4228 virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; }
4195 // virtual methods:
4196 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details = 0) const;
4197 virtual QCPPlottableInterface1D *interface1D() { return this; }
4229 4198
4230 4199 protected:
4231 4200 // property members:
@@ -4894,8 +4863,8 Q_DECLARE_METATYPE(QCPColorGradient::GradientPreset)
4894 4863 /* end of 'src/colorgradient.h' */
4895 4864
4896 4865
4897 /* including file 'src/selectiondecorator-bracket.h', size 4442 */
4898 /* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */
4866 /* including file 'src/selectiondecorator-bracket.h', size 4426 */
4867 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
4899 4868
4900 4869 class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator {
4901 4870 Q_GADGET
@@ -4947,7 +4916,7 public:
4947 4916 virtual void drawBracket(QCPPainter *painter, int direction) const;
4948 4917
4949 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 4921 protected:
4953 4922 // property members:
@@ -4969,8 +4938,8 Q_DECLARE_METATYPE(QCPSelectionDecoratorBracket::BracketStyle)
4969 4938 /* end of 'src/selectiondecorator-bracket.h' */
4970 4939
4971 4940
4972 /* including file 'src/layoutelements/layoutelement-axisrect.h', size 7507 */
4973 /* commit 77ba168312f935543fc31d1ae9b4cdcf34aae4f9 2017-08-13 18:29:48 +0200 */
4941 /* including file 'src/layoutelements/layoutelement-axisrect.h', size 7528 */
4942 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
4974 4943
4975 4944 class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement {
4976 4945 Q_OBJECT
@@ -5068,6 +5037,7 protected:
5068 5037 // non-property members:
5069 5038 QList<QCPRange> mDragStartHorzRange, mDragStartVertRange;
5070 5039 QCP::AntialiasedElements mAADragBackup, mNotAADragBackup;
5040 QPoint mDragStart;
5071 5041 bool mDragging;
5072 5042 QHash<QCPAxis::AxisType, QList<QCPAxis *> > mAxes;
5073 5043
@@ -5408,8 +5378,8 private:
5408 5378 /* end of 'src/layoutelements/layoutelement-textelement.h' */
5409 5379
5410 5380
5411 /* including file 'src/layoutelements/layoutelement-colorscale.h', size 5923 */
5412 /* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */
5381 /* including file 'src/layoutelements/layoutelement-colorscale.h', size 5907 */
5382 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
5413 5383
5414 5384
5415 5385 class QCPColorScaleAxisRectPrivate : public QCPAxisRect {
@@ -5428,7 +5398,7 protected:
5428 5398 using QCPAxisRect::mouseReleaseEvent;
5429 5399 using QCPAxisRect::wheelEvent;
5430 5400 using QCPAxisRect::update;
5431 virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
5401 virtual void draw(QCPPainter *painter);
5432 5402 void updateGradientImage();
5433 5403 Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts);
5434 5404 Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts);
@@ -5516,8 +5486,8 private:
5516 5486 /* end of 'src/layoutelements/layoutelement-colorscale.h' */
5517 5487
5518 5488
5519 /* including file 'src/plottables/plottable-graph.h', size 9294 */
5520 /* commit f3881770eaf7366171012ad01cad2aaf5f61dd27 2017-06-23 02:48:21 +0200 */
5489 /* including file 'src/plottables/plottable-graph.h', size 8826 */
5490 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
5521 5491
5522 5492 class QCP_LIB_DECL QCPGraphData {
5523 5493 public:
@@ -5654,20 +5624,11 protected:
5654 5624 QVector<QPointF> dataToStepRightLines(const QVector<QCPGraphData> &data) const;
5655 5625 QVector<QPointF> dataToStepCenterLines(const QVector<QCPGraphData> &data) const;
5656 5626 QVector<QPointF> dataToImpulseLines(const QVector<QCPGraphData> &data) const;
5657 QVector<QCPDataRange> getNonNanSegments(const QVector<QPointF> *lineData,
5658 Qt::Orientation keyOrientation) const;
5659 QVector<QPair<QCPDataRange, QCPDataRange> >
5660 getOverlappingSegments(QVector<QCPDataRange> thisSegments, const QVector<QPointF> *thisData,
5661 QVector<QCPDataRange> otherSegments,
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;
5627 void addFillBasePoints(QVector<QPointF> *lines) const;
5628 void removeFillBasePoints(QVector<QPointF> *lines) const;
5629 QPointF lowerFillBasePoint(double lowerKey) const;
5630 QPointF upperFillBasePoint(double upperKey) const;
5631 const QPolygonF getChannelFillPolygon(const QVector<QPointF> *lines) const;
5671 5632 int findIndexBelowX(const QVector<QPointF> *data, double x) const;
5672 5633 int findIndexAboveX(const QVector<QPointF> *data, double x) const;
5673 5634 int findIndexBelowY(const QVector<QPointF> *data, double y) const;
@@ -6464,8 +6425,8 Q_DECLARE_METATYPE(QCPFinancial::ChartStyle)
6464 6425 /* end of 'src/plottables/plottable-financial.h' */
6465 6426
6466 6427
6467 /* including file 'src/plottables/plottable-errorbar.h', size 7727 */
6468 /* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */
6428 /* including file 'src/plottables/plottable-errorbar.h', size 7567 */
6429 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
6469 6430
6470 6431 class QCP_LIB_DECL QCPErrorBarsData {
6471 6432 public:
@@ -6544,17 +6505,16 public:
6544 6505 void addData(double errorMinus, double errorPlus);
6545 6506
6546 6507 // virtual methods of 1d plottable interface:
6547 virtual int dataCount() const Q_DECL_OVERRIDE;
6548 virtual double dataMainKey(int index) const Q_DECL_OVERRIDE;
6549 virtual double dataSortKey(int index) const Q_DECL_OVERRIDE;
6550 virtual double dataMainValue(int index) const Q_DECL_OVERRIDE;
6551 virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE;
6552 virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE;
6553 virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE;
6554 virtual QCPDataSelection selectTestRect(const QRectF &rect,
6555 bool onlySelectable) const Q_DECL_OVERRIDE;
6556 virtual int findBegin(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE;
6557 virtual int findEnd(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE;
6508 virtual int dataCount() const;
6509 virtual double dataMainKey(int index) const;
6510 virtual double dataSortKey(int index) const;
6511 virtual double dataMainValue(int index) const;
6512 virtual QCPRange dataValueRange(int index) const;
6513 virtual QPointF dataPixelPosition(int index) const;
6514 virtual bool sortKeyIsMainKey() const;
6515 virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const;
6516 virtual int findBegin(double sortKey, bool expandedRange = true) const;
6517 virtual int findEnd(double sortKey, bool expandedRange = true) const;
6558 6518
6559 6519 // reimplemented virtual methods:
6560 6520 virtual double selectTest(const QPointF &pos, bool onlySelectable,
@@ -1,12 +1,7
1 1 #include "SqpApplication.h"
2 2
3 #include <Data/IDataProvider.h>
4 3 #include <DataSource/DataSourceController.h>
5 #include <Network/NetworkController.h>
6 4 #include <QThread>
7 #include <Time/TimeController.h>
8 #include <Variable/Variable.h>
9 #include <Variable/VariableController.h>
10 5 #include <Visualization/VisualizationController.h>
11 6
12 7 Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication")
@@ -15,72 +10,25 class SqpApplication::SqpApplicationPrivate {
15 10 public:
16 11 SqpApplicationPrivate()
17 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 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 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 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 19 virtual ~SqpApplicationPrivate()
62 20 {
21 qCInfo(LOG_SqpApplication()) << tr("SqpApplicationPrivate destruction");
63 22 m_DataSourceControllerThread.quit();
64 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 25 m_VisualizationControllerThread.quit();
73 26 m_VisualizationControllerThread.wait();
74 27 }
75 28
76 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 30 std::unique_ptr<VisualizationController> m_VisualizationController;
81 31 QThread m_DataSourceControllerThread;
82 QThread m_NetworkControllerThread;
83 QThread m_VariableControllerThread;
84 32 QThread m_VisualizationControllerThread;
85 33 };
86 34
@@ -88,31 +36,20 public:
88 36 SqpApplication::SqpApplication(int &argc, char **argv)
89 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 41 connect(&impl->m_DataSourceControllerThread, &QThread::started,
94 42 impl->m_DataSourceController.get(), &DataSourceController::initialize);
95 43 connect(&impl->m_DataSourceControllerThread, &QThread::finished,
96 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 46 connect(&impl->m_VisualizationControllerThread, &QThread::started,
109 47 impl->m_VisualizationController.get(), &VisualizationController::initialize);
110 48 connect(&impl->m_VisualizationControllerThread, &QThread::finished,
111 49 impl->m_VisualizationController.get(), &VisualizationController::finalize);
112 50
51
113 52 impl->m_DataSourceControllerThread.start();
114 impl->m_NetworkControllerThread.start();
115 impl->m_VariableControllerThread.start();
116 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 66 return *impl->m_DataSourceController;
130 67 }
131 68
132 NetworkController &SqpApplication::networkController() 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
69 VisualizationController &SqpApplication::visualizationController() const noexcept
148 70 {
149 71 return *impl->m_VisualizationController;
150 72 }
@@ -1,4 +1,4
1 #include "SidePane/SqpSidePane.h"
1 #include "sidepane/SqpSidePane.h"
2 2 #include "ui_SqpSidePane.h"
3 3
4 4 #include <QAction>
@@ -22,16 +22,16 static const QString SQPSIDEPANESTYLESHEET
22 22 " }";
23 23 }
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);
28 // sidePaneLayout->setContentsMargins(0, 0, 0, 0);
29 // this->setLayout(sidePaneLayout);
27 QVBoxLayout *sidePaneLayout = new QVBoxLayout(this);
28 sidePaneLayout->setContentsMargins(0, 0, 0, 0);
29 this->setLayout(sidePaneLayout);
30 30
31 31 ui->setupUi(this);
32 m_SidePaneToolbar = new QToolBar();
32 m_SidePaneToolbar = new QToolBar(this);
33 33 m_SidePaneToolbar->setOrientation(Qt::Vertical);
34 this->layout()->addWidget(m_SidePaneToolbar);
34 sidePaneLayout->addWidget(m_SidePaneToolbar);
35 35
36 36 m_SidePaneToolbar->setStyleSheet(SQPSIDEPANESTYLESHEET);
37 37 }
This diff has been collapsed as it changes many lines, (1395 lines changed) Show them Hide them
@@ -23,7 +23,7
23 23 ** Version: 2.0.0-beta **
24 24 ****************************************************************************/
25 25
26 #include "Visualization/qcustomplot.h"
26 #include "visualization/qcustomplot.h"
27 27
28 28
29 29 /* including file 'src/vector2d.cpp', size 7340 */
@@ -1574,10 +1574,7 void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialia
1574 1574
1575 1575 \see initializeParentPlot
1576 1576 */
1577 void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot)
1578 {
1579 Q_UNUSED(parentPlot)
1580 }
1577 void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot){Q_UNUSED(parentPlot)}
1581 1578
1582 1579 /*! \internal
1583 1580
@@ -2102,8 +2099,8 bool QCPRange::validRange(const QCPRange &range)
2102 2099 /* end of 'src/axis/range.cpp' */
2103 2100
2104 2101
2105 /* including file 'src/selection.cpp', size 21906 */
2106 /* commit 820d2282db70144c358c13433cd74b4175f9252b 2017-07-24 00:24:17 +0200 */
2102 /* including file 'src/selection.cpp', size 21898 */
2103 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
2107 2104
2108 2105 ////////////////////////////////////////////////////////////////////////////////////////////////////
2109 2106 //////////////////// QCPDataRange
@@ -2406,7 +2403,7 QCPDataSelection &QCPDataSelection::operator+=(const QCPDataRange &other)
2406 2403 }
2407 2404
2408 2405 /*!
2409 Removes all data point indices that are described by \a other from this data selection.
2406 Removes all data point indices that are described by \a other from this data range.
2410 2407 */
2411 2408 QCPDataSelection &QCPDataSelection::operator-=(const QCPDataSelection &other)
2412 2409 {
@@ -2417,7 +2414,7 QCPDataSelection &QCPDataSelection::operator-=(const QCPDataSelection &other)
2417 2414 }
2418 2415
2419 2416 /*!
2420 Removes all data point indices that are described by \a other from this data selection.
2417 Removes all data point indices that are described by \a other from this data range.
2421 2418 */
2422 2419 QCPDataSelection &QCPDataSelection::operator-=(const QCPDataRange &other)
2423 2420 {
@@ -2930,8 +2927,8 void QCPSelectionRect::draw(QCPPainter *painter)
2930 2927 /* end of 'src/selectionrect.cpp' */
2931 2928
2932 2929
2933 /* including file 'src/layout.cpp', size 74663 */
2934 /* commit a872eb91ec087561efd83dd9cb041a26ab95ce55 2017-07-31 00:21:41 +0200 */
2930 /* including file 'src/layout.cpp', size 74302 */
2931 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
2935 2932
2936 2933 ////////////////////////////////////////////////////////////////////////////////////////////////////
2937 2934 //////////////////// QCPMarginGroup
@@ -3572,13 +3569,12 QCPLayout::QCPLayout()
3572 3569 }
3573 3570
3574 3571 /*!
3575 If \a phase is \ref upLayout, calls \ref updateLayout, which subclasses may reimplement to
3576 reposition and resize their cells.
3572 First calls the QCPLayoutElement::update base class implementation to update the margins on this
3573 layout.
3577 3574
3578 Finally, the call is propagated down to all child \ref QCPLayoutElement "QCPLayoutElements".
3575 Then calls \ref updateLayout which subclasses reimplement to reposition and resize their cells.
3579 3576
3580 For details about this method and the update phases, see the documentation of \ref
3581 QCPLayoutElement::update.
3577 Finally, \ref update is called on all child elements.
3582 3578 */
3583 3579 void QCPLayout::update(UpdatePhase phase)
3584 3580 {
@@ -4243,7 +4239,7 void QCPLayoutGrid::setWrap(int count)
4243 4239
4244 4240 If you want to have all current elements arranged in the new order, set \a rearrange to true. The
4245 4241 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
4242 cells are skipped during build-up of the new cell order, which shifts the succeding element's
4247 4243 index. The rearranging is performed even if the specified \a order is already the current fill
4248 4244 order. Thus this method can be used to re-wrap the current elements.
4249 4245
@@ -4338,8 +4334,7 void QCPLayoutGrid::insertRow(int newIndex)
4338 4334
4339 4335 /*!
4340 4336 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
4342 right).
4337 newIndex range from 0 (inserts a row at the left) to \a rowCount (appends a row at the right).
4343 4338
4344 4339 \see insertRow
4345 4340 */
@@ -4413,9 +4408,7 void QCPLayoutGrid::indexToRowCol(int index, int &row, int &column) const
4413 4408 {
4414 4409 row = -1;
4415 4410 column = -1;
4416 const int nCols = columnCount();
4417 const int nRows = rowCount();
4418 if (nCols == 0 || nRows == 0)
4411 if (columnCount() == 0 || rowCount() == 0)
4419 4412 return;
4420 4413 if (index < 0 || index >= elementCount()) {
4421 4414 qDebug() << Q_FUNC_INFO << "index out of bounds:" << index;
@@ -4424,13 +4417,13 void QCPLayoutGrid::indexToRowCol(int index, int &row, int &column) const
4424 4417
4425 4418 switch (mFillOrder) {
4426 4419 case foRowsFirst: {
4427 column = index / nRows;
4428 row = index % nRows;
4420 column = index / rowCount();
4421 row = index % rowCount();
4429 4422 break;
4430 4423 }
4431 4424 case foColumnsFirst: {
4432 row = index / nCols;
4433 column = index % nCols;
4425 row = index / columnCount();
4426 column = index % columnCount();
4434 4427 break;
4435 4428 }
4436 4429 }
@@ -4596,8 +4589,9 QSize QCPLayoutGrid::minimumSizeHint() const
4596 4589 result.rwidth() += minColWidths.at(i);
4597 4590 for (int i = 0; i < minRowHeights.size(); ++i)
4598 4591 result.rheight() += minRowHeights.at(i);
4599 result.rwidth() += qMax(0, columnCount() - 1) * mColumnSpacing;
4600 result.rheight() += qMax(0, rowCount() - 1) * mRowSpacing;
4592 result.rwidth()
4593 += qMax(0, columnCount() - 1) * mColumnSpacing + mMargins.left() + mMargins.right();
4594 result.rheight() += qMax(0, rowCount() - 1) * mRowSpacing + mMargins.top() + mMargins.bottom();
4601 4595 return result;
4602 4596 }
4603 4597
@@ -4612,8 +4606,9 QSize QCPLayoutGrid::maximumSizeHint() const
4612 4606 result.setWidth(qMin(result.width() + maxColWidths.at(i), QWIDGETSIZE_MAX));
4613 4607 for (int i = 0; i < maxRowHeights.size(); ++i)
4614 4608 result.setHeight(qMin(result.height() + maxRowHeights.at(i), QWIDGETSIZE_MAX));
4615 result.rwidth() += qMax(0, columnCount() - 1) * mColumnSpacing;
4616 result.rheight() += qMax(0, rowCount() - 1) * mRowSpacing;
4609 result.rwidth()
4610 += qMax(0, columnCount() - 1) * mColumnSpacing + mMargins.left() + mMargins.right();
4611 result.rheight() += qMax(0, rowCount() - 1) * mRowSpacing + mMargins.top() + mMargins.bottom();
4617 4612 return result;
4618 4613 }
4619 4614
@@ -4622,9 +4617,8 QSize QCPLayoutGrid::maximumSizeHint() const
4622 4617 Places the minimum column widths and row heights into \a minColWidths and \a minRowHeights
4623 4618 respectively.
4624 4619
4625 The minimum height of a row is the largest minimum height of any element's outer rect in that
4626 row. The minimum width of a column is the largest minimum width of any element's outer rect in
4627 that column.
4620 The minimum height of a row is the largest minimum height of any element in that row. The minimum
4621 width of a column is the largest minimum width of any element in that column.
4628 4622
4629 4623 This is a helper function for \ref updateLayout.
4630 4624
@@ -4637,13 +4631,11 void QCPLayoutGrid::getMinimumRowColSizes(QVector<int> *minColWidths,
4637 4631 *minRowHeights = QVector<int>(rowCount(), 0);
4638 4632 for (int row = 0; row < rowCount(); ++row) {
4639 4633 for (int col = 0; col < columnCount(); ++col) {
4640 if (QCPLayoutElement *el = mElements.at(row).at(col)) {
4641 QSize minHint = el->minimumSizeHint();
4642 QSize min = el->minimumSize();
4634 if (mElements.at(row).at(col)) {
4635 QSize minHint = mElements.at(row).at(col)->minimumSizeHint();
4636 QSize min = mElements.at(row).at(col)->minimumSize();
4643 4637 QSize final(min.width() > 0 ? min.width() : minHint.width(),
4644 4638 min.height() > 0 ? min.height() : minHint.height());
4645 final += QSize(el->margins().left() + el->margins().right(),
4646 el->margins().top() + el->margins().bottom());
4647 4639 if (minColWidths->at(col) < final.width())
4648 4640 (*minColWidths)[col] = final.width();
4649 4641 if (minRowHeights->at(row) < final.height())
@@ -4658,9 +4650,8 void QCPLayoutGrid::getMinimumRowColSizes(QVector<int> *minColWidths,
4658 4650 Places the maximum column widths and row heights into \a maxColWidths and \a maxRowHeights
4659 4651 respectively.
4660 4652
4661 The maximum height of a row is the smallest maximum height of any element's outer rect in that
4662 row. The maximum width of a column is the smallest maximum width of any element's outer rect in
4663 that column.
4653 The maximum height of a row is the smallest maximum height of any element in that row. The
4654 maximum width of a column is the smallest maximum width of any element in that column.
4664 4655
4665 4656 This is a helper function for \ref updateLayout.
4666 4657
@@ -4673,13 +4664,11 void QCPLayoutGrid::getMaximumRowColSizes(QVector<int> *maxColWidths,
4673 4664 *maxRowHeights = QVector<int>(rowCount(), QWIDGETSIZE_MAX);
4674 4665 for (int row = 0; row < rowCount(); ++row) {
4675 4666 for (int col = 0; col < columnCount(); ++col) {
4676 if (QCPLayoutElement *el = mElements.at(row).at(col)) {
4677 QSize maxHint = el->maximumSizeHint();
4678 QSize max = el->maximumSize();
4667 if (mElements.at(row).at(col)) {
4668 QSize maxHint = mElements.at(row).at(col)->maximumSizeHint();
4669 QSize max = mElements.at(row).at(col)->maximumSize();
4679 4670 QSize final(max.width() < QWIDGETSIZE_MAX ? max.width() : maxHint.width(),
4680 4671 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 4672 if (maxColWidths->at(col) > final.width())
4684 4673 (*maxColWidths)[col] = final.width();
4685 4674 if (maxRowHeights->at(row) > final.height())
@@ -4828,25 +4817,22 void QCPLayoutInset::setInsetRect(int index, const QRectF &rect)
4828 4817 void QCPLayoutInset::updateLayout()
4829 4818 {
4830 4819 for (int i = 0; i < mElements.size(); ++i) {
4831 QCPLayoutElement *el = mElements.at(i);
4832 4820 QRect insetRect;
4833 4821 QSize finalMinSize, finalMaxSize;
4834 QSize minSizeHint = el->minimumSizeHint();
4835 QSize maxSizeHint = el->maximumSizeHint();
4836 finalMinSize.setWidth(el->minimumSize().width() > 0 ? el->minimumSize().width()
4837 : minSizeHint.width());
4838 finalMinSize.setHeight(el->minimumSize().height() > 0 ? el->minimumSize().height()
4839 : minSizeHint.height());
4840 finalMaxSize.setWidth(el->maximumSize().width() < QWIDGETSIZE_MAX
4841 ? el->maximumSize().width()
4822 QSize minSizeHint = mElements.at(i)->minimumSizeHint();
4823 QSize maxSizeHint = mElements.at(i)->maximumSizeHint();
4824 finalMinSize.setWidth(mElements.at(i)->minimumSize().width() > 0
4825 ? mElements.at(i)->minimumSize().width()
4826 : minSizeHint.width());
4827 finalMinSize.setHeight(mElements.at(i)->minimumSize().height() > 0
4828 ? mElements.at(i)->minimumSize().height()
4829 : minSizeHint.height());
4830 finalMaxSize.setWidth(mElements.at(i)->maximumSize().width() < QWIDGETSIZE_MAX
4831 ? mElements.at(i)->maximumSize().width()
4842 4832 : maxSizeHint.width());
4843 finalMaxSize.setHeight(el->maximumSize().height() < QWIDGETSIZE_MAX
4844 ? el->maximumSize().height()
4833 finalMaxSize.setHeight(mElements.at(i)->maximumSize().height() < QWIDGETSIZE_MAX
4834 ? mElements.at(i)->maximumSize().height()
4845 4835 : 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 4836 if (mInsetPlacement.at(i) == ipFree) {
4851 4837 insetRect = QRect(rect().x() + rect().width() * mInsetRect.at(i).x(),
4852 4838 rect().y() + rect().height() * mInsetRect.at(i).y(),
@@ -7161,8 +7147,8 QVector<double> QCPAxisTickerLog::createTickVector(double tickStep, const QCPRan
7161 7147 /* end of 'src/axis/axistickerlog.cpp' */
7162 7148
7163 7149
7164 /* including file 'src/axis/axis.cpp', size 99397 */
7165 /* commit 0cc4d9f61f7bf45321a88fec89d909b020ffa26f 2017-08-14 00:43:29 +0200 */
7150 /* including file 'src/axis/axis.cpp', size 94458 */
7151 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
7166 7152
7167 7153
7168 7154 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -8654,11 +8640,11 double QCPAxis::coordToPixel(double value) const
8654 8640 }
8655 8641 else // mScaleType == stLogarithmic
8656 8642 {
8657 if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just
8658 // draw it outside visible range
8643 if (value >= 0 && mRange.upper < 0) // invalid value for logarithmic scale, just draw it
8644 // outside visible range
8659 8645 return !mRangeReversed ? mAxisRect->right() + 200 : mAxisRect->left() - 200;
8660 else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale,
8661 // just draw it outside visible range
8646 else if (value <= 0 && mRange.upper > 0) // invalid value for logarithmic scale, just
8647 // draw it outside visible range
8662 8648 return !mRangeReversed ? mAxisRect->left() - 200 : mAxisRect->right() + 200;
8663 8649 else {
8664 8650 if (!mRangeReversed)
@@ -8684,11 +8670,11 double QCPAxis::coordToPixel(double value) const
8684 8670 }
8685 8671 else // mScaleType == stLogarithmic
8686 8672 {
8687 if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just
8688 // draw it outside visible range
8673 if (value >= 0 && mRange.upper < 0) // invalid value for logarithmic scale, just draw it
8674 // outside visible range
8689 8675 return !mRangeReversed ? mAxisRect->top() - 200 : mAxisRect->bottom() + 200;
8690 else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale,
8691 // just draw it outside visible range
8676 else if (value <= 0 && mRange.upper > 0) // invalid value for logarithmic scale, just
8677 // draw it outside visible range
8692 8678 return !mRangeReversed ? mAxisRect->bottom() + 200 : mAxisRect->top() - 200;
8693 8679 else {
8694 8680 if (!mRangeReversed)
@@ -8879,132 +8865,6 void QCPAxis::deselectEvent(bool *selectionStateChanged)
8879 8865
8880 8866 /*! \internal
8881 8867
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 8868 A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter
9009 8869 before drawing axis lines.
9010 8870
@@ -9394,14 +9254,16 void QCPAxisPainterPrivate::draw(QCPPainter *painter)
9394 9254 painter->setBrush(QBrush(basePen.color()));
9395 9255 QCPVector2D baseLineVector(baseLine.dx(), baseLine.dy());
9396 9256 if (lowerEnding.style() != QCPLineEnding::esNone)
9397 lowerEnding.draw(painter, QCPVector2D(baseLine.p1())
9398 - baseLineVector.normalized() * lowerEnding.realLength()
9399 * (lowerEnding.inverted() ? -1 : 1),
9257 lowerEnding.draw(painter,
9258 QCPVector2D(baseLine.p1())
9259 - baseLineVector.normalized() * lowerEnding.realLength()
9260 * (lowerEnding.inverted() ? -1 : 1),
9400 9261 -baseLineVector);
9401 9262 if (upperEnding.style() != QCPLineEnding::esNone)
9402 upperEnding.draw(painter, QCPVector2D(baseLine.p2())
9403 + baseLineVector.normalized() * upperEnding.realLength()
9404 * (upperEnding.inverted() ? -1 : 1),
9263 upperEnding.draw(painter,
9264 QCPVector2D(baseLine.p2())
9265 + baseLineVector.normalized() * upperEnding.realLength()
9266 * (upperEnding.inverted() ? -1 : 1),
9405 9267 baseLineVector);
9406 9268 painter->setAntialiasing(antialiasingBackup);
9407 9269
@@ -9661,15 +9523,12 void QCPAxisPainterPrivate::placeTickLabel(QCPPainter *painter, double position,
9661 9523 cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()
9662 9524 * mParentPlot->bufferDevicePixelRatio());
9663 9525 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
9664 #ifdef QCP_DEVICEPIXELRATIO_FLOAT
9665 cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatioF());
9666 #else
9667 9526 cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatio());
9668 9527 #endif
9669 #endif
9670 9528 }
9671 9529 else
9672 9530 cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size());
9531 cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size());
9673 9532 cachedLabel->pixmap.fill(Qt::transparent);
9674 9533 QCPPainter cachePainter(&cachedLabel->pixmap);
9675 9534 cachePainter.setPen(painter->pen());
@@ -10034,8 +9893,8 void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString
10034 9893 /* end of 'src/axis/axis.cpp' */
10035 9894
10036 9895
10037 /* including file 'src/scatterstyle.cpp', size 17450 */
10038 /* commit 820d2282db70144c358c13433cd74b4175f9252b 2017-07-24 00:24:17 +0200 */
9896 /* including file 'src/scatterstyle.cpp', size 17420 */
9897 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
10039 9898
10040 9899 ////////////////////////////////////////////////////////////////////////////////////////////////////
10041 9900 //////////////////// QCPScatterStyle
@@ -10205,8 +10064,8 QCPScatterStyle::QCPScatterStyle(const QPixmap &pixmap)
10205 10064
10206 10065 The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly
10207 10066 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
10209 original size by default. To for example double the size of the path, set \a size to 12.
10067 factor of \a size/6.0. Since the default \a size is 6, the custom path will appear at a its
10068 natural size by default. To double the size of the path for example, set \a size to 12.
10210 10069 */
10211 10070 QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen,
10212 10071 const QBrush &brush, double size)
@@ -10393,9 +10252,10 void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const
10393 10252 break;
10394 10253 }
10395 10254 case ssDiamond: {
10396 QPointF lineArray[4]
10397 = {QPointF(x - w, y), QPointF(x, y - w), QPointF(x + w, y), QPointF(x, y + w)};
10398 painter->drawPolygon(lineArray, 4);
10255 painter->drawLine(QLineF(x - w, y, x, y - w));
10256 painter->drawLine(QLineF(x, y - w, x + w, y));
10257 painter->drawLine(QLineF(x + w, y, x, y + w));
10258 painter->drawLine(QLineF(x, y + w, x - w, y));
10399 10259 break;
10400 10260 }
10401 10261 case ssStar: {
@@ -10406,46 +10266,46 void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const
10406 10266 break;
10407 10267 }
10408 10268 case ssTriangle: {
10409 QPointF lineArray[3] = {QPointF(x - w, y + 0.755 * w), QPointF(x + w, y + 0.755 * w),
10410 QPointF(x, y - 0.977 * w)};
10411 painter->drawPolygon(lineArray, 3);
10269 painter->drawLine(QLineF(x - w, y + 0.755 * w, x + w, y + 0.755 * w));
10270 painter->drawLine(QLineF(x + w, y + 0.755 * w, x, y - 0.977 * w));
10271 painter->drawLine(QLineF(x, y - 0.977 * w, x - w, y + 0.755 * w));
10412 10272 break;
10413 10273 }
10414 10274 case ssTriangleInverted: {
10415 QPointF lineArray[3] = {QPointF(x - w, y - 0.755 * w), QPointF(x + w, y - 0.755 * w),
10416 QPointF(x, y + 0.977 * w)};
10417 painter->drawPolygon(lineArray, 3);
10275 painter->drawLine(QLineF(x - w, y - 0.755 * w, x + w, y - 0.755 * w));
10276 painter->drawLine(QLineF(x + w, y - 0.755 * w, x, y + 0.977 * w));
10277 painter->drawLine(QLineF(x, y + 0.977 * w, x - w, y - 0.755 * w));
10418 10278 break;
10419 10279 }
10420 10280 case ssCrossSquare: {
10421 painter->drawRect(QRectF(x - w, y - w, mSize, mSize));
10422 10281 painter->drawLine(QLineF(x - w, y - w, x + w * 0.95, y + w * 0.95));
10423 10282 painter->drawLine(QLineF(x - w, y + w * 0.95, x + w * 0.95, y - w));
10283 painter->drawRect(QRectF(x - w, y - w, mSize, mSize));
10424 10284 break;
10425 10285 }
10426 10286 case ssPlusSquare: {
10427 painter->drawRect(QRectF(x - w, y - w, mSize, mSize));
10428 10287 painter->drawLine(QLineF(x - w, y, x + w * 0.95, y));
10429 10288 painter->drawLine(QLineF(x, y + w, x, y - w));
10289 painter->drawRect(QRectF(x - w, y - w, mSize, mSize));
10430 10290 break;
10431 10291 }
10432 10292 case ssCrossCircle: {
10433 painter->drawEllipse(QPointF(x, y), w, w);
10434 10293 painter->drawLine(QLineF(x - w * 0.707, y - w * 0.707, x + w * 0.670, y + w * 0.670));
10435 10294 painter->drawLine(QLineF(x - w * 0.707, y + w * 0.670, x + w * 0.670, y - w * 0.707));
10295 painter->drawEllipse(QPointF(x, y), w, w);
10436 10296 break;
10437 10297 }
10438 10298 case ssPlusCircle: {
10439 painter->drawEllipse(QPointF(x, y), w, w);
10440 10299 painter->drawLine(QLineF(x - w, y, x + w, y));
10441 10300 painter->drawLine(QLineF(x, y + w, x, y - w));
10301 painter->drawEllipse(QPointF(x, y), w, w);
10442 10302 break;
10443 10303 }
10444 10304 case ssPeace: {
10445 painter->drawEllipse(QPointF(x, y), w, w);
10446 10305 painter->drawLine(QLineF(x, y - w, x, y + w));
10447 10306 painter->drawLine(QLineF(x, y, x - w * 0.707, y + w * 0.707));
10448 10307 painter->drawLine(QLineF(x, y, x + w * 0.707, y + w * 0.707));
10308 painter->drawEllipse(QPointF(x, y), w, w);
10449 10309 break;
10450 10310 }
10451 10311 case ssPixmap: {
@@ -10476,8 +10336,8 void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const
10476 10336
10477 10337 // amalgamation: add datacontainer.cpp
10478 10338
10479 /* including file 'src/plottable.cpp', size 38845 */
10480 /* commit b0bed12626f942821097f43091126b6fb7163122 2017-08-13 17:17:33 +0200 */
10339 /* including file 'src/plottable.cpp', size 38861 */
10340 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
10481 10341
10482 10342 ////////////////////////////////////////////////////////////////////////////////////////////////////
10483 10343 //////////////////// QCPSelectionDecorator
@@ -10515,8 +10375,8 void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const
10515 10375 QCPSelectionDecorator::QCPSelectionDecorator()
10516 10376 : mPen(QColor(80, 80, 255), 2.5),
10517 10377 mBrush(Qt::NoBrush),
10518 mScatterStyle(),
10519 mUsedScatterProperties(QCPScatterStyle::spNone),
10378 mScatterStyle(QCPScatterStyle::ssNone, QPen(Qt::blue, 2), Qt::NoBrush, 6.0),
10379 mUsedScatterProperties(QCPScatterStyle::spPen),
10520 10380 mPlottable(0)
10521 10381 {
10522 10382 }
@@ -10559,8 +10419,6 void QCPSelectionDecorator::setScatterStyle(const QCPScatterStyle &scatterStyle,
10559 10419 Use this method to define which properties of the scatter style (set via \ref setScatterStyle)
10560 10420 will be used for selected data segments. All properties of the scatter style that are not
10561 10421 specified in \a properties will remain as specified in the plottable's original scatter style.
10562
10563 \see QCPScatterStyle::ScatterProperty
10564 10422 */
10565 10423 void QCPSelectionDecorator::setUsedScatterProperties(
10566 10424 const QCPScatterStyle::ScatterProperties &properties)
@@ -12765,8 +12623,8 QCP::Interaction QCPAbstractItem::selectionCategory() const
12765 12623 /* end of 'src/item.cpp' */
12766 12624
12767 12625
12768 /* including file 'src/core.cpp', size 125027 */
12769 /* commit 9ede7553208db59867d1ea9f1988cd90e3c7ffed 2017-08-13 17:25:24 +0200 */
12626 /* including file 'src/core.cpp', size 124243 */
12627 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
12770 12628
12771 12629 ////////////////////////////////////////////////////////////////////////////////////////////////////
12772 12630 //////////////////// QCustomPlot
@@ -13110,7 +12968,6 QCustomPlot::QCustomPlot(QWidget *parent)
13110 12968 mOpenGl(false),
13111 12969 mMouseHasMoved(false),
13112 12970 mMouseEventLayerable(0),
13113 mMouseSignalLayerable(0),
13114 12971 mReplotting(false),
13115 12972 mReplotQueued(false),
13116 12973 mOpenGlMultisamples(16),
@@ -13125,12 +12982,8 QCustomPlot::QCustomPlot(QWidget *parent)
13125 12982 currentLocale.setNumberOptions(QLocale::OmitGroupSeparator);
13126 12983 setLocale(currentLocale);
13127 12984 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
13128 #ifdef QCP_DEVICEPIXELRATIO_FLOAT
13129 setBufferDevicePixelRatio(QWidget::devicePixelRatioF());
13130 #else
13131 12985 setBufferDevicePixelRatio(QWidget::devicePixelRatio());
13132 12986 #endif
13133 #endif
13134 12987
13135 12988 mOpenGlAntialiasedElementsBackup = mAntialiasedElements;
13136 12989 mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels);
@@ -13532,10 +13385,6 void QCustomPlot::setSelectionRect(QCPSelectionRect *selectionRect)
13532 13385 }
13533 13386
13534 13387 /*!
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 13388 This method allows to enable OpenGL plot rendering, for increased plotting performance of
13540 13389 graphically demanding plots (thick lines, translucent fills, etc.).
13541 13390
@@ -15084,20 +14933,12 void QCustomPlot::mousePressEvent(QMouseEvent *event)
15084 14933 mSelectionRect->startSelection(event);
15085 14934 }
15086 14935 else {
15087 // no selection rect interaction, prepare for click signal emission and forward event to
15088 // layerable under the cursor:
14936 // no selection rect interaction, so forward event to layerable under the cursor:
15089 14937 QList<QVariant> details;
15090 14938 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 14939 for (int i = 0; i < candidates.size(); ++i) {
15099 event->accept(); // default impl of QCPLayerable's mouse events call ignore() on the
15100 // event, in that case propagate to next candidate in list
14940 event->accept(); // default impl of QCPLayerable's mouse events ignore the event, in
14941 // that case propagate to next candidate in list
15101 14942 candidates.at(i)->mousePressEvent(event, details.at(i));
15102 14943 if (event->isAccepted()) {
15103 14944 mMouseEventLayerable = candidates.at(i);
@@ -15168,25 +15009,22 void QCustomPlot::mouseReleaseEvent(QMouseEvent *event)
15168 15009 processPointSelection(event);
15169 15010
15170 15011 // emit specialized click signals of QCustomPlot instance:
15171 if (QCPAbstractPlottable *ap
15172 = qobject_cast<QCPAbstractPlottable *>(mMouseSignalLayerable)) {
15012 if (QCPAbstractPlottable *ap = qobject_cast<QCPAbstractPlottable *>(mMouseEventLayerable)) {
15173 15013 int dataIndex = 0;
15174 if (!mMouseSignalLayerableDetails.value<QCPDataSelection>().isEmpty())
15014 if (!mMouseEventLayerableDetails.value<QCPDataSelection>().isEmpty())
15175 15015 dataIndex
15176 = mMouseSignalLayerableDetails.value<QCPDataSelection>().dataRange().begin();
15016 = mMouseEventLayerableDetails.value<QCPDataSelection>().dataRange().begin();
15177 15017 emit plottableClick(ap, dataIndex, event);
15178 15018 }
15179 else if (QCPAxis *ax = qobject_cast<QCPAxis *>(mMouseSignalLayerable))
15180 emit axisClick(ax, mMouseSignalLayerableDetails.value<QCPAxis::SelectablePart>(),
15181 event);
15182 else if (QCPAbstractItem *ai = qobject_cast<QCPAbstractItem *>(mMouseSignalLayerable))
15019 else if (QCPAxis *ax = qobject_cast<QCPAxis *>(mMouseEventLayerable))
15020 emit axisClick(ax, mMouseEventLayerableDetails.value<QCPAxis::SelectablePart>(), event);
15021 else if (QCPAbstractItem *ai = qobject_cast<QCPAbstractItem *>(mMouseEventLayerable))
15183 15022 emit itemClick(ai, event);
15184 else if (QCPLegend *lg = qobject_cast<QCPLegend *>(mMouseSignalLayerable))
15023 else if (QCPLegend *lg = qobject_cast<QCPLegend *>(mMouseEventLayerable))
15185 15024 emit legendClick(lg, 0, event);
15186 15025 else if (QCPAbstractLegendItem *li
15187 = qobject_cast<QCPAbstractLegendItem *>(mMouseSignalLayerable))
15026 = qobject_cast<QCPAbstractLegendItem *>(mMouseEventLayerable))
15188 15027 emit legendClick(li->parentLegend(), li, event);
15189 mMouseSignalLayerable = 0;
15190 15028 }
15191 15029
15192 15030 if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the
@@ -16630,8 +16468,9 void QCPColorGradient::updateColorBuffer()
16630 16468 hue -= 1.0;
16631 16469 if (useAlpha) {
16632 16470 const QRgb rgb
16633 = QColor::fromHsvF(hue, (1 - t) * lowHsv.saturationF()
16634 + t * highHsv.saturationF(),
16471 = QColor::fromHsvF(hue,
16472 (1 - t) * lowHsv.saturationF()
16473 + t * highHsv.saturationF(),
16635 16474 (1 - t) * lowHsv.valueF() + t * highHsv.valueF())
16636 16475 .rgb();
16637 16476 const float alpha = (1 - t) * lowHsv.alphaF() + t * highHsv.alphaF();
@@ -16640,8 +16479,9 void QCPColorGradient::updateColorBuffer()
16640 16479 }
16641 16480 else {
16642 16481 mColorBuffer[i]
16643 = QColor::fromHsvF(hue, (1 - t) * lowHsv.saturationF()
16644 + t * highHsv.saturationF(),
16482 = QColor::fromHsvF(hue,
16483 (1 - t) * lowHsv.saturationF()
16484 + t * highHsv.saturationF(),
16645 16485 (1 - t) * lowHsv.valueF() + t * highHsv.valueF())
16646 16486 .rgb();
16647 16487 }
@@ -16958,8 +16798,8 QCPSelectionDecoratorBracket::getPixelCoordinates(const QCPPlottableInterface1D
16958 16798 /* end of 'src/selectiondecorator-bracket.cpp' */
16959 16799
16960 16800
16961 /* including file 'src/layoutelements/layoutelement-axisrect.cpp', size 47584 */
16962 /* commit 77ba168312f935543fc31d1ae9b4cdcf34aae4f9 2017-08-13 18:29:48 +0200 */
16801 /* including file 'src/layoutelements/layoutelement-axisrect.cpp', size 47509 */
16802 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
16963 16803
16964 16804
16965 16805 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -17213,7 +17053,7 QList<QCPAxis *> QCPAxisRect::axes() const
17213 17053 new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to
17214 17054 remove an axis, use \ref removeAxis instead of deleting it manually.
17215 17055
17216 You may inject QCPAxis instances (or subclasses of QCPAxis) by setting \a axis to an axis that was
17056 You may inject QCPAxis instances (or sublasses of QCPAxis) by setting \a axis to an axis that was
17217 17057 previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership
17218 17058 of the axis, so you may not delete it afterwards. Further, the \a axis must have been created
17219 17059 with this axis rect as parent and with the same axis type as specified in \a type. If this is not
@@ -17326,12 +17166,6 bool QCPAxisRect::removeAxis(QCPAxis *axis)
17326 17166 while (it.hasNext()) {
17327 17167 it.next();
17328 17168 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 17169 mAxes[it.key()].removeOne(axis);
17336 17170 if (qobject_cast<QCustomPlot *>(parentPlot())) // make sure this isn't called from
17337 17171 // QObject dtor when QCustomPlot is
@@ -18101,6 +17935,9 void QCPAxisRect::layoutChanged()
18101 17935 void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details)
18102 17936 {
18103 17937 Q_UNUSED(details)
17938 mDragStart = event->pos(); // need this even when not LeftButton is pressed, to determine in
17939 // releaseEvent whether it was a full click (no position change
17940 // between press and release)
18104 17941 if (event->buttons() & Qt::LeftButton) {
18105 17942 mDragging = true;
18106 17943 // initialize antialiasing backup in case we start dragging:
@@ -18146,13 +17983,13 void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
18146 17983 break;
18147 17984 if (ax->mScaleType == QCPAxis::stLinear) {
18148 17985 double diff
18149 = ax->pixelToCoord(startPos.x()) - ax->pixelToCoord(event->pos().x());
17986 = ax->pixelToCoord(mDragStart.x()) - ax->pixelToCoord(event->pos().x());
18150 17987 ax->setRange(mDragStartHorzRange.at(i).lower + diff,
18151 17988 mDragStartHorzRange.at(i).upper + diff);
18152 17989 }
18153 17990 else if (ax->mScaleType == QCPAxis::stLogarithmic) {
18154 17991 double diff
18155 = ax->pixelToCoord(startPos.x()) / ax->pixelToCoord(event->pos().x());
17992 = ax->pixelToCoord(mDragStart.x()) / ax->pixelToCoord(event->pos().x());
18156 17993 ax->setRange(mDragStartHorzRange.at(i).lower * diff,
18157 17994 mDragStartHorzRange.at(i).upper * diff);
18158 17995 }
@@ -18168,13 +18005,13 void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
18168 18005 break;
18169 18006 if (ax->mScaleType == QCPAxis::stLinear) {
18170 18007 double diff
18171 = ax->pixelToCoord(startPos.y()) - ax->pixelToCoord(event->pos().y());
18008 = ax->pixelToCoord(mDragStart.y()) - ax->pixelToCoord(event->pos().y());
18172 18009 ax->setRange(mDragStartVertRange.at(i).lower + diff,
18173 18010 mDragStartVertRange.at(i).upper + diff);
18174 18011 }
18175 18012 else if (ax->mScaleType == QCPAxis::stLogarithmic) {
18176 18013 double diff
18177 = ax->pixelToCoord(startPos.y()) / ax->pixelToCoord(event->pos().y());
18014 = ax->pixelToCoord(mDragStart.y()) / ax->pixelToCoord(event->pos().y());
18178 18015 ax->setRange(mDragStartVertRange.at(i).lower * diff,
18179 18016 mDragStartVertRange.at(i).upper * diff);
18180 18017 }
@@ -18185,7 +18022,7 void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
18185 18022 {
18186 18023 if (mParentPlot->noAntialiasingOnDrag())
18187 18024 mParentPlot->setNotAntialiasedElements(QCP::aeAll);
18188 mParentPlot->replot(QCustomPlot::rpQueuedReplot);
18025 mParentPlot->replot();
18189 18026 }
18190 18027 }
18191 18028 }
@@ -18246,8 +18083,8 void QCPAxisRect::wheelEvent(QWheelEvent *event)
18246 18083 /* end of 'src/layoutelements/layoutelement-axisrect.cpp' */
18247 18084
18248 18085
18249 /* including file 'src/layoutelements/layoutelement-legend.cpp', size 30971 */
18250 /* commit 305808813c9c6451dca8399c2fc66d68ebd24b5e 2017-08-15 23:03:07 +0200 */
18086 /* including file 'src/layoutelements/layoutelement-legend.cpp', size 30933 */
18087 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
18251 18088
18252 18089 ////////////////////////////////////////////////////////////////////////////////////////////////////
18253 18090 //////////////////// QCPAbstractLegendItem
@@ -18450,7 +18287,9 void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged)
18450 18287 QCPLegend::setIconBorderPen and \ref QCPLegend::setIconTextPadding.
18451 18288
18452 18289 The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend
18453 creates/removes legend items of this type.
18290 creates/removes legend items of this type in the default implementation. However, these functions
18291 may be reimplemented such that a different kind of legend item (e.g a direct subclass of
18292 QCPAbstractLegendItem) is used for that plottable.
18454 18293
18455 18294 Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of
18456 18295 QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout
@@ -18557,8 +18396,10 QSize QCPPlottableLegendItem::minimumSizeHint() const
18557 18396 QSize iconSize = mParentLegend->iconSize();
18558 18397 textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip,
18559 18398 mPlottable->name());
18560 result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width());
18561 result.setHeight(qMax(textRect.height(), iconSize.height()));
18399 result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width()
18400 + mMargins.left() + mMargins.right());
18401 result.setHeight(qMax(textRect.height(), iconSize.height()) + mMargins.top()
18402 + mMargins.bottom());
18562 18403 return result;
18563 18404 }
18564 18405
@@ -18572,14 +18413,10 QSize QCPPlottableLegendItem::minimumSizeHint() const
18572 18413
18573 18414 A legend is a small box somewhere in the plot which lists plottables with their name and icon.
18574 18415
18575 A legend is populated with legend items by calling \ref QCPAbstractPlottable::addToLegend on the
18576 plottable, for which a legend item shall be created. In the case of the main legend (\ref
18577 QCustomPlot::legend), simply adding plottables to the plot while \ref
18578 QCustomPlot::setAutoAddPlottableToLegend is set to true (the default) creates corresponding
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.
18416 Normally, the legend is populated by calling \ref QCPAbstractPlottable::addToLegend. The
18417 respective legend item can be removed with \ref QCPAbstractPlottable::removeFromLegend. However,
18418 QCPLegend also offers an interface to add and manipulate legend items directly: \ref item, \ref
18419 itemWithPlottable, \ref itemCount, \ref addItem, \ref removeItem, etc.
18583 18420
18584 18421 Since \ref QCPLegend derives from \ref QCPLayoutGrid, it can be placed in any position a \ref
18585 18422 QCPLayoutElement may be positioned. The legend items are themselves \ref QCPLayoutElement
@@ -19176,8 +19013,8 void QCPLegend::parentPlotInitialized(QCustomPlot *parentPlot)
19176 19013 /* end of 'src/layoutelements/layoutelement-legend.cpp' */
19177 19014
19178 19015
19179 /* including file 'src/layoutelements/layoutelement-textelement.cpp', size 12561 */
19180 /* commit a872eb91ec087561efd83dd9cb041a26ab95ce55 2017-07-31 00:21:41 +0200 */
19016 /* including file 'src/layoutelements/layoutelement-textelement.cpp', size 12759 */
19017 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
19181 19018
19182 19019 ////////////////////////////////////////////////////////////////////////////////////////////////////
19183 19020 //////////////////// QCPTextElement
@@ -19463,7 +19300,10 void QCPTextElement::draw(QCPPainter *painter)
19463 19300 QSize QCPTextElement::minimumSizeHint() const
19464 19301 {
19465 19302 QFontMetrics metrics(mFont);
19466 return metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size();
19303 QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size();
19304 result.rwidth() += mMargins.left() + mMargins.right();
19305 result.rheight() += mMargins.top() + mMargins.bottom();
19306 return result;
19467 19307 }
19468 19308
19469 19309 /* inherits documentation from base class */
@@ -19471,6 +19311,7 QSize QCPTextElement::maximumSizeHint() const
19471 19311 {
19472 19312 QFontMetrics metrics(mFont);
19473 19313 QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size();
19314 result.rheight() += mMargins.top() + mMargins.bottom();
19474 19315 result.setWidth(QWIDGETSIZE_MAX);
19475 19316 return result;
19476 19317 }
@@ -19998,12 +19839,14 void QCPColorScale::update(UpdatePhase phase)
19998 19839 switch (phase) {
19999 19840 case upMargins: {
20000 19841 if (mType == QCPAxis::atBottom || mType == QCPAxis::atTop) {
20001 setMaximumSize(QWIDGETSIZE_MAX, mBarWidth + mAxisRect.data()->margins().top()
20002 + mAxisRect.data()->margins().bottom()
20003 + margins().top() + margins().bottom());
20004 setMinimumSize(0, mBarWidth + mAxisRect.data()->margins().top()
20005 + mAxisRect.data()->margins().bottom() + margins().top()
20006 + margins().bottom());
19842 setMaximumSize(QWIDGETSIZE_MAX,
19843 mBarWidth + mAxisRect.data()->margins().top()
19844 + mAxisRect.data()->margins().bottom() + margins().top()
19845 + margins().bottom());
19846 setMinimumSize(0,
19847 mBarWidth + mAxisRect.data()->margins().top()
19848 + mAxisRect.data()->margins().bottom() + margins().top()
19849 + margins().bottom());
20007 19850 }
20008 19851 else {
20009 19852 setMaximumSize(mBarWidth + mAxisRect.data()->margins().left()
@@ -20260,8 +20103,8 void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectablePart
20260 20103 /* end of 'src/layoutelements/layoutelement-colorscale.cpp' */
20261 20104
20262 20105
20263 /* including file 'src/plottables/plottable-graph.cpp', size 73960 */
20264 /* commit 7e7381ef4f218e004d72a218820634fff0959d1b 2017-08-02 00:02:36 +0200 */
20106 /* including file 'src/plottables/plottable-graph.cpp', size 72363 */
20107 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
20265 20108
20266 20109 ////////////////////////////////////////////////////////////////////////////////////////////////////
20267 20110 //////////////////// QCPGraphData
@@ -20809,12 +20652,6 void QCPGraph::getLines(QVector<QPointF> *lines, const QCPDataRange &dataRange)
20809 20652 if (mLineStyle != lsNone)
20810 20653 getOptimizedLineData(&lineData, begin, end);
20811 20654
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 20655 switch (mLineStyle) {
20819 20656 case lsNone:
20820 20657 lines->clear();
@@ -20870,13 +20707,6 void QCPGraph::getScatters(QVector<QPointF> *scatters, const QCPDataRange &dataR
20870 20707
20871 20708 QVector<QCPGraphData> data;
20872 20709 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 20710 scatters->resize(data.size());
20881 20711 if (keyAxis->orientation() == Qt::Vertical) {
20882 20712 for (int i = 0; i < data.size(); ++i) {
@@ -20917,6 +20747,8 QVector<QPointF> QCPGraph::dataToLines(const QVector<QCPGraphData> &data) const
20917 20747 return result;
20918 20748 }
20919 20749
20750 result.reserve(data.size() + 2); // added 2 to reserve memory for lower/upper fill base points
20751 // that might be needed for fill
20920 20752 result.resize(data.size());
20921 20753
20922 20754 // transform data points to pixels:
@@ -20957,6 +20789,8 QVector<QPointF> QCPGraph::dataToStepLeftLines(const QVector<QCPGraphData> &data
20957 20789 return result;
20958 20790 }
20959 20791
20792 result.reserve(data.size() * 2 + 2); // added 2 to reserve memory for lower/upper fill base
20793 // points that might be needed for fill
20960 20794 result.resize(data.size() * 2);
20961 20795
20962 20796 // calculate steps from data and transform to pixel coordinates:
@@ -21007,6 +20841,8 QVector<QPointF> QCPGraph::dataToStepRightLines(const QVector<QCPGraphData> &dat
21007 20841 return result;
21008 20842 }
21009 20843
20844 result.reserve(data.size() * 2 + 2); // added 2 to reserve memory for lower/upper fill base
20845 // points that might be needed for fill
21010 20846 result.resize(data.size() * 2);
21011 20847
21012 20848 // calculate steps from data and transform to pixel coordinates:
@@ -21057,6 +20893,8 QVector<QPointF> QCPGraph::dataToStepCenterLines(const QVector<QCPGraphData> &da
21057 20893 return result;
21058 20894 }
21059 20895
20896 result.reserve(data.size() * 2 + 2); // added 2 to reserve memory for lower/upper fill base
20897 // points that might be needed for fill
21060 20898 result.resize(data.size() * 2);
21061 20899
21062 20900 // calculate steps from data and transform to pixel coordinates:
@@ -21119,7 +20957,8 QVector<QPointF> QCPGraph::dataToImpulseLines(const QVector<QCPGraphData> &data)
21119 20957 return result;
21120 20958 }
21121 20959
21122 result.resize(data.size() * 2);
20960 result.resize(data.size()
20961 * 2); // no need to reserve 2 extra points because impulse plot has no fill
21123 20962
21124 20963 // transform data points to pixels:
21125 20964 if (keyAxis->orientation() == Qt::Vertical) {
@@ -21148,16 +20987,15 QVector<QPointF> QCPGraph::dataToImpulseLines(const QVector<QCPGraphData> &data)
21148 20987
21149 20988 Draws the fill of the graph using the specified \a painter, with the currently set brush.
21150 20989
21151 Depending on whether a normal fill or a channel fill (\ref setChannelFillGraph) is needed, \ref
21152 getFillPolygon or \ref getChannelFillPolygon are used to find the according fill polygons.
20990 \a lines contains the points of the graph line, in pixel coordinates.
21153 20991
21154 In order to handle NaN Data points correctly (the fill needs to be split into disjoint areas),
21155 this method first determines a list of non-NaN segments with \ref getNonNanSegments, on which to
21156 operate. In the channel fill case, \ref getOverlappingSegments is used to consolidate the non-NaN
21157 segments of the two involved graphs, before passing the overlapping pairs to \ref
21158 getChannelFillPolygon.
20992 If the fill is a normal fill towards the zero-value-line, only the points in \a lines are
20993 required and two extra points at the zero-value-line, which are added by \ref addFillBasePoints
20994 and removed by \ref removeFillBasePoints after the fill drawing is done.
21159 20995
21160 Pass the points of this graph's line as \a lines, in pixel coordinates.
20996 On the other hand if the fill is a channel fill between this QCPGraph and another QCPGraph (\a
20997 mChannelFillGraph), the more complex polygon is calculated with the \ref getChannelFillPolygon
20998 function, and then drawn.
21161 20999
21162 21000 \see drawLinePlot, drawImpulsePlot, drawScatterPlot
21163 21001 */
@@ -21169,25 +21007,15 void QCPGraph::drawFill(QCPPainter *painter, QVector<QPointF> *lines) const
21169 21007 return;
21170 21008
21171 21009 applyFillAntialiasingHint(painter);
21172 QVector<QCPDataRange> segments = getNonNanSegments(lines, keyAxis()->orientation());
21173 21010 if (!mChannelFillGraph) {
21174 21011 // draw base fill under graph, fill goes all the way to the zero-value-line:
21175 for (int i = 0; i < segments.size(); ++i)
21176 painter->drawPolygon(getFillPolygon(lines, segments.at(i)));
21012 addFillBasePoints(lines);
21013 painter->drawPolygon(QPolygonF(*lines));
21014 removeFillBasePoints(lines);
21177 21015 }
21178 21016 else {
21179 // draw fill between this graph and mChannelFillGraph:
21180 QVector<QPointF> otherLines;
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 }
21017 // draw channel fill between this graph and mChannelFillGraph:
21018 painter->drawPolygon(getChannelFillPolygon(lines));
21191 21019 }
21192 21020 }
21193 21021
@@ -21380,8 +21208,12 void QCPGraph::getOptimizedLineData(QVector<QCPGraphData> *lineData,
21380 21208 else // don't use adaptive sampling algorithm, transfer points one-to-one from the data
21381 21209 // container into the output
21382 21210 {
21383 lineData->resize(dataCount);
21384 std::copy(begin, end, lineData->begin());
21211 QCPGraphDataContainer::const_iterator it = begin;
21212 lineData->reserve(dataCount + 2); // +2 for possible fill end points
21213 while (it != end) {
21214 lineData->append(*it);
21215 ++it;
21216 }
21385 21217 }
21386 21218 }
21387 21219
@@ -21650,177 +21482,151 void QCPGraph::getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin
21650 21482 }
21651 21483 }
21652 21484
21653 /*! \internal
21485 /*! \internal
21654 21486
21655 This method goes through the passed points in \a lineData and returns a list of the segments
21656 which don't contain NaN data points.
21487 The line vector generated by e.g. \ref getLines describes only the line that connects the data
21488 points. If the graph needs to be filled, two additional points need to be added at the
21489 value-zero-line in the lower and upper key positions of the graph. This function calculates these
21490 points and adds them to the end of \a lineData. Since the fill is typically drawn before the line
21491 stroke, these added points need to be removed again after the fill is done, with the
21492 removeFillBasePoints function.
21657 21493
21658 \a keyOrientation defines whether the \a x or \a y member of the passed QPointF is used to check
21659 for NaN. If \a keyOrientation is \c Qt::Horizontal, the \a y member is checked, if it is \c
21660 Qt::Vertical, the \a x member is checked.
21494 The expanding of \a lines by two points will not cause unnecessary memory reallocations, because
21495 the data vector generation functions (e.g. \ref getLines) reserve two extra points when they
21496 allocate memory for \a lines.
21661 21497
21662 \see getOverlappingSegments, drawFill
21498 \see removeFillBasePoints, lowerFillBasePoint, upperFillBasePoint
21663 21499 */
21664 QVector<QCPDataRange> QCPGraph::getNonNanSegments(const QVector<QPointF> *lineData,
21665 Qt::Orientation keyOrientation) const
21500 void QCPGraph::addFillBasePoints(QVector<QPointF> *lines) const
21666 21501 {
21667 QVector<QCPDataRange> result;
21668 const int n = lineData->size();
21669
21670 QCPDataRange currentSegment(-1, -1);
21671 int i = 0;
21502 if (!mKeyAxis) {
21503 qDebug() << Q_FUNC_INFO << "invalid key axis";
21504 return;
21505 }
21506 if (!lines) {
21507 qDebug() << Q_FUNC_INFO << "passed null as lineData";
21508 return;
21509 }
21510 if (lines->isEmpty())
21511 return;
21672 21512
21673 if (keyOrientation == Qt::Horizontal) {
21674 while (i < n) {
21675 while (i < n && qIsNaN(lineData->at(i).y())) // seek next non-NaN data point
21676 ++i;
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 }
21513 // append points that close the polygon fill at the key axis:
21514 if (mKeyAxis.data()->orientation() == Qt::Vertical) {
21515 *lines << upperFillBasePoint(lines->last().y());
21516 *lines << lowerFillBasePoint(lines->first().y());
21685 21517 }
21686 else // keyOrientation == Qt::Vertical
21687 {
21688 while (i < n) {
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 }
21518 else {
21519 *lines << upperFillBasePoint(lines->last().x());
21520 *lines << lowerFillBasePoint(lines->first().x());
21699 21521 }
21700 return result;
21701 21522 }
21702 21523
21703 /*! \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.
21524 /*! \internal
21714 21525
21715 It is assumed that the passed segments in \a thisSegments are ordered ascending by index, and
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.
21526 removes the two points from \a lines that were added by \ref addFillBasePoints.
21718 21527
21719 \see getNonNanSegments, segmentsIntersect, drawFill, getChannelFillPolygon
21528 \see addFillBasePoints, lowerFillBasePoint, upperFillBasePoint
21720 21529 */
21721 QVector<QPair<QCPDataRange, QCPDataRange> > QCPGraph::getOverlappingSegments(
21722 QVector<QCPDataRange> thisSegments, const QVector<QPointF> *thisData,
21723 QVector<QCPDataRange> otherSegments, const QVector<QPointF> *otherData) const
21530 void QCPGraph::removeFillBasePoints(QVector<QPointF> *lines) const
21724 21531 {
21725 QVector<QPair<QCPDataRange, QCPDataRange> > result;
21726 if (thisData->isEmpty() || otherData->isEmpty() || thisSegments.isEmpty()
21727 || otherSegments.isEmpty())
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;
21532 if (!lines) {
21533 qDebug() << Q_FUNC_INFO << "passed null as lineData";
21534 return;
21771 21535 }
21536 if (lines->isEmpty())
21537 return;
21772 21538
21773 return result;
21539 lines->remove(lines->size() - 2, 2);
21774 21540 }
21775 21541
21776 /*! \internal
21777
21778 Returns whether the segments defined by the coordinates (aLower, aUpper) and (bLower, bUpper)
21779 have overlap.
21542 /*! \internal
21780 21543
21781 The output parameter \a bPrecedence indicates whether the \a b segment reaches farther than the
21782 \a a segment or not. If \a bPrecedence returns 1, segment \a b reaches the farthest to higher
21783 coordinates (i.e. bUpper > aUpper). If it returns -1, segment \a a reaches the farthest. Only if
21784 both segment's upper bounds are identical, 0 is returned as \a bPrecedence.
21544 called by \ref addFillBasePoints to conveniently assign the point which closes the fill polygon
21545 on the lower side of the zero-value-line parallel to the key axis. The logarithmic axis scale
21546 case is a bit special, since the zero-value-line in pixel coordinates is in positive or negative
21547 infinity. So this case is handled separately by just closing the fill polygon on the axis which
21548 lies in the direction towards the zero value.
21785 21549
21786 It is assumed that the lower bounds always have smaller or equal values than the upper bounds.
21550 \a lowerKey will be the the key (in pixels) of the returned point. Depending on whether the key
21551 axis is horizontal or vertical, \a lowerKey will end up as the x or y value of the returned
21552 point, respectively.
21787 21553
21788 \see getOverlappingSegments
21554 \see upperFillBasePoint, addFillBasePoints
21789 21555 */
21790 bool QCPGraph::segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper,
21791 int &bPrecedence) const
21556 QPointF QCPGraph::lowerFillBasePoint(double lowerKey) const
21792 21557 {
21793 bPrecedence = 0;
21794 if (aLower > bUpper) {
21795 bPrecedence = -1;
21796 return false;
21797 }
21798 else if (bLower > aUpper) {
21799 bPrecedence = 1;
21800 return false;
21558 QCPAxis *keyAxis = mKeyAxis.data();
21559 QCPAxis *valueAxis = mValueAxis.data();
21560 if (!keyAxis || !valueAxis) {
21561 qDebug() << Q_FUNC_INFO << "invalid key or value axis";
21562 return QPointF();
21801 21563 }
21802 else {
21803 if (aUpper > bUpper)
21804 bPrecedence = -1;
21805 else if (aUpper < bUpper)
21806 bPrecedence = 1;
21807 21564
21808 return true;
21565 QPointF point;
21566 if (valueAxis->scaleType() == QCPAxis::stLinear) {
21567 if (keyAxis->axisType() == QCPAxis::atLeft) {
21568 point.setX(valueAxis->coordToPixel(0));
21569 point.setY(lowerKey);
21570 }
21571 else if (keyAxis->axisType() == QCPAxis::atRight) {
21572 point.setX(valueAxis->coordToPixel(0));
21573 point.setY(lowerKey);
21574 }
21575 else if (keyAxis->axisType() == QCPAxis::atTop) {
21576 point.setX(lowerKey);
21577 point.setY(valueAxis->coordToPixel(0));
21578 }
21579 else if (keyAxis->axisType() == QCPAxis::atBottom) {
21580 point.setX(lowerKey);
21581 point.setY(valueAxis->coordToPixel(0));
21582 }
21809 21583 }
21584 else // valueAxis->mScaleType == QCPAxis::stLogarithmic
21585 {
21586 // In logarithmic scaling we can't just draw to value zero so we just fill all the way
21587 // to the axis which is in the direction towards zero
21588 if (keyAxis->orientation() == Qt::Vertical) {
21589 if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed())
21590 || (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is
21591 // negative, zero
21592 // is on opposite
21593 // side of key axis
21594 point.setX(keyAxis->axisRect()->right());
21595 else
21596 point.setX(keyAxis->axisRect()->left());
21597 point.setY(lowerKey);
21598 }
21599 else if (keyAxis->axisType() == QCPAxis::atTop
21600 || keyAxis->axisType() == QCPAxis::atBottom) {
21601 point.setX(lowerKey);
21602 if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed())
21603 || (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is
21604 // negative, zero
21605 // is on opposite
21606 // side of key axis
21607 point.setY(keyAxis->axisRect()->top());
21608 else
21609 point.setY(keyAxis->axisRect()->bottom());
21610 }
21611 }
21612 return point;
21810 21613 }
21811 21614
21812 21615 /*! \internal
21813 21616
21814 Returns the point which closes the fill polygon on the zero-value-line parallel to the key axis.
21815 The logarithmic axis scale case is a bit special, since the zero-value-line in pixel coordinates
21816 is in positive or negative infinity. So this case is handled separately by just closing the fill
21817 polygon on the axis which lies in the direction towards the zero value.
21617 called by \ref addFillBasePoints to conveniently assign the point which closes the fill
21618 polygon on the upper side of the zero-value-line parallel to the key axis. The logarithmic axis
21619 scale case is a bit special, since the zero-value-line in pixel coordinates is in positive or
21620 negative infinity. So this case is handled separately by just closing the fill polygon on the
21621 axis which lies in the direction towards the zero value.
21818 21622
21819 \a matchingDataPoint will provide the key (in pixels) of the returned point. Depending on whether
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.
21623 \a upperKey will be the the key (in pixels) of the returned point. Depending on whether the key
21624 axis is horizontal or vertical, \a upperKey will end up as the x or y value of the returned
21625 point, respectively.
21626
21627 \see lowerFillBasePoint, addFillBasePoints
21822 21628 */
21823 QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const
21629 QPointF QCPGraph::upperFillBasePoint(double upperKey) const
21824 21630 {
21825 21631 QCPAxis *keyAxis = mKeyAxis.data();
21826 21632 QCPAxis *valueAxis = mValueAxis.data();
@@ -21829,16 +21635,23 QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const
21829 21635 return QPointF();
21830 21636 }
21831 21637
21832 QPointF result;
21638 QPointF point;
21833 21639 if (valueAxis->scaleType() == QCPAxis::stLinear) {
21834 if (keyAxis->orientation() == Qt::Horizontal) {
21835 result.setX(matchingDataPoint.x());
21836 result.setY(valueAxis->coordToPixel(0));
21640 if (keyAxis->axisType() == QCPAxis::atLeft) {
21641 point.setX(valueAxis->coordToPixel(0));
21642 point.setY(upperKey);
21837 21643 }
21838 else // keyAxis->orientation() == Qt::Vertical
21839 {
21840 result.setX(valueAxis->coordToPixel(0));
21841 result.setY(matchingDataPoint.y());
21644 else if (keyAxis->axisType() == QCPAxis::atRight) {
21645 point.setX(valueAxis->coordToPixel(0));
21646 point.setY(upperKey);
21647 }
21648 else if (keyAxis->axisType() == QCPAxis::atTop) {
21649 point.setX(upperKey);
21650 point.setY(valueAxis->coordToPixel(0));
21651 }
21652 else if (keyAxis->axisType() == QCPAxis::atBottom) {
21653 point.setX(upperKey);
21654 point.setY(valueAxis->coordToPixel(0));
21842 21655 }
21843 21656 }
21844 21657 else // valueAxis->mScaleType == QCPAxis::stLogarithmic
@@ -21851,80 +21664,40 QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const
21851 21664 // negative, zero
21852 21665 // is on opposite
21853 21666 // side of key axis
21854 result.setX(keyAxis->axisRect()->right());
21667 point.setX(keyAxis->axisRect()->right());
21855 21668 else
21856 result.setX(keyAxis->axisRect()->left());
21857 result.setY(matchingDataPoint.y());
21669 point.setX(keyAxis->axisRect()->left());
21670 point.setY(upperKey);
21858 21671 }
21859 21672 else if (keyAxis->axisType() == QCPAxis::atTop
21860 21673 || keyAxis->axisType() == QCPAxis::atBottom) {
21861 result.setX(matchingDataPoint.x());
21674 point.setX(upperKey);
21862 21675 if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed())
21863 21676 || (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is
21864 21677 // negative, zero
21865 21678 // is on opposite
21866 21679 // side of key axis
21867 result.setY(keyAxis->axisRect()->top());
21680 point.setY(keyAxis->axisRect()->top());
21868 21681 else
21869 result.setY(keyAxis->axisRect()->bottom());
21682 point.setY(keyAxis->axisRect()->bottom());
21870 21683 }
21871 21684 }
21872 return result;
21685 return point;
21873 21686 }
21874 21687
21875 21688 /*! \internal
21876 21689
21877 Returns the polygon needed for drawing normal fills between this graph and the key axis.
21690 Generates the polygon needed for drawing channel fills between this graph and the graph specified
21691 in \a mChannelFillGraph (see \ref setChannelFillGraph). The data points representing the line of
21692 this graph in pixel coordinates must be passed in \a lines, the corresponding points of the other
21693 graph are generated by calling its \ref getLines method.
21878 21694
21879 Pass the graph's data points (in pixel coordinates) as \a lineData, and specify the \a segment
21880 which shall be used for the fill. The collection of \a lineData points described by \a segment
21881 must not contain NaN data points (see \ref getNonNanSegments).
21882
21883 The returned fill polygon will be closed at the key axis (the zero-value line) for linear value
21884 axes. For logarithmic value axes the polygon will reach just beyond the corresponding axis rect
21885 side (see \ref getFillBasePoint).
21886
21887 For increased performance (due to implicit sharing), keep the returned QPolygonF const.
21888
21889 \see drawFill, getNonNanSegments
21890 */
21891 const QPolygonF QCPGraph::getFillPolygon(const QVector<QPointF> *lineData,
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
21695 This method may return an empty polygon if the key ranges of the two graphs have no overlap of if
21696 they don't have the same orientation (e.g. one key axis vertical, the other horizontal). For
21697 increased performance (due to implicit sharing), it is recommended to keep the returned QPolygonF
21698 const.
21923 21699 */
21924 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData,
21925 QCPDataRange thisSegment,
21926 const QVector<QPointF> *otherData,
21927 QCPDataRange otherSegment) const
21700 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *lines) const
21928 21701 {
21929 21702 if (!mChannelFillGraph)
21930 21703 return QPolygonF();
@@ -21945,35 +21718,55 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData
21945 21718 // fits, valueAxis will fit too, because it's always orthogonal to
21946 21719 // keyAxis)
21947 21720
21948 if (thisData->isEmpty())
21721 if (lines->isEmpty())
21949 21722 return QPolygonF();
21950 QVector<QPointF> thisSegmentData(thisSegment.size());
21951 QVector<QPointF> otherSegmentData(otherSegment.size());
21952 std::copy(thisData->constBegin() + thisSegment.begin(),
21953 thisData->constBegin() + thisSegment.end(), thisSegmentData.begin());
21954 std::copy(otherData->constBegin() + otherSegment.begin(),
21955 otherData->constBegin() + otherSegment.end(), otherSegmentData.begin());
21723 QVector<QPointF> otherData;
21724 mChannelFillGraph.data()->getLines(&otherData,
21725 QCPDataRange(0, mChannelFillGraph.data()->dataCount()));
21726 if (otherData.isEmpty())
21727 return QPolygonF();
21728 QVector<QPointF> thisData;
21729 thisData.reserve(
21730 lines->size()
21731 + otherData.size()); // because we will join both vectors at end of this function
21732 for (int i = 0; i < lines->size(); ++i) // don't use the vector<<(vector), it squeezes
21733 // internally, which ruins the performance tuning with
21734 // reserve()
21735 thisData << lines->at(i);
21736
21956 21737 // pointers to be able to swap them, depending which data range needs cropping:
21957 QVector<QPointF> *staticData = &thisSegmentData;
21958 QVector<QPointF> *croppedData = &otherSegmentData;
21738 QVector<QPointF> *staticData = &thisData;
21739 QVector<QPointF> *croppedData = &otherData;
21959 21740
21960 21741 // crop both vectors to ranges in which the keys overlap (which coord is key, depends on
21961 21742 // axisType):
21962 21743 if (keyAxis->orientation() == Qt::Horizontal) {
21963 21744 // x is key
21745 // if an axis range is reversed, the data point keys will be descending. Reverse them, since
21746 // following algorithm assumes ascending keys:
21747 if (staticData->first().x() > staticData->last().x()) {
21748 int size = staticData->size();
21749 for (int i = 0; i < size / 2; ++i)
21750 qSwap((*staticData)[i], (*staticData)[size - 1 - i]);
21751 }
21752 if (croppedData->first().x() > croppedData->last().x()) {
21753 int size = croppedData->size();
21754 for (int i = 0; i < size / 2; ++i)
21755 qSwap((*croppedData)[i], (*croppedData)[size - 1 - i]);
21756 }
21964 21757 // crop lower bound:
21965 21758 if (staticData->first().x() < croppedData->first().x()) // other one must be cropped
21966 21759 qSwap(staticData, croppedData);
21967 const int lowBound = findIndexBelowX(croppedData, staticData->first().x());
21760 int lowBound = findIndexBelowX(croppedData, staticData->first().x());
21968 21761 if (lowBound == -1)
21969 21762 return QPolygonF(); // key ranges have no overlap
21970 21763 croppedData->remove(0, lowBound);
21971 // set lowest point of cropped data to fit exactly key position of first static data point
21972 // via linear interpolation:
21764 // set lowest point of cropped data to fit exactly key position of first static data
21765 // point via linear interpolation:
21973 21766 if (croppedData->size() < 2)
21974 21767 return QPolygonF(); // need at least two points for interpolation
21975 21768 double slope;
21976 if (!qFuzzyCompare(croppedData->at(1).x(), croppedData->at(0).x()))
21769 if (croppedData->at(1).x() - croppedData->at(0).x() != 0)
21977 21770 slope = (croppedData->at(1).y() - croppedData->at(0).y())
21978 21771 / (croppedData->at(1).x() - croppedData->at(0).x());
21979 21772 else
@@ -21989,12 +21782,12 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData
21989 21782 if (highBound == -1)
21990 21783 return QPolygonF(); // key ranges have no overlap
21991 21784 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
21993 // via linear interpolation:
21785 // set highest point of cropped data to fit exactly key position of last static data
21786 // point via linear interpolation:
21994 21787 if (croppedData->size() < 2)
21995 return QPolygonF(); // need at least two points for interpolation
21996 const int li = croppedData->size() - 1; // last index
21997 if (!qFuzzyCompare(croppedData->at(li).x(), croppedData->at(li - 1).x()))
21788 return QPolygonF(); // need at least two points for interpolation
21789 int li = croppedData->size() - 1; // last index
21790 if (croppedData->at(li).x() - croppedData->at(li - 1).x() != 0)
21998 21791 slope = (croppedData->at(li).y() - croppedData->at(li - 1).y())
21999 21792 / (croppedData->at(li).x() - croppedData->at(li - 1).x());
22000 21793 else
@@ -22006,20 +21799,36 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData
22006 21799 else // mKeyAxis->orientation() == Qt::Vertical
22007 21800 {
22008 21801 // y is key
21802 // similar to "x is key" but switched x,y. Further, lower/upper meaning is inverted compared
21803 // to x,
21804 // because in pixel coordinates, y increases from top to bottom, not bottom to top like data
21805 // coordinate.
21806 // if an axis range is reversed, the data point keys will be descending. Reverse them, since
21807 // following algorithm assumes ascending keys:
21808 if (staticData->first().y() < staticData->last().y()) {
21809 int size = staticData->size();
21810 for (int i = 0; i < size / 2; ++i)
21811 qSwap((*staticData)[i], (*staticData)[size - 1 - i]);
21812 }
21813 if (croppedData->first().y() < croppedData->last().y()) {
21814 int size = croppedData->size();
21815 for (int i = 0; i < size / 2; ++i)
21816 qSwap((*croppedData)[i], (*croppedData)[size - 1 - i]);
21817 }
22009 21818 // crop lower bound:
22010 if (staticData->first().y() < croppedData->first().y()) // other one must be cropped
21819 if (staticData->first().y() > croppedData->first().y()) // other one must be cropped
22011 21820 qSwap(staticData, croppedData);
22012 int lowBound = findIndexBelowY(croppedData, staticData->first().y());
21821 int lowBound = findIndexAboveY(croppedData, staticData->first().y());
22013 21822 if (lowBound == -1)
22014 21823 return QPolygonF(); // key ranges have no overlap
22015 21824 croppedData->remove(0, lowBound);
22016 // set lowest point of cropped data to fit exactly key position of first static data point
22017 // via linear interpolation:
21825 // set lowest point of cropped data to fit exactly key position of first static data
21826 // point via linear interpolation:
22018 21827 if (croppedData->size() < 2)
22019 21828 return QPolygonF(); // need at least two points for interpolation
22020 21829 double slope;
22021 if (!qFuzzyCompare(croppedData->at(1).y(),
22022 croppedData->at(0).y())) // avoid division by zero in step plots
21830 if (croppedData->at(1).y() - croppedData->at(0).y()
21831 != 0) // avoid division by zero in step plots
22023 21832 slope = (croppedData->at(1).x() - croppedData->at(0).x())
22024 21833 / (croppedData->at(1).y() - croppedData->at(0).y());
22025 21834 else
@@ -22029,19 +21838,19 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData
22029 21838 (*croppedData)[0].setY(staticData->first().y());
22030 21839
22031 21840 // crop upper bound:
22032 if (staticData->last().y() > croppedData->last().y()) // other one must be cropped
21841 if (staticData->last().y() < croppedData->last().y()) // other one must be cropped
22033 21842 qSwap(staticData, croppedData);
22034 int highBound = findIndexAboveY(croppedData, staticData->last().y());
21843 int highBound = findIndexBelowY(croppedData, staticData->last().y());
22035 21844 if (highBound == -1)
22036 21845 return QPolygonF(); // key ranges have no overlap
22037 21846 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
22039 // via linear interpolation:
21847 // set highest point of cropped data to fit exactly key position of last static data
21848 // point via linear interpolation:
22040 21849 if (croppedData->size() < 2)
22041 21850 return QPolygonF(); // need at least two points for interpolation
22042 21851 int li = croppedData->size() - 1; // last index
22043 if (!qFuzzyCompare(croppedData->at(li).y(),
22044 croppedData->at(li - 1).y())) // avoid division by zero in step plots
21852 if (croppedData->at(li).y() - croppedData->at(li - 1).y()
21853 != 0) // avoid division by zero in step plots
22045 21854 slope = (croppedData->at(li).x() - croppedData->at(li - 1).x())
22046 21855 / (croppedData->at(li).y() - croppedData->at(li - 1).y());
22047 21856 else
@@ -22052,17 +21861,16 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData
22052 21861 }
22053 21862
22054 21863 // return joined:
22055 for (int i = otherSegmentData.size() - 1; i >= 0;
21864 for (int i = otherData.size() - 1; i >= 0;
22056 21865 --i) // insert reversed, otherwise the polygon will be twisted
22057 thisSegmentData << otherSegmentData.at(i);
22058 return QPolygonF(thisSegmentData);
21866 thisData << otherData.at(i);
21867 return QPolygonF(thisData);
22059 21868 }
22060 21869
22061 21870 /*! \internal
22062 21871
22063 21872 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
22065 axis is horizontal.
21873 \a data points are ordered ascending, as is the case when plotting with horizontal key axis.
22066 21874
22067 21875 Used to calculate the channel fill polygon, see \ref getChannelFillPolygon.
22068 21876 */
@@ -22082,8 +21890,7 int QCPGraph::findIndexAboveX(const QVector<QPointF> *data, double x) const
22082 21890 /*! \internal
22083 21891
22084 21892 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
22086 axis is horizontal.
21893 \a data points are ordered ascending, as is the case when plotting with horizontal key axis.
22087 21894
22088 21895 Used to calculate the channel fill polygon, see \ref getChannelFillPolygon.
22089 21896 */
@@ -22103,19 +21910,18 int QCPGraph::findIndexBelowX(const QVector<QPointF> *data, double x) const
22103 21910 /*! \internal
22104 21911
22105 21912 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
22107 axis is vertical.
21913 \a data points are ordered descending, as is the case when plotting with vertical key axis.
22108 21914
22109 21915 Used to calculate the channel fill polygon, see \ref getChannelFillPolygon.
22110 21916 */
22111 21917 int QCPGraph::findIndexAboveY(const QVector<QPointF> *data, double y) const
22112 21918 {
22113 for (int i = data->size() - 1; i >= 0; --i) {
21919 for (int i = 0; i < data->size(); ++i) {
22114 21920 if (data->at(i).y() < y) {
22115 if (i < data->size() - 1)
22116 return i + 1;
21921 if (i > 0)
21922 return i - 1;
22117 21923 else
22118 return data->size() - 1;
21924 return 0;
22119 21925 }
22120 21926 }
22121 21927 return -1;
@@ -22191,19 +21997,19 double QCPGraph::pointDistance(const QPointF &pixelPoint,
22191 21997 /*! \internal
22192 21998
22193 21999 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
22195 axis is vertical.
22000 \a data points are ordered descending, as is the case when plotting with vertical key axis (since
22001 keys are ordered ascending).
22196 22002
22197 22003 Used to calculate the channel fill polygon, see \ref getChannelFillPolygon.
22198 22004 */
22199 22005 int QCPGraph::findIndexBelowY(const QVector<QPointF> *data, double y) const
22200 22006 {
22201 for (int i = 0; i < data->size(); ++i) {
22007 for (int i = data->size() - 1; i >= 0; --i) {
22202 22008 if (data->at(i).y() > y) {
22203 if (i > 0)
22204 return i - 1;
22009 if (i < data->size() - 1)
22010 return i + 1;
22205 22011 else
22206 return 0;
22012 return data->size() - 1;
22207 22013 }
22208 22014 }
22209 22015 return -1;
@@ -22211,8 +22017,8 int QCPGraph::findIndexBelowY(const QVector<QPointF> *data, double y) const
22211 22017 /* end of 'src/plottables/plottable-graph.cpp' */
22212 22018
22213 22019
22214 /* including file 'src/plottables/plottable-curve.cpp', size 63527 */
22215 /* commit 63bcca79007f7f56dce5dd035560f2e871d1dfc1 2017-07-20 18:02:21 +0200 */
22020 /* including file 'src/plottables/plottable-curve.cpp', size 60009 */
22021 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
22216 22022
22217 22023 ////////////////////////////////////////////////////////////////////////////////////////////////////
22218 22024 //////////////////// QCPCurveData
@@ -22376,7 +22182,6 QCPCurve::QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis)
22376 22182
22377 22183 setScatterStyle(QCPScatterStyle());
22378 22184 setLineStyle(lsLine);
22379 setScatterSkip(0);
22380 22185 }
22381 22186
22382 22187 QCPCurve::~QCPCurve()
@@ -23079,74 +22884,54 QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double oth
23079 22884 double value, double keyMin, double valueMax, double keyMax,
23080 22885 double valueMin) const
23081 22886 {
23082 // The intersection point interpolation here is done in pixel coordinates, so we don't need to
23083 // differentiate between different axis scale types. Note that the nomenclature
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
22887 double intersectKey = keyMin; // initial value is just fail-safe
22888 double intersectValue = valueMax; // initial value is just fail-safe
23097 22889 switch (otherRegion) {
23098 22890 case 1: // top and left edge
23099 22891 {
23100 intersectValuePx = valueMaxPx;
23101 intersectKeyPx = otherKeyPx
23102 + (keyPx - otherKeyPx) / (valuePx - otherValuePx)
23103 * (intersectValuePx - otherValuePx);
23104 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx)
23105 || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not
23106 // intersected, then it must be left
23107 // edge (qMin/qMax necessary since
23108 // axes may be reversed)
22892 intersectValue = valueMax;
22893 intersectKey
22894 = otherKey
22895 + (key - otherKey) / (value - otherValue) * (intersectValue - otherValue);
22896 if (intersectKey < keyMin
22897 || intersectKey > keyMax) // doesn't intersect, so must intersect other:
23109 22898 {
23110 intersectKeyPx = keyMinPx;
23111 intersectValuePx = otherValuePx
23112 + (valuePx - otherValuePx) / (keyPx - otherKeyPx)
23113 * (intersectKeyPx - otherKeyPx);
22899 intersectKey = keyMin;
22900 intersectValue
22901 = otherValue
22902 + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey);
23114 22903 }
23115 22904 break;
23116 22905 }
23117 22906 case 2: // left edge
23118 22907 {
23119 intersectKeyPx = keyMinPx;
23120 intersectValuePx
23121 = otherValuePx
23122 + (valuePx - otherValuePx) / (keyPx - otherKeyPx) * (intersectKeyPx - otherKeyPx);
22908 intersectKey = keyMin;
22909 intersectValue
22910 = otherValue + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey);
23123 22911 break;
23124 22912 }
23125 22913 case 3: // bottom and left edge
23126 22914 {
23127 intersectValuePx = valueMinPx;
23128 intersectKeyPx = otherKeyPx
23129 + (keyPx - otherKeyPx) / (valuePx - otherValuePx)
23130 * (intersectValuePx - otherValuePx);
23131 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx)
23132 || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not
23133 // intersected, then it must be left
23134 // edge (qMin/qMax necessary since
23135 // axes may be reversed)
22915 intersectValue = valueMin;
22916 intersectKey
22917 = otherKey
22918 + (key - otherKey) / (value - otherValue) * (intersectValue - otherValue);
22919 if (intersectKey < keyMin
22920 || intersectKey > keyMax) // doesn't intersect, so must intersect other:
23136 22921 {
23137 intersectKeyPx = keyMinPx;
23138 intersectValuePx = otherValuePx
23139 + (valuePx - otherValuePx) / (keyPx - otherKeyPx)
23140 * (intersectKeyPx - otherKeyPx);
22922 intersectKey = keyMin;
22923 intersectValue
22924 = otherValue
22925 + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey);
23141 22926 }
23142 22927 break;
23143 22928 }
23144 22929 case 4: // top edge
23145 22930 {
23146 intersectValuePx = valueMaxPx;
23147 intersectKeyPx = otherKeyPx
23148 + (keyPx - otherKeyPx) / (valuePx - otherValuePx)
23149 * (intersectValuePx - otherValuePx);
22931 intersectValue = valueMax;
22932 intersectKey
22933 = otherKey
22934 + (key - otherKey) / (value - otherValue) * (intersectValue - otherValue);
23150 22935 break;
23151 22936 }
23152 22937 case 5: {
@@ -23155,63 +22940,53 QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double oth
23155 22940 }
23156 22941 case 6: // bottom edge
23157 22942 {
23158 intersectValuePx = valueMinPx;
23159 intersectKeyPx = otherKeyPx
23160 + (keyPx - otherKeyPx) / (valuePx - otherValuePx)
23161 * (intersectValuePx - otherValuePx);
22943 intersectValue = valueMin;
22944 intersectKey
22945 = otherKey
22946 + (key - otherKey) / (value - otherValue) * (intersectValue - otherValue);
23162 22947 break;
23163 22948 }
23164 22949 case 7: // top and right edge
23165 22950 {
23166 intersectValuePx = valueMaxPx;
23167 intersectKeyPx = otherKeyPx
23168 + (keyPx - otherKeyPx) / (valuePx - otherValuePx)
23169 * (intersectValuePx - otherValuePx);
23170 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx)
23171 || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not
23172 // intersected, then it must be right
23173 // edge (qMin/qMax necessary since
23174 // axes may be reversed)
22951 intersectValue = valueMax;
22952 intersectKey
22953 = otherKey
22954 + (key - otherKey) / (value - otherValue) * (intersectValue - otherValue);
22955 if (intersectKey < keyMin
22956 || intersectKey > keyMax) // doesn't intersect, so must intersect other:
23175 22957 {
23176 intersectKeyPx = keyMaxPx;
23177 intersectValuePx = otherValuePx
23178 + (valuePx - otherValuePx) / (keyPx - otherKeyPx)
23179 * (intersectKeyPx - otherKeyPx);
22958 intersectKey = keyMax;
22959 intersectValue
22960 = otherValue
22961 + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey);
23180 22962 }
23181 22963 break;
23182 22964 }
23183 22965 case 8: // right edge
23184 22966 {
23185 intersectKeyPx = keyMaxPx;
23186 intersectValuePx
23187 = otherValuePx
23188 + (valuePx - otherValuePx) / (keyPx - otherKeyPx) * (intersectKeyPx - otherKeyPx);
22967 intersectKey = keyMax;
22968 intersectValue
22969 = otherValue + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey);
23189 22970 break;
23190 22971 }
23191 22972 case 9: // bottom and right edge
23192 22973 {
23193 intersectValuePx = valueMinPx;
23194 intersectKeyPx = otherKeyPx
23195 + (keyPx - otherKeyPx) / (valuePx - otherValuePx)
23196 * (intersectValuePx - otherValuePx);
23197 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx)
23198 || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not
23199 // intersected, then it must be right
23200 // edge (qMin/qMax necessary since
23201 // axes may be reversed)
22974 intersectValue = valueMin;
22975 intersectKey
22976 = otherKey
22977 + (key - otherKey) / (value - otherValue) * (intersectValue - otherValue);
22978 if (intersectKey < keyMin
22979 || intersectKey > keyMax) // doesn't intersect, so must intersect other:
23202 22980 {
23203 intersectKeyPx = keyMaxPx;
23204 intersectValuePx = otherValuePx
23205 + (valuePx - otherValuePx) / (keyPx - otherKeyPx)
23206 * (intersectKeyPx - otherKeyPx);
22981 intersectKey = keyMax;
22982 intersectValue
22983 = otherValue
22984 + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey);
23207 22985 }
23208 22986 break;
23209 22987 }
23210 22988 }
23211 if (mKeyAxis->orientation() == Qt::Horizontal)
23212 return QPointF(intersectKeyPx, intersectValuePx);
23213 else
23214 return QPointF(intersectValuePx, intersectKeyPx);
22989 return coordsToPixels(intersectKey, intersectValue);
23215 22990 }
23216 22991
23217 22992 /*! \internal
@@ -23724,79 +23499,44 bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double
23724 23499 double keyMin, double valueMax, double keyMax, double valueMin,
23725 23500 QPointF &crossA, QPointF &crossB) const
23726 23501 {
23727 // The intersection point interpolation here is done in pixel coordinates, so we don't need to
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);
23502 QList<QPointF> intersections; // x of QPointF corresponds to key and y to value
23741 23503 if (qFuzzyIsNull(key - prevKey)) // line is parallel to value axis
23742 23504 {
23743 // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5
23744 // is traversed here
23505 // due to region filter in mayTraverseR(), if line is parallel to value or key axis, R is
23506 // traversed here
23745 23507 intersections.append(
23746 mKeyAxis->orientation() == Qt::Horizontal
23747 ? QPointF(keyPx, valueMinPx)
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));
23508 QPointF(key, valueMin)); // direction will be taken care of at end of method
23509 intersections.append(QPointF(key, valueMax));
23752 23510 }
23753 23511 else if (qFuzzyIsNull(value - prevValue)) // line is parallel to key axis
23754 23512 {
23755 // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5
23756 // is traversed here
23513 // due to region filter in mayTraverseR(), if line is parallel to value or key axis, R is
23514 // traversed here
23757 23515 intersections.append(
23758 mKeyAxis->orientation() == Qt::Horizontal
23759 ? QPointF(keyMinPx, valuePx)
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));
23516 QPointF(keyMin, value)); // direction will be taken care of at end of method
23517 intersections.append(QPointF(keyMax, value));
23764 23518 }
23765 23519 else // line is skewed
23766 23520 {
23767 23521 double gamma;
23768 double keyPerValuePx = (keyPx - prevKeyPx) / (valuePx - prevValuePx);
23522 double keyPerValue = (key - prevKey) / (value - prevValue);
23769 23523 // check top of rect:
23770 gamma = prevKeyPx + (valueMaxPx - prevValuePx) * keyPerValuePx;
23771 if (gamma >= qMin(keyMinPx, keyMaxPx)
23772 && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed
23773 intersections.append(mKeyAxis->orientation() == Qt::Horizontal
23774 ? QPointF(gamma, valueMaxPx)
23775 : QPointF(valueMaxPx, gamma));
23524 gamma = prevKey + (valueMax - prevValue) * keyPerValue;
23525 if (gamma >= keyMin && gamma <= keyMax)
23526 intersections.append(QPointF(gamma, valueMax));
23776 23527 // check bottom of rect:
23777 gamma = prevKeyPx + (valueMinPx - prevValuePx) * keyPerValuePx;
23778 if (gamma >= qMin(keyMinPx, keyMaxPx)
23779 && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed
23780 intersections.append(mKeyAxis->orientation() == Qt::Horizontal
23781 ? QPointF(gamma, valueMinPx)
23782 : QPointF(valueMinPx, gamma));
23783 const double valuePerKeyPx = 1.0 / keyPerValuePx;
23528 gamma = prevKey + (valueMin - prevValue) * keyPerValue;
23529 if (gamma >= keyMin && gamma <= keyMax)
23530 intersections.append(QPointF(gamma, valueMin));
23531 double valuePerKey = 1.0 / keyPerValue;
23784 23532 // check left of rect:
23785 gamma = prevValuePx + (keyMinPx - prevKeyPx) * valuePerKeyPx;
23786 if (gamma >= qMin(valueMinPx, valueMaxPx)
23787 && gamma <= qMax(valueMinPx,
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));
23533 gamma = prevValue + (keyMin - prevKey) * valuePerKey;
23534 if (gamma >= valueMin && gamma <= valueMax)
23535 intersections.append(QPointF(keyMin, gamma));
23792 23536 // check right of rect:
23793 gamma = prevValuePx + (keyMaxPx - prevKeyPx) * valuePerKeyPx;
23794 if (gamma >= qMin(valueMinPx, valueMaxPx)
23795 && gamma <= qMax(valueMinPx,
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));
23537 gamma = prevValue + (keyMax - prevKey) * valuePerKey;
23538 if (gamma >= valueMin && gamma <= valueMax)
23539 intersections.append(QPointF(keyMax, gamma));
23800 23540 }
23801 23541
23802 23542 // handle cases where found points isn't exactly 2:
@@ -23825,16 +23565,12 bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double
23825 23565 }
23826 23566
23827 23567 // possibly re-sort points so optimized point segment has same direction as original segment:
23828 double xDelta = keyPx - prevKeyPx;
23829 double yDelta = valuePx - prevValuePx;
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())
23568 if ((key - prevKey) * (intersections.at(1).x() - intersections.at(0).x())
23569 + (value - prevValue) * (intersections.at(1).y() - intersections.at(0).y())
23834 23570 < 0) // scalar product of both segments < 0 -> opposite direction
23835 23571 intersections.move(0, 1);
23836 crossA = intersections.at(0);
23837 crossB = intersections.at(1);
23572 crossA = coordsToPixels(intersections.at(0).x(), intersections.at(0).y());
23573 crossB = coordsToPixels(intersections.at(1).x(), intersections.at(1).y());
23838 23574 return true;
23839 23575 }
23840 23576
@@ -25945,8 +25681,8 QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iter
25945 25681 /* end of 'src/plottables/plottable-statisticalbox.cpp' */
25946 25682
25947 25683
25948 /* including file 'src/plottables/plottable-colormap.cpp', size 47881 */
25949 /* commit 83a770151292397b3ba4984108d7ed167a9aec65 2017-08-13 16:22:21 +0200 */
25684 /* including file 'src/plottables/plottable-colormap.cpp', size 47531 */
25685 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
25950 25686
25951 25687 ////////////////////////////////////////////////////////////////////////////////////////////////////
25952 25688 //////////////////// QCPColorMapData
@@ -26617,7 +26353,6 QCPColorMap::QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis)
26617 26353 : QCPAbstractPlottable(keyAxis, valueAxis),
26618 26354 mDataScaleType(QCPAxis::stLinear),
26619 26355 mMapData(new QCPColorMapData(10, 10, QCPRange(0, 5), QCPRange(0, 5))),
26620 mGradient(QCPColorGradient::gpCold),
26621 26356 mInterpolate(true),
26622 26357 mTightBoundary(false),
26623 26358 mMapImageInvalidated(true)
@@ -26977,82 +26712,74 void QCPColorMap::updateMapImage()
26977 26712 mMapImage = QImage(
26978 26713 QSize(valueSize * valueOversamplingFactor, keySize * keyOversamplingFactor), format);
26979 26714
26980 if (mMapImage.isNull()) {
26981 qDebug() << Q_FUNC_INFO << "Couldn't create map image (possibly too large for memory)";
26982 mMapImage = QImage(QSize(10, 10), format);
26983 mMapImage.fill(Qt::black);
26984 }
26985 else {
26986 QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates.
26987 // Either the final mMapImage, or if we need
26988 // oversampling, mUndersampledMapImage
26989 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) {
26990 // resize undersampled map image to actual key/value cell sizes:
26991 if (keyAxis->orientation() == Qt::Horizontal
26992 && (mUndersampledMapImage.width() != keySize
26993 || mUndersampledMapImage.height() != valueSize))
26994 mUndersampledMapImage = QImage(QSize(keySize, valueSize), format);
26995 else if (keyAxis->orientation() == Qt::Vertical
26996 && (mUndersampledMapImage.width() != valueSize
26997 || mUndersampledMapImage.height() != keySize))
26998 mUndersampledMapImage = QImage(QSize(valueSize, keySize), format);
26999 localMapImage
27000 = &mUndersampledMapImage; // make the colorization run on the undersampled image
27001 }
27002 else if (!mUndersampledMapImage.isNull())
27003 mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size
27004 // has changed) but mUndersampledMapImage still has
27005 // nonzero size, free it
27006
27007 const double *rawData = mMapData->mData;
27008 const unsigned char *rawAlpha = mMapData->mAlpha;
27009 if (keyAxis->orientation() == Qt::Horizontal) {
27010 const int lineCount = valueSize;
27011 const int rowCount = keySize;
27012 for (int line = 0; line < lineCount; ++line) {
27013 QRgb *pixels = reinterpret_cast<QRgb *>(localMapImage->scanLine(
27014 lineCount - 1 - line)); // invert scanline index because QImage counts scanlines
27015 // from top, but our vertical index counts from bottom
27016 // (mathematical coordinate system)
27017 if (rawAlpha)
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 }
26715 QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates.
26716 // Either the final mMapImage, or if we need oversampling,
26717 // mUndersampledMapImage
26718 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) {
26719 // resize undersampled map image to actual key/value cell sizes:
26720 if (keyAxis->orientation() == Qt::Horizontal
26721 && (mUndersampledMapImage.width() != keySize
26722 || mUndersampledMapImage.height() != valueSize))
26723 mUndersampledMapImage = QImage(QSize(keySize, valueSize), format);
26724 else if (keyAxis->orientation() == Qt::Vertical
26725 && (mUndersampledMapImage.width() != valueSize
26726 || mUndersampledMapImage.height() != keySize))
26727 mUndersampledMapImage = QImage(QSize(valueSize, keySize), format);
26728 localMapImage
26729 = &mUndersampledMapImage; // make the colorization run on the undersampled image
26730 }
26731 else if (!mUndersampledMapImage.isNull())
26732 mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has
26733 // changed) but mUndersampledMapImage still has nonzero
26734 // size, free it
26735
26736 const double *rawData = mMapData->mData;
26737 const unsigned char *rawAlpha = mMapData->mAlpha;
26738 if (keyAxis->orientation() == Qt::Horizontal) {
26739 const int lineCount = valueSize;
26740 const int rowCount = keySize;
26741 for (int line = 0; line < lineCount; ++line) {
26742 QRgb *pixels = reinterpret_cast<QRgb *>(localMapImage->scanLine(
26743 lineCount - 1 - line)); // invert scanline index because QImage counts scanlines
26744 // from top, but our vertical index counts from bottom
26745 // (mathematical coordinate system)
26746 if (rawAlpha)
26747 mGradient.colorize(rawData + line * rowCount, rawAlpha + line * rowCount,
26748 mDataRange, pixels, rowCount, 1,
26749 mDataScaleType == QCPAxis::stLogarithmic);
26750 else
26751 mGradient.colorize(rawData + line * rowCount, mDataRange, pixels, rowCount, 1,
26752 mDataScaleType == QCPAxis::stLogarithmic);
27043 26753 }
27044
27045 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) {
27046 if (keyAxis->orientation() == Qt::Horizontal)
27047 mMapImage = mUndersampledMapImage.scaled(
27048 keySize * keyOversamplingFactor, valueSize * valueOversamplingFactor,
27049 Qt::IgnoreAspectRatio, Qt::FastTransformation);
26754 }
26755 else // keyAxis->orientation() == Qt::Vertical
26756 {
26757 const int lineCount = keySize;
26758 const int rowCount = valueSize;
26759 for (int line = 0; line < lineCount; ++line) {
26760 QRgb *pixels = reinterpret_cast<QRgb *>(localMapImage->scanLine(
26761 lineCount - 1 - line)); // invert scanline index because QImage counts scanlines
26762 // from top, but our vertical index counts from bottom
26763 // (mathematical coordinate system)
26764 if (rawAlpha)
26765 mGradient.colorize(rawData + line, rawAlpha + line, mDataRange, pixels, rowCount,
26766 lineCount, mDataScaleType == QCPAxis::stLogarithmic);
27050 26767 else
27051 mMapImage = mUndersampledMapImage.scaled(
27052 valueSize * valueOversamplingFactor, keySize * keyOversamplingFactor,
27053 Qt::IgnoreAspectRatio, Qt::FastTransformation);
26768 mGradient.colorize(rawData + line, mDataRange, pixels, rowCount, lineCount,
26769 mDataScaleType == QCPAxis::stLogarithmic);
27054 26770 }
27055 26771 }
26772
26773 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) {
26774 if (keyAxis->orientation() == Qt::Horizontal)
26775 mMapImage = mUndersampledMapImage.scaled(keySize * keyOversamplingFactor,
26776 valueSize * valueOversamplingFactor,
26777 Qt::IgnoreAspectRatio, Qt::FastTransformation);
26778 else
26779 mMapImage = mUndersampledMapImage.scaled(valueSize * valueOversamplingFactor,
26780 keySize * keyOversamplingFactor,
26781 Qt::IgnoreAspectRatio, Qt::FastTransformation);
26782 }
27056 26783 mMapData->mDataModified = false;
27057 26784 mMapImageInvalidated = false;
27058 26785 }
@@ -28215,8 +27942,8 QRectF QCPFinancial::selectionHitBox(QCPFinancialDataContainer::const_iterator i
28215 27942 /* end of 'src/plottables/plottable-financial.cpp' */
28216 27943
28217 27944
28218 /* including file 'src/plottables/plottable-errorbar.cpp', size 37355 */
28219 /* commit 6f159843e9ec9ea6431b26591937aea13a9f2751 2017-07-25 11:13:32 +0200 */
27945 /* including file 'src/plottables/plottable-errorbar.cpp', size 37210 */
27946 /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
28220 27947
28221 27948 ////////////////////////////////////////////////////////////////////////////////////////////////////
28222 27949 //////////////////// QCPErrorBarsData
@@ -28947,8 +28674,8 void QCPErrorBars::getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it
28947 28674 QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index);
28948 28675 if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y()))
28949 28676 return;
28950 QCPAxis *errorAxis = mErrorType == etValueError ? mValueAxis.data() : mKeyAxis.data();
28951 QCPAxis *orthoAxis = mErrorType == etValueError ? mKeyAxis.data() : mValueAxis.data();
28677 QCPAxis *errorAxis = mErrorType == etValueError ? mValueAxis : mKeyAxis;
28678 QCPAxis *orthoAxis = mErrorType == etValueError ? mKeyAxis : mValueAxis;
28952 28679 const double centerErrorAxisPixel
28953 28680 = errorAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y();
28954 28681 const double centerOrthoAxisPixel
@@ -29082,10 +28809,6 double QCPErrorBars::pointDistance(const QPointF &pixelPoint,
29082 28809 closestData = mDataContainer->constEnd();
29083 28810 if (!mDataPlottable || mDataContainer->isEmpty())
29084 28811 return -1.0;
29085 if (!mKeyAxis || !mValueAxis) {
29086 qDebug() << Q_FUNC_INFO << "invalid key or value axis";
29087 return -1.0;
29088 }
29089 28812
29090 28813 QCPErrorBarsDataContainer::const_iterator begin, end;
29091 28814 getVisibleDataBounds(begin, end, QCPDataRange(0, dataCount()));
@@ -1,7 +1,9
1 <?xml version="1.0" encoding="UTF-8"?>
2 1 <ui version="4.0">
3 <class>DataSourceWidget</class>
4 <widget class="QWidget" name="DataSourceWidget">
2 <author/>
3 <comment/>
4 <exportmacro/>
5 <class>SqpSidePane</class>
6 <widget name="SqpSidePane" class="QWidget">
5 7 <property name="geometry">
6 8 <rect>
7 9 <x>0</x>
@@ -11,23 +13,9
11 13 </rect>
12 14 </property>
13 15 <property name="windowTitle">
14 <string>Data sources</string>
16 <string>Form</string>
15 17 </property>
16 <layout class="QGridLayout" name="gridLayout">
17 <item row="0" column="0">
18 <widget class="QLineEdit" name="filterLineEdit"/>
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>
29 </layout>
30 18 </widget>
31 <resources/>
19 <pixmapfunction/>
32 20 <connections/>
33 21 </ui>
@@ -14,23 +14,21
14 14 <string>Form</string>
15 15 </property>
16 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 17 <item>
30 18 <widget class="QTabWidget" name="tabWidget">
31 19 <property name="currentIndex">
32 <number>-1</number>
20 <number>0</number>
33 21 </property>
22 <widget class="QWidget" name="firstView">
23 <attribute name="title">
24 <string>View 1</string>
25 </attribute>
26 </widget>
27 <widget class="QWidget" name="secondView">
28 <attribute name="title">
29 <string>+</string>
30 </attribute>
31 </widget>
34 32 </widget>
35 33 </item>
36 34 </layout>
@@ -1,7 +1,9
1 <?xml version="1.0" encoding="UTF-8"?>
2 1 <ui version="4.0">
3 <class>VariableInspectorWidget</class>
4 <widget class="QWidget" name="VariableInspectorWidget">
2 <author/>
3 <comment/>
4 <exportmacro/>
5 <class>VisualizationZoneWidget</class>
6 <widget name="VisualizationZoneWidget" class="QWidget">
5 7 <property name="geometry">
6 8 <rect>
7 9 <x>0</x>
@@ -11,21 +13,9
11 13 </rect>
12 14 </property>
13 15 <property name="windowTitle">
14 <string>Variables</string>
16 <string>Form</string>
15 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 18 </widget>
29 <resources/>
19 <pixmapfunction/>
30 20 <connections/>
31 21 </ui>
@@ -1,8 +1,7
1 # Ignore false positive relative to App macro
1 2 \.h:\d+:.IPSIS_S04.*found: ui
2 3 qcustomplot\.h:\d+:.IPSIS
3 4 qcustomplot\.cpp:\d+:.IPSIS
4
5 # Ignore false positive relative to App macro
6 5 SqpApplication\.h:\d+:.IPSIS_S03.*found: sqpApp
7 6 SqpApplication\.h:\d+:.IPSIS_S04_VARIABLE.*found: sqpApp
8 7
@@ -17,14 +17,7 SCIQLOP_FIND_QT(Core)
17 17 FILE (GLOB_RECURSE MODULE_SOURCES
18 18 ${INCLUDES_DIR}/*.h)
19 19
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
20 ADD_LIBRARY(${SQPPLUGIN_LIBRARY_NAME} ${MODULE_SOURCES})
28 21
29 22 # Add the files to the list of files to be analyzed
30 23 LIST(APPEND CHECKSTYLE_INPUT_FILES ${MODULE_SOURCES})
1 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
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 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
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 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
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 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
This diff has been collapsed as it changes many lines, (29129 lines changed) Show them Hide them
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 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
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 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
General Comments 5
there are 2 general comments from older versions, show them
Under Review
author

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

Changed commits:
  * 1 added
  * 0 removed

Changed files:
  * M core/CMakeLists.txt
Approved
author

Status change > Approved

note
author

Pull request merged and closed