1 #include "apitracemodel.h"
3 #include "apitracecall.h"
4 #include "loaderthread.h"
5 #include "trace_parser.hpp"
9 class VariantVisitor : public Trace::Visitor
12 virtual void visit(Trace::Null *)
16 virtual void visit(Trace::Bool *node)
18 m_variant = QVariant(node->value);
20 virtual void visit(Trace::SInt *node)
22 m_variant = QVariant(node->value);
24 virtual void visit(Trace::UInt *node)
26 m_variant = QVariant(node->value);
28 virtual void visit(Trace::Float *node)
30 m_variant = QVariant(node->value);
32 virtual void visit(Trace::String *node)
34 m_variant = QVariant(QString::fromStdString(node->value));
36 virtual void visit(Trace::Enum *e)
38 m_variant = QVariant(QString::fromStdString(e->sig->first));
40 virtual void visit(Trace::Bitmask *bitmask)
42 //XXX we should probably convert it to QImage
43 visit(static_cast<Trace::UInt *>(bitmask));
45 virtual void visit(Trace::Struct *str)
47 //XXX: need a custom QVariant type for this one
49 for (int i = 0; i < str->members.size(); ++i) {
51 str->members[i]->visit(vst);
52 lst.append(vst.variant());
54 m_variant = QVariant(lst);
56 virtual void visit(Trace::Array *array)
59 for (int i = 0; i < array->values.size(); ++i) {
61 array->values[i]->visit(vst);
62 lst.append(vst.variant());
64 m_variant = QVariant(lst);
66 virtual void visit(Trace::Blob *blob)
68 QByteArray barray = QByteArray::fromRawData(blob->buf, blob->size);
69 m_variant = QVariant(barray);
71 virtual void visit(Trace::Pointer *ptr)
73 m_variant = QVariant(ptr->value);
76 QVariant variant() const
84 ApiTraceModel::ApiTraceModel(QObject *parent)
85 : QAbstractItemModel(parent)
87 m_loader = new LoaderThread();
88 connect(m_loader, SIGNAL(parsedCalls(const QList<Trace::Call*>&)),
89 SLOT(appendCalls(const QList<Trace::Call*>&)));
92 ApiTraceModel::~ApiTraceModel()
98 QVariant ApiTraceModel::data(const QModelIndex &index, int role) const
100 if (!index.isValid())
103 if (role != Qt::DisplayRole)
106 ApiTraceCall *item = m_calls.value(index.row());
111 switch (index.column()) {
116 for (int i = 0; i < item->argNames.count(); ++i) {
117 str += item->argNames[i];
118 str += QString::fromLatin1(" = ");
119 str += item->argValues[i].toString();
120 if (i < item->argNames.count() - 1)
121 str += QString::fromLatin1(", ");
126 return item->returnValue.toString();
132 Qt::ItemFlags ApiTraceModel::flags(const QModelIndex &index) const
134 if (!index.isValid())
137 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
140 QVariant ApiTraceModel::headerData(int section, Qt::Orientation orientation,
143 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
146 return tr("Function");
148 return tr("Arguments");
160 QModelIndex ApiTraceModel::index(int row, int column,
161 const QModelIndex &parent) const
163 if (parent.isValid() && parent.column() != 0)
164 return QModelIndex();
166 ApiTraceCall *call = m_calls.value(row);
169 return createIndex(row, column, call);
171 return QModelIndex();
174 bool ApiTraceModel::hasChildren(const QModelIndex &parent) const
176 return parent.isValid() ? false : (rowCount() > 0);
179 QModelIndex ApiTraceModel::parent(const QModelIndex &index) const
181 if (!index.isValid())
182 return QModelIndex();
185 return QModelIndex();
188 int ApiTraceModel::rowCount(const QModelIndex &parent) const
190 return m_calls.count();
193 int ApiTraceModel::columnCount(const QModelIndex &parent) const
195 return parent.isValid() ? 0 : 3;
199 bool ApiTraceModel::insertRows(int position, int rows,
200 const QModelIndex &parent)
205 bool ApiTraceModel::removeRows(int position, int rows,
206 const QModelIndex &parent)
212 if (m_calls.count() <= position)
215 beginRemoveRows(parent, position, position + rows - 1);
216 for (int i = 0; i < rows; ++i) {
217 ApiTraceCall *call = m_calls.value(i);
226 void ApiTraceModel::loadTraceFile(const QString &fileName)
228 if (m_loader->isRunning()) {
229 m_loader->terminate();
232 removeRows(0, m_calls.count(), QModelIndex());
234 m_loader->loadFile(fileName);
237 void ApiTraceModel::appendCalls(const QList<Trace::Call*> traceCalls)
239 beginInsertRows(QModelIndex(), m_calls.count(),
240 m_calls.count() + traceCalls.count());
241 foreach(Trace::Call *call, traceCalls) {
242 ApiTraceCall *apiCall = new ApiTraceCall;
243 apiCall->name = QString::fromStdString(call->sig->name);
245 QString argumentsText;
246 for (int i = 0; i < call->sig->arg_names.size(); ++i) {
248 QString::fromStdString(call->sig->arg_names[i]);
250 VariantVisitor retVisitor;
252 call->ret->visit(retVisitor);
253 apiCall->returnValue = retVisitor.variant();
255 for (int i = 0; i < call->args.size(); ++i) {
256 VariantVisitor argVisitor;
257 call->args[i]->visit(argVisitor);
258 apiCall->argValues += argVisitor.variant();
260 m_calls.append(apiCall);
264 qDeleteAll(traceCalls);
267 #include "apitracemodel.moc"