LCOV - code coverage report
Current view: top level - qt - dbc_tree_model.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 97.4 % 115 112
Test Date: 2026-10-20 13:34:58 Functions: 100.0 % 11 11
Branches: 80.2 % 212 170

             Branch data     Line data    Source code
       1                 :             : // SPDX-License-Identifier: MIT
       2                 :             : #include "dbc_tree_model.h"
       3                 :             : #include <QVariantList>
       4                 :             : #include <QVariantMap>
       5                 :             : #include <limits>
       6                 :             : #include <stdexcept>
       7                 :             : 
       8                 :             : namespace {
       9                 :          20 :     QVariantList ToVariantList(const ValueDescriptions &values) {
      10                 :          20 :         QVariantList descriptions;
      11         [ +  + ]:          50 :         for (const ValueDescriptions::value_type &entry : values) {
      12                 :          30 :             QVariantMap pair;
      13         [ +  + ]:          30 :             if (const std::int64_t *number = std::get_if<std::int64_t>(&entry.first))
      14   [ +  -  +  - ]:          10 :                 pair.insert("value", QVariant::fromValue(static_cast<qlonglong>(*number)));
      15                 :             :             else
      16   [ +  -  +  - ]:          20 :                 pair.insert("value", QVariant::fromValue(
      17         [ +  - ]:          40 :                                          static_cast<qulonglong>(std::get<std::uint64_t>(entry.first))));
      18   [ +  -  +  -  :          30 :             pair.insert("description", QString::fromStdString(entry.second));
                   +  - ]
      19         [ +  - ]:          30 :             descriptions.append(pair);
      20                 :          30 :         }
      21                 :          20 :         return descriptions;
      22                 :           0 :     }
      23                 :             : } // namespace
      24                 :             : 
      25                 :           6 : DbcTreeModel::DbcTreeModel(QObject *parent) : QAbstractItemModel(parent) {}
      26                 :             : 
      27                 :          12 : void DbcTreeModel::SetTree(std::unique_ptr<TreeNode> root) {
      28   [ +  +  +  +  :          12 :     if (root && (root->GetType() != NodeType::Root || root->GetParent()))
             -  +  +  + ]
      29         [ +  - ]:           2 :         throw std::invalid_argument("Model requires a detached root node");
      30                 :          10 :     beginResetModel();
      31                 :          10 :     m_root = std::move(root);
      32                 :          10 :     endResetModel();
      33                 :          10 : }
      34                 :             : 
      35                 :        2110 : const TreeNode *DbcTreeModel::Node(const QModelIndex &index) const {
      36   [ +  +  +  -  :        6258 :     if (!index.isValid() || index.model() != this || index.column() < 0 ||
                   +  - ]
      37   [ +  +  -  +  :        6258 :         index.column() >= ColumnCount || index.row() < 0)
                   +  + ]
      38                 :          39 :         return nullptr;
      39                 :        2071 :     return static_cast<const TreeNode *>(index.internalPointer());
      40                 :             : }
      41                 :             : 
      42                 :        1254 : QModelIndex DbcTreeModel::index(int row, int column, const QModelIndex &parentIndex) const {
      43   [ +  +  +  +  :        3134 :     if (row < 0 || column < 0 || column >= ColumnCount ||
          +  +  +  +  +  
                      + ]
      44         [ +  + ]:        1880 :         (parentIndex.isValid() && parentIndex.column() != 0))
      45                 :          28 :         return {};
      46         [ +  + ]:        1226 :     const TreeNode *owner = parentIndex.isValid() ? Node(parentIndex) : m_root.get();
      47         [ +  + ]:        1226 :     if (!owner)
      48                 :           2 :         return {};
      49                 :        1224 :     const TreeNode *child = owner->GetChild(static_cast<std::size_t>(row));
      50         [ +  + ]:        1224 :     return child ? createIndex(row, column, const_cast<TreeNode *>(child)) : QModelIndex();
      51                 :             : }
      52                 :             : 
      53                 :         783 : QModelIndex DbcTreeModel::parent(const QModelIndex &childIndex) const {
      54                 :         783 :     const TreeNode *child = Node(childIndex);
      55         [ +  + ]:         783 :     const TreeNode *owner = child ? child->GetParent() : nullptr;
      56   [ +  +  +  +  :         783 :     if (!owner || owner == m_root.get())
                   +  + ]
      57                 :         336 :         return {};
      58                 :         447 :     return createIndex(static_cast<int>(owner->GetRow()), 0, const_cast<TreeNode *>(owner));
      59                 :             : }
      60                 :             : 
      61                 :         700 : int DbcTreeModel::rowCount(const QModelIndex &parentIndex) const {
      62   [ +  +  +  +  :         700 :     if (parentIndex.isValid() && parentIndex.column() != 0)
                   +  + ]
      63                 :         204 :         return 0;
      64         [ +  + ]:         496 :     const TreeNode *owner = parentIndex.isValid() ? Node(parentIndex) : m_root.get();
      65         [ +  + ]:         496 :     if (!owner)
      66                 :          53 :         return 0;
      67         [ +  - ]:         443 :     return static_cast<int>(qMin(owner->GetChildCount(), static_cast<std::size_t>(std::numeric_limits<int>::max())));
      68                 :             : }
      69                 :             : 
      70                 :         395 : int DbcTreeModel::columnCount(const QModelIndex &parentIndex) const {
      71   [ +  +  +  + ]:         395 :     return parentIndex.isValid() && !Node(parentIndex) ? 0 : ColumnCount;
      72                 :             : }
      73                 :             : 
      74                 :         240 : QVariant DbcTreeModel::data(const QModelIndex &item, int role) const {
      75         [ +  - ]:         240 :     const TreeNode *node = Node(item);
      76         [ +  + ]:         240 :     if (!node)
      77                 :           2 :         return {};
      78         [ +  - ]:         238 :     const FrameInfo *frame = node->GetFrame();
      79         [ +  - ]:         238 :     const SignalInfo *signal = node->GetSignal();
      80                 :         238 :     QString comment;
      81         [ +  + ]:         238 :     if (frame != nullptr)
      82         [ +  - ]:         126 :         comment = QString::fromStdString(frame->comment);
      83         [ +  - ]:         112 :     else if (signal != nullptr)
      84         [ +  - ]:         112 :         comment = QString::fromStdString(signal->comment);
      85   [ +  +  +  + ]:         238 :     if (role == Qt::ToolTipRole || role == CommentRole)
      86                 :          41 :         return comment;
      87         [ +  + ]:         197 :     if (role == NodeTypeRole)
      88         [ +  - ]:           2 :         return static_cast<int>(node->GetType());
      89   [ +  +  +  + ]:         195 :     if (role == ValueDescriptionsRole && signal) {
      90         [ +  - ]:          20 :         return ToVariantList(signal->valueDescriptions);
      91                 :             :     }
      92         [ +  + ]:         175 :     if (frame) {
      93         [ +  + ]:         103 :         if (role == CanIdRole)
      94                 :          10 :             return frame->canId;
      95         [ +  + ]:          93 :         if (role == PayloadLengthRole)
      96                 :          10 :             return static_cast<int>(frame->dlc);
      97         [ +  + ]:          83 :         if (role == ExtendedRole)
      98                 :          10 :             return frame->isExtended;
      99                 :             :     }
     100         [ +  + ]:         145 :     if (signal) {
     101         [ +  + ]:          72 :         if (role == StartBitRole)
     102                 :          10 :             return signal->startBit;
     103         [ +  + ]:          62 :         if (role == BitLengthRole)
     104                 :          10 :             return signal->length;
     105         [ +  + ]:          52 :         if (role == LittleEndianRole)
     106                 :          10 :             return signal->isLittleEndian;
     107         [ +  + ]:          42 :         if (role == SignedRole)
     108                 :          10 :             return signal->isSigned;
     109         [ +  + ]:          32 :         if (role == UnitRole)
     110         [ +  - ]:          10 :             return QString::fromStdString(signal->unit);
     111                 :             :     }
     112         [ +  + ]:          95 :     if (role != Qt::DisplayRole)
     113                 :          66 :         return {};
     114   [ +  +  +  +  :          29 :     switch (item.column()) {
          +  +  +  +  +  
                      - ]
     115                 :           9 :         case Name:
     116   [ +  -  +  - ]:           9 :             return QString::fromStdString(node->GetName());
     117                 :           4 :         case CanId:
     118   [ +  +  +  -  :           8 :             return frame ? QVariant(QString("0x%1").arg(frame->canId, 0, 16).toUpper()) : QVariant();
          +  -  +  -  +  
          +  +  +  +  +  
          -  -  -  -  -  
                      - ]
     119                 :           2 :         case PayloadLength:
     120         [ +  + ]:           2 :             return frame ? QVariant(static_cast<int>(frame->dlc)) : QVariant();
     121                 :           2 :         case StartBit:
     122         [ +  + ]:           2 :             return signal ? QVariant(signal->startBit) : QVariant();
     123                 :           2 :         case BitLength:
     124         [ +  + ]:           2 :             return signal ? QVariant(signal->length) : QVariant();
     125                 :           3 :         case ByteOrder:
     126   [ +  +  +  +  :           3 :             return signal ? QVariant(signal->isLittleEndian ? "Intel" : "Motorola") : QVariant();
                   +  - ]
     127                 :           3 :         case Signed:
     128   [ +  +  +  +  :           3 :             return signal ? QVariant(signal->isSigned ? "Signed" : "Unsigned") : QVariant();
                   +  - ]
     129                 :           2 :         case Unit:
     130   [ +  +  +  -  :           4 :             return signal ? QVariant(QString::fromStdString(signal->unit)) : QVariant();
             +  +  -  - ]
     131                 :           2 :         case Comment:
     132                 :           2 :             return comment;
     133                 :           0 :         default:
     134                 :           0 :             return {};
     135                 :             :     }
     136                 :         238 : }
     137                 :             : 
     138                 :          30 : QVariant DbcTreeModel::headerData(int section, Qt::Orientation orientation, int role) const {
     139                 :             :     static const char *const headers[] = {"Name", "CAN ID", "Payload (bytes)", "Start bit", "Length (bits)", "Byte order", "Signedness", "Unit", "Comment"};
     140   [ +  +  +  +  :          30 :     if (orientation != Qt::Horizontal || role != Qt::DisplayRole || section < 0 || section >= ColumnCount)
             +  +  +  + ]
     141                 :          12 :         return {};
     142         [ +  - ]:          18 :     return QString::fromLatin1(headers[section]);
     143                 :             : }
     144                 :             : 
     145                 :          39 : Qt::ItemFlags DbcTreeModel::flags(const QModelIndex &item) const {
     146         [ +  + ]:          39 :     return Node(item) ? Qt::ItemIsEnabled | Qt::ItemIsSelectable : Qt::NoItemFlags;
     147                 :             : }
        

Generated by: LCOV version 2.0-1