]> git.cworth.org Git - apitrace/blob - gui/apitracemodel.cpp
Cleanup the event model code.
[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 <QImage>
9 #include <QVariant>
10
11
12 ApiTraceModel::ApiTraceModel(QObject *parent)
13     : QAbstractItemModel(parent),
14       m_trace(0)
15 {
16 }
17
18 ApiTraceModel::~ApiTraceModel()
19 {
20     m_trace = 0;
21 }
22
23 QVariant ApiTraceModel::data(const QModelIndex &index, int role) const
24 {
25     if (!index.isValid())
26         return QVariant();
27
28     if (index.column() != 0)
29         return QVariant();
30
31     ApiTraceEvent *itm = item(index);
32     if (!itm) {
33         return QVariant();
34     }
35
36     switch (role) {
37     case Qt::DisplayRole:
38         return itm->staticText().text();
39     case Qt::DecorationRole:
40         return QImage();
41     case ApiTraceModel::EventRole:
42         return QVariant::fromValue(itm);
43     }
44
45     return QVariant();
46 }
47
48 Qt::ItemFlags ApiTraceModel::flags(const QModelIndex &index) const
49 {
50     if (!index.isValid())
51         return 0;
52
53     return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
54 }
55
56 QVariant ApiTraceModel::headerData(int section, Qt::Orientation orientation,
57                                    int role ) const
58 {
59     if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
60         switch (section) {
61         case 0:
62             return tr("Events");
63         case 1:
64             return tr("Flags");
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     ApiTraceEvent *event = item(parent);
81     if (event) {
82         if (event->type() != ApiTraceEvent::Frame) {
83             qDebug()<<"got a valid parent but it's not a frame "<<event->type();
84             return QModelIndex();
85         }
86         ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
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         ApiTraceEvent *event = item(parent);
106         if (event && event->type() == ApiTraceEvent::Frame) {
107             ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
108             return !frame->calls.isEmpty();
109         } else
110             return false;
111     } else {
112         return (rowCount() > 0);
113     }
114 }
115
116 QModelIndex ApiTraceModel::parent(const QModelIndex &index) const
117 {
118     if (!index.isValid())
119         return QModelIndex();
120
121     ApiTraceEvent *event = item(index);
122     if (event && event->type() == ApiTraceEvent::Call) {
123         ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
124         Q_ASSERT(call->parentFrame);
125         return createIndex(call->parentFrame->number,
126                            0, call->parentFrame);
127     }
128     return QModelIndex();
129 }
130
131 int ApiTraceModel::rowCount(const QModelIndex &parent) const
132 {
133     if (!parent.isValid())
134         return m_trace->numFrames();
135
136     ApiTraceEvent *event = item(parent);
137     if (!event || event->type() == ApiTraceEvent::Call)
138         return 0;
139
140     ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
141     if (frame)
142         return frame->calls.count();
143
144     return 0;
145 }
146
147 int ApiTraceModel::columnCount(const QModelIndex &parent) const
148 {
149     return 1;
150 }
151
152 bool ApiTraceModel::insertRows(int position, int rows,
153                                const QModelIndex &parent)
154 {
155     return false;
156 }
157
158 bool ApiTraceModel::removeRows(int position, int rows,
159                                const QModelIndex &parent)
160 {
161     bool success = true;
162
163     Q_UNUSED(parent);
164
165     beginRemoveRows(parent, position, position + rows - 1);
166     //XXX remove it from ApiTrace
167     endRemoveRows();
168
169     return success;
170 }
171
172 void ApiTraceModel::setApiTrace(ApiTrace *trace)
173 {
174     if (m_trace == trace)
175         return;
176     if (m_trace)
177         disconnect(m_trace);
178     m_trace = trace;
179     connect(m_trace, SIGNAL(framesInvalidated()),
180             this, SLOT(invalidateFrames()));
181     connect(m_trace, SIGNAL(framesAdded(int, int)),
182             this, SLOT(appendFrames(int, int)));
183 }
184
185 const ApiTrace * ApiTraceModel::apiTrace() const
186 {
187     return m_trace;
188 }
189
190 void ApiTraceModel::invalidateFrames()
191 {
192     beginResetModel();
193     endResetModel();
194 }
195
196 void ApiTraceModel::appendFrames(int oldCount, int numAdded)
197 {
198     beginInsertRows(QModelIndex(), oldCount,
199                     oldCount + numAdded - 1);
200     endInsertRows();
201 }
202
203 ApiTraceEvent * ApiTraceModel::item(const QModelIndex &index) const
204 {
205     if (!index.isValid())
206         return 0;
207     return static_cast<ApiTraceEvent*>(index.internalPointer());
208 }
209
210 void ApiTraceModel::stateSetOnEvent(ApiTraceEvent *event)
211 {
212     if (!event)
213         return;
214
215     if (event->type() == ApiTraceEvent::Call) {
216         ApiTraceCall *call = static_cast<ApiTraceCall*>(event);
217         ApiTraceFrame *frame = call->parentFrame;
218         int row = frame->calls.indexOf(call);
219         QModelIndex index = createIndex(row, 0, call);
220         emit dataChanged(index, index);
221     } else if (event->type() == ApiTraceEvent::Frame) {
222         ApiTraceFrame *frame = static_cast<ApiTraceFrame*>(event);
223         const QList<ApiTraceFrame*> frames = m_trace->frames();
224         int row = frames.indexOf(frame);
225         QModelIndex index = createIndex(row, 0, frame);
226         emit dataChanged(index, index);
227     }
228 }
229
230 #include "apitracemodel.moc"