blob: a510c437118153b2e2da50d5ef683f2160ad5823 [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 Rusin3176ebe2011-09-06 21:11:36 -0400221 connect(m_trace, SIGNAL(frameLoaded(ApiTraceFrame*)),
222 this, SLOT(frameChanged(ApiTraceFrame*)));
Zack Rusin601e8372011-03-24 22:23:21 -0400223}
224
Zack Rusinf6667d12011-03-30 11:03:37 -0400225const ApiTrace * ApiTraceModel::apiTrace() const
Zack Rusin601e8372011-03-24 22:23:21 -0400226{
Zack Rusinf6667d12011-03-30 11:03:37 -0400227 return m_trace;
228}
Zack Rusin601e8372011-03-24 22:23:21 -0400229
Zack Rusinf6667d12011-03-30 11:03:37 -0400230void ApiTraceModel::invalidateFrames()
231{
232 beginResetModel();
233 endResetModel();
234}
Zack Rusin91065372011-03-26 01:54:10 -0400235
Zack Rusinb56e03d2011-04-20 23:58:52 -0400236void ApiTraceModel::beginAddingFrames(int oldCount, int numAdded)
Zack Rusinf6667d12011-03-30 11:03:37 -0400237{
238 beginInsertRows(QModelIndex(), oldCount,
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400239 oldCount + numAdded - 1);
Zack Rusinf6667d12011-03-30 11:03:37 -0400240}
Zack Rusin601e8372011-03-24 22:23:21 -0400241
Zack Rusinf6667d12011-03-30 11:03:37 -0400242ApiTraceEvent * ApiTraceModel::item(const QModelIndex &index) const
243{
244 if (!index.isValid())
245 return 0;
246 return static_cast<ApiTraceEvent*>(index.internalPointer());
Zack Rusin601e8372011-03-24 22:23:21 -0400247}
248
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400249void ApiTraceModel::stateSetOnEvent(ApiTraceEvent *event)
250{
251 if (!event)
252 return;
253
254 if (event->type() == ApiTraceEvent::Call) {
255 ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
Zack Rusinead6aad2011-04-15 22:16:18 -0400256 ApiTraceFrame *frame = call->parentFrame();
Zack Rusin1d31b6c2011-04-26 22:30:25 -0400257 int row = frame->callIndex(call);
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400258 QModelIndex index = createIndex(row, 0, call);
259 emit dataChanged(index, index);
260 } else if (event->type() == ApiTraceEvent::Frame) {
261 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
262 const QList<ApiTraceFrame*> frames = m_trace->frames();
263 int row = frames.indexOf(frame);
264 QModelIndex index = createIndex(row, 0, frame);
265 emit dataChanged(index, index);
266 }
267}
268
Zack Rusinc52d18a2011-04-11 00:15:07 -0400269QModelIndex ApiTraceModel::callIndex(int callNum) const
270{
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400271 ApiTraceCall *call = m_trace->callWithIndex(callNum);
Zack Rusinf54c4fc2011-04-12 23:39:13 -0400272 return indexForCall(call);
273}
Zack Rusinc52d18a2011-04-11 00:15:07 -0400274
Zack Rusinf54c4fc2011-04-12 23:39:13 -0400275QModelIndex ApiTraceModel::indexForCall(ApiTraceCall *call) const
276{
Zack Rusinc52d18a2011-04-11 00:15:07 -0400277 if (!call) {
278 return QModelIndex();
279 }
280
Zack Rusinead6aad2011-04-15 22:16:18 -0400281 ApiTraceFrame *frame = call->parentFrame();
Zack Rusinc52d18a2011-04-11 00:15:07 -0400282 Q_ASSERT(frame);
283
Zack Rusin1d31b6c2011-04-26 22:30:25 -0400284 int row = frame->callIndex(call);
Zack Rusinc52d18a2011-04-11 00:15:07 -0400285 if (row < 0) {
Zack Rusinead6aad2011-04-15 22:16:18 -0400286 qDebug() << "Couldn't find call num "<<call->index()<<" inside parent!";
Zack Rusinc52d18a2011-04-11 00:15:07 -0400287 return QModelIndex();
288 }
289 return createIndex(row, 0, call);
290}
291
Zack Rusin0ddd2502011-04-17 02:34:45 -0400292void ApiTraceModel::callChanged(ApiTraceCall *call)
293{
Zack Rusin63efea82011-04-17 17:10:45 -0400294 ApiTrace *trace = call->parentFrame()->parentTrace();
Zack Rusin9af5bff2011-04-18 01:05:50 -0400295
Zack Rusincc0b4912011-04-19 01:59:20 -0400296#if 0
Zack Rusin9af5bff2011-04-18 01:05:50 -0400297 qDebug()<<"Call changed = "<<call->edited();
Zack Rusin63efea82011-04-17 17:10:45 -0400298 qDebug()<<"\ttrace edited = "<<trace->edited();
299 qDebug()<<"\ttrace file = "<<trace->fileName();
300 qDebug()<<"\ttrace needs saving = "<<trace->needsSaving();
Zack Rusin9af5bff2011-04-18 01:05:50 -0400301#endif
302
Zack Rusinb53b1612011-04-19 01:33:58 -0400303 Q_ASSERT(trace);
304 if (trace->needsSaving())
305 trace->save();
306
Zack Rusin9af5bff2011-04-18 01:05:50 -0400307 ApiTraceFrame *frame = call->parentFrame();
Zack Rusin1d31b6c2011-04-26 22:30:25 -0400308 int row = frame->callIndex(call);
Zack Rusin9af5bff2011-04-18 01:05:50 -0400309 QModelIndex index = createIndex(row, 0, call);
310 emit dataChanged(index, index);
Zack Rusin0ddd2502011-04-17 02:34:45 -0400311}
312
Zack Rusinb56e03d2011-04-20 23:58:52 -0400313void ApiTraceModel::endAddingFrames()
314{
315 endInsertRows();
316}
317
Zack Rusin3176ebe2011-09-06 21:11:36 -0400318bool ApiTraceModel::canFetchMore(const QModelIndex &parent) const
319{
320 if (parent.isValid()) {
321 ApiTraceEvent *event = item(parent);
322 if (event && event->type() == ApiTraceEvent::Frame) {
323 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
324 return !frame->loaded() && !m_loadingFrames.contains(frame);
325 } else
326 return false;
327 } else {
328 return false;
329 }
330}
331
332void ApiTraceModel::fetchMore(const QModelIndex &parent)
333{
334 if (parent.isValid()) {
335 ApiTraceEvent *event = item(parent);
336 if (event && event->type() == ApiTraceEvent::Frame) {
337 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
338 QModelIndex index = createIndex(frame->number, 0, frame);
339
340 Q_ASSERT(!frame->loaded());
341 m_loadingFrames.insert(frame);
342 beginInsertRows(index, 0,
343 frame->numChildrenToLoad() - 1);
344
345 m_trace->loadFrame(frame);
346 }
347 }
348}
349
350void ApiTraceModel::frameChanged(ApiTraceFrame *frame)
351{
352 QModelIndex index = createIndex(frame->number, 0, frame);
353#if 0
354 qDebug()<<"Frame loaded = "<<frame->loaded();
355 qDebug()<<"\tframe idx = "<<frame->number;
356 qDebug()<<"\tis empty = "<<frame->isEmpty();
357 qDebug()<<"\tnum children = "<<frame->numChildren();
358 qDebug()<<"\tindex is "<<index;
359#endif
360
361
362 endInsertRows();
363
364 emit dataChanged(index, index);
365}
366
Zack Rusin601e8372011-03-24 22:23:21 -0400367#include "apitracemodel.moc"