static bool isVariantEditable(const QVariant &var) { if (var.canConvert<ApiArray>()) { ApiArray array = var.value<ApiArray>(); QVector<QVariant> vals = array.values(); if (vals.isEmpty()) return false; else return isVariantEditable(vals.first()); } switch (var.userType()) { case QVariant::Bool: case QVariant::Int: case QVariant::UInt: case QVariant::LongLong: case QVariant::ULongLong: case QMetaType::Float: case QVariant::Double: case QVariant::String: return true; default: return false; } }
static void writeValue(trace::Writer &writer, const QVariant &var, unsigned &id) { int arrayType = QMetaType::type("ApiArray"); int bitmaskType = QMetaType::type("ApiBitmask"); int structType = QMetaType::type("ApiStruct"); int pointerType = QMetaType::type("ApiPointer"); int enumType = QMetaType::type("ApiEnum"); int type = var.userType(); switch(type) { case QVariant::Bool: writer.writeBool(var.toBool()); break; case QVariant::ByteArray: { QByteArray ba = var.toByteArray(); writer.writeBlob((const void*)ba.constData(), ba.size()); } break; case QVariant::Double: writer.writeDouble(var.toDouble()); break; case QMetaType::Float: writer.writeFloat(var.toFloat()); break; case QVariant::Int: writer.writeSInt(var.toInt()); break; case QVariant::LongLong: writer.writeSInt(var.toLongLong()); break; case QVariant::String: { QString str = var.toString(); writer.writeString(str.toLocal8Bit().constData(), str.length()); } break; case QVariant::UInt: writer.writeUInt(var.toInt()); break; case QVariant::ULongLong: writer.writeUInt(var.toLongLong()); break; default: if (type == arrayType) { ApiArray array = var.value<ApiArray>(); QVector<QVariant> vals = array.values(); writer.beginArray(vals.count()); foreach(QVariant el, vals) { writer.beginElement(); writeValue(writer, el, ++id); writer.endElement(); } writer.endArray(); } else if (type == bitmaskType) {
static bool isVariantStringArray(const QVariant &var) { if (var.isNull() || var.userType() != QMetaType::type("ApiArray")) return false; ApiArray array = var.value<ApiArray>(); QVector<QVariant> origValues = array.values(); if (origValues.isEmpty() || origValues.first().userType() != QVariant::String) return false; return true; }
QVariant ArgumentsEditor::arrayFromEditor(const ApiArray &origArray, bool *changed) const { QVector<QVariant> vals; QVector<QVariant> origValues = origArray.values(); Q_ASSERT(isVariantStringArray(QVariant::fromValue(origArray))); *changed = false; //shaders for (int i = 0; i < m_ui.selectStringCB->count(); ++i) { QVariant val = m_ui.selectStringCB->itemData(i); QVariant origValue = origValues[i]; if (origValue != val) *changed = true; vals.append(val); } return QVariant::fromValue(ApiArray(vals)); }
QVariant ArgumentsEditor::arrayFromIndex(const QModelIndex &parentIndex, const ApiArray &origArray, bool *changed) const { QVector<QVariant> origValues = origArray.values(); *changed = false; if (origValues.isEmpty()) return QVariant::fromValue(ApiArray()); QVector<QVariant> lst; for (int i = 0; i < origValues.count(); ++i) { QModelIndex valIdx = m_model->index(i, 1, parentIndex); QVariant var = valIdx.data(); QVariant origValue = origValues[i]; if (var != origValue) *changed = true; //qDebug()<<"\t\tarray "<<i<<") "<<var; lst.append(var); } return QVariant::fromValue(ApiArray(lst)); }
void ArgumentsEditor::setupCall() { m_model->clear(); QStringList headers; headers.append(tr("Argument")); headers.append(tr("Value")); m_model->setColumnCount(2); m_model->setHorizontalHeaderLabels(headers); m_ui.argsTabWidget->removeTab( m_ui.argsTabWidget->indexOf(m_ui.shaderTab)); if (!m_call) return; m_ui.callLabel->setText(m_call->name()); QStandardItem *rootItem = m_model->invisibleRootItem(); for (int i = 0; i < m_call->argNames().count(); ++i) { QString argName = m_call->argNames()[i]; QVariant val = m_call->arguments()[i]; QStandardItem *nameItem = new QStandardItem(argName); nameItem->setFlags(nameItem->flags() ^ Qt::ItemIsEditable); QList<QStandardItem*> topRow; topRow.append(nameItem); if (val.canConvert<ApiArray>()) { ApiArray array = val.value<ApiArray>(); QVector<QVariant> vals = array.values(); QVariant firstVal = vals.value(0); if (firstVal.userType() == QVariant::String) { m_ui.argsTabWidget->addTab( m_ui.shaderTab, argName); setupShaderEditor(vals); delete nameItem; continue; } else if (isVariantEditable(firstVal)) { for (int i = 0; i < vals.count(); ++i) { QList<QStandardItem*> row; QStandardItem *idx = new QStandardItem(); idx->setFlags(idx->flags() ^ Qt::ItemIsEditable); idx->setText(tr("%1)").arg(i)); QStandardItem *col = new QStandardItem(); col->setFlags(col->flags() | Qt::ItemIsEditable); col->setData(vals[i], Qt::EditRole); row.append(idx); row.append(col); nameItem->appendRow(row); } } else { qDebug()<<"\tUnsupported array = "<<firstVal; delete nameItem; continue; } } else if (val.canConvert<ApiPointer>()) { ApiPointer ptr = val.value<ApiPointer>(); QStandardItem *item = new QStandardItem(); item->setFlags(item->flags() ^ Qt::ItemIsEditable); item->setText(ptr.toString()); QIcon icon(":/resources/emblem-locked.png"); item->setIcon(icon); item->setToolTip(tr("Argument is read-only")); topRow.append(item); } else if (val.canConvert<ApiEnum>()) { ApiEnum en = val.value<ApiEnum>(); QStandardItem *item = new QStandardItem(); item->setFlags(item->flags() ^ Qt::ItemIsEditable); item->setText(en.toString()); QIcon icon(":/resources/emblem-locked.png"); item->setIcon(icon); item->setToolTip(tr("Argument is read-only")); topRow.append(item); } else if (val.canConvert<ApiBitmask>()) { ApiBitmask mask = val.value<ApiBitmask>(); QStandardItem *item = new QStandardItem(); item->setFlags(item->flags() ^ Qt::ItemIsEditable); item->setText(mask.toString()); QIcon icon(":/resources/emblem-locked.png"); item->setIcon(icon); item->setToolTip(tr("Argument is read-only")); topRow.append(item); } else if (val.canConvert<ApiStruct>()) { ApiStruct str = val.value<ApiStruct>(); QStandardItem *item = new QStandardItem(); item->setFlags(item->flags() ^ Qt::ItemIsEditable); item->setText(str.toString()); QIcon icon(":/resources/emblem-locked.png"); item->setIcon(icon); item->setToolTip(tr("Argument is read-only")); topRow.append(item); } else if (val.userType() == QVariant::ByteArray) { QByteArray ba = val.value<QByteArray>(); QStandardItem *item = new QStandardItem(); item->setFlags(item->flags() ^ Qt::ItemIsEditable); item->setText( tr("<binary data, size = %1 bytes>").arg(ba.size())); QIcon icon(":/resources/emblem-locked.png"); item->setIcon(icon); item->setToolTip(tr("Argument is read-only")); topRow.append(item); } else { QStandardItem *item = new QStandardItem(); if (isVariantEditable(val)) { item->setFlags(item->flags() | Qt::ItemIsEditable); } else { QIcon icon(":/resources/emblem-locked.png"); item->setIcon(icon); item->setFlags(item->flags() ^ Qt::ItemIsEditable); item->setToolTip(tr("Argument is read-only")); } item->setData(val, Qt::EditRole); topRow.append(item); } rootItem->appendRow(topRow); } }