1 /* proto_node.cpp
2  *
3  * Wireshark - Network traffic analyzer
4  * By Gerald Combs <gerald@wireshark.org>
5  * Copyright 1998 Gerald Combs
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  */
9 
10 #include <ui/qt/utils/proto_node.h>
11 
12 #include <epan/prefs.h>
13 
ProtoNode(proto_node * node)14 ProtoNode::ProtoNode(proto_node *node) :
15     node_(node)
16 {
17 }
18 
isValid() const19 bool ProtoNode::isValid() const
20 {
21     return node_;
22 }
23 
isChild() const24 bool ProtoNode::isChild() const
25 {
26     return node_ && node_->parent;
27 }
28 
parentNode()29 ProtoNode ProtoNode::parentNode()
30 {
31     if (node_) {
32         return ProtoNode(node_->parent);
33     }
34     return ProtoNode(NULL);
35 }
36 
labelText() const37 QString ProtoNode::labelText() const
38 {
39     if (!node_) {
40         return QString();
41     }
42     field_info *fi = PNODE_FINFO(node_);
43     if (!fi) {
44         return QString();
45     }
46 
47     QString label;
48     /* was a free format label produced? */
49     if (fi->rep) {
50         label = fi->rep->representation;
51     }
52     else { /* no, make a generic label */
53         gchar label_str[ITEM_LABEL_LENGTH];
54         proto_item_fill_label(fi, label_str);
55         label = label_str;
56     }
57 
58     // Generated takes precedence.
59     if (proto_item_is_generated(node_)) {
60         label.prepend("[");
61         label.append("]");
62     }
63     if (proto_item_is_hidden(node_)) {
64         label.prepend("<");
65         label.append(">");
66     }
67     return label;
68 }
69 
childrenCount() const70 int ProtoNode::childrenCount() const
71 {
72     if (!node_) return 0;
73 
74     int row_count = 0;
75     ChildIterator kids = children();
76     while (kids.element().isValid())
77     {
78         row_count++;
79         kids.next();
80     }
81 
82     return row_count;
83 }
84 
row()85 int ProtoNode::row()
86 {
87     if (!isChild()) {
88         return -1;
89     }
90 
91     int cur_row = 0;
92     ProtoNode::ChildIterator kids = parentNode().children();
93     while (kids.element().isValid())
94     {
95         if (kids.element().protoNode() == node_) {
96             break;
97         }
98         cur_row++;
99         kids.next();
100     }
101     if (! kids.element().isValid()) {
102         return -1;
103     }
104     return cur_row;
105 }
106 
isExpanded() const107 bool ProtoNode::isExpanded() const
108 {
109     if (node_ && node_->finfo && node_->first_child && tree_expanded(node_->finfo->tree_type)) {
110         return true;
111     }
112     return false;
113 }
114 
protoNode() const115 proto_node * ProtoNode::protoNode() const
116 {
117     return node_;
118 }
119 
children() const120 ProtoNode::ChildIterator ProtoNode::children() const
121 {
122     proto_node *child = node_->first_child;
123     while (child && isHidden(child)) {
124         child = child->next;
125     }
126 
127     return ProtoNode::ChildIterator(child);
128 }
129 
ChildIterator(ProtoNode::ChildIterator::NodePtr n)130 ProtoNode::ChildIterator::ChildIterator(ProtoNode::ChildIterator::NodePtr n)
131 {
132     node = n;
133 }
134 
hasNext()135 bool ProtoNode::ChildIterator::hasNext()
136 {
137     if (! node || node->next == Q_NULLPTR)
138         return false;
139     return true;
140 }
141 
next()142 ProtoNode::ChildIterator ProtoNode::ChildIterator::next()
143 {
144     do {
145         node = node->next;
146     } while (node && isHidden(node));
147     return *this;
148 }
149 
element()150 ProtoNode ProtoNode::ChildIterator::element()
151 {
152     return ProtoNode(node);
153 }
154 
isHidden(proto_node * node)155 bool ProtoNode::isHidden(proto_node * node)
156 {
157     return PROTO_ITEM_IS_HIDDEN(node) && !prefs.display_hidden_proto_items;
158 }
159