]> git.cworth.org Git - apitrace/blob - gui/apitracemodel.cpp
A lot better data conversions.
[apitrace] / gui / apitracemodel.cpp
1 #include "apitracemodel.h"
2
3 #include "apitracecall.h"
4 #include "loaderthread.h"
5 #include "trace_parser.hpp"
6
7 #include <QDebug>
8 #include <QVariant>
9
10
11 ApiTraceModel::ApiTraceModel(QObject *parent)
12     : QAbstractItemModel(parent)
13 {
14     m_loader = new LoaderThread();
15
16     connect(m_loader, SIGNAL(parsedCalls(const QList<Trace::Call*>&)),
17             SLOT(appendCalls(const QList<Trace::Call*>&)));
18 }
19
20 ApiTraceModel::~ApiTraceModel()
21 {
22     qDeleteAll(m_calls);
23     delete m_loader;
24 }
25
26 QVariant ApiTraceModel::data(const QModelIndex &index, int role) const
27 {
28     if (!index.isValid())
29         return QVariant();
30
31     if (role != Qt::DisplayRole)
32         return QVariant();
33
34     ApiTraceCall *item = m_calls.value(index.row());
35
36     if (!item)
37         return QVariant();
38
39     switch (index.column()) {
40     case 0: {
41         QString str;
42         str += QString::number(index.row());
43         str += QLatin1String(") ");
44         str += item->name;
45         str += QLatin1String("(");
46         for (int i = 0; i < item->argNames.count(); ++i) {
47             str += item->argNames[i];
48             str += QString::fromLatin1(" = ");
49             str += apiVariantToString(item->argValues[i]);
50             if (i < item->argNames.count() - 1)
51                 str += QString::fromLatin1(", ");
52         }
53         str += QLatin1String(")");
54
55         if (item->returnValue.isValid()) {
56             str += QLatin1String(" = ");
57             str += apiVariantToString(item->returnValue);
58         }
59         return str;
60     }
61     default:
62         return QVariant();
63     }
64 }
65
66 Qt::ItemFlags ApiTraceModel::flags(const QModelIndex &index) const
67 {
68     if (!index.isValid())
69         return 0;
70
71     return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
72 }
73
74 QVariant ApiTraceModel::headerData(int section, Qt::Orientation orientation,
75                                    int role ) const
76 {
77     if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
78         switch (section) {
79         case 0:
80             return tr("Function");
81         default:
82             //fall through
83             break;
84         }
85     }
86
87     return QVariant();
88 }
89
90 QModelIndex ApiTraceModel::index(int row, int column,
91                                  const QModelIndex &parent) const
92 {
93     if (parent.isValid() && parent.column() != 0)
94         return QModelIndex();
95
96     ApiTraceCall *call = m_calls.value(row);
97
98     if (call)
99         return createIndex(row, column, call);
100     else
101         return QModelIndex();
102 }
103
104 bool ApiTraceModel::hasChildren(const QModelIndex &parent) const
105 {
106     return parent.isValid() ? false : (rowCount() > 0);
107 }
108
109 QModelIndex ApiTraceModel::parent(const QModelIndex &index) const
110 {
111     if (!index.isValid())
112         return QModelIndex();
113
114     //list for now
115     return QModelIndex();
116 }
117
118 int ApiTraceModel::rowCount(const QModelIndex &parent) const
119 {
120     return m_calls.count();
121 }
122
123 int ApiTraceModel::columnCount(const QModelIndex &parent) const
124 {
125     return parent.isValid() ? 0 : 1;
126 }
127
128
129 bool ApiTraceModel::insertRows(int position, int rows,
130                                const QModelIndex &parent)
131 {
132     return false;
133 }
134
135 bool ApiTraceModel::removeRows(int position, int rows,
136                                const QModelIndex &parent)
137 {
138     bool success = true;
139
140     Q_UNUSED(parent);
141
142     if (m_calls.count() <= position)
143         return false;
144
145     beginRemoveRows(parent, position, position + rows - 1);
146     for (int i = 0; i < rows; ++i) {
147         ApiTraceCall *call = m_calls.value(i);
148         m_calls.removeAt(i);
149         delete call;
150     }
151     endRemoveRows();
152
153     return success;
154 }
155
156 void ApiTraceModel::loadTraceFile(const QString &fileName)
157 {
158     if (m_loader->isRunning()) {
159         m_loader->terminate();
160         m_loader->wait();
161     }
162     removeRows(0, m_calls.count(), QModelIndex());
163
164     m_loader->loadFile(fileName);
165 }
166
167 void ApiTraceModel::appendCalls(const QList<Trace::Call*> traceCalls)
168 {
169     beginInsertRows(QModelIndex(), m_calls.count(),
170                     m_calls.count() + traceCalls.count());
171     foreach(Trace::Call *call, traceCalls) {
172         ApiTraceCall *apiCall = new ApiTraceCall;
173         apiCall->name = QString::fromStdString(call->sig->name);
174
175         QString argumentsText;
176         for (int i = 0; i < call->sig->arg_names.size(); ++i) {
177             apiCall->argNames +=
178                 QString::fromStdString(call->sig->arg_names[i]);
179         }
180         if (call->ret) {
181             VariantVisitor retVisitor;
182             call->ret->visit(retVisitor);
183             apiCall->returnValue = retVisitor.variant();
184         }
185         for (int i = 0; i < call->args.size(); ++i) {
186             VariantVisitor argVisitor;
187             call->args[i]->visit(argVisitor);
188             apiCall->argValues += argVisitor.variant();
189         }
190
191         m_calls.append(apiCall);
192     }
193     endInsertRows();
194
195     qDeleteAll(traceCalls);
196 }
197
198 #include "apitracemodel.moc"