This repository has been archived on 2020-09-07. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
libs/piqt_utils/piintrospector/containers_view.cpp

202 lines
5.3 KiB
C++

#include "containers_view.h"
#include <QTreeView>
#include <QSortFilterProxyModel>
#include <cxxabi.h>
const QString demangle(const char * name) {
int status = -4;
char * res = abi::__cxa_demangle(name, NULL, NULL, &status);
QString ret((status == 0) ? res : name);
free(res);
return ret;
}
enum ColumnContainers {
ccType,
ccCount,
ccBytesAllocated,
ccBytesUsed,
ccColumnCount,
};
ContainersModel::ContainersModel() {
mode_changes = false;
all.resize(columnCount(), 0L);
prev_all.resize(all.size(), 0L);
}
#ifdef PIP_INTROSPECTION
void ContainersModel::update(const PIMap<uint, PIIntrospectionContainers::Type> & td, const PIMap<uint, PIString> & tn) {
prev_typedata = typedata;
typedata = td;
typenames = tn;
PIVector<uint> ntypeids = tn.keys();
for (int i = 0; i < ntypeids.size_s(); ++i) {
if (typeids.size_s() > i)
if (typeids[i] == ntypeids[i]) continue;
beginInsertRows(QModelIndex(), i, i);
typeids.insert(i, ntypeids[i]);
endInsertRows();
}
prev_all = all;
all.fill(0U);
for (auto i = td.constBegin(); i != td.constEnd(); ++i) {
all[ccCount] += i.value().count;
all[ccBytesAllocated] += i.value().bytes_allocated;
all[ccBytesUsed] += i.value().bytes_used;
}
dataChanged(index(1, 0), index(columnCount(), typeids.size_s() - 1));
emit headerDataChanged(Qt::Horizontal, 1, columnCount());
}
#endif
void ContainersModel::clear() {
#ifdef PIP_INTROSPECTION
beginRemoveRows(QModelIndex(), 0, typeids.size_s() - 1);
typedata.clear();
prev_typedata.clear();
typenames.clear();
typeids.clear();
all.fill(0L);
endRemoveRows();
#endif
}
int ContainersModel::rowCount(const QModelIndex & parent) const {
return typeids.size_s();
}
int ContainersModel::columnCount(const QModelIndex & parent) const {
return ccColumnCount;
}
QModelIndex ContainersModel::index(int row, int column, const QModelIndex & parent) const {
#ifdef PIP_INTROSPECTION
if (row >= typenames.size_s() || row >= typedata.size_s()) return QModelIndex();
#endif
return createIndex(row, column, typeids[row]);
}
bool ContainersModel::hasChildren(const QModelIndex & parent) const {
if (!parent.isValid()) return true;
return false;
}
QVariant ContainersModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (orientation != Qt::Horizontal || role != Qt::DisplayRole) return QVariant();
PIVector<llong> ret = all;
if (mode_changes) {
for (int i = 0; i < all.size_s(); ++i)
ret[i] -= prev_all[i];
}
switch (section) {
case ccType : return tr("Type");
case ccCount : return tr("Count (%1)").arg(ret[ccCount]);
case ccBytesAllocated: return tr("Allocated (%1)").arg(PI2QString(PIString::readableSize(ret[ccBytesAllocated])));
case ccBytesUsed : return tr("Used (%1)").arg(PI2QString(PIString::readableSize(ret[ccBytesUsed])));
default: break;
}
return QVariant();
}
QVariant ContainersModel::data(const QModelIndex & index, int role) const {
if (role != Qt::DisplayRole && role != Qt::UserRole) return QVariant();
#ifdef PIP_INTROSPECTION
uint id = uint(index.internalId());
llong v = 0L;
if (mode_changes) {
switch (index.column()) {
case ccType: return demangle(typenames.value(id).dataAscii());
case ccCount: return int(typedata.value(id).count) - int(prev_typedata.value(id).count);
case ccBytesAllocated:
v = typedata.value(id).bytes_allocated;
v -= prev_typedata.value(id).bytes_allocated;
if (role == Qt::UserRole) return piAbs(v);
return PI2QString(PIString::readableSize(v));
case ccBytesUsed:
v = typedata.value(id).bytes_used;
v -= prev_typedata.value(id).bytes_used;
if (role == Qt::UserRole) return piAbs(v);
return PI2QString(PIString::readableSize(v));
}
} else {
switch (index.column()) {
case ccType: return demangle(typenames.value(id).dataAscii());
case ccCount: return typedata.value(id).count;
case ccBytesAllocated:
v = typedata.value(id).bytes_allocated;
if (role == Qt::UserRole) return v;
return PI2QString(PIString::readableSize(v));
case ccBytesUsed:
v = typedata.value(id).bytes_used;
if (role == Qt::UserRole) return v;
return PI2QString(PIString::readableSize(v));
}
}
#endif
return QVariant();
}
Qt::ItemFlags ContainersModel::flags(const QModelIndex & index) const {
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
void ContainersModel::setChangesMode(bool yes) {
mode_changes = yes;
dataChanged(index(1, 0), index(columnCount(), typeids.size_s() - 1));
emit headerDataChanged(Qt::Horizontal, 1, columnCount());
}
ContainersView::ContainersView(QWidget * parent): QWidget(parent) {
setupUi(this);
model = new ContainersModel();
connect(radioChanges, SIGNAL(toggled(bool)), model, SLOT(setChangesMode(bool)));
QSortFilterProxyModel * proxy = new QSortFilterProxyModel();
proxy->setSourceModel(model);
proxy->setSortRole(Qt::UserRole);
proxy->setDynamicSortFilter(false);
treeContainers->setModel(proxy);
}
ContainersView::~ContainersView() {
}
void ContainersView::changeEvent(QEvent * e) {
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
retranslateUi(this);
break;
default:
break;
}
}
#ifdef PIP_INTROSPECTION
void ContainersView::showContainers(const PIMap<uint, PIIntrospectionContainers::Type> & data, const PIMap<uint, PIString> & typenames) {
model->update(data, typenames);
}
#endif
void ContainersView::clear() {
model->clear();
}