blob: 951d6ac085c006dc9eff305e9f8b34e00020c66c [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())
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);
56 QString text = frame->staticText().text();
57 if (frame->state().isEmpty())
58 return QString::fromLatin1("<b>%1</b>").arg(text);
59 else
60 return QString::fromLatin1("<b>%1</b><br/>%2")
61 .arg(text)
62 .arg(stateText);
63 }
64 }
Zack Rusinc1acc7f2011-04-02 01:34:04 -040065 case ApiTraceModel::EventRole:
66 return QVariant::fromValue(itm);
Zack Rusin601e8372011-03-24 22:23:21 -040067 }
Zack Rusinf6667d12011-03-30 11:03:37 -040068
69 return QVariant();
Zack Rusin601e8372011-03-24 22:23:21 -040070}
71
72Qt::ItemFlags ApiTraceModel::flags(const QModelIndex &index) const
73{
74 if (!index.isValid())
75 return 0;
76
77 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
78}
79
80QVariant ApiTraceModel::headerData(int section, Qt::Orientation orientation,
81 int role ) const
82{
83 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
84 switch (section) {
85 case 0:
Zack Rusinc1acc7f2011-04-02 01:34:04 -040086 return tr("Events");
87 case 1:
88 return tr("Flags");
Zack Rusin601e8372011-03-24 22:23:21 -040089 default:
90 //fall through
91 break;
92 }
93 }
94
95 return QVariant();
96}
97
98QModelIndex ApiTraceModel::index(int row, int column,
99 const QModelIndex &parent) const
100{
101 if (parent.isValid() && parent.column() != 0)
102 return QModelIndex();
103
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400104 ApiTraceEvent *event = item(parent);
105 if (event) {
106 if (event->type() != ApiTraceEvent::Frame) {
107 qDebug()<<"got a valid parent but it's not a frame "<<event->type();
Zack Rusinf6667d12011-03-30 11:03:37 -0400108 return QModelIndex();
109 }
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400110 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
Zack Rusinf6667d12011-03-30 11:03:37 -0400111 ApiTraceCall *call = frame->calls.value(row);
112 if (call)
113 return createIndex(row, column, call);
114 else
115 return QModelIndex();
116 } else {
117 ApiTraceFrame *frame = m_trace->frameAt(row);
118 if (frame)
119 return createIndex(row, column, frame);
120 else
121 return QModelIndex();
122 }
123 return QModelIndex();
Zack Rusin601e8372011-03-24 22:23:21 -0400124}
125
126bool ApiTraceModel::hasChildren(const QModelIndex &parent) const
127{
Zack Rusinf6667d12011-03-30 11:03:37 -0400128 if (parent.isValid()) {
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400129 ApiTraceEvent *event = item(parent);
130 if (event && event->type() == ApiTraceEvent::Frame) {
131 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
Zack Rusinf6667d12011-03-30 11:03:37 -0400132 return !frame->calls.isEmpty();
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400133 } else
Zack Rusinf6667d12011-03-30 11:03:37 -0400134 return false;
135 } else {
136 return (rowCount() > 0);
137 }
Zack Rusin601e8372011-03-24 22:23:21 -0400138}
139
140QModelIndex ApiTraceModel::parent(const QModelIndex &index) const
141{
142 if (!index.isValid())
143 return QModelIndex();
144
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400145 ApiTraceEvent *event = item(index);
146 if (event && event->type() == ApiTraceEvent::Call) {
147 ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
Zack Rusinead6aad2011-04-15 22:16:18 -0400148 Q_ASSERT(call->parentFrame());
149 return createIndex(call->parentFrame()->number,
150 0, call->parentFrame());
Zack Rusinf6667d12011-03-30 11:03:37 -0400151 }
Zack Rusin601e8372011-03-24 22:23:21 -0400152 return QModelIndex();
153}
154
155int ApiTraceModel::rowCount(const QModelIndex &parent) const
156{
Zack Rusinf6667d12011-03-30 11:03:37 -0400157 if (!parent.isValid())
158 return m_trace->numFrames();
159
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400160 ApiTraceEvent *event = item(parent);
161 if (!event || event->type() == ApiTraceEvent::Call)
Zack Rusinf6667d12011-03-30 11:03:37 -0400162 return 0;
163
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400164 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
Zack Rusinf6667d12011-03-30 11:03:37 -0400165 if (frame)
166 return frame->calls.count();
167
168 return 0;
Zack Rusin601e8372011-03-24 22:23:21 -0400169}
170
171int ApiTraceModel::columnCount(const QModelIndex &parent) const
172{
Zack Rusinf6667d12011-03-30 11:03:37 -0400173 return 1;
Zack Rusin601e8372011-03-24 22:23:21 -0400174}
175
Zack Rusin601e8372011-03-24 22:23:21 -0400176bool ApiTraceModel::insertRows(int position, int rows,
177 const QModelIndex &parent)
178{
179 return false;
180}
181
182bool ApiTraceModel::removeRows(int position, int rows,
183 const QModelIndex &parent)
184{
185 bool success = true;
186
187 Q_UNUSED(parent);
188
Zack Rusin601e8372011-03-24 22:23:21 -0400189 beginRemoveRows(parent, position, position + rows - 1);
Zack Rusinf6667d12011-03-30 11:03:37 -0400190 //XXX remove it from ApiTrace
Zack Rusin601e8372011-03-24 22:23:21 -0400191 endRemoveRows();
192
193 return success;
194}
195
Zack Rusinf6667d12011-03-30 11:03:37 -0400196void ApiTraceModel::setApiTrace(ApiTrace *trace)
Zack Rusin601e8372011-03-24 22:23:21 -0400197{
Zack Rusinf6667d12011-03-30 11:03:37 -0400198 if (m_trace == trace)
199 return;
200 if (m_trace)
201 disconnect(m_trace);
202 m_trace = trace;
Zack Rusinca164112011-04-11 02:23:09 -0400203 connect(m_trace, SIGNAL(invalidated()),
204 this, SLOT(invalidateFrames()));
Zack Rusinf6667d12011-03-30 11:03:37 -0400205 connect(m_trace, SIGNAL(framesInvalidated()),
206 this, SLOT(invalidateFrames()));
207 connect(m_trace, SIGNAL(framesAdded(int, int)),
208 this, SLOT(appendFrames(int, int)));
Zack Rusin0ddd2502011-04-17 02:34:45 -0400209 connect(m_trace, SIGNAL(changed(ApiTraceCall*)),
210 this, SLOT(callChanged(ApiTraceCall*)));
Zack Rusin601e8372011-03-24 22:23:21 -0400211}
212
Zack Rusinf6667d12011-03-30 11:03:37 -0400213const ApiTrace * ApiTraceModel::apiTrace() const
Zack Rusin601e8372011-03-24 22:23:21 -0400214{
Zack Rusinf6667d12011-03-30 11:03:37 -0400215 return m_trace;
216}
Zack Rusin601e8372011-03-24 22:23:21 -0400217
Zack Rusinf6667d12011-03-30 11:03:37 -0400218void ApiTraceModel::invalidateFrames()
219{
220 beginResetModel();
221 endResetModel();
222}
Zack Rusin91065372011-03-26 01:54:10 -0400223
Zack Rusinf6667d12011-03-30 11:03:37 -0400224void ApiTraceModel::appendFrames(int oldCount, int numAdded)
225{
226 beginInsertRows(QModelIndex(), oldCount,
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400227 oldCount + numAdded - 1);
Zack Rusin601e8372011-03-24 22:23:21 -0400228 endInsertRows();
Zack Rusinf6667d12011-03-30 11:03:37 -0400229}
Zack Rusin601e8372011-03-24 22:23:21 -0400230
Zack Rusinf6667d12011-03-30 11:03:37 -0400231ApiTraceEvent * ApiTraceModel::item(const QModelIndex &index) const
232{
233 if (!index.isValid())
234 return 0;
235 return static_cast<ApiTraceEvent*>(index.internalPointer());
Zack Rusin601e8372011-03-24 22:23:21 -0400236}
237
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400238void ApiTraceModel::stateSetOnEvent(ApiTraceEvent *event)
239{
240 if (!event)
241 return;
242
243 if (event->type() == ApiTraceEvent::Call) {
244 ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
Zack Rusinead6aad2011-04-15 22:16:18 -0400245 ApiTraceFrame *frame = call->parentFrame();
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400246 int row = frame->calls.indexOf(call);
247 QModelIndex index = createIndex(row, 0, call);
248 emit dataChanged(index, index);
249 } else if (event->type() == ApiTraceEvent::Frame) {
250 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
251 const QList<ApiTraceFrame*> frames = m_trace->frames();
252 int row = frames.indexOf(frame);
253 QModelIndex index = createIndex(row, 0, frame);
254 emit dataChanged(index, index);
255 }
256}
257
Zack Rusinc52d18a2011-04-11 00:15:07 -0400258QModelIndex ApiTraceModel::callIndex(int callNum) const
259{
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400260 ApiTraceCall *call = m_trace->callWithIndex(callNum);
Zack Rusinf54c4fc2011-04-12 23:39:13 -0400261 return indexForCall(call);
262}
Zack Rusinc52d18a2011-04-11 00:15:07 -0400263
Zack Rusinf54c4fc2011-04-12 23:39:13 -0400264QModelIndex ApiTraceModel::indexForCall(ApiTraceCall *call) const
265{
Zack Rusinc52d18a2011-04-11 00:15:07 -0400266 if (!call) {
267 return QModelIndex();
268 }
269
Zack Rusinead6aad2011-04-15 22:16:18 -0400270 ApiTraceFrame *frame = call->parentFrame();
Zack Rusinc52d18a2011-04-11 00:15:07 -0400271 Q_ASSERT(frame);
272
273 int row = frame->calls.indexOf(call);
274 if (row < 0) {
Zack Rusinead6aad2011-04-15 22:16:18 -0400275 qDebug() << "Couldn't find call num "<<call->index()<<" inside parent!";
Zack Rusinc52d18a2011-04-11 00:15:07 -0400276 return QModelIndex();
277 }
278 return createIndex(row, 0, call);
279}
280
Zack Rusin0ddd2502011-04-17 02:34:45 -0400281void ApiTraceModel::callChanged(ApiTraceCall *call)
282{
Zack Rusin63efea82011-04-17 17:10:45 -0400283 ApiTrace *trace = call->parentFrame()->parentTrace();
Zack Rusin9af5bff2011-04-18 01:05:50 -0400284
Zack Rusincc0b4912011-04-19 01:59:20 -0400285#if 0
Zack Rusin9af5bff2011-04-18 01:05:50 -0400286 qDebug()<<"Call changed = "<<call->edited();
Zack Rusin63efea82011-04-17 17:10:45 -0400287 qDebug()<<"\ttrace edited = "<<trace->edited();
288 qDebug()<<"\ttrace file = "<<trace->fileName();
289 qDebug()<<"\ttrace needs saving = "<<trace->needsSaving();
Zack Rusin9af5bff2011-04-18 01:05:50 -0400290#endif
291
Zack Rusinb53b1612011-04-19 01:33:58 -0400292 Q_ASSERT(trace);
293 if (trace->needsSaving())
294 trace->save();
295
Zack Rusin9af5bff2011-04-18 01:05:50 -0400296 ApiTraceFrame *frame = call->parentFrame();
297 int row = frame->calls.indexOf(call);
298 QModelIndex index = createIndex(row, 0, call);
299 emit dataChanged(index, index);
Zack Rusin0ddd2502011-04-17 02:34:45 -0400300}
301
Zack Rusin601e8372011-03-24 22:23:21 -0400302#include "apitracemodel.moc"