blob: 63e54cfe907720ec8ca942bf9fa3d66e258fde03 [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>")
47 .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")
51 .arg(call->index)
Zack Rusin1563a692011-04-02 02:07:24 -040052 .arg(call->name)
53 .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 Rusinf6667d12011-03-30 11:03:37 -0400148 Q_ASSERT(call->parentFrame);
149 return createIndex(call->parentFrame->number,
150 0, call->parentFrame);
151 }
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;
203 connect(m_trace, SIGNAL(framesInvalidated()),
204 this, SLOT(invalidateFrames()));
205 connect(m_trace, SIGNAL(framesAdded(int, int)),
206 this, SLOT(appendFrames(int, int)));
Zack Rusin601e8372011-03-24 22:23:21 -0400207}
208
Zack Rusinf6667d12011-03-30 11:03:37 -0400209const ApiTrace * ApiTraceModel::apiTrace() const
Zack Rusin601e8372011-03-24 22:23:21 -0400210{
Zack Rusinf6667d12011-03-30 11:03:37 -0400211 return m_trace;
212}
Zack Rusin601e8372011-03-24 22:23:21 -0400213
Zack Rusinf6667d12011-03-30 11:03:37 -0400214void ApiTraceModel::invalidateFrames()
215{
216 beginResetModel();
217 endResetModel();
218}
Zack Rusin91065372011-03-26 01:54:10 -0400219
Zack Rusinf6667d12011-03-30 11:03:37 -0400220void ApiTraceModel::appendFrames(int oldCount, int numAdded)
221{
222 beginInsertRows(QModelIndex(), oldCount,
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400223 oldCount + numAdded - 1);
Zack Rusin601e8372011-03-24 22:23:21 -0400224 endInsertRows();
Zack Rusinf6667d12011-03-30 11:03:37 -0400225}
Zack Rusin601e8372011-03-24 22:23:21 -0400226
Zack Rusinf6667d12011-03-30 11:03:37 -0400227ApiTraceEvent * ApiTraceModel::item(const QModelIndex &index) const
228{
229 if (!index.isValid())
230 return 0;
231 return static_cast<ApiTraceEvent*>(index.internalPointer());
Zack Rusin601e8372011-03-24 22:23:21 -0400232}
233
Zack Rusinc1acc7f2011-04-02 01:34:04 -0400234void ApiTraceModel::stateSetOnEvent(ApiTraceEvent *event)
235{
236 if (!event)
237 return;
238
239 if (event->type() == ApiTraceEvent::Call) {
240 ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
241 ApiTraceFrame *frame = call->parentFrame;
242 int row = frame->calls.indexOf(call);
243 QModelIndex index = createIndex(row, 0, call);
244 emit dataChanged(index, index);
245 } else if (event->type() == ApiTraceEvent::Frame) {
246 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
247 const QList<ApiTraceFrame*> frames = m_trace->frames();
248 int row = frames.indexOf(frame);
249 QModelIndex index = createIndex(row, 0, frame);
250 emit dataChanged(index, index);
251 }
252}
253
Zack Rusin601e8372011-03-24 22:23:21 -0400254#include "apitracemodel.moc"