1 #include "util/statmodel.h"
2 
3 #include <limits>
4 
5 #include "moc_statmodel.cpp"
6 #include "util/math.h"
7 
StatModel(QObject * pParent)8 StatModel::StatModel(QObject* pParent)
9         : QAbstractTableModel(pParent) {
10 
11     setHeaderData(STAT_COLUMN_NAME, Qt::Horizontal, tr("Name"));
12     setHeaderData(STAT_COLUMN_COUNT, Qt::Horizontal, tr("Count"));
13     setHeaderData(STAT_COLUMN_TYPE, Qt::Horizontal, tr("Type"));
14     setHeaderData(STAT_COLUMN_UNITS, Qt::Horizontal, tr("Units"));
15     setHeaderData(STAT_COLUMN_SUM, Qt::Horizontal, tr("Sum"));
16     setHeaderData(STAT_COLUMN_MIN, Qt::Horizontal, tr("Min"));
17     setHeaderData(STAT_COLUMN_MAX, Qt::Horizontal, tr("Max"));
18     setHeaderData(STAT_COLUMN_MEAN, Qt::Horizontal, tr("Mean"));
19     setHeaderData(STAT_COLUMN_VARIANCE, Qt::Horizontal, tr("Variance"));
20     setHeaderData(STAT_COLUMN_STDDEV, Qt::Horizontal, tr("Standard Deviation"));
21 }
22 
~StatModel()23 StatModel::~StatModel() {
24 }
25 
statUpdated(const Stat & stat)26 void StatModel::statUpdated(const Stat& stat) {
27     auto it = m_statNameToRow.constFind(stat.m_tag);
28     if (it != m_statNameToRow.constEnd()) {
29         int row = it.value();
30         m_stats[row] = stat;
31         QModelIndex left = index(row, 0);
32         QModelIndex right = index(row, columnCount() - 1);
33         emit dataChanged(left, right);
34     } else {
35         beginInsertRows(QModelIndex(), m_stats.size(),
36                         m_stats.size());
37         m_statNameToRow[stat.m_tag] = m_stats.size();
38         m_stats.append(stat);
39         endInsertRows();
40     }
41 }
42 
rowCount(const QModelIndex & parent) const43 int StatModel::rowCount(const QModelIndex& parent) const {
44     if (parent.isValid()) {
45         return 0;
46     }
47     return m_stats.size();
48 }
49 
columnCount(const QModelIndex & parent) const50 int StatModel::columnCount(const QModelIndex& parent) const {
51     if (parent.isValid()) {
52         return 0;
53     }
54     return NUM_STAT_COLUMNS;
55 }
56 
data(const QModelIndex & index,int role) const57 QVariant StatModel::data(const QModelIndex& index,
58                             int role) const {
59     if (!index.isValid() || (role != Qt::DisplayRole &&
60                              role != Qt::EditRole)) {
61         return QVariant();
62     }
63 
64     int row = index.row();
65     int column = index.column();
66 
67     if (row < 0 || row >= m_stats.size()) {
68         return QVariant();
69     }
70 
71     const Stat& stat = m_stats.at(row);
72     switch (column) {
73         case STAT_COLUMN_NAME:
74             return stat.m_tag;
75         case STAT_COLUMN_TYPE:
76             return stat.m_type;
77         case STAT_COLUMN_COUNT:
78             return stat.m_report_count;
79         case STAT_COLUMN_SUM:
80             return stat.m_sum;
81         case STAT_COLUMN_MIN:
82             return std::numeric_limits<double>::max() == stat.m_min ?
83                     QVariant("XXX") : QVariant(stat.m_min);
84         case STAT_COLUMN_MAX:
85             return std::numeric_limits<double>::min() == stat.m_max ?
86                     QVariant("XXX") : QVariant(stat.m_max);
87         case STAT_COLUMN_MEAN:
88             return stat.m_report_count > 0 ?
89                     QVariant(stat.m_sum / stat.m_report_count) : QVariant("XXX");
90         case STAT_COLUMN_VARIANCE:
91             return stat.variance();
92         case STAT_COLUMN_STDDEV:
93             return sqrt(stat.variance());
94         case STAT_COLUMN_UNITS:
95             return stat.valueUnits();
96     }
97     return QVariant();
98 }
99 
setHeaderData(int section,Qt::Orientation orientation,const QVariant & value,int role)100 bool StatModel::setHeaderData(int section,
101                               Qt::Orientation orientation,
102                               const QVariant& value,
103                               int role) {
104     int numColumns = columnCount();
105     if (section < 0 || section >= numColumns) {
106         return false;
107     }
108 
109     if (orientation != Qt::Horizontal) {
110         // We only care about horizontal headers.
111         return false;
112     }
113 
114     if (m_headerInfo.size() != numColumns) {
115         m_headerInfo.resize(numColumns);
116     }
117 
118     m_headerInfo[section][role] = value;
119     emit headerDataChanged(orientation, section, section);
120     return true;
121 }
122 
headerData(int section,Qt::Orientation orientation,int role) const123 QVariant StatModel::headerData(int section,
124                                Qt::Orientation orientation,
125                                int role) const {
126     if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
127         QVariant headerValue = m_headerInfo.value(section).value(role);
128         if (!headerValue.isValid()) {
129             // Try EditRole if DisplayRole wasn't present
130             headerValue = m_headerInfo.value(section).value(Qt::EditRole);
131         }
132         if (!headerValue.isValid()) {
133             headerValue = QVariant(section).toString();
134         }
135         return headerValue;
136     }
137     return QAbstractTableModel::headerData(section, orientation, role);
138 }
139