]> git.cworth.org Git - apitrace/blobdiff - gui/argumentseditor.cpp
Update downloads link.
[apitrace] / gui / argumentseditor.cpp
index 4648f1cdd072705a1e0db2bd3ab6c6ed7272ebc0..e6345ea5659eac2301561c0fe102dee907b1082b 100644 (file)
 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:
         return true;
     default:
@@ -27,79 +36,60 @@ isVariantEditable(const QVariant &var)
     }
 }
 
-
-ArgumentsItemEditorFactory::ArgumentsItemEditorFactory()
-    : QItemEditorFactory()
+static bool
+isVariantStringArray(const QVariant &var)
 {
-}
+    if (var.isNull() || var.userType() != QMetaType::type("ApiArray"))
+        return false;
 
-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;
+    ApiArray array = var.value<ApiArray>();
+    QVector<QVariant> origValues = array.values();
+    if (origValues.isEmpty() ||
+        origValues.first().userType() != QVariant::String)
+        return false;
+
+    return true;
 }
 
-QByteArray
-ArgumentsItemEditorFactory::valuePropertyName(QVariant::Type type) const
+
+
+void setArgumentsItemEditorFactory ()
 {
-    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";
-    }
+    QItemEditorCreatorBase *booleanComboBoxEditorCreator =
+    new QStandardItemEditorCreator<BooleanComboBoxEditorCreator>();
+    QItemEditorCreatorBase *uIntEditorCreator =
+    new QStandardItemEditorCreator<UIntEditorCreator>();
+    QItemEditorCreatorBase *intEditorCreator =
+    new QStandardItemEditorCreator<IntEditorCreator>();
+    QItemEditorCreatorBase *uLongLongEditorCreator =
+    new QStandardItemEditorCreator<ULongLongEditorCreator>();
+    QItemEditorCreatorBase *longLongEditorCreator =
+    new QStandardItemEditorCreator<LongLongEditorCreator>();
+    QItemEditorCreatorBase *pixmapEditorCreator =
+    new QStandardItemEditorCreator<PixmapEditorCreator>();
+    QItemEditorCreatorBase *floatEditorCreator =
+    new QStandardItemEditorCreator<FloatEditorCreator>();
+    QItemEditorCreatorBase *doubleEditorCreator =
+    new QStandardItemEditorCreator<DoubleEditorCreator>();
+    QItemEditorCreatorBase *invalidEditorCreator =
+    new QStandardItemEditorCreator<InvalidEditorCreator>();
+
+    QItemEditorFactory *factory =
+        new QItemEditorFactory();
+
+    QVariant::Type typeFloat = static_cast<QVariant::Type> (qMetaTypeId<float>());
+
+    factory->registerEditor(QVariant::Bool, booleanComboBoxEditorCreator);
+    factory->registerEditor(QVariant::UInt, uIntEditorCreator);
+    factory->registerEditor(QVariant::Int, intEditorCreator);
+    factory->registerEditor(QVariant::ULongLong, uLongLongEditorCreator);
+    factory->registerEditor(QVariant::LongLong, longLongEditorCreator);
+    factory->registerEditor(QVariant::Pixmap, pixmapEditorCreator);
+    factory->registerEditor(typeFloat, floatEditorCreator);
+    factory->registerEditor(QVariant::Double, doubleEditorCreator);
+    factory->registerEditor(QVariant::Invalid, invalidEditorCreator);
+
+    QItemEditorFactory::setDefaultFactory(factory);
 }
 
 BooleanComboBox::BooleanComboBox(QWidget *parent)
@@ -129,14 +119,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
@@ -152,12 +141,13 @@ void ArgumentsEditor::init()
             SLOT(currentSourceChanged(int)));
     connect(m_ui.glslEdit, SIGNAL(textChanged()),
             SLOT(sourceChanged()));
+    connect(m_ui.revertButton, SIGNAL(clicked()),
+            SLOT(revert()));
+
+    setArgumentsItemEditorFactory ();
 
     m_ui.argsTree->setModel(m_model);
-    QItemEditorFactory *factory =
-        new ArgumentsItemEditorFactory();
 
-    QItemEditorFactory::setDefaultFactory(factory);
 }
 
 void ArgumentsEditor::setupCall()
