33 const QString &windowTitle,
35 : QDialog(parent), properties_(std::move(properties)) {
36 setWindowTitle(windowTitle);
40void NodeDetailsDialog::setupUI() {
41 setMinimumSize(400, 300);
44 auto *layout =
new QVBoxLayout(
this);
46 treeWidget_ =
new QTreeWidget(
this);
47 treeWidget_->setHeaderLabels({tr(
"Property"), tr(
"Value")});
48 treeWidget_->setRootIsDecorated(
true);
49 treeWidget_->setAnimated(
false);
50 treeWidget_->setUniformRowHeights(
true);
51 treeWidget_->setAlternatingRowColors(
true);
52 treeWidget_->setIndentation(20);
53 treeWidget_->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
54 treeWidget_->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
55 treeWidget_->header()->setStretchLastSection(
true);
56 treeWidget_->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
58 layout->addWidget(treeWidget_);
61 populateTree(
nullptr, QString(), properties_);
62 treeWidget_->expandToDepth(1);
65void NodeDetailsDialog::populateTree(QTreeWidgetItem *parent,
const QString &key,
67 QTreeWidgetItem *item =
nullptr;
69 if (value.is_object()) {
70 QString label = key.isEmpty() ? tr(
"(root)") : key;
71 item =
new QTreeWidgetItem({label, tr(
"(object)")});
73 for (
auto it = value.begin(); it != value.end(); ++it) {
74 QString childKey = QString::fromStdString(it.key().str());
75 populateTree(item, childKey, it.value());
77 }
else if (value.is_array()) {
78 item =
new QTreeWidgetItem({key, tr(
"[%1 items]").arg(value.size())});
81 for (
const auto &elem : value) {
82 QString indexKey = QStringLiteral(
"[%1]").arg(index++);
83 populateTree(item, indexKey, elem);
86 QString displayValue = valueToDisplayString(value, key);
87 item =
new QTreeWidgetItem({key, displayValue});
89 if (value.is_boolean()) {
90 item->setForeground(1, QColor(0, 100, 0));
91 }
else if (value.is_number()) {
92 item->setForeground(1, QColor(0, 0, 150));
93 }
else if (value.is_null()) {
94 item->setForeground(1, QColor(128, 128, 128));
99 parent->addChild(item);
101 treeWidget_->addTopLevelItem(item);
105QString NodeDetailsDialog::valueToDisplayString(
const AcavJson &value,
106 const QString &key) {
107 if (value.is_boolean()) {
108 return value.get<
bool>() ? QStringLiteral(
"true") : QStringLiteral(
"false");
110 if (value.is_number_integer()) {
111 int64_t num = value.get<int64_t>();
113 if (key == QStringLiteral(
"nodePtr")) {
114 return QStringLiteral(
"0x%1").arg(
static_cast<quint64
>(num), 0, 16);
116 return QString::number(num);
118 if (value.is_number_unsigned()) {
119 uint64_t num = value.get<uint64_t>();
121 if (key == QStringLiteral(
"nodePtr")) {
122 return QStringLiteral(
"0x%1").arg(num, 0, 16);
124 return QString::number(num);
126 if (value.is_number_float()) {
127 return QString::number(value.get<
double>());
129 if (value.is_string()) {
130 return QString::fromStdString(value.get<InternedString>().str());
132 if (value.is_null()) {
133 return QStringLiteral(
"null");
135 return QStringLiteral(
"(unknown)");
nlohmann::basic_json< std::map, std::vector, InternedString, bool, int64_t, uint64_t, double, std::allocator, nlohmann::adl_serializer, std::vector< uint8_t > > AcavJson
Custom JSON type using InternedString for automatic string deduplication.
Non-modal dialog displaying AST node properties in a tree view.
NodeDetailsDialog(AcavJson properties, const QString &windowTitle, QWidget *parent=nullptr)
Create a node details dialog.