blob: 8f4892f63e494d5580ecdc361d3b64ccb63b71a6 [file] [log] [blame]
Zack Rusin601e8372011-03-24 22:23:21 -04001#include "apitracemodel.h"
2
3#include "apitracecall.h"
Zack Rusinebf971e2011-09-06 17:44:43 -04004#include "traceloader.h"
Zack Rusin601e8372011-03-24 22:23:21 -04005#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);
Zack Rusined40bc62011-08-28 17:11:02 -040045 if (!call->hasState())
Zack Rusin344923b2011-04-03 17:22:11 -040046 return QString::fromLatin1("%1)&nbsp;<b>%2</b>")
Zack Rusinead6aad2011-04-15 22:16:18 -040047 .arg(call->index())
48 .arg(call->name());
Zack Rusin1563a692011-04-02 02:07:24 -040049 else
Zack Rusin344923b2011-04-03 17:22:11 -040050 return QString::fromLatin1("%1)&nbsp;<b>%2</b><br/>%3")
Zack Rusinead6aad2011-04-15 22:16:18 -040051 .arg(call->index())
52 .arg(call->name())
Zack Rusin1563a692011-04-02 02:07:24 -040053 .arg(stateText);
54 } else {
55 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(itm);
Zack Rusin9e292fc2011-04-26 23:03:42 -040056 QString text = QObject::tr("%1)&nbsp;Frame&nbsp;")
57 .arg(frame->number);
58 int binaryDataSize = frame->binaryDataSize() / 1024;
Zack Rusined40bc62011-08-28 17:11:02 -040059 if (!frame->hasState())
Zack Rusin9e292fc2011-04-26 23:03:42 -040060 return QObject::tr(
61 "<b>%1&nbsp;</b>(binary&nbsp;data&nbsp;size&nbsp;=&nbsp;%2kB)")
Zack Rusin1563a692011-04-02 02:07:24 -040062 .arg(text)
Zack Rusin9e292fc2011-04-26 23:03:42 -040063 .arg(binaryDataSize);
64 else
65 return QObject::tr(
66 "<b>%1&nbsp;(binary&nbsp;data&nbsp;size&nbsp;=&nbsp;%2kB)</b>"
67 "<br/>%3")
68 .arg(text)
69 .arg(binaryDataSize)
Zack Rusin1563a692011-04-02 02:07:24 -040070 .arg(stateText);
71 }
72 }
Zack Rusinc1acc7f2011-04-02 01:34:04 -040073 case ApiTraceModel::EventRole:
74 return QVariant::fromValue(itm);
Zack Rusin601e8372011-03-24 22:23:21 -040075 }
Zack Rusinf6667d12011-03-30 11:03:37 -040076
77 return QVariant();
Zack Rusin601e8372011-03-24 22:23:21 -040078}
79
80Qt::ItemFlags ApiTraceModel::flags(const QModelIndex &index) const
81{
82 if (!index.isValid())
83 return 0;
84
85 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
86}
87
88QVariant ApiTraceModel::headerData(int section, Qt::Orientation orientation,
89 int role ) const
90{
91 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
92 switch (section) {
93 case 0:
Zack Rusinc1acc7f2011-04-02 01:34:04 -040094 return tr("Events");
95 case 1:
96 return tr("Flags");
Zack Rusin601e8372011-03-24 22:23:21 -040097 default:
98 //fall through
99 break;
100 }
101 }
102
103 return QVariant();
104}
105
106QModelIndex ApiTraceModel::index(int row, int column,
107 const QModelIndex &parent) const
108{
Zack Rusinb56e03d2011-04-20 23:58:52 -0400109 if ((parent.isValid() && parent.column() != 0) || column != 0)
Zack Rusin601e8372011-03-24 22:23:21 -0400110 return QModelIndex();
111
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400112 ApiTraceEvent *event = item(parent);
113 if (event) {
114 if (event->type() != ApiTraceEvent::Frame) {
115 qDebug()<<"got a valid parent but it's not a frame "<<event->type();
Zack Rusinf6667d12011-03-30 11:03:37 -0400116 return QModelIndex();
117 }
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400118 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
Zack Rusin1d31b6c2011-04-26 22:30:25 -0400119 ApiTraceCall *call = frame->call(row);
Zack Rusinf6667d12011-03-30 11:03:37 -0400120 if (call)
121 return createIndex(row, column, call);
122 else
123 return QModelIndex();
124 } else {
125 ApiTraceFrame *frame = m_trace->frameAt(row);
126 if (frame)
127 return createIndex(row, column, frame);
128 else
129 return QModelIndex();
130 }
131 return QModelIndex();
Zack Rusin601e8372011-03-24 22:23:21 -0400132}
133
134bool ApiTraceModel::hasChildren(const QModelIndex &parent) const
135{
Zack Rusinf6667d12011-03-30 11:03:37 -0400136 if (parent.isValid()) {
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400137 ApiTraceEvent *event = item(parent);
138 if (event && event->type() == ApiTraceEvent::Frame) {
139 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
Zack Rusin1d31b6c2011-04-26 22:30:25 -0400140 return !frame->isEmpty();
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400141 } else
Zack Rusinf6667d12011-03-30 11:03:37 -0400142 return false;
143 } else {
144 return (rowCount() > 0);
145 }
Zack Rusin601e8372011-03-24 22:23:21 -0400146}
147
148QModelIndex ApiTraceModel::parent(const QModelIndex &index) const
149{
150 if (!index.isValid())
151 return QModelIndex();
152
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400153 ApiTraceEvent *event = item(index);
154 if (event && event->type() == ApiTraceEvent::Call) {
155 ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
Zack Rusinead6aad2011-04-15 22:16:18 -0400156 Q_ASSERT(call->parentFrame());
157 return createIndex(call->parentFrame()->number,
158 0, call->parentFrame());
Zack Rusinf6667d12011-03-30 11:03:37 -0400159 }
Zack Rusin601e8372011-03-24 22:23:21 -0400160 return QModelIndex();
161}
162
163int ApiTraceModel::rowCount(const QModelIndex &parent) const
164{
Zack Rusinf6667d12011-03-30 11:03:37 -0400165 if (!parent.isValid())
166 return m_trace->numFrames();
167
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400168 ApiTraceEvent *event = item(parent);
169 if (!event || event->type() == ApiTraceEvent::Call)
Zack Rusinf6667d12011-03-30 11:03:37 -0400170 return 0;
171
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400172 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
Zack Rusinf6667d12011-03-30 11:03:37 -0400173 if (frame)
Zack Rusin1d31b6c2011-04-26 22:30:25 -0400174 return frame->numChildren();
Zack Rusinf6667d12011-03-30 11:03:37 -0400175
176 return 0;
Zack Rusin601e8372011-03-24 22:23:21 -0400177}
178
179int ApiTraceModel::columnCount(const QModelIndex &parent) const
180{
Zack Rusinf6667d12011-03-30 11:03:37 -0400181 return 1;
Zack Rusin601e8372011-03-24 22:23:21 -0400182}
183
Zack Rusin601e8372011-03-24 22:23:21 -0400184bool ApiTraceModel::insertRows(int position, int rows,
185 const QModelIndex &parent)
186{
187 return false;
188}
189
190bool ApiTraceModel::removeRows(int position, int rows,
191 const QModelIndex &parent)
192{
193 bool success = true;
194
195 Q_UNUSED(parent);
196
Zack Rusin601e8372011-03-24 22:23:21 -0400197 beginRemoveRows(parent, position, position + rows - 1);
Zack Rusinf6667d12011-03-30 11:03:37 -0400198 //XXX remove it from ApiTrace
Zack Rusin601e8372011-03-24 22:23:21 -0400199 endRemoveRows();
200
201 return success;
202}
203
Zack Rusinf6667d12011-03-30 11:03:37 -0400204void ApiTraceModel::setApiTrace(ApiTrace *trace)
Zack Rusin601e8372011-03-24 22:23:21 -0400205{
Zack Rusinf6667d12011-03-30 11:03:37 -0400206 if (m_trace == trace)
207 return;
208 if (m_trace)
209 disconnect(m_trace);
210 m_trace = trace;
Zack Rusinca164112011-04-11 02:23:09 -0400211 connect(m_trace, SIGNAL(invalidated()),
212 this, SLOT(invalidateFrames()));
Zack Rusinf6667d12011-03-30 11:03:37 -0400213 connect(m_trace, SIGNAL(framesInvalidated()),
214 this, SLOT(invalidateFrames()));
Zack Rusinb56e03d2011-04-20 23:58:52 -0400215 connect(m_trace, SIGNAL(beginAddingFrames(int, int)),
216 this, SLOT(beginAddingFrames(int, int)));
217 connect(m_trace, SIGNAL(endAddingFrames()),
218 this, SLOT(endAddingFrames()));
Zack Rusin0ddd2502011-04-17 02:34:45 -0400219 connect(m_trace, SIGNAL(changed(ApiTraceCall*)),
220 this, SLOT(callChanged(ApiTraceCall*)));
Zack Rusinf682e192011-09-07 01:36:41 -0400221 connect(m_trace, SIGNAL(beginLoadingFrame(ApiTraceFrame*,int)),
222 this, SLOT(beginLoadingFrame(ApiTraceFrame*,int)));
223 connect(m_trace, SIGNAL(endLoadingFrame(ApiTraceFrame*)),
224 this, SLOT(endLoadingFrame(ApiTraceFrame*)));
225
Zack Rusin601e8372011-03-24 22:23:21 -0400226}
227
Zack Rusinf6667d12011-03-30 11:03:37 -0400228const ApiTrace * ApiTraceModel::apiTrace() const
Zack Rusin601e8372011-03-24 22:23:21 -0400229{
Zack Rusinf6667d12011-03-30 11:03:37 -0400230 return m_trace;
231}
Zack Rusin601e8372011-03-24 22:23:21 -0400232
Zack Rusinf6667d12011-03-30 11:03:37 -0400233void ApiTraceModel::invalidateFrames()
234{
235 beginResetModel();
236 endResetModel();
237}
Zack Rusin91065372011-03-26 01:54:10 -0400238
Zack Rusinb56e03d2011-04-20 23:58:52 -0400239void ApiTraceModel::beginAddingFrames(int oldCount, int numAdded)
Zack Rusinf6667d12011-03-30 11:03:37 -0400240{
241 beginInsertRows(QModelIndex(), oldCount,
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400242 oldCount + numAdded - 1);
Zack Rusinf6667d12011-03-30 11:03:37 -0400243}
Zack Rusin601e8372011-03-24 22:23:21 -0400244
Zack Rusinf6667d12011-03-30 11:03:37 -0400245ApiTraceEvent * ApiTraceModel::item(const QModelIndex &index) const
246{
247 if (!index.isValid())
248 return 0;
249 return static_cast<ApiTraceEvent*>(index.internalPointer());
Zack Rusin601e8372011-03-24 22:23:21 -0400250}
251
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400252void ApiTraceModel::stateSetOnEvent(ApiTraceEvent *event)
253{
254 if (!event)
255 return;
256
257 if (event->type() == ApiTraceEvent::Call) {
258 ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
Zack Rusinead6aad2011-04-15 22:16:18 -0400259 ApiTraceFrame *frame = call->parentFrame();
Zack Rusin1d31b6c2011-04-26 22:30:25 -0400260 int row = frame->callIndex(call);
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400261 QModelIndex index = createIndex(row, 0, call);
262 emit dataChanged(index, index);
263 } else if (event->type() == ApiTraceEvent::Frame) {
264 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
265 const QList<ApiTraceFrame*> frames = m_trace->frames();
266 int row = frames.indexOf(frame);
267 QModelIndex index = createIndex(row, 0, frame);
268 emit dataChanged(index, index);
269 }
270}
271
Zack Rusinc52d18a2011-04-11 00:15:07 -0400272QModelIndex ApiTraceModel::callIndex(int callNum) const
273{
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400274 ApiTraceCall *call = m_trace->callWithIndex(callNum);
Zack Rusinf54c4fc2011-04-12 23:39:13 -0400275 return indexForCall(call);
276}
Zack Rusinc52d18a2011-04-11 00:15:07 -0400277
Zack Rusinf54c4fc2011-04-12 23:39:13 -0400278QModelIndex ApiTraceModel::indexForCall(ApiTraceCall *call) const
279{
Zack Rusinc52d18a2011-04-11 00:15:07 -0400280 if (!call) {
281 return QModelIndex();
282 }
283
Zack Rusinead6aad2011-04-15 22:16:18 -0400284 ApiTraceFrame *frame = call->parentFrame();
Zack Rusinc52d18a2011-04-11 00:15:07 -0400285 Q_ASSERT(frame);
286
Zack Rusin1d31b6c2011-04-26 22:30:25 -0400287 int row = frame->callIndex(call);
Zack Rusinc52d18a2011-04-11 00:15:07 -0400288 if (row < 0) {
Zack Rusinead6aad2011-04-15 22:16:18 -0400289 qDebug() << "Couldn't find call num "<<call->index()<<" inside parent!";
Zack Rusinc52d18a2011-04-11 00:15:07 -0400290 return QModelIndex();
291 }
292 return createIndex(row, 0, call);
293}
294
Zack Rusin0ddd2502011-04-17 02:34:45 -0400295void ApiTraceModel::callChanged(ApiTraceCall *call)
296{
Zack Rusin63efea82011-04-17 17:10:45 -0400297 ApiTrace *trace = call->parentFrame()->parentTrace();
Zack Rusin9af5bff2011-04-18 01:05:50 -0400298
Zack Rusincc0b4912011-04-19 01:59:20 -0400299#if 0
Zack Rusin9af5bff2011-04-18 01:05:50 -0400300 qDebug()<<"Call changed = "<<call->edited();
Zack Rusin63efea82011-04-17 17:10:45 -0400301 qDebug()<<"\ttrace edited = "<<trace->edited();
302 qDebug()<<"\ttrace file = "<<trace->fileName();
303 qDebug()<<"\ttrace needs saving = "<<trace->needsSaving();
Zack Rusin9af5bff2011-04-18 01:05:50 -0400304#endif
305
Zack Rusinb53b1612011-04-19 01:33:58 -0400306 Q_ASSERT(trace);
307 if (trace->needsSaving())
308 trace->save();
309
Zack Rusin9af5bff2011-04-18 01:05:50 -0400310 ApiTraceFrame *frame = call->parentFrame();
Zack Rusin1d31b6c2011-04-26 22:30:25 -0400311 int row = frame->callIndex(call);
Zack Rusin9af5bff2011-04-18 01:05:50 -0400312 QModelIndex index = createIndex(row, 0, call);
313 emit dataChanged(index, index);
Zack Rusin0ddd2502011-04-17 02:34:45 -0400314}
315
Zack Rusinb56e03d2011-04-20 23:58:52 -0400316void ApiTraceModel::endAddingFrames()
317{
318 endInsertRows();
319}
320
Zack Rusin3176ebe2011-09-06 21:11:36 -0400321bool ApiTraceModel::canFetchMore(const QModelIndex &parent) const
322{
323 if (parent.isValid()) {
324 ApiTraceEvent *event = item(parent);
325 if (event && event->type() == ApiTraceEvent::Frame) {
326 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
327 return !frame->loaded() && !m_loadingFrames.contains(frame);
328 } else
329 return false;
330 } else {
331 return false;
332 }
333}
334
335void ApiTraceModel::fetchMore(const QModelIndex &parent)
336{
337 if (parent.isValid()) {
338 ApiTraceEvent *event = item(parent);
339 if (event && event->type() == ApiTraceEvent::Frame) {
340 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
341 QModelIndex index = createIndex(frame->number, 0, frame);
342
343 Q_ASSERT(!frame->loaded());
344 m_loadingFrames.insert(frame);
Zack Rusin3176ebe2011-09-06 21:11:36 -0400345
346 m_trace->loadFrame(frame);
347 }
348 }
349}
350
Zack Rusinf682e192011-09-07 01:36:41 -0400351void ApiTraceModel::beginLoadingFrame(ApiTraceFrame *frame, int numAdded)
352{
353 QModelIndex index = createIndex(frame->number, 0, frame);
354 beginInsertRows(index, 0, numAdded - 1);
355}
356
357void ApiTraceModel::endLoadingFrame(ApiTraceFrame *frame)
Zack Rusin3176ebe2011-09-06 21:11:36 -0400358{
359 QModelIndex index = createIndex(frame->number, 0, frame);
360#if 0
361 qDebug()<<"Frame loaded = "<<frame->loaded();
362 qDebug()<<"\tframe idx = "<<frame->number;
363 qDebug()<<"\tis empty = "<<frame->isEmpty();
364 qDebug()<<"\tnum children = "<<frame->numChildren();
365 qDebug()<<"\tindex is "<<index;
366#endif
367
Zack Rusin3176ebe2011-09-06 21:11:36 -0400368 endInsertRows();
369
370 emit dataChanged(index, index);
Zack Rusinf682e192011-09-07 01:36:41 -0400371
372 m_loadingFrames.remove(frame);
Zack Rusin3176ebe2011-09-06 21:11:36 -0400373}
374
Zack Rusin601e8372011-03-24 22:23:21 -0400375#include "apitracemodel.moc"