blob: acc4452c11e33d750464a61920de8b37e72518dc [file] [log] [blame]
Zack Rusin601e8372011-03-24 22:23:21 -04001#include "apitracemodel.h"
2
3#include "apitracecall.h"
4#include "loaderthread.h"
5#include "trace_parser.hpp"
6
Zack Rusin91065372011-03-26 01:54:10 -04007#include <QDebug>
Zack Rusinc1acc7f2011-04-02 01:34:04 -04008#include <QImage>
Zack Rusin601e8372011-03-24 22:23:21 -04009#include <QVariant>
10
Zack Rusin601e8372011-03-24 22:23:21 -040011
12ApiTraceModel::ApiTraceModel(QObject *parent)
Zack Rusinf6667d12011-03-30 11:03:37 -040013 : QAbstractItemModel(parent),
14 m_trace(0)
Zack Rusin601e8372011-03-24 22:23:21 -040015{
Zack Rusin601e8372011-03-24 22:23:21 -040016}
17
18ApiTraceModel::~ApiTraceModel()
19{
Zack Rusinf6667d12011-03-30 11:03:37 -040020 m_trace = 0;
Zack Rusin601e8372011-03-24 22:23:21 -040021}
22
23QVariant ApiTraceModel::data(const QModelIndex &index, int role) const
24{
25 if (!index.isValid())
26 return QVariant();
27
Zack Rusinf6667d12011-03-30 11:03:37 -040028 if (index.column() != 0)
Zack Rusin601e8372011-03-24 22:23:21 -040029 return QVariant();
30
Zack Rusinf6667d12011-03-30 11:03:37 -040031 ApiTraceEvent *itm = item(index);
Zack Rusinc1acc7f2011-04-02 01:34:04 -040032 if (!itm) {
33 return QVariant();
34 }
35
36 switch (role) {
37 case Qt::DisplayRole:
38 return itm->staticText().text();
39 case Qt::DecorationRole:
40 return QImage();
Zack Rusin1563a692011-04-02 02:07:24 -040041 case Qt::ToolTipRole: {
42 const QString stateText = tr("State info available.");
43 if (itm->type() == ApiTraceEvent::Call) {
44 ApiTraceCall *call = static_cast<ApiTraceCall*>(itm);
45 if (call->state().isEmpty())
46 return QString::fromLatin1("<b>%1</b>").arg(call->name);
47 else
48 return QString::fromLatin1("<b>%1</b><br/>%2")
49 .arg(call->name)
50 .arg(stateText);
51 } else {
52 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(itm);
53 QString text = frame->staticText().text();
54 if (frame->state().isEmpty())
55 return QString::fromLatin1("<b>%1</b>").arg(text);
56 else
57 return QString::fromLatin1("<b>%1</b><br/>%2")
58 .arg(text)
59 .arg(stateText);
60 }
61 }
Zack Rusinc1acc7f2011-04-02 01:34:04 -040062 case ApiTraceModel::EventRole:
63 return QVariant::fromValue(itm);
Zack Rusin601e8372011-03-24 22:23:21 -040064 }
Zack Rusinf6667d12011-03-30 11:03:37 -040065
66 return QVariant();
Zack Rusin601e8372011-03-24 22:23:21 -040067}
68
69Qt::ItemFlags ApiTraceModel::flags(const QModelIndex &index) const
70{
71 if (!index.isValid())
72 return 0;
73
74 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
75}
76
77QVariant ApiTraceModel::headerData(int section, Qt::Orientation orientation,
78 int role ) const
79{
80 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
81 switch (section) {
82 case 0:
Zack Rusinc1acc7f2011-04-02 01:34:04 -040083 return tr("Events");
84 case 1:
85 return tr("Flags");
Zack Rusin601e8372011-03-24 22:23:21 -040086 default:
87 //fall through
88 break;
89 }
90 }
91
92 return QVariant();
93}
94
95QModelIndex ApiTraceModel::index(int row, int column,
96 const QModelIndex &parent) const
97{
98 if (parent.isValid() && parent.column() != 0)
99 return QModelIndex();
100
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400101 ApiTraceEvent *event = item(parent);
102 if (event) {
103 if (event->type() != ApiTraceEvent::Frame) {
104 qDebug()<<"got a valid parent but it's not a frame "<<event->type();
Zack Rusinf6667d12011-03-30 11:03:37 -0400105 return QModelIndex();
106 }
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400107 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
Zack Rusinf6667d12011-03-30 11:03:37 -0400108 ApiTraceCall *call = frame->calls.value(row);
109 if (call)
110 return createIndex(row, column, call);
111 else
112 return QModelIndex();
113 } else {
114 ApiTraceFrame *frame = m_trace->frameAt(row);
115 if (frame)
116 return createIndex(row, column, frame);
117 else
118 return QModelIndex();
119 }
120 return QModelIndex();
Zack Rusin601e8372011-03-24 22:23:21 -0400121}
122
123bool ApiTraceModel::hasChildren(const QModelIndex &parent) const
124{
Zack Rusinf6667d12011-03-30 11:03:37 -0400125 if (parent.isValid()) {
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400126 ApiTraceEvent *event = item(parent);
127 if (event && event->type() == ApiTraceEvent::Frame) {
128 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
Zack Rusinf6667d12011-03-30 11:03:37 -0400129 return !frame->calls.isEmpty();
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400130 } else
Zack Rusinf6667d12011-03-30 11:03:37 -0400131 return false;
132 } else {
133 return (rowCount() > 0);
134 }
Zack Rusin601e8372011-03-24 22:23:21 -0400135}
136
137QModelIndex ApiTraceModel::parent(const QModelIndex &index) const
138{
139 if (!index.isValid())
140 return QModelIndex();
141
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400142 ApiTraceEvent *event = item(index);
143 if (event && event->type() == ApiTraceEvent::Call) {
144 ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
Zack Rusinf6667d12011-03-30 11:03:37 -0400145 Q_ASSERT(call->parentFrame);
146 return createIndex(call->parentFrame->number,
147 0, call->parentFrame);
148 }
Zack Rusin601e8372011-03-24 22:23:21 -0400149 return QModelIndex();
150}
151
152int ApiTraceModel::rowCount(const QModelIndex &parent) const
153{
Zack Rusinf6667d12011-03-30 11:03:37 -0400154 if (!parent.isValid())
155 return m_trace->numFrames();
156
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400157 ApiTraceEvent *event = item(parent);
158 if (!event || event->type() == ApiTraceEvent::Call)
Zack Rusinf6667d12011-03-30 11:03:37 -0400159 return 0;
160
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400161 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
Zack Rusinf6667d12011-03-30 11:03:37 -0400162 if (frame)
163 return frame->calls.count();
164
165 return 0;
Zack Rusin601e8372011-03-24 22:23:21 -0400166}
167
168int ApiTraceModel::columnCount(const QModelIndex &parent) const
169{
Zack Rusinf6667d12011-03-30 11:03:37 -0400170 return 1;
Zack Rusin601e8372011-03-24 22:23:21 -0400171}
172
Zack Rusin601e8372011-03-24 22:23:21 -0400173bool ApiTraceModel::insertRows(int position, int rows,
174 const QModelIndex &parent)
175{
176 return false;
177}
178
179bool ApiTraceModel::removeRows(int position, int rows,
180 const QModelIndex &parent)
181{
182 bool success = true;
183
184 Q_UNUSED(parent);
185
Zack Rusin601e8372011-03-24 22:23:21 -0400186 beginRemoveRows(parent, position, position + rows - 1);
Zack Rusinf6667d12011-03-30 11:03:37 -0400187 //XXX remove it from ApiTrace
Zack Rusin601e8372011-03-24 22:23:21 -0400188 endRemoveRows();
189
190 return success;
191}
192
Zack Rusinf6667d12011-03-30 11:03:37 -0400193void ApiTraceModel::setApiTrace(ApiTrace *trace)
Zack Rusin601e8372011-03-24 22:23:21 -0400194{
Zack Rusinf6667d12011-03-30 11:03:37 -0400195 if (m_trace == trace)
196 return;
197 if (m_trace)
198 disconnect(m_trace);
199 m_trace = trace;
200 connect(m_trace, SIGNAL(framesInvalidated()),
201 this, SLOT(invalidateFrames()));
202 connect(m_trace, SIGNAL(framesAdded(int, int)),
203 this, SLOT(appendFrames(int, int)));
Zack Rusin601e8372011-03-24 22:23:21 -0400204}
205
Zack Rusinf6667d12011-03-30 11:03:37 -0400206const ApiTrace * ApiTraceModel::apiTrace() const
Zack Rusin601e8372011-03-24 22:23:21 -0400207{
Zack Rusinf6667d12011-03-30 11:03:37 -0400208 return m_trace;
209}
Zack Rusin601e8372011-03-24 22:23:21 -0400210
Zack Rusinf6667d12011-03-30 11:03:37 -0400211void ApiTraceModel::invalidateFrames()
212{
213 beginResetModel();
214 endResetModel();
215}
Zack Rusin91065372011-03-26 01:54:10 -0400216
Zack Rusinf6667d12011-03-30 11:03:37 -0400217void ApiTraceModel::appendFrames(int oldCount, int numAdded)
218{
219 beginInsertRows(QModelIndex(), oldCount,
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400220 oldCount + numAdded - 1);
Zack Rusin601e8372011-03-24 22:23:21 -0400221 endInsertRows();
Zack Rusinf6667d12011-03-30 11:03:37 -0400222}
Zack Rusin601e8372011-03-24 22:23:21 -0400223
Zack Rusinf6667d12011-03-30 11:03:37 -0400224ApiTraceEvent * ApiTraceModel::item(const QModelIndex &index) const
225{
226 if (!index.isValid())
227 return 0;
228 return static_cast<ApiTraceEvent*>(index.internalPointer());
Zack Rusin601e8372011-03-24 22:23:21 -0400229}
230
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400231void ApiTraceModel::stateSetOnEvent(ApiTraceEvent *event)
232{
233 if (!event)
234 return;
235
236 if (event->type() == ApiTraceEvent::Call) {
237 ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
238 ApiTraceFrame *frame = call->parentFrame;
239 int row = frame->calls.indexOf(call);
240 QModelIndex index = createIndex(row, 0, call);
241 emit dataChanged(index, index);
242 } else if (event->type() == ApiTraceEvent::Frame) {
243 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
244 const QList<ApiTraceFrame*> frames = m_trace->frames();
245 int row = frames.indexOf(frame);
246 QModelIndex index = createIndex(row, 0, frame);
247 emit dataChanged(index, index);
248 }
249}
250
Zack Rusin601e8372011-03-24 22:23:21 -0400251#include "apitracemodel.moc"