Warning, file /frameworks/kquickcharts/src/datasource/ModelHistorySource.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * This file is part of KQuickCharts 0003 * SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0006 */ 0007 0008 #include "ModelHistorySource.h" 0009 0010 #include <QAbstractItemModel> 0011 #include <QDebug> 0012 #include <QTimer> 0013 #include <QVariantList> 0014 0015 #include "QmlDeprecated.h" 0016 0017 #if QUICKCHARTS_BUILD_DEPRECATED_SINCE(5, 78) 0018 0019 ModelHistorySource::ModelHistorySource(QObject *parent) 0020 : ModelSource(parent) 0021 { 0022 QML_DEPRECATED("ModelHistorySource", "5.78", "Use HistoryProxySource instead.") 0023 0024 connect(this, &ModelHistorySource::modelChanged, this, &ModelHistorySource::onModelChanged); 0025 } 0026 0027 int ModelHistorySource::itemCount() const 0028 { 0029 return m_history.size(); 0030 } 0031 0032 QVariant ModelHistorySource::item(int index) const 0033 { 0034 if (index < 0 || index >= m_history.size()) { 0035 return {}; 0036 } 0037 0038 return m_history.at(index); 0039 } 0040 0041 QVariant ModelHistorySource::minimum() const 0042 { 0043 if (m_history.isEmpty()) { 0044 return {}; 0045 } 0046 0047 auto minProperty = model()->property("minimum"); 0048 auto maxProperty = model()->property("maximum"); 0049 if (maxProperty.isValid() && maxProperty != minProperty) { 0050 return maxProperty; 0051 } 0052 0053 return *std::min_element(m_history.begin(), m_history.end()); 0054 } 0055 0056 QVariant ModelHistorySource::maximum() const 0057 { 0058 if (m_history.isEmpty()) { 0059 return {}; 0060 } 0061 0062 auto minProperty = model()->property("minimum"); 0063 auto maxProperty = model()->property("maximum"); 0064 if (maxProperty.isValid() && maxProperty != minProperty) { 0065 return maxProperty; 0066 } 0067 0068 return *std::max_element(m_history.begin(), m_history.end()); 0069 } 0070 0071 int ModelHistorySource::row() const 0072 { 0073 return m_row; 0074 } 0075 0076 void ModelHistorySource::setRow(int row) 0077 { 0078 if (m_row == row) { 0079 return; 0080 } 0081 0082 m_row = row; 0083 Q_EMIT rowChanged(); 0084 } 0085 0086 int ModelHistorySource::maximumHistory() const 0087 { 0088 return m_maximumHistory; 0089 } 0090 0091 void ModelHistorySource::setMaximumHistory(int maximumHistory) 0092 { 0093 if (m_maximumHistory == maximumHistory) { 0094 return; 0095 } 0096 0097 m_maximumHistory = maximumHistory; 0098 Q_EMIT maximumHistoryChanged(); 0099 } 0100 0101 int ModelHistorySource::interval() const 0102 { 0103 return m_updateTimer ? m_updateTimer->interval() : -1; 0104 } 0105 0106 void ModelHistorySource::setInterval(int newInterval) 0107 { 0108 if (m_updateTimer && newInterval == m_updateTimer->interval()) { 0109 return; 0110 } 0111 0112 if (newInterval > 0) { 0113 if (!m_updateTimer) { 0114 m_updateTimer = std::make_unique<QTimer>(); 0115 // We need precise timers to avoid missing updates when dealing with semi-constantly 0116 // updating model. That is, if the model updates at 500ms and we also update at that 0117 // rate, a drift of 2ms can cause us to miss updates. 0118 m_updateTimer->setTimerType(Qt::PreciseTimer); 0119 connect(m_updateTimer.get(), &QTimer::timeout, this, [this]() { 0120 if (!model()) { 0121 return; 0122 } 0123 0124 auto index = model()->index(m_row, column()); 0125 onDataChanged(index, index, {role()}); 0126 }); 0127 if (model()) { 0128 disconnect(model(), &QAbstractItemModel::dataChanged, this, &ModelHistorySource::onDataChanged); 0129 } 0130 } 0131 m_updateTimer->setInterval(newInterval); 0132 m_updateTimer->start(); 0133 } else { 0134 m_updateTimer.reset(); 0135 onModelChanged(); 0136 } 0137 0138 Q_EMIT intervalChanged(); 0139 } 0140 0141 void ModelHistorySource::clear() 0142 { 0143 m_history.clear(); 0144 Q_EMIT dataChanged(); 0145 } 0146 0147 void ModelHistorySource::onModelChanged() 0148 { 0149 if (model() && !m_updateTimer) { 0150 connect(model(), &QAbstractItemModel::dataChanged, this, &ModelHistorySource::onDataChanged); 0151 } 0152 } 0153 0154 void ModelHistorySource::onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) 0155 { 0156 if (!model()) { 0157 return; 0158 } 0159 0160 if (!roles.isEmpty() && !roles.contains(role())) { 0161 return; 0162 } 0163 0164 if (topLeft.row() > m_row || bottomRight.row() < m_row) { 0165 return; 0166 } 0167 0168 if (topLeft.column() > column() || bottomRight.column() < column()) { 0169 return; 0170 } 0171 0172 auto entry = model()->data(model()->index(m_row, column()), role()); 0173 0174 m_history.prepend(entry); 0175 while (m_history.size() > m_maximumHistory) { 0176 m_history.pop_back(); 0177 } 0178 0179 Q_EMIT dataChanged(); 0180 } 0181 0182 #include "moc_ModelHistorySource.cpp" 0183 0184 #endif // QUICKCHARTS_BUILD_DEPRECATED_SINCE