]> git.cworth.org Git - apitrace/blob - gui/apitracecall.cpp
Index shouldn't be bold, plus don't newline after index in tooltips
[apitrace] / gui / apitracecall.cpp
1 #include "apitracecall.h"
2
3 #include "trace_model.hpp"
4
5 #include <QDebug>
6 #include <QObject>
7
8 ApiPointer::ApiPointer(int val)
9     : m_value(val)
10 {
11 }
12
13 QString ApiPointer::toString() const
14 {
15     if (m_value)
16         return QString("0x%1").arg(m_value, 0, 16);
17     else
18         return QLatin1String("NULL");
19 }
20
21 QString apiVariantToString(const QVariant &variant)
22 {
23     if (variant.userType() == QVariant::Double) {
24         return QString::number(variant.toFloat());
25     }
26     if (variant.userType() == QVariant::ByteArray) {
27         float kb = variant.toByteArray().size()/1024.;
28         return QObject::tr("[binary data, size = %1kb]").arg(kb);
29     }
30
31     if (variant.userType() < QVariant::UserType) {
32         return variant.toString();
33     }
34
35     if (variant.canConvert<ApiPointer>()) {
36         return variant.value<ApiPointer>().toString();
37     }
38     if (variant.canConvert<ApiBitmask>()) {
39         return variant.value<ApiBitmask>().toString();
40     }
41     if (variant.canConvert<ApiStruct>()) {
42         return variant.value<ApiStruct>().toString();
43     }
44     if (variant.canConvert<ApiArray>()) {
45         return variant.value<ApiArray>().toString();
46     }
47
48     return QString();
49 }
50
51 ApiBitmask::ApiBitmask(const Trace::Bitmask *bitmask)
52     : m_value(0)
53 {
54     init(bitmask);
55 }
56
57
58 void ApiBitmask::init(const Trace::Bitmask *bitmask)
59 {
60     if (!bitmask)
61         return;
62
63     m_value = bitmask->value;
64     for (Trace::Bitmask::Signature::const_iterator it = bitmask->sig->begin();
65          it != bitmask->sig->end(); ++it) {
66         assert(it->second);
67         QPair<QString, unsigned long long> pair;
68
69         pair.first = QString::fromStdString(it->first);
70         pair.second = it->second;
71
72         m_sig.append(pair);
73     }
74 }
75
76 QString ApiBitmask::toString() const
77 {
78     QString str;
79     unsigned long long value = m_value;
80     bool first = true;
81     for (Signature::const_iterator it = m_sig.begin();
82          value != 0 && it != m_sig.end(); ++it) {
83         Q_ASSERT(it->second);
84         if ((value & it->second) == it->second) {
85             if (!first) {
86                 str += QLatin1String(" | ");
87             }
88             str += it->first;
89             value &= ~it->second;
90             first = false;
91         }
92     }
93     if (value || first) {
94         if (!first) {
95             str += QLatin1String(" | ");
96         }
97         str += QString::fromLatin1("0x%1").arg(value, 0, 16);
98     }
99     return str;
100 }
101
102 ApiStruct::ApiStruct(const Trace::Struct *s)
103 {
104     init(s);
105 }
106
107 QString ApiStruct::toString() const
108 {
109     QString str;
110
111     str += QLatin1String("{");
112     for (unsigned i = 0; i < m_members.count(); ++i) {
113         str += m_sig.memberNames[i];
114         str += QLatin1String(" = ");
115         str += apiVariantToString(m_members[i]);
116         if (i < m_members.count() - 1)
117             str += QLatin1String(", ");
118     }
119     str += QLatin1String("}");
120
121     return str;
122 }
123
124 void ApiStruct::init(const Trace::Struct *s)
125 {
126     if (!s)
127         return;
128
129     m_sig.name = QString::fromStdString(s->sig->name);
130     for (unsigned i = 0; i < s->members.size(); ++i) {
131         VariantVisitor vis;
132         m_sig.memberNames.append(
133             QString::fromStdString(s->sig->member_names[i]));
134         s->members[i]->visit(vis);
135         m_members.append(vis.variant());
136     }
137 }
138
139 void VariantVisitor::visit(Trace::Null *)
140 {
141     m_variant = QVariant(QLatin1String("NULL"));
142 }
143
144 void VariantVisitor::visit(Trace::Bool *node)
145 {
146     m_variant = QVariant(node->value);
147 }
148
149 void VariantVisitor::visit(Trace::SInt *node)
150 {
151     m_variant = QVariant(node->value);
152 }
153
154 void VariantVisitor::visit(Trace::UInt *node)
155 {
156     m_variant = QVariant(node->value);
157 }
158
159 void VariantVisitor::visit(Trace::Float *node)
160 {
161     m_variant = QVariant(node->value);
162 }
163
164 void VariantVisitor::visit(Trace::String *node)
165 {
166     m_variant = QVariant(QString::fromStdString(node->value));
167 }
168
169 void VariantVisitor::visit(Trace::Enum *e)
170 {
171     m_variant = QVariant(QString::fromStdString(e->sig->first));
172 }
173
174 void VariantVisitor::visit(Trace::Bitmask *bitmask)
175 {
176     m_variant = QVariant::fromValue(ApiBitmask(bitmask));
177 }
178
179 void VariantVisitor::visit(Trace::Struct *str)
180 {
181     m_variant = QVariant::fromValue(ApiStruct(str));
182 }
183
184 void VariantVisitor::visit(Trace::Array *array)
185 {
186     m_variant = QVariant::fromValue(ApiArray(array));
187 }
188
189 void VariantVisitor::visit(Trace::Blob *blob)
190 {
191     QByteArray barray = QByteArray::fromRawData(blob->buf, blob->size);
192     m_variant = QVariant(barray);
193 }
194
195 void VariantVisitor::visit(Trace::Pointer *ptr)
196 {
197     m_variant = QVariant::fromValue(ApiPointer(ptr->value));
198 }
199
200 ApiArray::ApiArray(const Trace::Array *arr)
201 {
202     init(arr);
203 }
204
205 QString ApiArray::toString() const
206 {
207     QString str;
208     str += QLatin1String("[");
209     for(int i = 0; i < m_array.count(); ++i) {
210         const QVariant &var = m_array[i];
211         str += apiVariantToString(var);
212         if (i < m_array.count() - 1)
213             str += QLatin1String(", ");
214     }
215     str += QLatin1String("]");
216
217     return str;
218 }
219
220 void ApiArray::init(const Trace::Array *arr)
221 {
222     if (!arr)
223         return;
224
225     for (int i = 0; i < arr->values.size(); ++i) {
226         VariantVisitor vis;
227         arr->values[i]->visit(vis);
228
229         m_array.append(vis.variant());
230     }
231 }
232
233 QStaticText ApiTraceCall::staticText() const
234 {
235     if (!m_staticText.text().isEmpty())
236         return m_staticText;
237
238     QString richText = QString::fromLatin1("<span style=\"font-weight:bold\">%1</span>(").arg(name);
239     for (int i = 0; i < argNames.count(); ++i) {
240         richText += QLatin1String("<span style=\"color:#0000ff\">");
241         QString argText = apiVariantToString(argValues[i]);
242
243         //if arguments are really long (e.g. shader text), cut them
244         // and elide it
245         if (argText.length() > 40) {
246             QString shortened = argText.mid(0, 40);
247             shortened[argText.length() - 5] = '.';
248             shortened[argText.length() - 4] = '.';
249             shortened[argText.length() - 3] = '.';
250             shortened[argText.length() - 2] = argText[argText.length() - 2];
251             shortened[argText.length() - 1] = argText[argText.length() - 1];
252             richText += shortened;
253         } else {
254             richText += argText;
255         }
256         richText += QLatin1String("</span>");
257         if (i < argNames.count() - 1)
258             richText += QString::fromLatin1(", ");
259     }
260     richText += QLatin1String(")");
261     if (returnValue.isValid()) {
262         richText += QLatin1String(" = ");
263         richText += QLatin1String("<span style=\"color:#0000ff\">");
264         richText += apiVariantToString(returnValue);
265         richText += QLatin1String("</span>");
266     }
267
268     m_staticText.setText(richText);
269     QTextOption opt;
270     opt.setWrapMode(QTextOption::NoWrap);
271     m_staticText.setTextOption(opt);
272     m_staticText.prepare();
273
274     return m_staticText;
275 }
276
277 QString ApiTraceCall::toHtml() const
278 {
279     if (!m_richText.isEmpty())
280         return m_richText;
281
282     m_richText = QString::fromLatin1("%1) <span style=\"font-weight:bold\">%2</span>(")
283                  .arg(index)
284                  .arg(name);
285     for (int i = 0; i < argNames.count(); ++i) {
286         m_richText += argNames[i];
287         m_richText += QString::fromLatin1(" = ");
288         m_richText += QLatin1String("<span style=\"color:#0000ff\">");
289         m_richText += apiVariantToString(argValues[i]);
290         m_richText += QLatin1String("</span>");
291         if (i < argNames.count() - 1)
292             m_richText += QString::fromLatin1(", ");
293     }
294     m_richText += QLatin1String(")");
295
296     if (returnValue.isValid()) {
297         m_richText += QLatin1String(" = ");
298         m_richText += QLatin1String("<span style=\"color:#0000ff\">");
299         m_richText += apiVariantToString(returnValue);
300         m_richText += QLatin1String("</span>");
301     }
302     return m_richText;
303 }
304
305 QString ApiTraceCall::filterText() const
306 {
307     if (!m_filterText.isEmpty())
308         return m_filterText;
309
310     m_filterText = name;
311     for (int i = 0; i < argNames.count(); ++i) {
312         m_filterText += argNames[i];
313         m_filterText += QString::fromLatin1(" = ");
314         m_filterText += apiVariantToString(argValues[i]);
315         if (i < argNames.count() - 1)
316             m_filterText += QString::fromLatin1(", ");
317     }
318     m_filterText += QLatin1String(")");
319
320     if (returnValue.isValid()) {
321         m_filterText += QLatin1String(" = ");
322         m_filterText += apiVariantToString(returnValue);
323     }
324     return m_filterText;
325 }
326
327 QStaticText ApiTraceFrame::staticText() const
328 {
329     if (!m_staticText.text().isEmpty())
330         return m_staticText;
331
332     QString richText =
333         QString::fromLatin1("<span style=\"font-weight:bold\">Frame %1</span>").arg(number);
334
335     m_staticText.setText(richText);
336     QTextOption opt;
337     opt.setWrapMode(QTextOption::NoWrap);
338     m_staticText.setTextOption(opt);
339     m_staticText.prepare();
340
341     return m_staticText;
342 }
343
344 int ApiTraceCall::numChildren() const
345 {
346     return 0;
347 }
348
349 int ApiTraceFrame::numChildren() const
350 {
351     return calls.count();
352 }
353
354 ApiTraceFrame::ApiTraceFrame()
355     : ApiTraceEvent(ApiTraceEvent::Frame)
356 {
357 }
358
359 ApiTraceCall::ApiTraceCall()
360     : ApiTraceEvent(ApiTraceEvent::Call)
361 {
362 }
363
364 ApiTraceEvent::ApiTraceEvent()
365     : m_type(ApiTraceEvent::None)
366 {
367 }
368
369 ApiTraceEvent::ApiTraceEvent(Type t)
370     : m_type(t)
371 {
372 }
373
374 ApiTraceCall::~ApiTraceCall()
375 {
376 }
377
378 QVariantMap ApiTraceEvent::state() const
379 {
380     return m_state;
381 }
382
383 void ApiTraceEvent::setState(const QVariantMap &state)
384 {
385     m_state = state;
386 }