diff --git a/core/include/Data/SqpRange.h b/core/include/Data/SqpRange.h index c6d8de8..e6c8936 100644 --- a/core/include/Data/SqpRange.h +++ b/core/include/Data/SqpRange.h @@ -26,8 +26,21 @@ struct SqpRange { { return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd); } + + bool operator==(const SqpRange &other) const + { + auto equals = [](const auto &v1, const auto &v2) { + return (std::isnan(v1) && std::isnan(v2)) || v1 == v2; + }; + + return equals(m_TStart, other.m_TStart) && equals(m_TEnd, other.m_TEnd); + } + bool operator!=(const SqpRange &other) const { return !(*this == other); } }; +const auto INVALID_RANGE + = SqpRange{std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; + inline QDebug operator<<(QDebug d, SqpRange obj) { auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart); diff --git a/core/include/Variable/Variable.h b/core/include/Variable/Variable.h index f1d4928..8c1d0bb 100644 --- a/core/include/Variable/Variable.h +++ b/core/include/Variable/Variable.h @@ -3,6 +3,7 @@ #include "CoreGlobal.h" +#include #include #include @@ -33,6 +34,14 @@ public: SqpRange cacheRange() const noexcept; void setCacheRange(const SqpRange &cacheRange) noexcept; + /// Returns the real range of the variable, i.e. the min and max x-axis values of the data + /// series between the range of the variable. The real range is updated each time the variable + /// range or the data series changed + /// @return the real range, invalid range if the data series is null or empty + /// @sa setDataSeries() + /// @sa setRange() + SqpRange realRange() const noexcept; + /// @return the data of the variable, nullptr if there is no data std::shared_ptr dataSeries() const noexcept; diff --git a/core/include/Variable/VariableAcquisitionWorker.h b/core/include/Variable/VariableAcquisitionWorker.h index 4c76379..25f7f0b 100644 --- a/core/include/Variable/VariableAcquisitionWorker.h +++ b/core/include/Variable/VariableAcquisitionWorker.h @@ -48,14 +48,14 @@ public slots: SqpRange dataRangeAcquired); void onVariableRetrieveDataInProgress(QUuid acqIdentifier, double progress); -private slots: - void onExecuteRequest(QUuid acqIdentifier); - private: void waitForFinish(); class VariableAcquisitionWorkerPrivate; spimpl::unique_impl_ptr impl; + +private slots: + void onExecuteRequest(QUuid acqIdentifier); }; #endif // SCIQLOP_VARIABLEACQUISITIONWORKER_H diff --git a/core/src/Variable/Variable.cpp b/core/src/Variable/Variable.cpp index 2148365..554dcf3 100644 --- a/core/src/Variable/Variable.cpp +++ b/core/src/Variable/Variable.cpp @@ -12,7 +12,11 @@ Q_LOGGING_CATEGORY(LOG_Variable, "Variable") struct Variable::VariablePrivate { explicit VariablePrivate(const QString &name, const SqpRange &dateTime, const QVariantHash &metadata) - : m_Name{name}, m_Range{dateTime}, m_Metadata{metadata}, m_DataSeries{nullptr} + : m_Name{name}, + m_Range{dateTime}, + m_Metadata{metadata}, + m_DataSeries{nullptr}, + m_RealRange{INVALID_RANGE} { } @@ -20,12 +24,32 @@ struct Variable::VariablePrivate { void lockWrite() { m_Lock.lockForWrite(); } void unlock() { m_Lock.unlock(); } + /// Updates real range according to current variable range and data series + void updateRealRange() + { + if (m_DataSeries) { + m_DataSeries->lockRead(); + auto end = m_DataSeries->cend(); + auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart); + auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd); + + m_RealRange = (minXAxisIt != end && maxXAxisIt != end) + ? SqpRange{minXAxisIt->x(), maxXAxisIt->x()} + : INVALID_RANGE; + m_DataSeries->unlock(); + } + else { + m_RealRange = INVALID_RANGE; + } + } + QString m_Name; SqpRange m_Range; SqpRange m_CacheRange; QVariantHash m_Metadata; std::shared_ptr m_DataSeries; + SqpRange m_RealRange; QReadWriteLock m_Lock; }; @@ -55,6 +79,7 @@ void Variable::setRange(const SqpRange &range) noexcept { impl->lockWrite(); impl->m_Range = range; + impl->updateRealRange(); impl->unlock(); } @@ -73,6 +98,11 @@ void Variable::setCacheRange(const SqpRange &cacheRange) noexcept impl->unlock(); } +SqpRange Variable::realRange() const noexcept +{ + return impl->m_RealRange; +} + void Variable::setDataSeries(std::shared_ptr dataSeries) noexcept { qCDebug(LOG_Variable()) << "TORM Variable::setDataSeries" @@ -83,6 +113,7 @@ void Variable::setDataSeries(std::shared_ptr dataSeries) noexcept } impl->lockWrite(); impl->m_DataSeries = dataSeries->clone(); + impl->updateRealRange(); impl->unlock(); } diff --git a/core/src/Variable/VariableAcquisitionWorker.cpp b/core/src/Variable/VariableAcquisitionWorker.cpp index 93aa9bb..f24a269 100644 --- a/core/src/Variable/VariableAcquisitionWorker.cpp +++ b/core/src/Variable/VariableAcquisitionWorker.cpp @@ -184,22 +184,6 @@ void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier, impl->unlock(); } -void VariableAcquisitionWorker::onExecuteRequest(QUuid acqIdentifier) -{ - qCDebug(LOG_VariableAcquisitionWorker()) << tr("onExecuteRequest") << QThread::currentThread(); - impl->lockRead(); - auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier); - if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) { - auto request = it->second; - impl->unlock(); - request.m_Provider->requestDataLoading(acqIdentifier, request.m_DataProviderParameters); - } - else { - impl->unlock(); - // TODO log no acqIdentifier recognized - } -} - void VariableAcquisitionWorker::initialize() { qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init") @@ -236,3 +220,19 @@ void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeVariable m_VIdentifierToCurrrentAcqIdNextIdPairMap.erase(vIdentifier); unlock(); } + +void VariableAcquisitionWorker::onExecuteRequest(QUuid acqIdentifier) +{ + qCDebug(LOG_VariableAcquisitionWorker()) << tr("onExecuteRequest") << QThread::currentThread(); + impl->lockRead(); + auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier); + if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) { + auto request = it->second; + impl->unlock(); + request.m_Provider->requestDataLoading(acqIdentifier, request.m_DataProviderParameters); + } + else { + impl->unlock(); + // TODO log no acqIdentifier recognized + } +} diff --git a/core/src/Variable/VariableModel.cpp b/core/src/Variable/VariableModel.cpp index f18e7e6..7e29f47 100644 --- a/core/src/Variable/VariableModel.cpp +++ b/core/src/Variable/VariableModel.cpp @@ -153,35 +153,21 @@ QVariant VariableModel::data(const QModelIndex &index, int role) const if (role == Qt::DisplayRole) { if (auto variable = impl->m_Variables.at(index.row()).get()) { - /// Lambda function that builds the variant to return for a time value - /// @param getValueFun function used to get for a data series the iterator on the entry - /// that contains the time value to display - auto dateTimeVariant = [variable](const auto &getValueFun) { - if (auto dataSeries = variable->dataSeries()) { - dataSeries->lockRead(); - auto it = getValueFun(*dataSeries); - auto resVariant = (it != dataSeries->cend()) - ? DateUtils::dateTime(it->x()).toString(DATETIME_FORMAT) - : QVariant{}; - dataSeries->unlock(); - return resVariant; - } - else { - return QVariant{}; - } - }; - switch (index.column()) { case NAME_COLUMN: return variable->name(); - case TSTART_COLUMN: - // Shows the min value of the data series above the range tstart - return dateTimeVariant([min = variable->range().m_TStart]( - const auto &dataSeries) { return dataSeries.minXAxisData(min); }); - case TEND_COLUMN: - // Shows the max value of the data series under the range tend - return dateTimeVariant([max = variable->range().m_TEnd]( - const auto &dataSeries) { return dataSeries.maxXAxisData(max); }); + case TSTART_COLUMN: { + auto range = variable->realRange(); + return range != INVALID_RANGE + ? DateUtils::dateTime(range.m_TStart).toString(DATETIME_FORMAT) + : QVariant{}; + } + case TEND_COLUMN: { + auto range = variable->realRange(); + return range != INVALID_RANGE + ? DateUtils::dateTime(range.m_TEnd).toString(DATETIME_FORMAT) + : QVariant{}; + } case UNIT_COLUMN: return variable->metadata().value(QStringLiteral("units")); case MISSION_COLUMN: diff --git a/core/vera-exclusions/exclusions.txt b/core/vera-exclusions/exclusions.txt index f1bd7ef..928edb5 100644 --- a/core/vera-exclusions/exclusions.txt +++ b/core/vera-exclusions/exclusions.txt @@ -2,6 +2,8 @@ Common/spimpl\.h:\d+:.* # Ignore false positive relative to two class definitions in a same file +ArrayData\.h:\d+:.*IPSIS_S01.* +ArrayDataIterator\.h:\d+:.*IPSIS_S01.* DataSourceItem\.h:\d+:.*IPSIS_S01.* DataSeries\.h:\d+:.*IPSIS_S01.* DataSeriesIterator\.h:\d+:.*IPSIS_S01.* @@ -16,34 +18,19 @@ DataSeries\.h:\d+:.*IPSIS_S04_VARIABLE.* DataSeries\.h:\d+:.*IPSIS_S04_NAMESPACE.*found: (dataseries_detail) # Ignore false positive relative to iterators -ArrayData\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (forward_iterator_tag) -ArrayData\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (IteratorValue) -ArrayData\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (ptrdiff_t) -ArrayData\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (value_type) -ArrayData\.h:\d+:.*IPSIS_S05.* -ArrayData\.h:\d+:.*IPSIS_S06.*found: (iterator_category) -ArrayData\.h:\d+:.*IPSIS_S06.*found: (forward_iterator_tag) -ArrayData\.h:\d+:.*IPSIS_S06.*found: (value_type) -ArrayData\.h:\d+:.*IPSIS_S06.*found: (IteratorValue) -ArrayData\.h:\d+:.*IPSIS_S06.*found: (difference_type) -ArrayData\.h:\d+:.*IPSIS_S06.*found: (ptrdiff_t) -ArrayData\.h:\d+:.*IPSIS_S06.*found: (pointer) -ArrayData\.h:\d+:.*IPSIS_S06.*found: (reference) -ArrayData\.h:\d+:.*IPSIS_S06.*found: (value_type) -DataSeriesIterator\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (forward_iterator_tag) -DataSeriesIterator\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (DataSeriesIteratorValue) -DataSeriesIterator\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (ptrdiff_t) -DataSeriesIterator\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (value_type) -DataSeriesIterator\.h:\d+:.*IPSIS_S05.* -DataSeriesIterator\.h:\d+:.*IPSIS_S06.*found: (iterator_category) -DataSeriesIterator\.h:\d+:.*IPSIS_S06.*found: (forward_iterator_tag) -DataSeriesIterator\.h:\d+:.*IPSIS_S06.*found: (value_type) -DataSeriesIterator\.h:\d+:.*IPSIS_S06.*found: (DataSeriesIteratorValue) -DataSeriesIterator\.h:\d+:.*IPSIS_S06.*found: (difference_type) -DataSeriesIterator\.h:\d+:.*IPSIS_S06.*found: (ptrdiff_t) -DataSeriesIterator\.h:\d+:.*IPSIS_S06.*found: (pointer) -DataSeriesIterator\.h:\d+:.*IPSIS_S06.*found: (reference) -DataSeriesIterator\.h:\d+:.*IPSIS_S06.*found: (value_type) +SqpIterator\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (forward_iterator_tag) +SqpIterator\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (T) +SqpIterator\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (ptrdiff_t) +SqpIterator\.h:\d+:.*IPSIS_S04_VARIABLE.*found: (value_type) +SqpIterator\.h:\d+:.*IPSIS_S06.*found: (iterator_category) +SqpIterator\.h:\d+:.*IPSIS_S06.*found: (forward_iterator_tag) +SqpIterator\.h:\d+:.*IPSIS_S06.*found: (value_type) +SqpIterator\.h:\d+:.*IPSIS_S06.*found: (T) +SqpIterator\.h:\d+:.*IPSIS_S06.*found: (difference_type) +SqpIterator\.h:\d+:.*IPSIS_S06.*found: (ptrdiff_t) +SqpIterator\.h:\d+:.*IPSIS_S06.*found: (pointer) +SqpIterator\.h:\d+:.*IPSIS_S06.*found: (reference) +SqpIterator\.h:\d+:.*IPSIS_S06.*found: (value_type) # Ignore false positive relative to an alias DataSourceItemAction\.h:\d+:.*IPSIS_S06.*found: (ExecuteFunction) diff --git a/gui/include/Visualization/VisualizationZoneWidget.h b/gui/include/Visualization/VisualizationZoneWidget.h index 1f5125f..6518706 100644 --- a/gui/include/Visualization/VisualizationZoneWidget.h +++ b/gui/include/Visualization/VisualizationZoneWidget.h @@ -42,15 +42,14 @@ public: bool contains(const Variable &variable) const override; QString name() const override; - -private slots: - void onVariableAdded(std::shared_ptr variable); - private: Ui::VisualizationZoneWidget *ui; class VisualizationZoneWidgetPrivate; spimpl::unique_impl_ptr impl; + +private slots: + void onVariableAdded(std::shared_ptr variable); }; #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H diff --git a/gui/src/DataSource/DataSourceWidget.cpp b/gui/src/DataSource/DataSourceWidget.cpp index e1de06d..454f76b 100644 --- a/gui/src/DataSource/DataSourceWidget.cpp +++ b/gui/src/DataSource/DataSourceWidget.cpp @@ -94,7 +94,7 @@ void DataSourceWidget::onTreeMenuRequested(const QPoint &pos) noexcept treeMenu.addActions(selectedItem->actions()); if (!treeMenu.isEmpty()) { - treeMenu.exec(mapToGlobal(pos)); + treeMenu.exec(QCursor::pos()); } } } diff --git a/gui/src/Settings/SqpSettingsGeneralWidget.cpp b/gui/src/Settings/SqpSettingsGeneralWidget.cpp index f4f7bcf..7b07e95 100644 --- a/gui/src/Settings/SqpSettingsGeneralWidget.cpp +++ b/gui/src/Settings/SqpSettingsGeneralWidget.cpp @@ -8,6 +8,12 @@ SqpSettingsGeneralWidget::SqpSettingsGeneralWidget(QWidget *parent) : QWidget{parent}, ui{new Ui::SqpSettingsGeneralWidget} { ui->setupUi(this); + + // Value limits + ui->toleranceInitSpinBox->setMinimum(0.); + ui->toleranceInitSpinBox->setMaximum(std::numeric_limits::max()); + ui->toleranceUpdateSpinBox->setMinimum(0.); + ui->toleranceUpdateSpinBox->setMaximum(std::numeric_limits::max()); } SqpSettingsGeneralWidget::~SqpSettingsGeneralWidget() noexcept diff --git a/gui/src/Variable/VariableInspectorWidget.cpp b/gui/src/Variable/VariableInspectorWidget.cpp index 94d06f9..3b9066c 100644 --- a/gui/src/Variable/VariableInspectorWidget.cpp +++ b/gui/src/Variable/VariableInspectorWidget.cpp @@ -189,7 +189,7 @@ void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept tableMenu.insertAction(firstAction, headerAction); // Displays menu - tableMenu.exec(mapToGlobal(pos)); + tableMenu.exec(QCursor::pos()); } } diff --git a/gui/src/Visualization/VisualizationGraphWidget.cpp b/gui/src/Visualization/VisualizationGraphWidget.cpp index 2245196..a8d4d3a 100644 --- a/gui/src/Visualization/VisualizationGraphWidget.cpp +++ b/gui/src/Visualization/VisualizationGraphWidget.cpp @@ -218,7 +218,7 @@ void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept } if (!graphMenu.isEmpty()) { - graphMenu.exec(mapToGlobal(pos)); + graphMenu.exec(QCursor::pos()); } } diff --git a/gui/ui/Settings/SqpSettingsGeneralWidget.ui b/gui/ui/Settings/SqpSettingsGeneralWidget.ui index 6b2a797..27bd20a 100644 --- a/gui/ui/Settings/SqpSettingsGeneralWidget.ui +++ b/gui/ui/Settings/SqpSettingsGeneralWidget.ui @@ -32,12 +32,6 @@ % - - 0.000000000000000 - - - 500.000000000000000 - @@ -58,12 +52,6 @@ % - - 0.000000000000000 - - - 500.000000000000000 -