X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=gui%2Fapitracecall.cpp;h=90ebca4c2db539fcf0d3f8397c0ae5deceb26378;hb=a1a3ad5737b10636a593289f21706baaee7a1f13;hp=2d41e25a4425f972b56d6f0daafabd8c694d5863;hpb=cc0b4911a0ccc002c1eed54637f67f21c56b40fc;p=apitrace diff --git a/gui/apitracecall.cpp b/gui/apitracecall.cpp index 2d41e25..90ebca4 100644 --- a/gui/apitracecall.cpp +++ b/gui/apitracecall.cpp @@ -4,9 +4,11 @@ #include "trace_model.hpp" #include +#include #include #define QT_USE_FAST_OPERATOR_PLUS #include +#include const char * const styleSheet = ".call {\n" @@ -42,20 +44,61 @@ const char * const styleSheet = //" -moz-box-shadow: 0 1px 5px #0061aa, inset 0 10px 20px #b6f9ff;\n" "}\n"; -ApiPointer::ApiPointer(unsigned long long val) - : m_value(val) -{ -} -QString ApiPointer::toString() const +// Qt::convertFromPlainText doesn't do precisely what we want +static QString +plainTextToHTML(const QString & plain, bool multiLine) { - if (m_value) - return QString("0x%1").arg(m_value, 0, 16); - else - return QLatin1String("NULL"); + int col = 0; + bool quote = false; + QString rich; + for (int i = 0; i < plain.length(); ++i) { + if (plain[i] == QLatin1Char('\n')){ + if (multiLine) { + rich += QLatin1String("
\n"); + } else { + rich += QLatin1String("\\n"); + } + col = 0; + quote = true; + } else { + if (plain[i] == QLatin1Char('\t')){ + if (multiLine) { + rich += QChar(0x00a0U); + ++col; + while (col % 8) { + rich += QChar(0x00a0U); + ++col; + } + } else { + rich += QLatin1String("\\t"); + } + quote = true; + } else if (plain[i].isSpace()) { + rich += QChar(0x00a0U); + quote = true; + } else if (plain[i] == QLatin1Char('<')) { + rich += QLatin1String("<"); + } else if (plain[i] == QLatin1Char('>')) { + rich += QLatin1String(">"); + } else if (plain[i] == QLatin1Char('&')) { + rich += QLatin1String("&"); + } else { + rich += plain[i]; + } + ++col; + } + } + + if (quote) { + return QLatin1Literal("\"") + rich + QLatin1Literal("\""); + } + + return rich; } -QString apiVariantToString(const QVariant &variant) +QString +apiVariantToString(const QVariant &variant, bool multiLine) { if (variant.userType() == QVariant::Double) { return QString::number(variant.toFloat()); @@ -70,6 +113,10 @@ QString apiVariantToString(const QVariant &variant) } } + if (variant.userType() == QVariant::String) { + return plainTextToHTML(variant.toString(), multiLine); + } + if (variant.userType() < QVariant::UserType) { return variant.toString(); } @@ -93,26 +140,159 @@ QString apiVariantToString(const QVariant &variant) return QString(); } + +void VariantVisitor::visit(Trace::Null *) +{ + m_variant = QVariant::fromValue(ApiPointer(0)); +} + +void VariantVisitor::visit(Trace::Bool *node) +{ + m_variant = QVariant(node->value); +} + +void VariantVisitor::visit(Trace::SInt *node) +{ + m_variant = QVariant(node->value); +} + +void VariantVisitor::visit(Trace::UInt *node) +{ + m_variant = QVariant(node->value); +} + +void VariantVisitor::visit(Trace::Float *node) +{ + m_variant = QVariant(node->value); +} + +void VariantVisitor::visit(Trace::String *node) +{ + m_variant = QVariant(QString::fromStdString(node->value)); +} + +void VariantVisitor::visit(Trace::Enum *e) +{ + QVariant val = QVariant(e->sig->value); + + m_variant = QVariant::fromValue( + ApiEnum(QString::fromStdString(e->sig->name), val)); +} + +void VariantVisitor::visit(Trace::Bitmask *bitmask) +{ + m_variant = QVariant::fromValue(ApiBitmask(bitmask)); +} + +void VariantVisitor::visit(Trace::Struct *str) +{ + m_variant = QVariant::fromValue(ApiStruct(str)); +} + +void VariantVisitor::visit(Trace::Array *array) +{ + m_variant = QVariant::fromValue(ApiArray(array)); +} + +void VariantVisitor::visit(Trace::Blob *blob) +{ + //XXX + //FIXME: this is a nasty hack. Trace::Blob's can't + // delete the contents in the destructor because + // the data is being used by other calls. We piggy back + // on that assumption and don't deep copy the data. If + // Blob's will start deleting the data we will need to + // start deep copying it or switch to using something like + // Boost's shared_ptr or Qt's QSharedPointer to handle it + QByteArray barray = QByteArray::fromRawData(blob->buf, blob->size); + m_variant = QVariant(barray); +} + +void VariantVisitor::visit(Trace::Pointer *ptr) +{ + m_variant = QVariant::fromValue(ApiPointer(ptr->value)); +} + + +ApiEnum::ApiEnum(const QString &name, const QVariant &val) + : m_name(name), + m_value(val) +{ +} + +QString ApiEnum::toString() const +{ + return m_name; +} + +QVariant ApiEnum::value() const +{ + return m_value; +} + +QString ApiEnum::name() const +{ + return m_name; +} + +unsigned long long ApiBitmask::value() const +{ + return m_value; +} + +ApiBitmask::Signature ApiBitmask::signature() const +{ + return m_sig; +} + +ApiStruct::Signature ApiStruct::signature() const +{ + return m_sig; +} + +QList ApiStruct::values() const +{ + return m_members; +} + +ApiPointer::ApiPointer(unsigned long long val) + : m_value(val) +{ +} + + +unsigned long long ApiPointer::value() const +{ + return m_value; +} + +QString ApiPointer::toString() const +{ + if (m_value) + return QString("0x%1").arg(m_value, 0, 16); + else + return QLatin1String("NULL"); +} + ApiBitmask::ApiBitmask(const Trace::Bitmask *bitmask) : m_value(0) { init(bitmask); } - void ApiBitmask::init(const Trace::Bitmask *bitmask) { if (!bitmask) return; m_value = bitmask->value; - for (Trace::Bitmask::Signature::const_iterator it = bitmask->sig->begin(); - it != bitmask->sig->end(); ++it) { - assert(it->second); + for (const Trace::BitmaskFlag *it = bitmask->sig->flags; + it != bitmask->sig->flags + bitmask->sig->num_flags; ++it) { + assert(it->value); QPair pair; - pair.first = QString::fromStdString(it->first); - pair.second = it->second; + pair.first = QString::fromStdString(it->name); + pair.second = it->value; m_sig.append(pair); } @@ -172,7 +352,7 @@ void ApiStruct::init(const Trace::Struct *s) return; m_sig.name = QString::fromStdString(s->sig->name); - for (unsigned i = 0; i < s->members.size(); ++i) { + for (unsigned i = 0; i < s->sig->num_members; ++i) { VariantVisitor vis; m_sig.memberNames.append( QString::fromStdString(s->sig->member_names[i])); @@ -181,81 +361,6 @@ void ApiStruct::init(const Trace::Struct *s) } } -void VariantVisitor::visit(Trace::Null *) -{ - m_variant = QVariant::fromValue(ApiPointer(0)); -} - -void VariantVisitor::visit(Trace::Bool *node) -{ - m_variant = QVariant(node->value); -} - -void VariantVisitor::visit(Trace::SInt *node) -{ - m_variant = QVariant(node->value); -} - -void VariantVisitor::visit(Trace::UInt *node) -{ - m_variant = QVariant(node->value); -} - -void VariantVisitor::visit(Trace::Float *node) -{ - m_variant = QVariant(node->value); -} - -void VariantVisitor::visit(Trace::String *node) -{ - m_variant = QVariant(QString::fromStdString(node->value)); -} - -void VariantVisitor::visit(Trace::Enum *e) -{ - VariantVisitor vis; - e->sig->second->visit(vis); - - QVariant val = vis.variant(); - - m_variant = QVariant::fromValue( - ApiEnum(QString::fromStdString(e->sig->first), val)); -} - -void VariantVisitor::visit(Trace::Bitmask *bitmask) -{ - m_variant = QVariant::fromValue(ApiBitmask(bitmask)); -} - -void VariantVisitor::visit(Trace::Struct *str) -{ - m_variant = QVariant::fromValue(ApiStruct(str)); -} - -void VariantVisitor::visit(Trace::Array *array) -{ - m_variant = QVariant::fromValue(ApiArray(array)); -} - -void VariantVisitor::visit(Trace::Blob *blob) -{ - //XXX - //FIXME: this is a nasty hack. Trace::Blob's can't - // delete the contents in the destructor because - // the data is being used by other calls. We piggy back - // on that assumption and don't deep copy the data. If - // Blob's will start deleting the data we will need to - // start deep copying it or switch to using something like - // Boost's shared_ptr or Qt's QSharedPointer to handle it - QByteArray barray = QByteArray::fromRawData(blob->buf, blob->size); - m_variant = QVariant(barray); -} - -void VariantVisitor::visit(Trace::Pointer *ptr) -{ - m_variant = QVariant::fromValue(ApiPointer(ptr->value)); -} - ApiArray::ApiArray(const Trace::Array *arr) { init(arr); @@ -266,6 +371,11 @@ ApiArray::ApiArray(const QList &vals) { } +QList ApiArray::values() const +{ + return m_array; +} + QString ApiArray::toString() const { QString str; @@ -294,189 +404,109 @@ void ApiArray::init(const Trace::Array *arr) } } -QStaticText ApiTraceCall::staticText() const +ApiTraceState::ApiTraceState() { - if (m_staticText && !m_staticText->text().isEmpty()) - return *m_staticText; +} - QVariantList argValues = arguments(); +ApiTraceState::ApiTraceState(const QVariantMap &parsedJson) +{ + m_parameters = parsedJson[QLatin1String("parameters")].toMap(); + QVariantMap attachedShaders = + parsedJson[QLatin1String("shaders")].toMap(); + QVariantMap::const_iterator itr; - QString richText = QString::fromLatin1( - "%1(").arg(m_name); - for (int i = 0; i < m_argNames.count(); ++i) { - richText += QLatin1String(""); - QString argText = apiVariantToString(argValues[i]); - //if arguments are really long (e.g. shader text), cut them - // and elide it - if (argText.length() > 40) { - QString shortened = argText.mid(0, 40); - shortened[argText.length() - 5] = '.'; - shortened[argText.length() - 4] = '.'; - shortened[argText.length() - 3] = '.'; - shortened[argText.length() - 2] = argText[argText.length() - 2]; - shortened[argText.length() - 1] = argText[argText.length() - 1]; - richText += shortened; - } else { - richText += argText; - } - richText += QLatin1String(""); - if (i < m_argNames.count() - 1) - richText += QLatin1String(", "); - } - richText += QLatin1String(")"); - if (m_returnValue.isValid()) { - richText += - QLatin1Literal(" = ") % - QLatin1Literal("") % - apiVariantToString(m_returnValue) % - QLatin1Literal(""); + for (itr = attachedShaders.constBegin(); itr != attachedShaders.constEnd(); + ++itr) { + QString type = itr.key(); + QString source = itr.value().toString(); + m_shaderSources[type] = source; } - if (!m_staticText) - m_staticText = new QStaticText(richText); - else - m_staticText->setText(richText); - QTextOption opt; - opt.setWrapMode(QTextOption::NoWrap); - m_staticText->setTextOption(opt); - m_staticText->prepare(); - - return *m_staticText; -} + m_uniforms = parsedJson[QLatin1String("uniforms")].toMap(); + + QVariantMap textures = + parsedJson[QLatin1String("textures")].toMap(); + for (itr = textures.constBegin(); itr != textures.constEnd(); ++itr) { + QVariantMap image = itr.value().toMap(); + QSize size(image[QLatin1String("__width__")].toInt(), + image[QLatin1String("__height__")].toInt()); + QString cls = image[QLatin1String("__class__")].toString(); + QString type = image[QLatin1String("__type__")].toString(); + bool normalized = + image[QLatin1String("__normalized__")].toBool(); + int numChannels = + image[QLatin1String("__channels__")].toInt(); -QString ApiTraceCall::toHtml() const -{ - if (!m_richText.isEmpty()) - return m_richText; + Q_ASSERT(type == QLatin1String("uint8")); + Q_ASSERT(normalized == true); - m_richText = QLatin1String("
"); + QByteArray dataArray = + image[QLatin1String("__data__")].toByteArray(); - if (m_helpUrl.isEmpty()) { - m_richText += QString::fromLatin1( - "%1) %2(") - .arg(m_index) - .arg(m_name); - } else { - m_richText += QString::fromLatin1( - "%1) %3(") - .arg(m_index) - .arg(m_helpUrl.toString()) - .arg(m_name); - } + ApiTexture tex; + tex.setSize(size); + tex.setNumChannels(numChannels); + tex.setLabel(itr.key()); + tex.contentsFromBase64(dataArray); - QVariantList argValues = arguments(); - for (int i = 0; i < m_argNames.count(); ++i) { - m_richText += - QLatin1String("") + - m_argNames[i] + - QLatin1String("") + - QLatin1Literal(" = ") + - QLatin1Literal("") + - apiVariantToString(argValues[i]) + - QLatin1Literal(""); - if (i < m_argNames.count() - 1) - m_richText += QLatin1String(", "); + m_textures.append(tex); } - m_richText += QLatin1String(")"); - if (m_returnValue.isValid()) { - m_richText += - QLatin1String(" = ") + - QLatin1String("") + - apiVariantToString(m_returnValue) + - QLatin1String(""); - } - m_richText += QLatin1String("
"); + QVariantMap fbos = + parsedJson[QLatin1String("framebuffer")].toMap(); + for (itr = fbos.constBegin(); itr != fbos.constEnd(); ++itr) { + QVariantMap buffer = itr.value().toMap(); + QSize size(buffer[QLatin1String("__width__")].toInt(), + buffer[QLatin1String("__height__")].toInt()); + QString cls = buffer[QLatin1String("__class__")].toString(); + QString type = buffer[QLatin1String("__type__")].toString(); + bool normalized = buffer[QLatin1String("__normalized__")].toBool(); + int numChannels = buffer[QLatin1String("__channels__")].toInt(); - if (hasError()) { - QString errorStr = - QString::fromLatin1( - "
%1
") - .arg(m_error); - m_richText += errorStr; - } + Q_ASSERT(type == QLatin1String("uint8")); + Q_ASSERT(normalized == true); - m_richText = - QString::fromLatin1( - "%2") - .arg(styleSheet) - .arg(m_richText); - m_richText.squeeze(); + QByteArray dataArray = + buffer[QLatin1String("__data__")].toByteArray(); - //qDebug()< & ApiTraceState::shaderSources() const { - if (m_staticText && !m_staticText->text().isEmpty()) - return *m_staticText; - - QString richText = - QString::fromLatin1("Frame %1").arg(number); - - if (!m_staticText) - m_staticText = new QStaticText(richText); - - QTextOption opt; - opt.setWrapMode(QTextOption::NoWrap); - m_staticText->setTextOption(opt); - m_staticText->prepare(); - - return *m_staticText; + return m_shaderSources; } -int ApiTraceCall::numChildren() const +const QVariantMap & ApiTraceState::uniforms() const { - return 0; + return m_uniforms; } -int ApiTraceFrame::numChildren() const +bool ApiTraceState::isEmpty() const { - return calls.count(); + return m_parameters.isEmpty(); } -ApiTraceFrame::ApiTraceFrame() - : ApiTraceEvent(ApiTraceEvent::Frame), - m_parentTrace(0) +const QList & ApiTraceState::textures() const { + return m_textures; } -ApiTraceCall::ApiTraceCall() - : ApiTraceEvent(ApiTraceEvent::Call), - m_hasBinaryData(false), - m_binaryDataIndex(0) +const QList & ApiTraceState::framebuffers() const { + return m_framebuffers; } ApiTraceEvent::ApiTraceEvent() @@ -491,8 +521,9 @@ ApiTraceEvent::ApiTraceEvent(Type t) { } -ApiTraceCall::~ApiTraceCall() +ApiTraceEvent::~ApiTraceEvent() { + delete m_staticText; } QVariantMap ApiTraceEvent::stateParameters() const @@ -510,129 +541,130 @@ void ApiTraceEvent::setState(const ApiTraceState &state) m_state = state; } -bool ApiTraceCall::hasBinaryData() const + +ApiTraceCall::ApiTraceCall() + : ApiTraceEvent(ApiTraceEvent::Call), + m_hasBinaryData(false), + m_binaryDataIndex(0) { - return m_hasBinaryData; } -int ApiTraceCall::binaryDataIndex() const + +ApiTraceCall::ApiTraceCall(const Trace::Call *call) + : ApiTraceEvent(ApiTraceEvent::Call), + m_hasBinaryData(false), + m_binaryDataIndex(0) { - return m_binaryDataIndex; + m_name = QString::fromStdString(call->sig->name); + m_index = call->no; + + QString argumentsText; + for (int i = 0; i < call->sig->num_args; ++i) { + m_argNames += + QString::fromStdString(call->sig->arg_names[i]); + } + if (call->ret) { + VariantVisitor retVisitor; + call->ret->visit(retVisitor); + m_returnValue = retVisitor.variant(); + } + for (int i = 0; i < call->args.size(); ++i) { + VariantVisitor argVisitor; + call->args[i]->visit(argVisitor); + m_argValues += argVisitor.variant(); + if (m_argValues[i].type() == QVariant::ByteArray) { + m_hasBinaryData = true; + m_binaryDataIndex = i; + } + } } -ApiTraceState::ApiTraceState() +ApiTraceCall::~ApiTraceCall() { } -ApiTraceState::ApiTraceState(const QVariantMap &parsedJson) + +bool ApiTraceCall::hasError() const { - m_parameters = parsedJson[QLatin1String("parameters")].toMap(); - QVariantMap attachedShaders = - parsedJson[QLatin1String("shaders")].toMap(); - QVariantMap::const_iterator itr; + return !m_error.isEmpty(); +} +QString ApiTraceCall::error() const +{ + return m_error; +} - for (itr = attachedShaders.constBegin(); itr != attachedShaders.constEnd(); - ++itr) { - QString type = itr.key(); - QString source = itr.value().toString(); - m_shaderSources[type] = source; +void ApiTraceCall::setError(const QString &msg) +{ + if (m_error != msg) { + ApiTrace *trace = parentTrace(); + m_error = msg; + m_richText = QString(); + if (trace) + trace->callError(this); } +} - QVariantList textureUnits = - parsedJson[QLatin1String("textures")].toList(); - for (int i = 0; i < textureUnits.count(); ++i) { - QVariantMap unit = textureUnits[i].toMap(); - for (itr = unit.constBegin(); itr != unit.constEnd(); ++itr) { - QVariantMap target = itr.value().toMap(); - if (target.count()) { - QVariantList levels = target[QLatin1String("levels")].toList(); - for (int j = 0; j < levels.count(); ++j) { - QVariantMap level = levels[j].toMap(); - QVariantMap image = level[QLatin1String("image")].toMap(); - QSize size(image[QLatin1String("__width__")].toInt(), - image[QLatin1String("__height__")].toInt()); - QString cls = image[QLatin1String("__class__")].toString(); - QString type = image[QLatin1String("__type__")].toString(); - bool normalized = - image[QLatin1String("__normalized__")].toBool(); - int numChannels = - image[QLatin1String("__channels__")].toInt(); - - Q_ASSERT(type == QLatin1String("uint8")); - Q_ASSERT(normalized == true); - - QByteArray dataArray = - image[QLatin1String("__data__")].toByteArray(); - - ApiTexture tex; - tex.setSize(size); - tex.setNumChannels(numChannels); - tex.setLevel(j); - tex.setUnit(i); - tex.setTarget(itr.key()); - tex.contentsFromBase64(dataArray); - - m_textures.append(tex); - } - } - } - } +ApiTrace * ApiTraceCall::parentTrace() const +{ + if (m_parentFrame) + return m_parentFrame->parentTrace(); + return NULL; +} - QVariantMap fbos = - parsedJson[QLatin1String("framebuffer")].toMap(); - for (itr = fbos.constBegin(); itr != fbos.constEnd(); ++itr) { - QVariantMap buffer = itr.value().toMap(); - QSize size(buffer[QLatin1String("__width__")].toInt(), - buffer[QLatin1String("__height__")].toInt()); - QString cls = buffer[QLatin1String("__class__")].toString(); - QString type = buffer[QLatin1String("__type__")].toString(); - bool normalized = buffer[QLatin1String("__normalized__")].toBool(); - int numChannels = buffer[QLatin1String("__channels__")].toInt(); +QVariantList ApiTraceCall::originalValues() const +{ + return m_argValues; +} - Q_ASSERT(type == QLatin1String("uint8")); - Q_ASSERT(normalized == true); +void ApiTraceCall::setEditedValues(const QVariantList &lst) +{ + ApiTrace *trace = parentTrace(); - QByteArray dataArray = - buffer[QLatin1String("__data__")].toByteArray(); + m_editedValues = lst; + //lets regenerate data + m_richText = QString(); + m_filterText = QString(); + delete m_staticText; + m_staticText = 0; - ApiFramebuffer fbo; - fbo.setSize(size); - fbo.setNumChannels(numChannels); - fbo.setType(itr.key()); - fbo.contentsFromBase64(dataArray); - m_framebuffers.append(fbo); + if (trace) { + if (!lst.isEmpty()) { + trace->callEdited(this); + } else { + trace->callReverted(this); + } } } -QVariantMap ApiTraceState::parameters() const +QVariantList ApiTraceCall::editedValues() const { - return m_parameters; + return m_editedValues; } -QMap ApiTraceState::shaderSources() const +bool ApiTraceCall::edited() const { - return m_shaderSources; + return !m_editedValues.isEmpty(); } -bool ApiTraceState::isEmpty() const +void ApiTraceCall::revert() { - return m_parameters.isEmpty(); + setEditedValues(QVariantList()); } -QList ApiTraceState::textures() const +void ApiTraceCall::setHelpUrl(const QUrl &url) { - return m_textures; + m_helpUrl = url; } -QList ApiTraceState::framebuffers() const +void ApiTraceCall::setParentFrame(ApiTraceFrame *frame) { - return m_framebuffers; + m_parentFrame = frame; } -QList ApiArray::values() const +ApiTraceFrame * ApiTraceCall::parentFrame()const { - return m_array; + return m_parentFrame; } int ApiTraceCall::index() const @@ -668,172 +700,248 @@ QUrl ApiTraceCall::helpUrl() const return m_helpUrl; } -ApiTraceCall::ApiTraceCall(const Trace::Call *call) - : ApiTraceEvent(ApiTraceEvent::Call), - m_hasBinaryData(false), - m_binaryDataIndex(0) +bool ApiTraceCall::hasBinaryData() const { - m_name = QString::fromStdString(call->sig->name); - m_index = call->no; - - QString argumentsText; - for (int i = 0; i < call->sig->arg_names.size(); ++i) { - m_argNames += - QString::fromStdString(call->sig->arg_names[i]); - } - if (call->ret) { - VariantVisitor retVisitor; - call->ret->visit(retVisitor); - m_returnValue = retVisitor.variant(); - } - for (int i = 0; i < call->args.size(); ++i) { - VariantVisitor argVisitor; - call->args[i]->visit(argVisitor); - m_argValues += argVisitor.variant(); - } + return m_hasBinaryData; } -void ApiTraceCall::setHelpUrl(const QUrl &url) +int ApiTraceCall::binaryDataIndex() const { - m_helpUrl = url; + return m_binaryDataIndex; } -void ApiTraceCall::setParentFrame(ApiTraceFrame *frame) +QStaticText ApiTraceCall::staticText() const { - m_parentFrame = frame; -} + if (m_staticText && !m_staticText->text().isEmpty()) + return *m_staticText; -ApiTraceFrame * ApiTraceCall::parentFrame()const -{ - return m_parentFrame; -} + QVariantList argValues = arguments(); -ApiTraceEvent::~ApiTraceEvent() -{ - delete m_staticText; -} + QString richText = QString::fromLatin1( + "%1(").arg(m_name); + for (int i = 0; i < m_argNames.count(); ++i) { + richText += QLatin1String(""); + QString argText = apiVariantToString(argValues[i]); -void ApiTraceCall::revert() -{ - setEditedValues(QVariantList()); -} + //if arguments are really long (e.g. shader text), cut them + // and elide it + if (argText.length() > 40) { + QString shortened = argText.mid(0, 40); + shortened[argText.length() - 5] = '.'; + shortened[argText.length() - 4] = '.'; + shortened[argText.length() - 3] = '.'; + shortened[argText.length() - 2] = argText[argText.length() - 2]; + shortened[argText.length() - 1] = argText[argText.length() - 1]; + richText += shortened; + } else { + richText += argText; + } + richText += QLatin1String(""); + if (i < m_argNames.count() - 1) + richText += QLatin1String(", "); + } + richText += QLatin1String(")"); + if (m_returnValue.isValid()) { + richText += + QLatin1Literal(" = ") % + QLatin1Literal("") % + apiVariantToString(m_returnValue) % + QLatin1Literal(""); + } -ApiTrace * ApiTraceFrame::parentTrace() const -{ - return m_parentTrace; -} + if (!m_staticText) + m_staticText = new QStaticText(richText); + else + m_staticText->setText(richText); + QTextOption opt; + opt.setWrapMode(QTextOption::NoWrap); + m_staticText->setTextOption(opt); + m_staticText->prepare(); -void ApiTraceFrame::setParentTrace(ApiTrace *trace) -{ - m_parentTrace = trace; + return *m_staticText; } -QVariantList ApiTraceCall::originalValues() const +QString ApiTraceCall::toHtml() const { - return m_argValues; -} + if (!m_richText.isEmpty()) + return m_richText; -void ApiTraceCall::setEditedValues(const QVariantList &lst) -{ - ApiTrace *trace = parentTrace(); + m_richText = QLatin1String("
"); - m_editedValues = lst; - //lets regenerate data - m_richText = QString(); - m_filterText = QString(); - delete m_staticText; - m_staticText = 0; + if (m_helpUrl.isEmpty()) { + m_richText += QString::fromLatin1( + "%1) %2(") + .arg(m_index) + .arg(m_name); + } else { + m_richText += QString::fromLatin1( + "%1) %3(") + .arg(m_index) + .arg(m_helpUrl.toString()) + .arg(m_name); + } - if (trace) { - if (!lst.isEmpty()) { - trace->callEdited(this); - } else { - trace->callReverted(this); - } + QVariantList argValues = arguments(); + for (int i = 0; i < m_argNames.count(); ++i) { + m_richText += + QLatin1String("") + + m_argNames[i] + + QLatin1String("") + + QLatin1Literal(" = ") + + QLatin1Literal("") + + apiVariantToString(argValues[i], true) + + QLatin1Literal(""); + if (i < m_argNames.count() - 1) + m_richText += QLatin1String(", "); } -} + m_richText += QLatin1String(")"); -QVariantList ApiTraceCall::editedValues() const -{ - return m_editedValues; -} + if (m_returnValue.isValid()) { + m_richText += + QLatin1String(" = ") + + QLatin1String("") + + apiVariantToString(m_returnValue, true) + + QLatin1String(""); + } + m_richText += QLatin1String("
"); -bool ApiTraceCall::edited() const -{ - return !m_editedValues.isEmpty(); + if (hasError()) { + QString errorStr = + QString::fromLatin1( + "
%1
") + .arg(m_error); + m_richText += errorStr; + } + + m_richText = + QString::fromLatin1( + "%2") + .arg(styleSheet) + .arg(m_richText); + m_richText.squeeze(); + + //qDebug()<text().isEmpty()) + return *m_staticText; + + QString richText; + + //mark the frame if it uploads more than a meg a frame + if (m_binaryDataSize > (1024*1024)) { + richText = + QObject::tr( + "" + "Frame %1" + "" + "    (%2MB)") + .arg(number) + .arg(double(m_binaryDataSize / (1024.*1024.)), 0, 'g', 2); + } else { + richText = + QObject::tr( + "Frame %1") + .arg(number); + } + + if (!m_staticText) + m_staticText = new QStaticText(richText); + + QTextOption opt; + opt.setWrapMode(QTextOption::NoWrap); + m_staticText->setTextOption(opt); + m_staticText->prepare(); + + return *m_staticText; } -unsigned long long ApiBitmask::value() const +int ApiTraceFrame::numChildren() const { - return m_value; + return m_calls.count(); } -ApiBitmask::Signature ApiBitmask::signature() const +ApiTrace * ApiTraceFrame::parentTrace() const { - return m_sig; + return m_parentTrace; } -ApiStruct::Signature ApiStruct::signature() const +void ApiTraceFrame::setParentTrace(ApiTrace *trace) { - return m_sig; + m_parentTrace = trace; } -QList ApiStruct::values() const +void ApiTraceFrame::addCall(ApiTraceCall *call) { - return m_members; + m_calls.append(call); + if (call->hasBinaryData()) { + QByteArray data = + call->arguments()[call->binaryDataIndex()].toByteArray(); + m_binaryDataSize += data.size(); + } } -unsigned long long ApiPointer::value() const +QList ApiTraceFrame::calls() const { - return m_value; + return m_calls; } -bool ApiTraceCall::hasError() const +ApiTraceCall * ApiTraceFrame::call(int idx) const { - return !m_error.isEmpty(); + return m_calls.value(idx); } -QString ApiTraceCall::error() const +int ApiTraceFrame::callIndex(ApiTraceCall *call) const { - return m_error; + return m_calls.indexOf(call); } -void ApiTraceCall::setError(const QString &msg) +bool ApiTraceFrame::isEmpty() const { - if (m_error != msg) { - ApiTrace *trace = parentTrace(); - m_error = msg; - m_richText = QString(); - if (trace) - trace->callError(this); - } + return m_calls.isEmpty(); } -ApiTrace * ApiTraceCall::parentTrace() const +int ApiTraceFrame::binaryDataSize() const { - if (m_parentFrame) - return m_parentFrame->parentTrace(); - return NULL; + return m_binaryDataSize; } -