File indexing completed on 2024-04-28 17:02:22
0001 /* 0002 This file is part of Massif Visualizer 0003 0004 Copyright 2010 Milian Wolff <mail@milianw.de> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Lesser General Public 0008 License as published by the Free Software Foundation; either 0009 version 2.1 of the License, or (at your option) version 3, or any 0010 later version accepted by the membership of KDE e.V. (or its 0011 successor approved by the membership of KDE e.V.), which shall 0012 act as a proxy defined in Section 6 of version 3 of the license. 0013 0014 This library is distributed in the hope that it will be useful, 0015 but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0017 Lesser General Public License for more details. 0018 0019 You should have received a copy of the GNU Lesser General Public 0020 License along with this library. If not, see <http://www.gnu.org/licenses/>. 0021 */ 0022 0023 #include "totalcostmodel.h" 0024 0025 #include "massifdata/filedata.h" 0026 #include "massifdata/snapshotitem.h" 0027 #include "massifdata/treeleafitem.h" 0028 #include "massifdata/util.h" 0029 0030 #include "KChartGlobal" 0031 #include "KChartLineAttributes" 0032 0033 #include <QtGui/QPen> 0034 0035 #include <KLocalizedString> 0036 0037 using namespace Massif; 0038 0039 TotalCostModel::TotalCostModel(QObject* parent): QAbstractTableModel(parent), m_data(0) 0040 { 0041 } 0042 0043 TotalCostModel::~TotalCostModel() 0044 { 0045 } 0046 0047 void TotalCostModel::setSource(const FileData* data) 0048 { 0049 if (m_data) { 0050 beginRemoveRows(QModelIndex(), 0, rowCount() - 1); 0051 m_data = 0; 0052 endRemoveRows(); 0053 } 0054 if (data) { 0055 beginInsertRows(QModelIndex(), 0, data->snapshots().size() - 1); 0056 m_data = data; 0057 endInsertRows(); 0058 } 0059 } 0060 0061 QModelIndex TotalCostModel::peak() const 0062 { 0063 Q_ASSERT(m_data); 0064 if (!m_data->peak()) { 0065 return QModelIndex(); 0066 } 0067 return index(m_data->snapshots().indexOf(m_data->peak()), 0); 0068 } 0069 0070 QVariant TotalCostModel::headerData(int section, Qt::Orientation orientation, int role) const 0071 { 0072 Q_ASSERT(orientation != Qt::Horizontal || section < columnCount()); 0073 if (section == 0 && orientation == Qt::Horizontal) { 0074 if ( role == KChart::DatasetPenRole ) { 0075 return QPen(Qt::red); 0076 } else if ( role == KChart::DatasetBrushRole ) { 0077 return QBrush(Qt::red); 0078 } else if ( role == Qt::DisplayRole ) { 0079 return i18n("Total Memory Heap Consumption"); 0080 } 0081 } 0082 return QAbstractItemModel::headerData(section, orientation, role); 0083 } 0084 0085 QVariant TotalCostModel::data(const QModelIndex& index, int role) const 0086 { 0087 // FIXME kdchart queries (-1, -1) for empty models 0088 if ( index.row() == -1 || index.column() == -1 ) { 0089 // qWarning() << "TotalCostModel::data: FIXME fix kdchart views to not query model data for invalid indices!"; 0090 return QVariant(); 0091 } 0092 0093 Q_ASSERT(index.row() >= 0 && index.row() < rowCount(index.parent())); 0094 Q_ASSERT(index.column() >= 0 && index.column() < columnCount(index.parent())); 0095 Q_ASSERT(m_data); 0096 Q_ASSERT(!index.parent().isValid()); 0097 0098 if ( role == KChart::LineAttributesRole ) { 0099 static KChart::LineAttributes attributes; 0100 attributes.setDisplayArea(true); 0101 if (index == m_selection) { 0102 attributes.setTransparency(255); 0103 } else { 0104 attributes.setTransparency(50); 0105 } 0106 return QVariant::fromValue(attributes); 0107 } 0108 if ( role == KChart::DatasetPenRole ) { 0109 return QPen(Qt::red); 0110 } else if ( role == KChart::DatasetBrushRole ) { 0111 return QBrush(Qt::red); 0112 } 0113 0114 if ( role != Qt::DisplayRole && role != Qt::ToolTipRole ) { 0115 return QVariant(); 0116 } 0117 0118 if ( role == Qt::ToolTipRole ) { 0119 // hack: the ToolTip will only be queried by KDChart and that one uses the 0120 // left index, but we want it to query the right one. but we also need to 0121 // take the very last data set into account to prevent an overflow there 0122 const SnapshotItem* snapshot = m_data->snapshots().at(qMin(index.row() + 1, m_data->snapshots().size() - 1)); 0123 return i18n("Snapshot #%1:\n" 0124 "Heap cost of %2\n" 0125 "Extra heap cost of %3\n" 0126 "Stack cost of %4", 0127 snapshot->number(), prettyCost(snapshot->memHeap()), prettyCost(snapshot->memHeapExtra()), 0128 prettyCost(snapshot->memStacks())); 0129 } 0130 0131 const SnapshotItem* snapshot = m_data->snapshots().at(index.row()); 0132 if (index.column() == 0) { 0133 return snapshot->time(); 0134 } else { 0135 Q_ASSERT(index.column() == 1); 0136 return snapshot->cost(); 0137 } 0138 } 0139 0140 int TotalCostModel::columnCount(const QModelIndex&) const 0141 { 0142 return 2; 0143 } 0144 0145 int TotalCostModel::rowCount(const QModelIndex& parent) const 0146 { 0147 if (!m_data) { 0148 return 0; 0149 } 0150 0151 if (parent.isValid()) { 0152 return 0; 0153 } else { 0154 // snapshot item 0155 return m_data->snapshots().count(); 0156 } 0157 } 0158 0159 QModelIndex TotalCostModel::indexForSnapshot(const SnapshotItem* snapshot) const 0160 { 0161 int row = m_data->snapshots().indexOf(const_cast<SnapshotItem*>(snapshot)); 0162 if (row == -1) { 0163 return QModelIndex(); 0164 } 0165 return index(row, 0); 0166 } 0167 0168 QModelIndex TotalCostModel::indexForTreeLeaf(const TreeLeafItem* node) const 0169 { 0170 Q_UNUSED(node) 0171 return QModelIndex(); 0172 } 0173 0174 ModelItem TotalCostModel::itemForIndex(const QModelIndex& idx) const 0175 { 0176 if (!idx.isValid() || idx.parent().isValid() || idx.row() > rowCount() || idx.column() > columnCount()) { 0177 return ModelItem(0, 0); 0178 } 0179 const SnapshotItem* snapshot = m_data->snapshots().at(idx.row()); 0180 return ModelItem(0, snapshot); 0181 } 0182 0183 QModelIndex TotalCostModel::indexForItem(const ModelItem& item) const 0184 { 0185 if ((!item.first && !item.second) || item.first) { 0186 return QModelIndex(); 0187 } 0188 return indexForSnapshot(item.second); 0189 } 0190 0191 void TotalCostModel::setSelection(const QModelIndex& index) 0192 { 0193 m_selection = index; 0194 }