@@ -187,7 +177,7 @@ void ArgumentsEditor::setupCall()
 
         if (val.canConvert<ApiArray>()) {
             ApiArray array = val.value<ApiArray>();
-            QList<QVariant> vals = array.values();
+            QVector<QVariant> vals = array.values();
 
             QVariant firstVal = vals.value(0);
             if (firstVal.userType() == QVariant::String) {
@@ -206,7 +196,7 @@ void ArgumentsEditor::setupCall()
 
                     QStandardItem *col = new QStandardItem();
                     col->setFlags(col->flags() | Qt::ItemIsEditable);
-                    col->setData(vals[i], Qt::DisplayRole);
+                    col->setData(vals[i], Qt::EditRole);
                     row.append(idx);
                     row.append(col);
                     nameItem->appendRow(row);
@@ -225,6 +215,15 @@ void ArgumentsEditor::setupCall()
             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();
@@ -265,14 +264,14 @@ void ArgumentsEditor::setupCall()
                 item->setFlags(item->flags() ^ Qt::ItemIsEditable);
                 item->setToolTip(tr("Argument is read-only"));
             }
-            item->setData(val, Qt::DisplayRole);
+            item->setData(val, Qt::EditRole);
             topRow.append(item);
         }
         rootItem->appendRow(topRow);
     }
 }
 
-void ArgumentsEditor::setupShaderEditor(const QList<QVariant> &sources)
+void ArgumentsEditor::setupShaderEditor(const QVector<QVariant> &sources)
 {
     m_ui.selectStringCB->clear();
     m_ui.glslEdit->clear();
@@ -298,28 +297,57 @@ void ArgumentsEditor::sourceChanged()
     QString str = m_ui.glslEdit->toPlainText();
     m_ui.lengthLabel->setText(
         tr("%1").arg(str.length()));
+
+    m_ui.selectStringCB->setItemData(
+        m_ui.selectStringCB->currentIndex(),
+        str);
 }
 
 void ArgumentsEditor::accept()
 {
     QStringList argNames = m_call->argNames();
-    QList<QVariant> originalValues = m_call->arguments();
+    QVector<QVariant> originalValues = m_call->arguments();
+    QVector<QVariant> 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);
+        QVariant editorValue = valueForName(argName, argValue, &valChanged);
+
+        newValues.append(editorValue);
+#if 0
         qDebug()<<"Arg = "<<argName;
         qDebug()<<"\toriginal = "<<argValue;
         qDebug()<<"\teditor   = "<<editorValue;
+        qDebug()<<"\tchanged  = "<<valChanged;
+#endif
+        if (valChanged)
+            changed = true;
     }
-
+    if (changed)
+        m_call->setEditedValues(newValues);
     QDialog::accept();
 }
 
 QVariant ArgumentsEditor::valueForName(const QString &name,
-                                       const QVariant &originalValue) const
+                                       const QVariant &originalValue,
+                                       bool *changed) const
 {
     QVariant val;
+
+    *changed = false;
+
+    //Handle string arrays specially
+    if (isVariantStringArray(originalValue)) {
+        ApiArray array = originalValue.value<ApiArray>();
+        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();
@@ -328,10 +356,12 @@ QVariant ArgumentsEditor::valueForName(const QString &name,
         if (argName == name) {
             if (originalValue.userType() == QMetaType::type("ApiArray")) {
                 ApiArray array = originalValue.value<ApiArray>();
-                val = arrayFromIndex(nameIdx, array);
+                val = arrayFromIndex(nameIdx, array, changed);
             } else {
                 QModelIndex valIdx = m_model->index(topRow, 1, QModelIndex());
                 val = valIdx.data();
+                if (val != originalValue)
+                    *changed = true;
             }
         }
     }
@@ -339,27 +369,52 @@ QVariant ArgumentsEditor::valueForName(const QString &name,
 }
 
 QVariant ArgumentsEditor::arrayFromIndex(const QModelIndex &parentIndex,
-                                         const ApiArray &origArray) const
+                                         const ApiArray &origArray,
+                                         bool *changed) const
 {
-    QList<QVariant> origValues = origArray.values();
-    QVariant newValue;
+    QVector<QVariant> origValues = origArray.values();
+
+    *changed = false;
+
     if (origValues.isEmpty())
         return QVariant::fromValue(ApiArray());
 
-    if (origValues.first().userType() == QVariant::String) {
-        //shaders
+    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));
+}
 
-    } else {
-        QList<QVariant> lst;
-        for (int i = 0; i < origValues.count(); ++i) {
-            QModelIndex valIdx = m_model->index(i, 1, parentIndex);
-            QVariant var = valIdx.data();
-            //qDebug()<<"\t\tarray "<<i<<") "<<var;
-            lst.append(var);
-        }
-        newValue = QVariant::fromValue(ApiArray(lst));
+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 newValue;
+    return QVariant::fromValue(ApiArray(vals));
+}
+
+void ArgumentsEditor::revert()
+{
+    m_call->revert();
+    setupCall();
 }
 
 #include "argumentseditor.moc"