| 324 | // ── Full node line ── |
| 325 | |
| 326 | QString fmtNodeLine(const Node& node, const Provider& prov, |
| 327 | uint64_t addr, int depth, int subLine, |
| 328 | const QString& comment, int colType, int colName, |
| 329 | const QString& typeOverride) { |
| 330 | QString ind = indent(depth); |
| 331 | QString type = typeOverride.isEmpty() ? typeName(node.kind, colType) : fit(typeOverride, colType); |
| 332 | QString name = fit(node.name, colName); |
| 333 | // Blank prefix for continuation lines (same width as type+sep+name+sep) |
| 334 | const int prefixW = colType + colName + 2 * kSepWidth; |
| 335 | |
| 336 | // Comment suffix (only present when a comment is provided; no trailing padding) |
| 337 | QString cmtSuffix = comment.isEmpty() ? QString() |
| 338 | : fit(comment, COL_COMMENT); |
| 339 | |
| 340 | // Mat4x4: subLine 0..3 = rows — no truncation so large floats always display fully |
| 341 | if (node.kind == NodeKind::Mat4x4) { |
| 342 | QString val = readValue(node, prov, addr, subLine); |
| 343 | if (subLine == 0) return ind + type + SEP + name + SEP + val + cmtSuffix; |
| 344 | return ind + QString(prefixW, ' ') + val + cmtSuffix; |
| 345 | } |
| 346 | |
| 347 | // Hex nodes and Padding: hex byte preview (ASCII padded to colName to align with value column) |
| 348 | if (isHexPreview(node.kind)) { |
| 349 | if (node.kind == NodeKind::Padding) { |
| 350 | const int totalSz = qMax(1, node.arrayLen); |
| 351 | const int lineOff = subLine * 8; |
| 352 | const int lineBytes = qMin(8, totalSz - lineOff); |
| 353 | QByteArray b = prov.isReadable(addr + lineOff, lineBytes) |
| 354 | ? prov.readBytes(addr + lineOff, lineBytes) : QByteArray(lineBytes, '\0'); |
| 355 | QString ascii = bytesToAscii(b, lineBytes).leftJustified(colName, ' '); |
| 356 | QString hex = bytesToHex(b, lineBytes).leftJustified(23, ' '); // 8*3-1 |
| 357 | if (subLine == 0) |
| 358 | return ind + type + SEP + ascii + SEP + hex + cmtSuffix; |
| 359 | return ind + QString(colType + (int)SEP.size(), ' ') + ascii + SEP + hex + cmtSuffix; |
| 360 | } |
| 361 | // Hex8..Hex64: single line, ASCII padded to colName so hex column aligns with value column |
| 362 | const int sz = sizeForKind(node.kind); |
| 363 | QByteArray b = prov.isReadable(addr, sz) |
| 364 | ? prov.readBytes(addr, sz) : QByteArray(sz, '\0'); |
| 365 | QString ascii = bytesToAscii(b, sz).leftJustified(colName, ' '); |
| 366 | QString hex = bytesToHex(b, sz).leftJustified(23, ' '); |
| 367 | return ind + type + SEP + ascii + SEP + hex + cmtSuffix; |
| 368 | } |
| 369 | |
| 370 | QString val = fit(readValue(node, prov, addr, subLine), COL_VALUE); |
| 371 | return ind + type + SEP + name + SEP + val + cmtSuffix; |
| 372 | } |
| 373 | |
| 374 | // ── Editable value (parse-friendly form for edit dialog) ── |
| 375 |
no test coverage detected