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->numChildren()
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 ApiTraceEvent *event = item(parent);
146 if (event->type() != ApiTraceEvent::Frame) {
147 qDebug()<<"got a valid parent but it's not a frame "<<event->type();
148 return QModelIndex();
150 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
151 ApiTraceCall *call = frame->call(row);
153 return createIndex(row, column, call);
155 return QModelIndex();
157 ApiTraceFrame *frame = m_trace->frameAt(row);
159 return createIndex(row, column, frame);
161 return QModelIndex();
163 return QModelIndex();
166 bool ApiTraceModel::hasChildren(const QModelIndex &parent) const
168 if (parent.isValid()) {
169 ApiTraceEvent *event = item(parent);
170 if (event && event->type() == ApiTraceEvent::Frame) {
171 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
172 return !frame->isEmpty();
176 return (rowCount() > 0);
180 QModelIndex ApiTraceModel::parent(const QModelIndex &index) const
182 if (!index.isValid())
183 return QModelIndex();
185 ApiTraceEvent *event = item(index);
186 if (event && event->type() == ApiTraceEvent::Call) {
187 ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
188 Q_ASSERT(call->parentFrame());
189 return createIndex(call->parentFrame()->number,
190 0, call->parentFrame());
192 return QModelIndex();
195 int ApiTraceModel::rowCount(const QModelIndex &parent) const
197 if (!parent.isValid())
198 return m_trace->numFrames();
200 ApiTraceEvent *event = item(parent);
201 if (!event || event->type() == ApiTraceEvent::Call)
204 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
206 return frame->numChildren();
211 int ApiTraceModel::columnCount(const QModelIndex &parent) const
216 bool ApiTraceModel::insertRows(int position, int rows,
217 const QModelIndex &parent)
222 bool ApiTraceModel::removeRows(int position, int rows,
223 const QModelIndex &parent)
229 beginRemoveRows(parent, position, position + rows - 1);
230 //XXX remove it from ApiTrace
236 void ApiTraceModel::setApiTrace(ApiTrace *trace)
238 if (m_trace == trace)
243 connect(m_trace, SIGNAL(invalidated()),
244 this, SLOT(invalidateFrames()));
245 connect(m_trace, SIGNAL(framesInvalidated()),
246 this, SLOT(invalidateFrames()));
247 connect(m_trace, SIGNAL(beginAddingFrames(int, int)),
248 this, SLOT(beginAddingFrames(int, int)));
249 connect(m_trace, SIGNAL(endAddingFrames()),
250 this, SLOT(endAddingFrames()));
251 connect(m_trace, SIGNAL(changed(ApiTraceCall*)),
252 this, SLOT(callChanged(ApiTraceCall*)));
253 connect(m_trace, SIGNAL(beginLoadingFrame(ApiTraceFrame*,int)),
254 this, SLOT(beginLoadingFrame(ApiTraceFrame*,int)));
255 connect(m_trace, SIGNAL(endLoadingFrame(ApiTraceFrame*)),
256 this, SLOT(endLoadingFrame(ApiTraceFrame*)));
260 const ApiTrace * ApiTraceModel::apiTrace() const
265 void ApiTraceModel::invalidateFrames()
271 void ApiTraceModel::beginAddingFrames(int oldCount, int numAdded)
273 beginInsertRows(QModelIndex(), oldCount,
274 oldCount + numAdded - 1);
277 ApiTraceEvent * ApiTraceModel::item(const QModelIndex &index) const
279 if (!index.isValid())
281 return static_cast<ApiTraceEvent*>(index.internalPointer());
284 void ApiTraceModel::stateSetOnEvent(ApiTraceEvent *event)
289 if (event->type() == ApiTraceEvent::Call) {
290 ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
291 ApiTraceFrame *frame = call->parentFrame();
292 int row = frame->callIndex(call);
293 QModelIndex index = createIndex(row, 0, call);
294 emit dataChanged(index, index);
295 } else if (event->type() == ApiTraceEvent::Frame) {
296 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
297 const QList<ApiTraceFrame*> frames = m_trace->frames();
298 int row = frames.indexOf(frame);
299 QModelIndex index = createIndex(row, 0, frame);
300 emit dataChanged(index, index);
304 QModelIndex ApiTraceModel::indexForCall(ApiTraceCall *call) const
307 return QModelIndex();
310 ApiTraceFrame *frame = call->parentFrame();
313 int row = frame->callIndex(call);
315 qDebug() << "Couldn't find call num "<<call->index()<<" inside parent!";
316 return QModelIndex();
318 return createIndex(row, 0, call);
321 void ApiTraceModel::callChanged(ApiTraceCall *call)
323 ApiTrace *trace = call->parentFrame()->parentTrace();
326 qDebug()<<"Call changed = "<<call->edited();
327 qDebug()<<"\ttrace edited = "<<trace->edited();
328 qDebug()<<"\ttrace file = "<<trace->fileName();
329 qDebug()<<"\ttrace needs saving = "<<trace->needsSaving();
333 if (trace->needsSaving())
336 ApiTraceFrame *frame = call->parentFrame();
337 int row = frame->callIndex(call);
338 QModelIndex index = createIndex(row, 0, call);
339 emit dataChanged(index, index);
342 void ApiTraceModel::endAddingFrames()
347 bool ApiTraceModel::canFetchMore(const QModelIndex &parent) const
349 if (parent.isValid()) {
350 ApiTraceEvent *event = item(parent);
351 if (event && event->type() == ApiTraceEvent::Frame) {
352 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
353 return !frame->isLoaded() && !m_loadingFrames.contains(frame);
361 void ApiTraceModel::fetchMore(const QModelIndex &parent)
363 if (parent.isValid()) {
364 ApiTraceEvent *event = item(parent);
365 if (event && event->type() == ApiTraceEvent::Frame) {
366 ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
367 QModelIndex index = createIndex(frame->number, 0, frame);
369 Q_ASSERT(!frame->isLoaded());
370 m_loadingFrames.insert(frame);
372 m_trace->loadFrame(frame);
377 void ApiTraceModel::beginLoadingFrame(ApiTraceFrame *frame, int numAdded)
379 QModelIndex index = createIndex(frame->number, 0, frame);
380 beginInsertRows(index, 0, numAdded - 1);
383 void ApiTraceModel::endLoadingFrame(ApiTraceFrame *frame)
385 QModelIndex index = createIndex(frame->number, 0, frame);
387 qDebug()<<"Frame loaded = "<<frame->loaded();
388 qDebug()<<"\tframe idx = "<<frame->number;
389 qDebug()<<"\tis empty = "<<frame->isEmpty();
390 qDebug()<<"\tnum children = "<<frame->numChildren();
391 qDebug()<<"\tindex is "<<index;
396 emit dataChanged(index, index);
398 m_loadingFrames.remove(frame);
401 #include "apitracemodel.moc"