blob: 5f2d9765df1cc44d045703b955c852d6a9ded406 [file] [log] [blame]
Zack Rusin91065372011-03-26 01:54:10 -04001#include "apitracecall.h"
2
Zack Rusin661842d2011-04-17 01:59:16 -04003#include "apitrace.h"
Zack Rusinebf971e2011-09-06 17:44:43 -04004#include "traceloader.h"
Zack Rusin91065372011-03-26 01:54:10 -04005#include "trace_model.hpp"
6
7#include <QDebug>
Zack Rusin9e292fc2011-04-26 23:03:42 -04008#include <QLocale>
Zack Rusin35451522011-04-02 23:44:53 -04009#include <QObject>
Zack Rusin5e277b02011-04-16 21:52:26 -040010#define QT_USE_FAST_OPERATOR_PLUS
11#include <QStringBuilder>
José Fonsecae8a1aa92011-04-21 09:13:23 +010012#include <QTextDocument>
Zack Rusin91065372011-03-26 01:54:10 -040013
Zack Rusinb53b1612011-04-19 01:33:58 -040014const char * const styleSheet =
15 ".call {\n"
16 " font-weight:bold;\n"
17 // text shadow looks great but doesn't work well in qtwebkit 4.7
18 " /*text-shadow: 0px 2px 3px #555;*/\n"
19 " font-size: 1.2em;\n"
20 "}\n"
21 ".arg-name {\n"
22 " border: 1px solid rgb(238,206,0);\n"
23 " border-radius: 4px;\n"
24 " background: yellow;\n"
25 " padding: 2px;\n"
26 " box-shadow: 0px 1px 3px dimgrey;\n"
27 " -webkit-transition: background 1s linear;\n"
28 "}\n"
29 ".arg-name:hover {\n"
30 " background: white;\n"
31 "}\n"
32 ".arg-value {\n"
33 " color: #0000ff;\n"
34 "}\n"
35 ".error {\n"
Zack Rusincc0b4912011-04-19 01:59:20 -040036 " border: 1px solid rgb(255,0,0);\n"
Zack Rusinb53b1612011-04-19 01:33:58 -040037 " margin: 10px;\n"
Zack Rusincc0b4912011-04-19 01:59:20 -040038 " padding: 1;\n"
39 " border-radius: 4px;\n"
40 // also looks great but qtwebkit doesn't support it
41 //" background: #6fb2e5;\n"
42 //" box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
43 //" -o-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
44 //" -webkit-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
45 //" -moz-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n"
Zack Rusinb53b1612011-04-19 01:33:58 -040046 "}\n";
47
Zack Rusin91065372011-03-26 01:54:10 -040048
José Fonsecae8a1aa92011-04-21 09:13:23 +010049// Qt::convertFromPlainText doesn't do precisely what we want
50static QString
51plainTextToHTML(const QString & plain, bool multiLine)
52{
53 int col = 0;
54 bool quote = false;
55 QString rich;
56 for (int i = 0; i < plain.length(); ++i) {
57 if (plain[i] == QLatin1Char('\n')){
58 if (multiLine) {
59 rich += QLatin1String("<br>\n");
60 } else {
61 rich += QLatin1String("\\n");
62 }
63 col = 0;
64 quote = true;
65 } else {
66 if (plain[i] == QLatin1Char('\t')){
67 if (multiLine) {
68 rich += QChar(0x00a0U);
69 ++col;
70 while (col % 8) {
71 rich += QChar(0x00a0U);
72 ++col;
73 }
74 } else {
75 rich += QLatin1String("\\t");
76 }
77 quote = true;
78 } else if (plain[i].isSpace()) {
79 rich += QChar(0x00a0U);
80 quote = true;
81 } else if (plain[i] == QLatin1Char('<')) {
82 rich += QLatin1String("&lt;");
83 } else if (plain[i] == QLatin1Char('>')) {
84 rich += QLatin1String("&gt;");
85 } else if (plain[i] == QLatin1Char('&')) {
86 rich += QLatin1String("&amp;");
87 } else {
88 rich += plain[i];
89 }
90 ++col;
91 }
92 }
93
94 if (quote) {
95 return QLatin1Literal("\"") + rich + QLatin1Literal("\"");
96 }
97
98 return rich;
99}
100
Zack Rusina1a3ad52011-08-27 19:19:18 -0400101QString
102apiVariantToString(const QVariant &variant, bool multiLine)
Zack Rusin91065372011-03-26 01:54:10 -0400103{
José Fonseca1fa61832011-11-05 08:50:25 +0000104 if (variant.isNull()) {
105 return QLatin1String("?");
106 }
107
Zack Rusin91065372011-03-26 01:54:10 -0400108 if (variant.userType() == QVariant::Double) {
109 return QString::number(variant.toFloat());
110 }
Zack Rusin35451522011-04-02 23:44:53 -0400111 if (variant.userType() == QVariant::ByteArray) {
Zack Rusin8e7a4ff2011-04-07 01:15:48 -0400112 if (variant.toByteArray().size() < 1024) {
113 int bytes = variant.toByteArray().size();
114 return QObject::tr("[binary data, size = %1 bytes]").arg(bytes);
115 } else {
116 float kb = variant.toByteArray().size()/1024.;
117 return QObject::tr("[binary data, size = %1 kb]").arg(kb);
118 }
Zack Rusin35451522011-04-02 23:44:53 -0400119 }
Zack Rusin91065372011-03-26 01:54:10 -0400120
José Fonsecae8a1aa92011-04-21 09:13:23 +0100121 if (variant.userType() == QVariant::String) {
122 return plainTextToHTML(variant.toString(), multiLine);
123 }
124
Zack Rusin91065372011-03-26 01:54:10 -0400125 if (variant.userType() < QVariant::UserType) {
126 return variant.toString();
127 }
128
129 if (variant.canConvert<ApiPointer>()) {
130 return variant.value<ApiPointer>().toString();
131 }
132 if (variant.canConvert<ApiBitmask>()) {
133 return variant.value<ApiBitmask>().toString();
134 }
135 if (variant.canConvert<ApiStruct>()) {
José Fonsecaa596a9e2011-09-27 10:19:28 +0100136 return variant.value<ApiStruct>().toString(multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400137 }
138 if (variant.canConvert<ApiArray>()) {
José Fonsecaa596a9e2011-09-27 10:19:28 +0100139 return variant.value<ApiArray>().toString(multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400140 }
Zack Rusind54055e2011-04-17 18:27:28 -0400141 if (variant.canConvert<ApiEnum>()) {
142 return variant.value<ApiEnum>().toString();
143 }
Zack Rusin91065372011-03-26 01:54:10 -0400144
145 return QString();
146}
147
Zack Rusina1a3ad52011-08-27 19:19:18 -0400148
José Fonsecab4a3d142011-10-27 07:43:19 +0100149void VariantVisitor::visit(trace::Null *)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400150{
151 m_variant = QVariant::fromValue(ApiPointer(0));
152}
153
José Fonsecab4a3d142011-10-27 07:43:19 +0100154void VariantVisitor::visit(trace::Bool *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400155{
156 m_variant = QVariant(node->value);
157}
158
José Fonsecab4a3d142011-10-27 07:43:19 +0100159void VariantVisitor::visit(trace::SInt *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400160{
161 m_variant = QVariant(node->value);
162}
163
José Fonsecab4a3d142011-10-27 07:43:19 +0100164void VariantVisitor::visit(trace::UInt *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400165{
166 m_variant = QVariant(node->value);
167}
168
José Fonsecab4a3d142011-10-27 07:43:19 +0100169void VariantVisitor::visit(trace::Float *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400170{
171 m_variant = QVariant(node->value);
172}
173
José Fonsecab4a3d142011-10-27 07:43:19 +0100174void VariantVisitor::visit(trace::String *node)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400175{
176 m_variant = QVariant(QString::fromStdString(node->value));
177}
178
José Fonsecab4a3d142011-10-27 07:43:19 +0100179void VariantVisitor::visit(trace::Enum *e)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400180{
Zack Rusin35c27932011-08-28 21:16:22 -0400181 ApiTraceEnumSignature *sig = 0;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400182
Zack Rusinebf971e2011-09-06 17:44:43 -0400183 if (m_loader) {
184 sig = m_loader->enumSignature(e->sig->id);
Zack Rusin35c27932011-08-28 21:16:22 -0400185 }
186 if (!sig) {
187 sig = new ApiTraceEnumSignature(
188 QString::fromStdString(e->sig->name),
189 QVariant(e->sig->value));
Zack Rusinebf971e2011-09-06 17:44:43 -0400190 if (m_loader) {
191 m_loader->addEnumSignature(e->sig->id, sig);
Zack Rusin35c27932011-08-28 21:16:22 -0400192 }
193 }
194
195 m_variant = QVariant::fromValue(ApiEnum(sig));
Zack Rusina1a3ad52011-08-27 19:19:18 -0400196}
197
José Fonsecab4a3d142011-10-27 07:43:19 +0100198void VariantVisitor::visit(trace::Bitmask *bitmask)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400199{
200 m_variant = QVariant::fromValue(ApiBitmask(bitmask));
201}
202
José Fonsecab4a3d142011-10-27 07:43:19 +0100203void VariantVisitor::visit(trace::Struct *str)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400204{
205 m_variant = QVariant::fromValue(ApiStruct(str));
206}
207
José Fonsecab4a3d142011-10-27 07:43:19 +0100208void VariantVisitor::visit(trace::Array *array)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400209{
210 m_variant = QVariant::fromValue(ApiArray(array));
211}
212
José Fonsecab4a3d142011-10-27 07:43:19 +0100213void VariantVisitor::visit(trace::Blob *blob)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400214{
Zack Rusin95237682011-09-27 12:04:10 -0400215 QByteArray barray = QByteArray(blob->buf, blob->size);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400216 m_variant = QVariant(barray);
217}
218
José Fonsecab4a3d142011-10-27 07:43:19 +0100219void VariantVisitor::visit(trace::Pointer *ptr)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400220{
221 m_variant = QVariant::fromValue(ApiPointer(ptr->value));
222}
223
224
Zack Rusin35c27932011-08-28 21:16:22 -0400225ApiEnum::ApiEnum(ApiTraceEnumSignature *sig)
226 : m_sig(sig)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400227{
228}
229
230QString ApiEnum::toString() const
231{
Zack Rusin35c27932011-08-28 21:16:22 -0400232 if (m_sig) {
233 return m_sig->name();
234 }
235 Q_ASSERT(!"should never happen");
236 return QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400237}
238
239QVariant ApiEnum::value() const
240{
Zack Rusin35c27932011-08-28 21:16:22 -0400241 if (m_sig) {
242 return m_sig->value();
243 }
244 Q_ASSERT(!"should never happen");
245 return QVariant();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400246}
247
248QString ApiEnum::name() const
249{
Zack Rusin35c27932011-08-28 21:16:22 -0400250 if (m_sig) {
251 return m_sig->name();
252 }
253 Q_ASSERT(!"should never happen");
254 return QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400255}
256
257unsigned long long ApiBitmask::value() const
258{
259 return m_value;
260}
261
262ApiBitmask::Signature ApiBitmask::signature() const
263{
264 return m_sig;
265}
266
267ApiStruct::Signature ApiStruct::signature() const
268{
269 return m_sig;
270}
271
272QList<QVariant> ApiStruct::values() const
273{
274 return m_members;
275}
276
277ApiPointer::ApiPointer(unsigned long long val)
278 : m_value(val)
279{
280}
281
282
283unsigned long long ApiPointer::value() const
284{
285 return m_value;
286}
287
288QString ApiPointer::toString() const
289{
290 if (m_value)
291 return QString("0x%1").arg(m_value, 0, 16);
292 else
293 return QLatin1String("NULL");
294}
295
José Fonsecab4a3d142011-10-27 07:43:19 +0100296ApiBitmask::ApiBitmask(const trace::Bitmask *bitmask)
Zack Rusin91065372011-03-26 01:54:10 -0400297 : m_value(0)
298{
299 init(bitmask);
300}
301
José Fonsecab4a3d142011-10-27 07:43:19 +0100302void ApiBitmask::init(const trace::Bitmask *bitmask)
Zack Rusin91065372011-03-26 01:54:10 -0400303{
304 if (!bitmask)
305 return;
306
307 m_value = bitmask->value;
José Fonsecab4a3d142011-10-27 07:43:19 +0100308 for (const trace::BitmaskFlag *it = bitmask->sig->flags;
José Fonsecafcfbf172011-05-28 13:20:01 +0100309 it != bitmask->sig->flags + bitmask->sig->num_flags; ++it) {
José Fonseca31b183a2011-05-28 12:21:15 +0100310 assert(it->value);
Zack Rusin91065372011-03-26 01:54:10 -0400311 QPair<QString, unsigned long long> pair;
312
José Fonseca31b183a2011-05-28 12:21:15 +0100313 pair.first = QString::fromStdString(it->name);
314 pair.second = it->value;
Zack Rusin91065372011-03-26 01:54:10 -0400315
316 m_sig.append(pair);
317 }
318}
319
320QString ApiBitmask::toString() const
321{
322 QString str;
323 unsigned long long value = m_value;
324 bool first = true;
325 for (Signature::const_iterator it = m_sig.begin();
326 value != 0 && it != m_sig.end(); ++it) {
327 Q_ASSERT(it->second);
328 if ((value & it->second) == it->second) {
329 if (!first) {
330 str += QLatin1String(" | ");
331 }
332 str += it->first;
333 value &= ~it->second;
334 first = false;
335 }
336 }
337 if (value || first) {
338 if (!first) {
339 str += QLatin1String(" | ");
340 }
341 str += QString::fromLatin1("0x%1").arg(value, 0, 16);
342 }
343 return str;
344}
345
José Fonsecab4a3d142011-10-27 07:43:19 +0100346ApiStruct::ApiStruct(const trace::Struct *s)
Zack Rusin91065372011-03-26 01:54:10 -0400347{
348 init(s);
349}
350
José Fonsecaa596a9e2011-09-27 10:19:28 +0100351QString ApiStruct::toString(bool multiLine) const
Zack Rusin91065372011-03-26 01:54:10 -0400352{
353 QString str;
354
355 str += QLatin1String("{");
356 for (unsigned i = 0; i < m_members.count(); ++i) {
Zack Rusin5e277b02011-04-16 21:52:26 -0400357 str += m_sig.memberNames[i] %
358 QLatin1Literal(" = ") %
José Fonsecaa596a9e2011-09-27 10:19:28 +0100359 apiVariantToString(m_members[i], multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400360 if (i < m_members.count() - 1)
361 str += QLatin1String(", ");
362 }
363 str += QLatin1String("}");
364
365 return str;
366}
367
José Fonsecab4a3d142011-10-27 07:43:19 +0100368void ApiStruct::init(const trace::Struct *s)
Zack Rusin91065372011-03-26 01:54:10 -0400369{
370 if (!s)
371 return;
372
373 m_sig.name = QString::fromStdString(s->sig->name);
José Fonseca1b23ed22011-05-28 13:01:16 +0100374 for (unsigned i = 0; i < s->sig->num_members; ++i) {
Zack Rusin35c27932011-08-28 21:16:22 -0400375 VariantVisitor vis(0);
Zack Rusin91065372011-03-26 01:54:10 -0400376 m_sig.memberNames.append(
377 QString::fromStdString(s->sig->member_names[i]));
378 s->members[i]->visit(vis);
379 m_members.append(vis.variant());
380 }
381}
382
José Fonsecab4a3d142011-10-27 07:43:19 +0100383ApiArray::ApiArray(const trace::Array *arr)
Zack Rusin91065372011-03-26 01:54:10 -0400384{
385 init(arr);
386}
387
Zack Rusin77ff98a2011-08-28 22:30:35 -0400388ApiArray::ApiArray(const QVector<QVariant> &vals)
Zack Rusinabb3fde2011-04-16 02:16:49 -0400389 : m_array(vals)
390{
391}
392
Zack Rusin77ff98a2011-08-28 22:30:35 -0400393QVector<QVariant> ApiArray::values() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400394{
395 return m_array;
396}
397
José Fonsecaa596a9e2011-09-27 10:19:28 +0100398QString ApiArray::toString(bool multiLine) const
Zack Rusin91065372011-03-26 01:54:10 -0400399{
400 QString str;
401 str += QLatin1String("[");
402 for(int i = 0; i < m_array.count(); ++i) {
403 const QVariant &var = m_array[i];
José Fonsecaa596a9e2011-09-27 10:19:28 +0100404 str += apiVariantToString(var, multiLine);
Zack Rusin91065372011-03-26 01:54:10 -0400405 if (i < m_array.count() - 1)
406 str += QLatin1String(", ");
407 }
408 str += QLatin1String("]");
409
410 return str;
411}
412
José Fonsecab4a3d142011-10-27 07:43:19 +0100413void ApiArray::init(const trace::Array *arr)
Zack Rusin91065372011-03-26 01:54:10 -0400414{
415 if (!arr)
416 return;
417
Zack Rusin3c70dbf2011-08-28 03:10:01 -0400418 m_array.reserve(arr->values.size());
Zack Rusin91065372011-03-26 01:54:10 -0400419 for (int i = 0; i < arr->values.size(); ++i) {
Zack Rusin35c27932011-08-28 21:16:22 -0400420 VariantVisitor vis(0);
Zack Rusin91065372011-03-26 01:54:10 -0400421 arr->values[i]->visit(vis);
422
423 m_array.append(vis.variant());
424 }
Zack Rusin77ff98a2011-08-28 22:30:35 -0400425 m_array.squeeze();
Zack Rusin91065372011-03-26 01:54:10 -0400426}
Zack Rusin18eade52011-03-26 14:23:35 -0400427
Zack Rusina1a3ad52011-08-27 19:19:18 -0400428ApiTraceState::ApiTraceState()
429{
430}
431
432ApiTraceState::ApiTraceState(const QVariantMap &parsedJson)
433{
434 m_parameters = parsedJson[QLatin1String("parameters")].toMap();
435 QVariantMap attachedShaders =
436 parsedJson[QLatin1String("shaders")].toMap();
437 QVariantMap::const_iterator itr;
438
439
440 for (itr = attachedShaders.constBegin(); itr != attachedShaders.constEnd();
441 ++itr) {
442 QString type = itr.key();
443 QString source = itr.value().toString();
444 m_shaderSources[type] = source;
445 }
446
447 m_uniforms = parsedJson[QLatin1String("uniforms")].toMap();
448
449 QVariantMap textures =
450 parsedJson[QLatin1String("textures")].toMap();
451 for (itr = textures.constBegin(); itr != textures.constEnd(); ++itr) {
452 QVariantMap image = itr.value().toMap();
453 QSize size(image[QLatin1String("__width__")].toInt(),
454 image[QLatin1String("__height__")].toInt());
455 QString cls = image[QLatin1String("__class__")].toString();
456 QString type = image[QLatin1String("__type__")].toString();
457 bool normalized =
458 image[QLatin1String("__normalized__")].toBool();
459 int numChannels =
460 image[QLatin1String("__channels__")].toInt();
461
462 Q_ASSERT(type == QLatin1String("uint8"));
463 Q_ASSERT(normalized == true);
Zack Rusindf95ce02011-08-27 19:46:16 -0400464 Q_UNUSED(normalized);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400465
466 QByteArray dataArray =
467 image[QLatin1String("__data__")].toByteArray();
468
469 ApiTexture tex;
470 tex.setSize(size);
471 tex.setNumChannels(numChannels);
472 tex.setLabel(itr.key());
473 tex.contentsFromBase64(dataArray);
474
475 m_textures.append(tex);
476 }
477
478 QVariantMap fbos =
479 parsedJson[QLatin1String("framebuffer")].toMap();
480 for (itr = fbos.constBegin(); itr != fbos.constEnd(); ++itr) {
481 QVariantMap buffer = itr.value().toMap();
482 QSize size(buffer[QLatin1String("__width__")].toInt(),
483 buffer[QLatin1String("__height__")].toInt());
484 QString cls = buffer[QLatin1String("__class__")].toString();
485 QString type = buffer[QLatin1String("__type__")].toString();
486 bool normalized = buffer[QLatin1String("__normalized__")].toBool();
487 int numChannels = buffer[QLatin1String("__channels__")].toInt();
488
489 Q_ASSERT(type == QLatin1String("uint8"));
490 Q_ASSERT(normalized == true);
Zack Rusindf95ce02011-08-27 19:46:16 -0400491 Q_UNUSED(normalized);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400492
493 QByteArray dataArray =
494 buffer[QLatin1String("__data__")].toByteArray();
495
496 ApiFramebuffer fbo;
497 fbo.setSize(size);
498 fbo.setNumChannels(numChannels);
499 fbo.setType(itr.key());
500 fbo.contentsFromBase64(dataArray);
501 m_framebuffers.append(fbo);
502 }
503}
504
505const QVariantMap & ApiTraceState::parameters() const
506{
507 return m_parameters;
508}
509
510const QMap<QString, QString> & ApiTraceState::shaderSources() const
511{
512 return m_shaderSources;
513}
514
515const QVariantMap & ApiTraceState::uniforms() const
516{
517 return m_uniforms;
518}
519
520bool ApiTraceState::isEmpty() const
521{
522 return m_parameters.isEmpty();
523}
524
525const QList<ApiTexture> & ApiTraceState::textures() const
526{
527 return m_textures;
528}
529
530const QList<ApiFramebuffer> & ApiTraceState::framebuffers() const
531{
532 return m_framebuffers;
533}
534
Zack Rusin353f0532011-09-15 20:23:27 -0400535ApiFramebuffer ApiTraceState::colorBuffer() const
536{
537 foreach (ApiFramebuffer fbo, m_framebuffers) {
538 if (fbo.type() == QLatin1String("GL_BACK")) {
539 return fbo;
540 }
541 }
542 foreach (ApiFramebuffer fbo, m_framebuffers) {
543 if (fbo.type() == QLatin1String("GL_FRONT")) {
544 return fbo;
545 }
546 }
547 return ApiFramebuffer();
548}
549
550
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400551ApiTraceCallSignature::ApiTraceCallSignature(const QString &name,
552 const QStringList &argNames)
553 : m_name(name),
554 m_argNames(argNames)
555{
556}
557
558ApiTraceCallSignature::~ApiTraceCallSignature()
559{
560}
561
562QUrl ApiTraceCallSignature::helpUrl() const
563{
564 return m_helpUrl;
565}
566
567void ApiTraceCallSignature::setHelpUrl(const QUrl &url)
568{
569 m_helpUrl = url;
570}
571
Zack Rusina1a3ad52011-08-27 19:19:18 -0400572ApiTraceEvent::ApiTraceEvent()
573 : m_type(ApiTraceEvent::None),
Zack Rusined40bc62011-08-28 17:11:02 -0400574 m_hasBinaryData(false),
575 m_binaryDataIndex(0),
576 m_state(0),
Zack Rusina1a3ad52011-08-27 19:19:18 -0400577 m_staticText(0)
578{
579}
580
581ApiTraceEvent::ApiTraceEvent(Type t)
582 : m_type(t),
Zack Rusined40bc62011-08-28 17:11:02 -0400583 m_hasBinaryData(false),
584 m_binaryDataIndex(0),
585 m_state(0),
Zack Rusina1a3ad52011-08-27 19:19:18 -0400586 m_staticText(0)
587{
588}
589
590ApiTraceEvent::~ApiTraceEvent()
591{
Zack Rusined40bc62011-08-28 17:11:02 -0400592 delete m_state;
Zack Rusina1a3ad52011-08-27 19:19:18 -0400593 delete m_staticText;
594}
595
596QVariantMap ApiTraceEvent::stateParameters() const
597{
Zack Rusined40bc62011-08-28 17:11:02 -0400598 if (m_state) {
599 return m_state->parameters();
600 } else {
601 return QVariantMap();
602 }
Zack Rusina1a3ad52011-08-27 19:19:18 -0400603}
604
Zack Rusined40bc62011-08-28 17:11:02 -0400605ApiTraceState *ApiTraceEvent::state() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400606{
607 return m_state;
608}
609
Zack Rusined40bc62011-08-28 17:11:02 -0400610void ApiTraceEvent::setState(ApiTraceState *state)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400611{
612 m_state = state;
613}
614
Zack Rusinebf971e2011-09-06 17:44:43 -0400615ApiTraceCall::ApiTraceCall(ApiTraceFrame *parentFrame,
616 TraceLoader *loader,
José Fonsecab4a3d142011-10-27 07:43:19 +0100617 const trace::Call *call)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400618 : ApiTraceEvent(ApiTraceEvent::Call),
Zack Rusined40bc62011-08-28 17:11:02 -0400619 m_parentFrame(parentFrame)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400620{
Zack Rusina1a3ad52011-08-27 19:19:18 -0400621 m_index = call->no;
622
Zack Rusinebf971e2011-09-06 17:44:43 -0400623 m_signature = loader->signature(call->sig->id);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400624
625 if (!m_signature) {
Zack Rusinb31e2142011-08-28 19:38:00 -0400626 QString name = QString::fromStdString(call->sig->name);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400627 QStringList argNames;
Zack Rusinf22d7992011-08-28 02:23:47 -0400628 argNames.reserve(call->sig->num_args);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400629 for (int i = 0; i < call->sig->num_args; ++i) {
Zack Rusinf22d7992011-08-28 02:23:47 -0400630 argNames += QString::fromStdString(call->sig->arg_names[i]);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400631 }
632 m_signature = new ApiTraceCallSignature(name, argNames);
Zack Rusinebf971e2011-09-06 17:44:43 -0400633 loader->addSignature(call->sig->id, m_signature);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400634 }
635 if (call->ret) {
Zack Rusinebf971e2011-09-06 17:44:43 -0400636 VariantVisitor retVisitor(loader);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400637 call->ret->visit(retVisitor);
638 m_returnValue = retVisitor.variant();
639 }
Zack Rusinf22d7992011-08-28 02:23:47 -0400640 m_argValues.reserve(call->args.size());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400641 for (int i = 0; i < call->args.size(); ++i) {
José Fonseca1fa61832011-11-05 08:50:25 +0000642 if (call->args[i]) {
643 VariantVisitor argVisitor(loader);
644 call->args[i]->visit(argVisitor);
645 m_argValues.append(argVisitor.variant());
646 if (m_argValues[i].type() == QVariant::ByteArray) {
647 m_hasBinaryData = true;
648 m_binaryDataIndex = i;
649 }
650 } else {
651 m_argValues.append(QVariant());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400652 }
653 }
Zack Rusinf736a622011-08-28 22:19:46 -0400654 m_argValues.squeeze();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400655}
656
657ApiTraceCall::~ApiTraceCall()
658{
659}
660
661
662bool ApiTraceCall::hasError() const
663{
664 return !m_error.isEmpty();
665}
666
667QString ApiTraceCall::error() const
668{
669 return m_error;
670}
671
672void ApiTraceCall::setError(const QString &msg)
673{
674 if (m_error != msg) {
Zack Rusina1a3ad52011-08-27 19:19:18 -0400675 m_error = msg;
676 m_richText = QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400677 }
678}
679
680ApiTrace * ApiTraceCall::parentTrace() const
681{
682 if (m_parentFrame)
683 return m_parentFrame->parentTrace();
684 return NULL;
685}
686
Zack Rusinf736a622011-08-28 22:19:46 -0400687QVector<QVariant> ApiTraceCall::originalValues() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400688{
689 return m_argValues;
690}
691
Zack Rusinf736a622011-08-28 22:19:46 -0400692void ApiTraceCall::setEditedValues(const QVector<QVariant> &lst)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400693{
694 ApiTrace *trace = parentTrace();
695
696 m_editedValues = lst;
697 //lets regenerate data
698 m_richText = QString();
Zack Rusindc792082011-08-27 23:29:19 -0400699 m_searchText = QString();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400700 delete m_staticText;
701 m_staticText = 0;
702
703 if (trace) {
704 if (!lst.isEmpty()) {
705 trace->callEdited(this);
706 } else {
707 trace->callReverted(this);
708 }
709 }
710}
711
Zack Rusinf736a622011-08-28 22:19:46 -0400712QVector<QVariant> ApiTraceCall::editedValues() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400713{
714 return m_editedValues;
715}
716
717bool ApiTraceCall::edited() const
718{
719 return !m_editedValues.isEmpty();
720}
721
722void ApiTraceCall::revert()
723{
Zack Rusinf736a622011-08-28 22:19:46 -0400724 setEditedValues(QVector<QVariant>());
Zack Rusina1a3ad52011-08-27 19:19:18 -0400725}
726
727void ApiTraceCall::setHelpUrl(const QUrl &url)
728{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400729 m_signature->setHelpUrl(url);
Zack Rusina1a3ad52011-08-27 19:19:18 -0400730}
731
732void ApiTraceCall::setParentFrame(ApiTraceFrame *frame)
733{
734 m_parentFrame = frame;
735}
736
737ApiTraceFrame * ApiTraceCall::parentFrame()const
738{
739 return m_parentFrame;
740}
741
742int ApiTraceCall::index() const
743{
744 return m_index;
745}
746
747QString ApiTraceCall::name() const
748{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400749 return m_signature->name();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400750}
751
752QStringList ApiTraceCall::argNames() const
753{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400754 return m_signature->argNames();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400755}
756
Zack Rusinf736a622011-08-28 22:19:46 -0400757QVector<QVariant> ApiTraceCall::arguments() const
Zack Rusina1a3ad52011-08-27 19:19:18 -0400758{
759 if (m_editedValues.isEmpty())
760 return m_argValues;
761 else
762 return m_editedValues;
763}
764
765QVariant ApiTraceCall::returnValue() const
766{
767 return m_returnValue;
768}
769
770QUrl ApiTraceCall::helpUrl() const
771{
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400772 return m_signature->helpUrl();
Zack Rusina1a3ad52011-08-27 19:19:18 -0400773}
774
775bool ApiTraceCall::hasBinaryData() const
776{
777 return m_hasBinaryData;
778}
779
780int ApiTraceCall::binaryDataIndex() const
781{
782 return m_binaryDataIndex;
783}
784
Zack Rusin18eade52011-03-26 14:23:35 -0400785QStaticText ApiTraceCall::staticText() const
786{
Zack Rusin53484b22011-04-16 11:56:19 -0400787 if (m_staticText && !m_staticText->text().isEmpty())
788 return *m_staticText;
Zack Rusin18eade52011-03-26 14:23:35 -0400789
Zack Rusinf736a622011-08-28 22:19:46 -0400790 QVector<QVariant> argValues = arguments();
Zack Rusin9af5bff2011-04-18 01:05:50 -0400791
Zack Rusin53484b22011-04-16 11:56:19 -0400792 QString richText = QString::fromLatin1(
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400793 "<span style=\"font-weight:bold\">%1</span>(").arg(
794 m_signature->name());
795 QStringList argNames = m_signature->argNames();
796 for (int i = 0; i < argNames.count(); ++i) {
Zack Rusin27cb2c42011-03-27 23:53:36 -0400797 richText += QLatin1String("<span style=\"color:#0000ff\">");
Zack Rusin9af5bff2011-04-18 01:05:50 -0400798 QString argText = apiVariantToString(argValues[i]);
Zack Rusindd7f2302011-03-31 22:55:57 -0400799
800 //if arguments are really long (e.g. shader text), cut them
801 // and elide it
802 if (argText.length() > 40) {
803 QString shortened = argText.mid(0, 40);
804 shortened[argText.length() - 5] = '.';
805 shortened[argText.length() - 4] = '.';
806 shortened[argText.length() - 3] = '.';
Zack Rusindf95ce02011-08-27 19:46:16 -0400807 shortened[argText.length() - 2] = argText.at(argText.length() - 2);
808 shortened[argText.length() - 1] = argText.at(argText.length() - 1);
Zack Rusindd7f2302011-03-31 22:55:57 -0400809 richText += shortened;
810 } else {
811 richText += argText;
812 }
Zack Rusin27cb2c42011-03-27 23:53:36 -0400813 richText += QLatin1String("</span>");
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400814 if (i < argNames.count() - 1)
Zack Rusin5e277b02011-04-16 21:52:26 -0400815 richText += QLatin1String(", ");
Zack Rusin27cb2c42011-03-27 23:53:36 -0400816 }
817 richText += QLatin1String(")");
Zack Rusinead6aad2011-04-15 22:16:18 -0400818 if (m_returnValue.isValid()) {
Zack Rusin5e277b02011-04-16 21:52:26 -0400819 richText +=
820 QLatin1Literal(" = ") %
821 QLatin1Literal("<span style=\"color:#0000ff\">") %
822 apiVariantToString(m_returnValue) %
823 QLatin1Literal("</span>");
José Fonseca908f38d2011-03-31 10:09:14 +0100824 }
Zack Rusin27cb2c42011-03-27 23:53:36 -0400825
Zack Rusin53484b22011-04-16 11:56:19 -0400826 if (!m_staticText)
827 m_staticText = new QStaticText(richText);
Zack Rusin9af5bff2011-04-18 01:05:50 -0400828 else
829 m_staticText->setText(richText);
Zack Rusin27cb2c42011-03-27 23:53:36 -0400830 QTextOption opt;
831 opt.setWrapMode(QTextOption::NoWrap);
Zack Rusin53484b22011-04-16 11:56:19 -0400832 m_staticText->setTextOption(opt);
833 m_staticText->prepare();
Zack Rusin27cb2c42011-03-27 23:53:36 -0400834
Zack Rusin53484b22011-04-16 11:56:19 -0400835 return *m_staticText;
Zack Rusin27cb2c42011-03-27 23:53:36 -0400836}
837
838QString ApiTraceCall::toHtml() const
839{
840 if (!m_richText.isEmpty())
841 return m_richText;
842
Zack Rusinb53b1612011-04-19 01:33:58 -0400843 m_richText = QLatin1String("<div class=\"call\">");
844
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400845 QUrl helpUrl = m_signature->helpUrl();
846 if (helpUrl.isEmpty()) {
Zack Rusinb53b1612011-04-19 01:33:58 -0400847 m_richText += QString::fromLatin1(
848 "%1) <span class=\"callName\">%2</span>(")
849 .arg(m_index)
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400850 .arg(m_signature->name());
Zack Rusinc97fadc2011-04-07 15:16:59 -0400851 } else {
Zack Rusinb53b1612011-04-19 01:33:58 -0400852 m_richText += QString::fromLatin1(
853 "%1) <span class=\"callName\"><a href=\"%2\">%3</a></span>(")
Zack Rusinead6aad2011-04-15 22:16:18 -0400854 .arg(m_index)
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400855 .arg(helpUrl.toString())
856 .arg(m_signature->name());
Zack Rusinc97fadc2011-04-07 15:16:59 -0400857 }
858
Zack Rusinf736a622011-08-28 22:19:46 -0400859 QVector<QVariant> argValues = arguments();
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400860 QStringList argNames = m_signature->argNames();
861 for (int i = 0; i < argNames.count(); ++i) {
Zack Rusinb53b1612011-04-19 01:33:58 -0400862 m_richText +=
863 QLatin1String("<span class=\"arg-name\">") +
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400864 argNames[i] +
Zack Rusinb53b1612011-04-19 01:33:58 -0400865 QLatin1String("</span>") +
866 QLatin1Literal(" = ") +
867 QLatin1Literal("<span class=\"arg-value\">") +
José Fonsecae8a1aa92011-04-21 09:13:23 +0100868 apiVariantToString(argValues[i], true) +
Zack Rusinb53b1612011-04-19 01:33:58 -0400869 QLatin1Literal("</span>");
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400870 if (i < argNames.count() - 1)
Zack Rusin5e277b02011-04-16 21:52:26 -0400871 m_richText += QLatin1String(", ");
Zack Rusin18eade52011-03-26 14:23:35 -0400872 }
873 m_richText += QLatin1String(")");
874
Zack Rusinead6aad2011-04-15 22:16:18 -0400875 if (m_returnValue.isValid()) {
Zack Rusin5e277b02011-04-16 21:52:26 -0400876 m_richText +=
877 QLatin1String(" = ") +
878 QLatin1String("<span style=\"color:#0000ff\">") +
José Fonsecae8a1aa92011-04-21 09:13:23 +0100879 apiVariantToString(m_returnValue, true) +
Zack Rusin5e277b02011-04-16 21:52:26 -0400880 QLatin1String("</span>");
Zack Rusin18eade52011-03-26 14:23:35 -0400881 }
Zack Rusinb53b1612011-04-19 01:33:58 -0400882 m_richText += QLatin1String("</div>");
883
Zack Rusincc0b4912011-04-19 01:59:20 -0400884 if (hasError()) {
885 QString errorStr =
886 QString::fromLatin1(
887 "<div class=\"error\">%1</div>")
888 .arg(m_error);
889 m_richText += errorStr;
890 }
891
Zack Rusinb53b1612011-04-19 01:33:58 -0400892 m_richText =
893 QString::fromLatin1(
894 "<html><head><style type=\"text/css\" media=\"all\">"
895 "%1</style></head><body>%2</body></html>")
896 .arg(styleSheet)
897 .arg(m_richText);
Zack Rusin5e277b02011-04-16 21:52:26 -0400898 m_richText.squeeze();
Zack Rusinb53b1612011-04-19 01:33:58 -0400899
900 //qDebug()<<m_richText;
Zack Rusin18eade52011-03-26 14:23:35 -0400901 return m_richText;
902}
Zack Rusinba3c1bf2011-03-27 17:12:06 -0400903
Zack Rusindc792082011-08-27 23:29:19 -0400904QString ApiTraceCall::searchText() const
Zack Rusinba3c1bf2011-03-27 17:12:06 -0400905{
Zack Rusindc792082011-08-27 23:29:19 -0400906 if (!m_searchText.isEmpty())
907 return m_searchText;
Zack Rusinba3c1bf2011-03-27 17:12:06 -0400908
Zack Rusinf736a622011-08-28 22:19:46 -0400909 QVector<QVariant> argValues = arguments();
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400910 m_searchText = m_signature->name() + QLatin1Literal("(");
911 QStringList argNames = m_signature->argNames();
912 for (int i = 0; i < argNames.count(); ++i) {
913 m_searchText += argNames[i] +
Zack Rusin5e277b02011-04-16 21:52:26 -0400914 QLatin1Literal(" = ") +
Zack Rusin9af5bff2011-04-18 01:05:50 -0400915 apiVariantToString(argValues[i]);
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400916 if (i < argNames.count() - 1)
Zack Rusindc792082011-08-27 23:29:19 -0400917 m_searchText += QLatin1String(", ");
Zack Rusinba3c1bf2011-03-27 17:12:06 -0400918 }
Zack Rusindc792082011-08-27 23:29:19 -0400919 m_searchText += QLatin1String(")");
Zack Rusinba3c1bf2011-03-27 17:12:06 -0400920
Zack Rusinead6aad2011-04-15 22:16:18 -0400921 if (m_returnValue.isValid()) {
Zack Rusindc792082011-08-27 23:29:19 -0400922 m_searchText += QLatin1Literal(" = ") +
Zack Rusin5e277b02011-04-16 21:52:26 -0400923 apiVariantToString(m_returnValue);
Zack Rusinba3c1bf2011-03-27 17:12:06 -0400924 }
Zack Rusindc792082011-08-27 23:29:19 -0400925 m_searchText.squeeze();
926 return m_searchText;
Zack Rusinba3c1bf2011-03-27 17:12:06 -0400927}
Zack Rusinf6667d12011-03-30 11:03:37 -0400928
Zack Rusina1a3ad52011-08-27 19:19:18 -0400929int ApiTraceCall::numChildren() const
930{
931 return 0;
932}
933
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400934bool ApiTraceCall::contains(const QString &str,
935 Qt::CaseSensitivity sensitivity) const
936{
937 QString txt = searchText();
938 return txt.contains(str, sensitivity);
939}
940
941
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400942ApiTraceFrame::ApiTraceFrame(ApiTrace *parentTrace)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400943 : ApiTraceEvent(ApiTraceEvent::Frame),
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400944 m_parentTrace(parentTrace),
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400945 m_binaryDataSize(0),
946 m_loaded(false),
Zack Rusin851d0b02011-09-14 22:04:07 -0400947 m_callsToLoad(0),
948 m_lastCallIndex(0)
Zack Rusina1a3ad52011-08-27 19:19:18 -0400949{
950}
951
Zack Rusinc1743432011-09-13 17:58:58 -0400952ApiTraceFrame::~ApiTraceFrame()
953{
954 qDeleteAll(m_calls);
955}
956
Zack Rusinf6667d12011-03-30 11:03:37 -0400957QStaticText ApiTraceFrame::staticText() const
958{
Zack Rusin53484b22011-04-16 11:56:19 -0400959 if (m_staticText && !m_staticText->text().isEmpty())
960 return *m_staticText;
Zack Rusinf6667d12011-03-30 11:03:37 -0400961
Zack Rusin45e094f2011-09-14 17:36:53 -0400962 QString richText = QObject::tr(
963 "<span style=\"font-weight:bold\">Frame %1</span>"
964 "&nbsp;&nbsp;&nbsp;"
965 "<span style=\"font-style:italic;font-size:small;font-weight:lighter;\"> "
966 "(%2 calls)</span>")
967 .arg(number)
968 .arg(m_loaded ? m_calls.count() : m_callsToLoad);
Zack Rusin9e292fc2011-04-26 23:03:42 -0400969
970 //mark the frame if it uploads more than a meg a frame
971 if (m_binaryDataSize > (1024*1024)) {
972 richText =
973 QObject::tr(
Zack Rusin45e094f2011-09-14 17:36:53 -0400974 "%1"
Zack Rusin9e292fc2011-04-26 23:03:42 -0400975 "<span style=\"font-style:italic;\">"
976 "&nbsp;&nbsp;&nbsp;&nbsp;(%2MB)</span>")
Zack Rusin45e094f2011-09-14 17:36:53 -0400977 .arg(richText)
Zack Rusin9e292fc2011-04-26 23:03:42 -0400978 .arg(double(m_binaryDataSize / (1024.*1024.)), 0, 'g', 2);
Zack Rusin9e292fc2011-04-26 23:03:42 -0400979 }
Zack Rusinf6667d12011-03-30 11:03:37 -0400980
Zack Rusin53484b22011-04-16 11:56:19 -0400981 if (!m_staticText)
982 m_staticText = new QStaticText(richText);
983
Zack Rusinf6667d12011-03-30 11:03:37 -0400984 QTextOption opt;
985 opt.setWrapMode(QTextOption::NoWrap);
Zack Rusin53484b22011-04-16 11:56:19 -0400986 m_staticText->setTextOption(opt);
987 m_staticText->prepare();
Zack Rusinf6667d12011-03-30 11:03:37 -0400988
Zack Rusin53484b22011-04-16 11:56:19 -0400989 return *m_staticText;
Zack Rusinf6667d12011-03-30 11:03:37 -0400990}
991
Zack Rusinf6667d12011-03-30 11:03:37 -0400992int ApiTraceFrame::numChildren() const
993{
Zack Rusin3176ebe2011-09-06 21:11:36 -0400994 return m_calls.count();
Zack Rusinf6667d12011-03-30 11:03:37 -0400995}
996
Zack Rusin7c1793e2011-04-16 23:14:25 -0400997ApiTrace * ApiTraceFrame::parentTrace() const
998{
999 return m_parentTrace;
1000}
1001
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001002void ApiTraceFrame::addCall(ApiTraceCall *call)
1003{
1004 m_calls.append(call);
Zack Rusin9e292fc2011-04-26 23:03:42 -04001005 if (call->hasBinaryData()) {
1006 QByteArray data =
1007 call->arguments()[call->binaryDataIndex()].toByteArray();
1008 m_binaryDataSize += data.size();
1009 }
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001010}
1011
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001012QVector<ApiTraceCall*> ApiTraceFrame::calls() const
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001013{
1014 return m_calls;
1015}
1016
1017ApiTraceCall * ApiTraceFrame::call(int idx) const
1018{
1019 return m_calls.value(idx);
1020}
1021
Zack Rusinda7579b2011-09-13 17:33:05 -04001022
1023ApiTraceCall * ApiTraceFrame::callWithIndex(int index) const
1024{
1025 QVector<ApiTraceCall*>::const_iterator itr;
1026 for (itr = m_calls.constBegin(); itr != m_calls.constEnd(); ++itr) {
1027 if ((*itr)->index() == index) {
1028 return *itr;
1029 }
1030 }
1031 return 0;
1032}
1033
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001034int ApiTraceFrame::callIndex(ApiTraceCall *call) const
1035{
1036 return m_calls.indexOf(call);
1037}
1038
1039bool ApiTraceFrame::isEmpty() const
1040{
Zack Rusin3176ebe2011-09-06 21:11:36 -04001041 if (m_loaded) {
1042 return m_calls.isEmpty();
1043 } else {
1044 return m_callsToLoad == 0;
1045 }
Zack Rusin1d31b6c2011-04-26 22:30:25 -04001046}
1047
Zack Rusin9e292fc2011-04-26 23:03:42 -04001048int ApiTraceFrame::binaryDataSize() const
1049{
1050 return m_binaryDataSize;
1051}
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001052
1053void ApiTraceFrame::setCalls(const QVector<ApiTraceCall*> &calls,
1054 quint64 binaryDataSize)
1055{
1056 m_calls = calls;
1057 m_binaryDataSize = binaryDataSize;
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001058 m_loaded = true;
Zack Rusin45e094f2011-09-14 17:36:53 -04001059 delete m_staticText;
1060 m_staticText = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001061}
1062
Zack Rusin1a9f7af2011-09-18 19:40:47 -04001063bool ApiTraceFrame::isLoaded() const
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001064{
1065 return m_loaded;
1066}
1067
1068void ApiTraceFrame::setLoaded(bool l)
1069{
1070 m_loaded = l;
1071}
1072
1073void ApiTraceFrame::setNumChildren(int num)
1074{
1075 m_callsToLoad = num;
Zack Rusin4d0ef5d2011-08-28 22:05:31 -04001076}
Zack Rusinebf971e2011-09-06 17:44:43 -04001077
1078void ApiTraceFrame::setParentTrace(ApiTrace *parent)
1079{
1080 m_parentTrace = parent;
1081}
Zack Rusin3176ebe2011-09-06 21:11:36 -04001082
1083int ApiTraceFrame::numChildrenToLoad() const
1084{
1085 return m_callsToLoad;
1086}
Zack Rusin8f98c3a2011-09-11 18:21:29 -04001087
1088ApiTraceCall *
1089ApiTraceFrame::findNextCall(ApiTraceCall *from,
1090 const QString &str,
1091 Qt::CaseSensitivity sensitivity) const
1092{
1093 Q_ASSERT(m_loaded);
1094
1095 int callIndex = 0;
1096
1097 if (from) {
1098 callIndex = m_calls.indexOf(from) + 1;
1099 }
1100
1101 for (int i = callIndex; i < m_calls.count(); ++i) {
1102 ApiTraceCall *call = m_calls[i];
1103 if (call->contains(str, sensitivity)) {
1104 return call;
1105 }
1106 }
1107 return 0;
1108}
1109
1110ApiTraceCall *
1111ApiTraceFrame::findPrevCall(ApiTraceCall *from,
1112 const QString &str,
1113 Qt::CaseSensitivity sensitivity) const
1114{
1115 Q_ASSERT(m_loaded);
1116
1117 int callIndex = m_calls.count() - 1;
1118
1119 if (from) {
1120 callIndex = m_calls.indexOf(from) - 1;
1121 }
1122
1123 for (int i = callIndex; i >= 0; --i) {
1124 ApiTraceCall *call = m_calls[i];
1125 if (call->contains(str, sensitivity)) {
1126 return call;
1127 }
1128 }
1129 return 0;
1130}
Zack Rusin851d0b02011-09-14 22:04:07 -04001131
1132void ApiTraceFrame::setLastCallIndex(unsigned index)
1133{
1134 m_lastCallIndex = index;
1135}
1136
1137unsigned ApiTraceFrame::lastCallIndex() const
1138{
1139 if (m_loaded && !m_calls.isEmpty()) {
1140 return m_calls.last()->index();
1141 } else {
1142 return m_lastCallIndex;
1143 }
1144}