]> git.cworth.org Git - apitrace/blob - gui/apitracemodel.cpp
Introduce ApiTrace which encapsulates the data.
[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       m_trace(0)
14 {
15 }
16
17 ApiTraceModel::~ApiTraceModel()
18 {
19     m_trace = 0;
20 }
21
22 QVariant ApiTraceModel::data(const QModelIndex &index, int role) const
23 {
24     if (!index.isValid())
25         return QVariant();
26
27     if (role != Qt::DisplayRole)
28         return QVariant();
29
30     //data only in the first column
31     if (index.column() != 0)
32         return QVariant();
33
34     ApiTraceEvent *itm = item(index);
35     if (itm) {
36         if (itm->type() == ApiTraceEvent::Frame) {
37             ApiTraceFrame *frame =
38                 static_cast<ApiTraceFrame *>(itm);
39             return QVariant::fromValue(frame);
40         } else if (itm->type() == ApiTraceEvent::Call) {
41             ApiTraceCall *call =
42                 static_cast<ApiTraceCall *>(itm);
43             return QVariant::fromValue(call);
44         }
45     }
46
47     return QVariant();
48 }
49
50 Qt::ItemFlags ApiTraceModel::flags(const QModelIndex &index) const
51 {
52     if (!index.isValid())
53         return 0;
54
55     return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
56 }
57
58 QVariant ApiTraceModel::headerData(int section, Qt::Orientation orientation,
59                                    int role ) const
60 {
61     if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
62         switch (section) {
63         case 0:
64             return tr("Event");
65         default:
66             //fall through
67             break;
68         }
69     }
70
71     return QVariant();
72 }
73
74 QModelIndex ApiTraceModel::index(int row, int column,
75                                  const QModelIndex &parent) const
76 {
77     if (parent.isValid() && parent.column() != 0)
78         return QModelIndex();
79
80     if (parent.isValid()) {
81         QVariant data = parent.data();
82         ApiTraceFrame *frame = data.value<ApiTraceFrame*>();
83         if (!frame) {
84             qDebug()<<"got a valid parent but it's not a frame "<<data;
85             return QModelIndex();
86         }
87         ApiTraceCall *call = frame->calls.value(row);
88         if (call)
89             return createIndex(row, column, call);
90         else
91             return QModelIndex();
92     } else {
93         ApiTraceFrame *frame = m_trace->frameAt(row);
94         if (frame)
95             return createIndex(row, column, frame);
96         else
97             return QModelIndex();
98     }
99     return QModelIndex();
100 }
101
102 bool ApiTraceModel::hasChildren(const QModelIndex &parent) const
103 {
104     if (parent.isValid()) {
105         ApiTraceFrame *frame = parent.data().value<ApiTraceFrame*>();
106         if (frame)
107             return !frame->calls.isEmpty();
108         else
109             return false;
110     } else {
111         return (rowCount() > 0);
112     }
113 }
114
115 QModelIndex ApiTraceModel::parent(const QModelIndex &index) const
116 {
117     if (!index.isValid())
118         return QModelIndex();
119
120     ApiTraceCall *call = index.data().value<ApiTraceCall*>();
121     if (call) {
122         Q_ASSERT(call->parentFrame);
123         return createIndex(call->parentFrame->number,
124                            0, call->parentFrame);
125     }
126     return QModelIndex();
127 }
128
129 int ApiTraceModel::rowCount(const QModelIndex &parent) const
130 {
131     if (!parent.isValid())
132         return m_trace->numFrames();
133
134     ApiTraceCall *call = parent.data().value<ApiTraceCall*>();
135     if (call)
136         return 0;
137
138     ApiTraceFrame *frame = parent.data().value<ApiTraceFrame*>();
139     if (frame)
140         return frame->calls.count();
141
142     return 0;
143 }
144
145 int ApiTraceModel::columnCount(const QModelIndex &parent) const
146 {
147     return 1;
148 }
149
150
151 bool ApiTraceModel::insertRows(int position, int rows,
152                                const QModelIndex &parent)
153 {
154     return false;
155 }
156
157 bool ApiTraceModel::removeRows(int position, int rows,
158                                const QModelIndex &parent)
159 {
160     bool success = true;
161
162     Q_UNUSED(parent);
163
164     beginRemoveRows(parent, position, position + rows - 1);
165     //XXX remove it from ApiTrace
166     endRemoveRows();
167
168     return success;
169 }
170
171 void ApiTraceModel::setApiTrace(ApiTrace *trace)
172 {
173     if (m_trace == trace)
174         return;
175     if (m_trace)
176         disconnect(m_trace);
177     m_trace = trace;
178     connect(m_trace, SIGNAL(framesInvalidated()),
179             this, SLOT(invalidateFrames()));
180     connect(m_trace, SIGNAL(framesAdded(int, int)),
181             this, SLOT(appendFrames(int, int)));
182 }
183
184 const ApiTrace * ApiTraceModel::apiTrace() const
185 {
186     return m_trace;
187 }
188
189 void ApiTraceModel::invalidateFrames()
190 {
191     beginResetModel();
192     endResetModel();
193 }
194
195 void ApiTraceModel::appendFrames(int oldCount, int numAdded)
196 {
197     beginInsertRows(QModelIndex(), oldCount,
198                     oldCount + numAdded);
199     endInsertRows();
200 }
201
202 ApiTraceEvent * ApiTraceModel::item(const QModelIndex &index) const
203 {
204     if (!index.isValid())
205         return 0;
206     return static_cast<ApiTraceEvent*>(index.internalPointer());
207 }
208
209 #include "apitracemodel.moc"