X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=gui%2Fargumentseditor.cpp;h=1ee519ea444d672598d414f7dc12f559c4914862;hb=1b8305c0c318b54e71c180323baf748bc9656976;hp=7e0974a70aaf61630af63e0db5120ae2b15dbd8a;hpb=4b3d3bf911c2fd927ce6570e1e52e7b3286746ad;p=apitrace diff --git a/gui/argumentseditor.cpp b/gui/argumentseditor.cpp index 7e0974a..1ee519e 100644 --- a/gui/argumentseditor.cpp +++ b/gui/argumentseditor.cpp @@ -1,5 +1,7 @@ #include "argumentseditor.h" +#include "apitracecall.h" + #include #include #include @@ -8,10 +10,139 @@ #include #include -#include "apitracecall.h" + +static bool +isVariantEditable(const QVariant &var) +{ + if (var.canConvert()) { + ApiArray array = var.value(); + QVector 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 QVariant::Double: + return true; + default: + return false; + } +} + +static bool +isVariantStringArray(const QVariant &var) +{ + if (var.isNull() || var.userType() != QMetaType::type("ApiArray")) + return false; + + ApiArray array = var.value(); + QVector origValues = array.values(); + if (origValues.isEmpty() || + origValues.first().userType() != QVariant::String) + return false; + + return true; +} + +ArgumentsItemEditorFactory::ArgumentsItemEditorFactory() + : QItemEditorFactory() +{ +} + +QWidget * ArgumentsItemEditorFactory::createEditor(QVariant::Type type, + QWidget *parent) const +{ + switch (type) { + case QVariant::Bool: { + BooleanComboBox *cb = new BooleanComboBox(parent); + cb->setFrame(false); + return cb; + } + case QVariant::UInt: { + QSpinBox *sb = new QSpinBox(parent); + sb->setFrame(false); + sb->setMaximum(INT_MAX); + return sb; } + case QVariant::Int: { + QSpinBox *sb = new QSpinBox(parent); + sb->setFrame(false); + sb->setMinimum(INT_MIN); + sb->setMaximum(INT_MAX); + return sb; + } + case QVariant::ULongLong: { + QSpinBox *sb = new QSpinBox(parent); + sb->setFrame(false); + sb->setMaximum(INT_MAX); + return sb; } + case QVariant::LongLong: { + QSpinBox *sb = new QSpinBox(parent); + sb->setFrame(false); + sb->setMinimum(INT_MIN); + sb->setMaximum(INT_MAX); + return sb; + } + case QVariant::Pixmap: + return new QLabel(parent); + case QVariant::Double: { + QDoubleSpinBox *sb = new QDoubleSpinBox(parent); + sb->setFrame(false); + sb->setMinimum(-DBL_MAX); + sb->setMaximum(DBL_MAX); + sb->setDecimals(8); + return sb; + } + default: + break; + } + return 0; +} + +QByteArray +ArgumentsItemEditorFactory::valuePropertyName(QVariant::Type type) const +{ + switch (type) { + case QVariant::Bool: + return "currentIndex"; + case QVariant::UInt: + case QVariant::Int: + case QVariant::LongLong: + case QVariant::ULongLong: + case QVariant::Double: + return "value"; +#if 0 + case QVariant::String: +#endif + default: + return "text"; + } +} + +BooleanComboBox::BooleanComboBox(QWidget *parent) + : QComboBox(parent) +{ + addItem(tr("False")); + addItem(tr("True")); +} + +void BooleanComboBox::setValue(bool value) +{ + setCurrentIndex(value ? 1 : 0); +} + +bool BooleanComboBox::value() const +{ + return (currentIndex() == 1); +} ArgumentsEditor::ArgumentsEditor(QWidget *parent) - : QWidget(parent), + : QDialog(parent), m_model(new QStandardItemModel()), m_call(0) { @@ -20,14 +151,13 @@ ArgumentsEditor::ArgumentsEditor(QWidget *parent) ArgumentsEditor::~ArgumentsEditor() { + delete m_model; } void ArgumentsEditor::setCall(ApiTraceCall *call) { - if (m_call != call) { - m_call = call; - setupCall(); - } + m_call = call; + setupCall(); } ApiTraceCall * ArgumentsEditor::call() const @@ -39,6 +169,13 @@ void ArgumentsEditor::init() { m_ui.setupUi(this); + connect(m_ui.selectStringCB, SIGNAL(currentIndexChanged(int)), + SLOT(currentSourceChanged(int))); + connect(m_ui.glslEdit, SIGNAL(textChanged()), + SLOT(sourceChanged())); + connect(m_ui.revertButton, SIGNAL(clicked()), + SLOT(revert())); + m_ui.argsTree->setModel(m_model); QItemEditorFactory *factory = new ArgumentsItemEditorFactory(); @@ -61,29 +198,28 @@ void ArgumentsEditor::setupCall() if (!m_call) return; - m_ui.callLabel->setText(m_call->name); + 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->argValues[i]; + 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 topRow; topRow.append(nameItem); - qDebug()<<"arg "<()) { + ApiEnum en = val.value(); + 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 mask = val.value(); QStandardItem *item = new QStandardItem(); @@ -140,7 +288,15 @@ void ArgumentsEditor::setupCall() } else { QStandardItem *item = new QStandardItem(); - item->setFlags(item->flags() | Qt::ItemIsEditable); + + 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::DisplayRole); topRow.append(item); } @@ -148,99 +304,150 @@ void ArgumentsEditor::setupCall() } } -void ArgumentsEditor::setupShaderEditor(const QList &sources) +void ArgumentsEditor::setupShaderEditor(const QVector &sources) { + m_ui.selectStringCB->clear(); + m_ui.glslEdit->clear(); + for (int i = 0; i < sources.count(); ++i) { + m_ui.selectStringCB->addItem( + tr("Shader string: %1").arg(i), + sources[i]); + } + m_ui.selectStringCB->setCurrentIndex(0); } -ArgumentsItemEditorFactory::ArgumentsItemEditorFactory() - : QItemEditorFactory() +void ArgumentsEditor::currentSourceChanged(int idx) { + QVariant source = m_ui.selectStringCB->itemData(idx); + QString str = source.toString(); + m_ui.glslEdit->setPlainText(source.toString()); + m_ui.lengthLabel->setText( + tr("%1").arg(str.length())); } -QWidget * ArgumentsItemEditorFactory::createEditor(QVariant::Type type, - QWidget *parent) const +void ArgumentsEditor::sourceChanged() { - switch (type) { - case QVariant::Bool: { - BooleanComboBox *cb = new BooleanComboBox(parent); - cb->setFrame(false); - return cb; - } - case QVariant::UInt: { - QSpinBox *sb = new QSpinBox(parent); - sb->setFrame(false); - sb->setMaximum(INT_MAX); - return sb; } - case QVariant::Int: { - QSpinBox *sb = new QSpinBox(parent); - sb->setFrame(false); - sb->setMinimum(INT_MIN); - sb->setMaximum(INT_MAX); - return sb; - } - case QVariant::ULongLong: { - QSpinBox *sb = new QSpinBox(parent); - sb->setFrame(false); - sb->setMaximum(INT_MAX); - return sb; } - case QVariant::LongLong: { - QSpinBox *sb = new QSpinBox(parent); - sb->setFrame(false); - sb->setMinimum(INT_MIN); - sb->setMaximum(INT_MAX); - return sb; - } - case QVariant::Pixmap: - return new QLabel(parent); - case QVariant::Double: { - QDoubleSpinBox *sb = new QDoubleSpinBox(parent); - sb->setFrame(false); - sb->setMinimum(-DBL_MAX); - sb->setMaximum(DBL_MAX); - sb->setDecimals(10); - return sb; - } - default: - break; - } - return 0; + QString str = m_ui.glslEdit->toPlainText(); + m_ui.lengthLabel->setText( + tr("%1").arg(str.length())); + + m_ui.selectStringCB->setItemData( + m_ui.selectStringCB->currentIndex(), + str); } -QByteArray -ArgumentsItemEditorFactory::valuePropertyName(QVariant::Type type) const +void ArgumentsEditor::accept() { - switch (type) { - case QVariant::Bool: - return "currentIndex"; - case QVariant::UInt: - case QVariant::Int: - case QVariant::LongLong: - case QVariant::ULongLong: - case QVariant::Double: - return "value"; + QStringList argNames = m_call->argNames(); + QVector originalValues = m_call->arguments(); + QVector newValues; + bool changed = false; + for (int i = 0; i < argNames.count(); ++i) { + bool valChanged = false; + QString argName = argNames[i]; + QVariant argValue = originalValues[i]; + QVariant editorValue = valueForName(argName, argValue, &valChanged); + + newValues.append(editorValue); #if 0 - case QVariant::String: + qDebug()<<"Arg = "<setEditedValues(newValues); + QDialog::accept(); } -BooleanComboBox::BooleanComboBox(QWidget *parent) - : QComboBox(parent) +QVariant ArgumentsEditor::valueForName(const QString &name, + const QVariant &originalValue, + bool *changed) const { - addItem(tr("False")); - addItem(tr("True")); + QVariant val; + + *changed = false; + + //Handle string arrays specially + if (isVariantStringArray(originalValue)) { + ApiArray array = originalValue.value(); + return arrayFromEditor(array, changed); + } + + if (!isVariantEditable(originalValue)) { + return originalValue; + } + + for (int topRow = 0; topRow < m_model->rowCount(); ++topRow) { + QModelIndex nameIdx = m_model->index(topRow, 0, QModelIndex()); + QString argName = nameIdx.data().toString(); + /* we display shaders in a separate widget so + * the ordering might be different */ + if (argName == name) { + if (originalValue.userType() == QMetaType::type("ApiArray")) { + ApiArray array = originalValue.value(); + val = arrayFromIndex(nameIdx, array, changed); + } else { + QModelIndex valIdx = m_model->index(topRow, 1, QModelIndex()); + val = valIdx.data(); + if (val != originalValue) + *changed = true; + } + } + } + return val; } -void BooleanComboBox::setValue(bool value) +QVariant ArgumentsEditor::arrayFromIndex(const QModelIndex &parentIndex, + const ApiArray &origArray, + bool *changed) const { - setCurrentIndex(value ? 1 : 0); + QVector origValues = origArray.values(); + + *changed = false; + + if (origValues.isEmpty()) + return QVariant::fromValue(ApiArray()); + + QVector 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 "< vals; + QVector 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)); +} + +void ArgumentsEditor::revert() +{ + m_call->revert(); + setupCall(); } #include "argumentseditor.moc"