diff --git a/src/libs/asn1editor/asn1editorconst.h b/src/libs/asn1editor/asn1editorconst.h index 704c6061a52bd31b7068e2876f0e287a7cd1f052..da6185b434a5c92c520b25a42a43783ff186251b 100644 --- a/src/libs/asn1editor/asn1editorconst.h +++ b/src/libs/asn1editor/asn1editorconst.h @@ -31,5 +31,5 @@ const int DEFAULT_ROLE = Qt::UserRole + 4; const int MODEL_NAME_INDEX = 0; const int MODEL_TYPE_INDEX = 1; const int MODEL_VALUE_INDEX = 2; -const int MODEL_IS_OPTIONAL_INDEX = 3; +const int MODEL_IS_PRESENT_INDEX = 3; } diff --git a/src/libs/asn1editor/asn1itemmodel.cpp b/src/libs/asn1editor/asn1itemmodel.cpp index a9c91ca9df75a921c8f8ca9abdcc94524191d62a..27f85200e3a0626e1f13b17774b54563f1fb08aa 100644 --- a/src/libs/asn1editor/asn1itemmodel.cpp +++ b/src/libs/asn1editor/asn1itemmodel.cpp @@ -76,7 +76,7 @@ void Asn1ItemModel::setAsn1Model(const std::unique_ptr setItem(0, MODEL_NAME_INDEX, itemMap["item"]); setItem(0, MODEL_TYPE_INDEX, itemMap["type"]); setItem(0, MODEL_VALUE_INDEX, itemMap["value"]); - setItem(0, MODEL_IS_OPTIONAL_INDEX, itemMap["present"]); + setItem(0, MODEL_IS_PRESENT_INDEX, itemMap["present"]); } /*! @@ -261,17 +261,16 @@ QStandardItem *Asn1ItemModel::createSequenceItem(const Asn1Acn::Types::Sequence } ItemMap childItem = createModelItems(asnSequenceComponent->type(), asnSequenceComponent->name()); - childItem["present"]->setCheckable(true); - childItem["present"]->setCheckState(asnSequenceComponent->isOptional() ? Qt::Checked : Qt::Unchecked); - - if (QStandardItem *valueItem = childItem["value"]) { - if (valueItem->text().isEmpty()) { - const std::optional defaultValue = asnSequenceComponent->defaultValue(); - if (defaultValue.has_value()) { - valueItem->setText(defaultValue.value()); - valueItem->setData(true, DEFAULT_ROLE); - } - } + if (asnSequenceComponent->isOptional()) { + childItem["present"]->setEnabled(true); + childItem["present"]->setCheckable(true); + } else { + childItem["present"]->setCheckState(Qt::Checked); + } + + const std::optional defaultValue = asnSequenceComponent->defaultValue(); + if (defaultValue.has_value()) { + childItem["value"]->setData(defaultValue.value(), DEFAULT_ROLE); } parent->appendRow(childItem["item"]); @@ -398,6 +397,7 @@ QStandardItem *Asn1ItemModel::createPresentItem() { QStandardItem *item = new QStandardItem(); item->setEnabled(false); + item->setEditable(false); return item; } @@ -405,7 +405,22 @@ QStandardItem *Asn1ItemModel::createPresentItem() bool Asn1ItemModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (index.column() == MODEL_VALUE_INDEX) { - itemFromIndex(index)->setData(false, DEFAULT_ROLE); + if (auto item = itemFromIndex(index.siblingAtColumn(MODEL_IS_PRESENT_INDEX))) { + if (item->isCheckable()) { + item->setCheckState(value.isNull() ? Qt::Unchecked : Qt::Checked); + } + } + } else if (index.column() == MODEL_IS_PRESENT_INDEX && role == Qt::CheckStateRole) { + if (auto item = itemFromIndex(index.siblingAtColumn(MODEL_VALUE_INDEX))) { + if (value.value() == Qt::Unchecked) { + item->setText(QString()); + } else if (item->text().isEmpty()) { + const QVariant defaultValue = item->data(DEFAULT_ROLE); + if (!defaultValue.isNull()) { + item->setText(defaultValue.toString()); + } + } + } } return QStandardItemModel::setData(index, value, role); } diff --git a/src/libs/asn1editor/asn1treeview.cpp b/src/libs/asn1editor/asn1treeview.cpp index 98a8d1e8769114b80036679621331725b1685a27..9f9494111a583aaf851d07b388682b6063374ada 100644 --- a/src/libs/asn1editor/asn1treeview.cpp +++ b/src/libs/asn1editor/asn1treeview.cpp @@ -84,9 +84,7 @@ void Asn1TreeView::setAsn1Value(const QVariantMap &asn1Value) setChildValue(nameItem, asn1Value["seqofvalue"], seqOfSize); } else if (asnType.startsWith("choice", Qt::CaseInsensitive)) { QString choiceValue = asn1Value["choice"].toMap()["name"].toString(); - m_ItemModel->item(row, MODEL_VALUE_INDEX)->setText(choiceValue); - setChildValue(nameItem, asn1Value["choice"], -1, itemChoiceIndex(nameItem, choiceValue)); } else if (asnType.startsWith("integer", Qt::CaseInsensitive) || asnType.startsWith("double", Qt::CaseInsensitive) || asnType.startsWith("real", Qt::CaseInsensitive) || asnType.startsWith("string", Qt::CaseInsensitive) @@ -175,6 +173,7 @@ void Asn1TreeView::setChildRowValue(const QStandardItem *rootItem, int childInde const QStandardItem *childItem = rootItem->child(childIndex, MODEL_TYPE_INDEX); const QString asnType = childItem ? rootItem->child(childIndex, MODEL_TYPE_INDEX)->text() : ""; auto *child = rootItem->child(childIndex, MODEL_VALUE_INDEX); + const QString defaultValue = child->data(DEFAULT_ROLE).toString(); if (asnType.startsWith("integer", Qt::CaseInsensitive) || asnType.startsWith("double", Qt::CaseInsensitive) || asnType.startsWith("real", Qt::CaseInsensitive) || asnType.startsWith("string", Qt::CaseInsensitive) @@ -182,11 +181,11 @@ void Asn1TreeView::setChildRowValue(const QStandardItem *rootItem, int childInde || asnType.startsWith("BIT STRING", Qt::CaseInsensitive) || asnType.startsWith("OCTET STRING", Qt::CaseInsensitive) || asnType.startsWith("IA5String", Qt::CaseInsensitive) - || asnType.startsWith("NumericString", Qt::CaseInsensitive)) + || asnType.startsWith("NumericString", Qt::CaseInsensitive)) { child->setText(asn1Value.toMap()["value"].toString()); - else if (asnType.startsWith("bool", Qt::CaseInsensitive)) + } else if (asnType.startsWith("bool", Qt::CaseInsensitive)) { child->setText(asn1Value.toMap()["value"].toString().toLower()); - else if (asnType.startsWith("sequenceOf", Qt::CaseInsensitive) + } else if (asnType.startsWith("sequenceOf", Qt::CaseInsensitive) || asnType.startsWith("sequence of", Qt::CaseInsensitive)) { int seqOfSize = asn1Value.toMap()["seqofvalue"].toList().count(); child->setText(QString::number(seqOfSize)); @@ -199,6 +198,15 @@ void Asn1TreeView::setChildRowValue(const QStandardItem *rootItem, int childInde setChildRowValue(rootItem->child(childIndex), itemChoiceIndex(rootItem->child(childIndex), choiceValue), asn1Value.toMap()["choice"]); } + if (child->text().isEmpty()) { + if (!defaultValue.isEmpty()) { + child->setText(defaultValue); + } + } else if (auto present = rootItem->child(childIndex, MODEL_IS_PRESENT_INDEX)) { + if (present->isCheckable()) { + present->setCheckState(Qt::Checked); + } + } } /*! @@ -307,17 +315,17 @@ QString Asn1TreeView::getItemValue(const QStandardItem *item, const QString &sep QString asnValue; modelIndex = itemIndex.sibling(item->row(), MODEL_VALUE_INDEX); if (modelIndex.isValid()) { - if (modelIndex.data(DEFAULT_ROLE).toBool()) { - return {}; - } asnValue = model->itemFromIndex(modelIndex)->text(); } + if (asnValue.isEmpty()) { - const bool isOptional = - itemIndex.sibling(item->row(), MODEL_IS_OPTIONAL_INDEX).data(Qt::CheckStateRole).value() - == Qt::Checked; - if (isOptional) { - return {}; + auto presentIndex = itemIndex.sibling(item->row(), MODEL_IS_PRESENT_INDEX); + if (auto presentItem = model->itemFromIndex(presentIndex)) { + if (presentItem->isCheckable()) { + if (presentItem->checkState() == Qt::Unchecked) { + return {}; + } + } } } diff --git a/tests/unittests/asn1editor/tst_asn1itemmodel.cpp b/tests/unittests/asn1editor/tst_asn1itemmodel.cpp index 1b2b44689e6da6f488d3b9faf836c5a1928da77e..85e21cf8fc495ffee61a0bd6d2f03d7a148c0ac7 100644 --- a/tests/unittests/asn1editor/tst_asn1itemmodel.cpp +++ b/tests/unittests/asn1editor/tst_asn1itemmodel.cpp @@ -356,22 +356,16 @@ void tst_Asn1ItemModel::testSequenceTypeModel() QCOMPARE(itemModel->item(0, MODEL_NAME_INDEX)->child(0)->text(), QString("intVal")); QCOMPARE(itemModel->item(0, MODEL_NAME_INDEX)->child(0, MODEL_TYPE_INDEX)->text(), QString("INTEGER")); - QCOMPARE(itemModel->item(0, MODEL_NAME_INDEX)->child(0, MODEL_IS_OPTIONAL_INDEX)->data(Qt::CheckStateRole).toBool(), - false); QCOMPARE(toAsn1Type(itemModel->item(0, MODEL_NAME_INDEX)->child(0, MODEL_VALUE_INDEX)->data(ASN1TYPE_ROLE)), Asn1Acn::Types::Type::INTEGER); QCOMPARE(itemModel->item(0, MODEL_NAME_INDEX)->child(1)->text(), QString("realVal")); QCOMPARE(itemModel->item(0, MODEL_NAME_INDEX)->child(1, MODEL_TYPE_INDEX)->text(), QString("REAL")); - QCOMPARE(itemModel->item(0, MODEL_NAME_INDEX)->child(1, MODEL_IS_OPTIONAL_INDEX)->data(Qt::CheckStateRole).toBool(), - false); QCOMPARE(toAsn1Type(itemModel->item(0, MODEL_NAME_INDEX)->child(1, MODEL_VALUE_INDEX)->data(ASN1TYPE_ROLE)), Asn1Acn::Types::Type::REAL); QCOMPARE(itemModel->item(0, MODEL_NAME_INDEX)->child(2)->text(), QString("boolVal")); QCOMPARE(itemModel->item(0, MODEL_NAME_INDEX)->child(2, MODEL_TYPE_INDEX)->text(), QString("BOOLEAN")); - QCOMPARE(itemModel->item(0, MODEL_NAME_INDEX)->child(2, MODEL_IS_OPTIONAL_INDEX)->data(Qt::CheckStateRole).toBool(), - true); QCOMPARE(toAsn1Type(itemModel->item(0, MODEL_NAME_INDEX)->child(2, MODEL_VALUE_INDEX)->data(ASN1TYPE_ROLE)), Asn1Acn::Types::Type::BOOLEAN); }