From c1acc7fdacf6940b634940dbefa8e2c98128076f Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sat, 2 Apr 2011 01:34:04 -0400 Subject: [PATCH] Cleanup the event model code. now we show a marker next to frames which have cached state --- gui/apicalldelegate.cpp | 55 +++++++++++++++------------- gui/apicalldelegate.h | 3 ++ gui/apitracefilter.cpp | 16 +++++--- gui/apitracemodel.cpp | 81 ++++++++++++++++++++++++++--------------- gui/apitracemodel.h | 5 +++ gui/mainwindow.cpp | 18 ++++++--- 6 files changed, 113 insertions(+), 65 deletions(-) diff --git a/gui/apicalldelegate.cpp b/gui/apicalldelegate.cpp index 5376c0d..4eb542b 100644 --- a/gui/apicalldelegate.cpp +++ b/gui/apicalldelegate.cpp @@ -1,14 +1,17 @@ #include "apicalldelegate.h" #include "apitracecall.h" +#include "apitracemodel.h" +#include #include #include #include #include ApiCallDelegate::ApiCallDelegate(QWidget *parent) - : QStyledItemDelegate(parent) + : QStyledItemDelegate(parent), + m_stateEmblem(":/resources/dialog-information.png") { } @@ -16,40 +19,42 @@ void ApiCallDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { - ApiTraceCall *call = index.data().value(); - if (call) { - QStaticText text = call->staticText(); + QVariant var = index.data(ApiTraceModel::EventRole); + ApiTraceEvent *event = var.value(); + + Q_ASSERT(index.column() == 0); + + if (event) { + QPoint offset; + QStaticText text = event->staticText(); //text.setTextWidth(option.rect.width()); - QStyledItemDelegate::paint(painter, option, index); - painter->drawStaticText(option.rect.topLeft(), text); - } else { - ApiTraceFrame *frame = index.data().value(); - if (frame) { - QStaticText text = frame->staticText(); - //text.setTextWidth(option.rect.width()); - QStyledItemDelegate::paint(painter, option, index); - painter->drawStaticText(option.rect.topLeft(), text); - } else { - QStyledItemDelegate::paint(painter, option, index); + //QStyledItemDelegate::paint(painter, option, index); + QStyle *style = QApplication::style(); + style->drawControl(QStyle::CE_ItemViewItem, &option, painter, 0); + if (!event->state().isEmpty()) { + QPixmap px = m_stateEmblem.pixmap(option.rect.height(), option.rect.height()); + painter->drawPixmap(option.rect.topLeft(), px); + offset = QPoint(option.rect.height() + 5, 0); } + painter->drawStaticText(option.rect.topLeft() + offset, text); + } else { + QStyledItemDelegate::paint(painter, option, index); } } QSize ApiCallDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { - ApiTraceCall *call = index.data().value(); - if (call) { - QStaticText text = call->staticText(); + ApiTraceEvent *event = + index.data(ApiTraceModel::EventRole).value(); + + Q_ASSERT(index.column() == 0); + + if (event) { + QStaticText text = event->staticText(); //text.setTextWidth(option.rect.width()); + //qDebug()<<"text size = "<(); - if (frame) { - QStaticText text = frame->staticText(); - //text.setTextWidth(option.rect.width()); - return text.size().toSize(); - } } return QStyledItemDelegate::sizeHint(option, index); } diff --git a/gui/apicalldelegate.h b/gui/apicalldelegate.h index a29a178..525ab83 100644 --- a/gui/apicalldelegate.h +++ b/gui/apicalldelegate.h @@ -14,6 +14,9 @@ public: const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + +private: + QIcon m_stateEmblem; }; #endif diff --git a/gui/apitracefilter.cpp b/gui/apitracefilter.cpp index 24c56bf..c467a8c 100644 --- a/gui/apitracefilter.cpp +++ b/gui/apitracefilter.cpp @@ -1,6 +1,7 @@ #include "apitracefilter.h" #include "apitracecall.h" +#include "apitracemodel.h" #include @@ -13,14 +14,19 @@ bool ApiTraceFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent); - QVariant varientData = sourceModel()->data(index0); - ApiTraceCall *call = varientData.value(); + QVariant varientData = sourceModel()->data(index0, ApiTraceModel::EventRole); + ApiTraceEvent *event = varientData.value(); - if (!call) { - ApiTraceFrame *frame = varientData.value(); - return frame != 0; + Q_ASSERT(event); + if (!event) + return false; + + //we don't filter frames + if (event->type() == ApiTraceEvent::Frame) { + return true; } + ApiTraceCall *call = static_cast(event); QString function = call->name; if (!m_text.isEmpty()) { diff --git a/gui/apitracemodel.cpp b/gui/apitracemodel.cpp index c135bc1..501dd98 100644 --- a/gui/apitracemodel.cpp +++ b/gui/apitracemodel.cpp @@ -5,6 +5,7 @@ #include "trace_parser.hpp" #include +#include #include @@ -24,24 +25,21 @@ QVariant ApiTraceModel::data(const QModelIndex &index, int role) const if (!index.isValid()) return QVariant(); - if (role != Qt::DisplayRole) - return QVariant(); - - //data only in the first column if (index.column() != 0) return QVariant(); ApiTraceEvent *itm = item(index); - if (itm) { - if (itm->type() == ApiTraceEvent::Frame) { - ApiTraceFrame *frame = - static_cast(itm); - return QVariant::fromValue(frame); - } else if (itm->type() == ApiTraceEvent::Call) { - ApiTraceCall *call = - static_cast(itm); - return QVariant::fromValue(call); - } + if (!itm) { + return QVariant(); + } + + switch (role) { + case Qt::DisplayRole: + return itm->staticText().text(); + case Qt::DecorationRole: + return QImage(); + case ApiTraceModel::EventRole: + return QVariant::fromValue(itm); } return QVariant(); @@ -61,7 +59,9 @@ QVariant ApiTraceModel::headerData(int section, Qt::Orientation orientation, if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { switch (section) { case 0: - return tr("Event"); + return tr("Events"); + case 1: + return tr("Flags"); default: //fall through break; @@ -77,13 +77,13 @@ QModelIndex ApiTraceModel::index(int row, int column, if (parent.isValid() && parent.column() != 0) return QModelIndex(); - if (parent.isValid()) { - QVariant data = parent.data(); - ApiTraceFrame *frame = data.value(); - if (!frame) { - qDebug()<<"got a valid parent but it's not a frame "<type() != ApiTraceEvent::Frame) { + qDebug()<<"got a valid parent but it's not a frame "<type(); return QModelIndex(); } + ApiTraceFrame *frame = static_cast(event); ApiTraceCall *call = frame->calls.value(row); if (call) return createIndex(row, column, call); @@ -102,10 +102,11 @@ QModelIndex ApiTraceModel::index(int row, int column, bool ApiTraceModel::hasChildren(const QModelIndex &parent) const { if (parent.isValid()) { - ApiTraceFrame *frame = parent.data().value(); - if (frame) + ApiTraceEvent *event = item(parent); + if (event && event->type() == ApiTraceEvent::Frame) { + ApiTraceFrame *frame = static_cast(event); return !frame->calls.isEmpty(); - else + } else return false; } else { return (rowCount() > 0); @@ -117,8 +118,9 @@ QModelIndex ApiTraceModel::parent(const QModelIndex &index) const if (!index.isValid()) return QModelIndex(); - ApiTraceCall *call = index.data().value(); - if (call) { + ApiTraceEvent *event = item(index); + if (event && event->type() == ApiTraceEvent::Call) { + ApiTraceCall *call = static_cast(event); Q_ASSERT(call->parentFrame); return createIndex(call->parentFrame->number, 0, call->parentFrame); @@ -131,11 +133,11 @@ int ApiTraceModel::rowCount(const QModelIndex &parent) const if (!parent.isValid()) return m_trace->numFrames(); - ApiTraceCall *call = parent.data().value(); - if (call) + ApiTraceEvent *event = item(parent); + if (!event || event->type() == ApiTraceEvent::Call) return 0; - ApiTraceFrame *frame = parent.data().value(); + ApiTraceFrame *frame = static_cast(event); if (frame) return frame->calls.count(); @@ -147,7 +149,6 @@ int ApiTraceModel::columnCount(const QModelIndex &parent) const return 1; } - bool ApiTraceModel::insertRows(int position, int rows, const QModelIndex &parent) { @@ -195,7 +196,7 @@ void ApiTraceModel::invalidateFrames() void ApiTraceModel::appendFrames(int oldCount, int numAdded) { beginInsertRows(QModelIndex(), oldCount, - oldCount + numAdded); + oldCount + numAdded - 1); endInsertRows(); } @@ -206,4 +207,24 @@ ApiTraceEvent * ApiTraceModel::item(const QModelIndex &index) const return static_cast(index.internalPointer()); } +void ApiTraceModel::stateSetOnEvent(ApiTraceEvent *event) +{ + if (!event) + return; + + if (event->type() == ApiTraceEvent::Call) { + ApiTraceCall *call = static_cast(event); + ApiTraceFrame *frame = call->parentFrame; + int row = frame->calls.indexOf(call); + QModelIndex index = createIndex(row, 0, call); + emit dataChanged(index, index); + } else if (event->type() == ApiTraceEvent::Frame) { + ApiTraceFrame *frame = static_cast(event); + const QList frames = m_trace->frames(); + int row = frames.indexOf(frame); + QModelIndex index = createIndex(row, 0, frame); + emit dataChanged(index, index); + } +} + #include "apitracemodel.moc" diff --git a/gui/apitracemodel.h b/gui/apitracemodel.h index d9ac9dd..cf90159 100644 --- a/gui/apitracemodel.h +++ b/gui/apitracemodel.h @@ -13,12 +13,17 @@ class ApiTraceEvent; class ApiTraceModel : public QAbstractItemModel { Q_OBJECT +public: + enum Roles { + EventRole = Qt::UserRole + 1 + }; public: ApiTraceModel(QObject *parent = 0); ~ApiTraceModel(); void setApiTrace(ApiTrace *trace); const ApiTrace *apiTrace() const; + void stateSetOnEvent(ApiTraceEvent *event); public: /* QAbstractItemModel { */ diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 12d46ef..93add0e 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -43,8 +43,9 @@ MainWindow::MainWindow() m_proxyModel->setSourceModel(m_model); m_ui.callView->setModel(m_proxyModel); m_ui.callView->setItemDelegate(new ApiCallDelegate); - for (int column = 0; column < m_model->columnCount(); ++column) - m_ui.callView->resizeColumnToContents(column); + m_ui.callView->resizeColumnToContents(0); + m_ui.callView->header()->swapSections(0, 1); + m_ui.callView->setColumnWidth(1, 42); QToolBar *toolBar = addToolBar(tr("Navigation")); m_filterEdit = new QLineEdit(toolBar); @@ -105,13 +106,19 @@ void MainWindow::loadTrace(const QString &fileName) void MainWindow::callItemSelected(const QModelIndex &index) { - ApiTraceCall *call = index.data().value(); - if (call) { + ApiTraceEvent *event = + index.data(ApiTraceModel::EventRole).value(); + + if (event && event->type() == ApiTraceEvent::Call) { + ApiTraceCall *call = static_cast(event); m_ui.detailsWebView->setHtml(call->toHtml()); m_ui.detailsDock->show(); m_selectedEvent = call; } else { - m_selectedEvent = index.data().value(); + if (event && event->type() == ApiTraceEvent::Frame) { + m_selectedEvent = static_cast(event); + } else + m_selectedEvent = 0; m_ui.detailsDock->hide(); } if (m_selectedEvent && !m_selectedEvent->state().isEmpty()) { @@ -294,6 +301,7 @@ void MainWindow::parseState(const QVariantMap ¶ms) QVariantMap::const_iterator itr; m_stateEvent->setState(params); + m_model->stateSetOnEvent(m_stateEvent); if (m_selectedEvent == m_stateEvent) { fillStateForFrame(); } else { -- 2.43.0