1 #include "apitracemodel.h"
3 #include "apitracecall.h"
4 #include "traceloader.h"
5 #include "trace_parser.hpp"
13 ApiTraceModel::ApiTraceModel(QObject *parent)
14 : QAbstractItemModel(parent),
19 ApiTraceModel::~ApiTraceModel()
24 QVariant ApiTraceModel::data(const QModelIndex &index, int role) const
29 if (index.column() != 0)
32 ApiTraceEvent *itm = item(index);
39 return itm->staticText().text();
40 case Qt::DecorationRole:
42 case Qt::ToolTipRole: {
43 const QString stateText = tr("State info available.");
44 if (itm->type() == ApiTraceEvent::Call) {
45 ApiTraceCall *call = static_cast<ApiTraceCall*>(itm);
46 if (!call->hasState())
47 return QString::fromLatin1("%1) <b>%2</b>")
51 return QString::fromLatin1("%1) <b>%2</b><br/>%3")
56 const char *htmlTempl =
60 "<span style=\"font-weight:bold; font-size:large; vertical-align:center; padding-bottom: 30px \">\n"
63 "<div >%3 calls%4</div>\n"
67 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(itm);
68 QString thumbStr, sizeStr;
70 if (frame->hasState()) {
71 static const char *imgTempl =
72 "<img style=\"float:left;\" "
73 "src=\"data:image/png;base64,%1\"/>\n";
74 static const char *sizeTempl =
77 ApiFramebuffer fbo = frame->state()->colorBuffer();
78 QImage thumb = fbo.thumb();
79 if (!thumb.isNull()) {
82 buffer.open(QIODevice::WriteOnly);
83 thumb.save(&buffer, "PNG");
84 thumbStr = tr(imgTempl).arg(
85 QString(buffer.data().toBase64()));
88 int binaryDataSize = frame->binaryDataSize() / 1024;
89 if (binaryDataSize > 0) {
90 sizeStr = tr(sizeTempl).arg(binaryDataSize);
94 int numCalls = frame->isLoaded()
95 ? frame->numTotalCalls()
96 : frame->numChildrenToLoad();
105 case ApiTraceModel::EventRole:
106 return QVariant::fromValue(itm);
112 Qt::ItemFlags ApiTraceModel::flags(const QModelIndex &index) const
114 if (!index.isValid())
117 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
120 QVariant ApiTraceModel::headerData(int section, Qt::Orientation orientation,
123 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
138 QModelIndex ApiTraceModel::index(int row, int column,
139 const QModelIndex &parent) const
141 if ((parent.isValid() && parent.column() != 0) || column != 0)
142 return QModelIndex();
144 //qDebug()<<"At row = "<<row<<", column = "<<column<<", parent "<<parent;
145 ApiTraceEvent *parentEvent = item(parent);
147 ApiTraceEvent *event = parentEvent->eventAtRow(row);
149 Q_ASSERT(event->type() == ApiTraceEvent::Call);
150 return createIndex(row, column, event);
152 return QModelIndex();
155 ApiTraceFrame *frame = m_trace->frameAt(row);
157 return createIndex(row, column, frame);
159 return QModelIndex();
161 return QModelIndex();
164 bool ApiTraceModel::hasChildren(const QModelIndex &parent) const
166 if (parent.isValid()) {
167 ApiTraceEvent *event = item(parent);
170 if (event->type() == ApiTraceEvent::Frame) {
171 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
172 return !frame->isEmpty();
174 Q_ASSERT(event->type() == ApiTraceEvent::Call);
175 ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
176 return call->numChildren() != 0;
179 return (rowCount() > 0);
183 QModelIndex ApiTraceModel::parent(const QModelIndex &index) const
185 if (!index.isValid())
186 return QModelIndex();
188 ApiTraceEvent *event = item(index);
190 if (event->type() == ApiTraceEvent::Call) {
191 ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
193 if (call->parentCall()) {
194 ApiTraceCall *parentCall = call->parentCall();
195 ApiTraceEvent *topEvent = parentCall->parentEvent();
196 return createIndex(topEvent->callIndex(parentCall), 0, parentCall);
198 Q_ASSERT(call->parentFrame());
199 return createIndex(call->parentFrame()->number,
200 0, call->parentFrame());
203 return QModelIndex();
206 int ApiTraceModel::rowCount(const QModelIndex &parent) const
208 if (!parent.isValid())
209 return m_trace->numFrames();
211 ApiTraceEvent *event = item(parent);
215 return event->numChildren();
218 int ApiTraceModel::columnCount(const QModelIndex &parent) const
223 bool ApiTraceModel::insertRows(int position, int rows,
224 const QModelIndex &parent)
229 bool ApiTraceModel::removeRows(int position, int rows,
230 const QModelIndex &parent)
236 beginRemoveRows(parent, position, position + rows - 1);
237 //XXX remove it from ApiTrace
243 void ApiTraceModel::setApiTrace(ApiTrace *trace)
245 if (m_trace == trace)
250 connect(m_trace, SIGNAL(invalidated()),
251 this, SLOT(invalidateFrames()));
252 connect(m_trace, SIGNAL(framesInvalidated()),
253 this, SLOT(invalidateFrames()));
254 connect(m_trace, SIGNAL(beginAddingFrames(int, int)),
255 this, SLOT(beginAddingFrames(int, int)));
256 connect(m_trace, SIGNAL(endAddingFrames()),
257 this, SLOT(endAddingFrames()));
258 connect(m_trace, SIGNAL(changed(ApiTraceEvent*)),
259 this, SLOT(changed(ApiTraceEvent*)));
260 connect(m_trace, SIGNAL(beginLoadingFrame(ApiTraceFrame*,int)),
261 this, SLOT(beginLoadingFrame(ApiTraceFrame*,int)));
262 connect(m_trace, SIGNAL(endLoadingFrame(ApiTraceFrame*)),
263 this, SLOT(endLoadingFrame(ApiTraceFrame*)));
267 const ApiTrace * ApiTraceModel::apiTrace() const
272 void ApiTraceModel::invalidateFrames()
278 void ApiTraceModel::beginAddingFrames(int oldCount, int numAdded)
280 beginInsertRows(QModelIndex(), oldCount,
281 oldCount + numAdded - 1);
284 ApiTraceEvent * ApiTraceModel::item(const QModelIndex &index) const
286 if (!index.isValid())
288 return static_cast<ApiTraceEvent*>(index.internalPointer());
291 void ApiTraceModel::stateSetOnEvent(ApiTraceEvent *event)
296 if (event->type() == ApiTraceEvent::Call) {
297 ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
298 QModelIndex index = indexForCall(call);
299 emit dataChanged(index, index);
300 } else if (event->type() == ApiTraceEvent::Frame) {
301 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
302 const QList<ApiTraceFrame*> & frames = m_trace->frames();
303 int row = frames.indexOf(frame);
304 QModelIndex index = createIndex(row, 0, frame);
305 emit dataChanged(index, index);
309 QModelIndex ApiTraceModel::indexForCall(ApiTraceCall *call) const
312 return QModelIndex();
315 ApiTraceEvent *parentEvent = call->parentEvent();
316 Q_ASSERT(parentEvent);
318 int row = parentEvent->callIndex(call);
320 qDebug() << "Couldn't find call num "<<call->index()<<" inside parent!";
321 return QModelIndex();
323 return createIndex(row, 0, call);
326 void ApiTraceModel::changed(ApiTraceEvent *event)
328 if (event->type() == ApiTraceEvent::Call) {
329 callChanged(static_cast<ApiTraceCall*>(event));
330 } else if (event->type() == ApiTraceEvent::Frame) {
331 frameChanged(static_cast<ApiTraceFrame*>(event));
335 void ApiTraceModel::callChanged(ApiTraceCall *call)
337 ApiTrace *trace = call->parentFrame()->parentTrace();
340 qDebug()<<"Call changed = "<<call->edited();
341 qDebug()<<"\ttrace edited = "<<trace->edited();
342 qDebug()<<"\ttrace file = "<<trace->fileName();
343 qDebug()<<"\ttrace needs saving = "<<trace->needsSaving();
347 if (trace->needsSaving())
350 QModelIndex index = indexForCall(call);
351 emit dataChanged(index, index);
354 void ApiTraceModel::frameChanged(ApiTraceFrame *frame)
356 const QList<ApiTraceFrame*> & frames = m_trace->frames();
357 int row = frames.indexOf(frame);
358 QModelIndex index = createIndex(row, 0, frame);
359 emit dataChanged(index, index);
362 void ApiTraceModel::endAddingFrames()
367 bool ApiTraceModel::canFetchMore(const QModelIndex &parent) const
369 if (parent.isValid()) {
370 ApiTraceEvent *event = item(parent);
371 if (event && event->type() == ApiTraceEvent::Frame) {
372 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
373 return !frame->isLoaded() && !m_loadingFrames.contains(frame);
381 void ApiTraceModel::fetchMore(const QModelIndex &parent)
383 if (parent.isValid()) {
384 ApiTraceEvent *event = item(parent);
385 if (event && event->type() == ApiTraceEvent::Frame) {
386 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
387 QModelIndex index = createIndex(frame->number, 0, frame);
389 Q_ASSERT(!frame->isLoaded());
390 m_loadingFrames.insert(frame);
392 m_trace->loadFrame(frame);
397 void ApiTraceModel::beginLoadingFrame(ApiTraceFrame *frame, int numAdded)
399 QModelIndex index = createIndex(frame->number, 0, frame);
400 beginInsertRows(index, 0, numAdded - 1);
403 void ApiTraceModel::endLoadingFrame(ApiTraceFrame *frame)
405 QModelIndex index = createIndex(frame->number, 0, frame);
407 qDebug()<<"Frame loaded = "<<frame->loaded();
408 qDebug()<<"\tframe idx = "<<frame->number;
409 qDebug()<<"\tis empty = "<<frame->isEmpty();
410 qDebug()<<"\tnum children = "<<frame->numChildren();
411 qDebug()<<"\tindex is "<<index;
416 emit dataChanged(index, index);
418 m_loadingFrames.remove(frame);
421 #include "apitracemodel.moc"