Kerberos: add kerberos_inject_longterm_key() helper function
[wireshark-sm.git] / ui / qt / models / proto_tree_model.cpp
blobfe6f7f957e9e961613c5a11a309a65f8bb4277e2
1 /* proto_tree_model.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
10 #include <ui/qt/models/proto_tree_model.h>
12 #include <epan/prefs.h>
13 #include <wsutil/wslog.h>
15 #include <ui/qt/utils/color_utils.h>
17 #include <QApplication>
18 #include <QPalette>
19 #include <QFont>
21 // To do:
22 // - Add ProtoTreeDelegate
23 // - Add ProtoTreeModel to CaptureFile
25 ProtoTreeModel::ProtoTreeModel(QObject * parent) :
26 QAbstractItemModel(parent)
28 root_node_ = new ProtoNode(NULL);
31 ProtoTreeModel::~ProtoTreeModel()
33 delete root_node_;
36 Qt::ItemFlags ProtoTreeModel::flags(const QModelIndex &index) const
38 Qt::ItemFlags item_flags = QAbstractItemModel::flags(index);
39 if (rowCount(index) < 1) {
40 item_flags |= Qt::ItemNeverHasChildren;
43 return item_flags;
46 QModelIndex ProtoTreeModel::index(int row, int, const QModelIndex &parent) const
48 ProtoNode *parent_node = root_node_;
50 if (parent.isValid()) {
51 // index is not a top level item.
52 parent_node = protoNodeFromIndex(parent);
55 if (! parent_node->isValid())
56 return QModelIndex();
58 ProtoNode *child = parent_node->child(row);
59 if (! child) {
60 return QModelIndex();
63 return createIndex(row, 0, static_cast<void *>(child));
66 QModelIndex ProtoTreeModel::parent(const QModelIndex &index) const
68 if (!index.isValid())
69 return QModelIndex();
71 ProtoNode *parent_node = protoNodeFromIndex(index)->parentNode();
72 return indexFromProtoNode(parent_node);
75 int ProtoTreeModel::rowCount(const QModelIndex &parent) const
77 if (parent.isValid()) {
78 return protoNodeFromIndex(parent)->childrenCount();
80 return root_node_->childrenCount();
83 // The QItemDelegate documentation says
84 // "When displaying items from a custom model in a standard view, it is
85 // often sufficient to simply ensure that the model returns appropriate
86 // data for each of the roles that determine the appearance of items in
87 // views."
88 // We might want to move this to a delegate regardless.
89 QVariant ProtoTreeModel::data(const QModelIndex &index, int role) const
91 if (!index.isValid())
92 return QVariant();
94 ProtoNode *index_node = protoNodeFromIndex(index);
95 FieldInformation finfo(index_node);
96 if (!finfo.isValid()) {
97 return QVariant();
100 switch (role) {
101 case Qt::DisplayRole:
102 return index_node->labelText();
103 case Qt::BackgroundRole:
105 switch(finfo.flag(PI_SEVERITY_MASK)) {
106 case(0):
107 break;
108 case(PI_COMMENT):
109 return ColorUtils::expert_color_comment;
110 case(PI_CHAT):
111 return ColorUtils::expert_color_chat;
112 case(PI_NOTE):
113 return ColorUtils::expert_color_note;
114 case(PI_WARN):
115 return ColorUtils::expert_color_warn;
116 case(PI_ERROR):
117 return ColorUtils::expert_color_error;
118 default:
119 ws_warning("Unhandled severity flag: %u", finfo.flag(PI_SEVERITY_MASK));
121 if (finfo.headerInfo().type == FT_PROTOCOL) {
122 return QApplication::palette().window();
124 return QApplication::palette().base();
126 case Qt::ForegroundRole:
128 if (finfo.flag(PI_SEVERITY_MASK)) {
129 return ColorUtils::expert_color_foreground;
131 if (finfo.isLink()) {
132 return ColorUtils::themeLinkBrush();
134 if (finfo.headerInfo().type == FT_PROTOCOL) {
135 return QApplication::palette().windowText();
137 return QApplication::palette().text();
139 case Qt::FontRole:
140 if (finfo.isLink()) {
141 QFont font;
142 font.setUnderline(true);
143 return font;
145 default:
146 break;
149 return QVariant();
152 void ProtoTreeModel::setRootNode(proto_node *root_node)
154 beginResetModel();
155 delete root_node_;
156 root_node_ = new ProtoNode(root_node);
157 endResetModel();
158 if (!root_node) return;
160 int row_count = root_node_->childrenCount();
161 if (row_count < 1) return;
162 beginInsertRows(QModelIndex(), 0, row_count - 1);
163 endInsertRows();
166 ProtoNode* ProtoTreeModel::protoNodeFromIndex(const QModelIndex &index) const
168 return static_cast<ProtoNode*>(index.internalPointer());
171 QModelIndex ProtoTreeModel::indexFromProtoNode(ProtoNode *index_node) const
173 if (!index_node) {
174 return QModelIndex();
177 int row = index_node->row();
179 if (!index_node->isValid() || row < 0) {
180 return QModelIndex();
183 return createIndex(row, 0, static_cast<void *>(index_node));
186 struct find_hfid_ {
187 int hfid;
188 ProtoNode *node;
191 // NOLINTNEXTLINE(misc-no-recursion)
192 bool ProtoTreeModel::foreachFindHfid(ProtoNode *node, void *find_hfid_ptr)
194 struct find_hfid_ *find_hfid = (struct find_hfid_ *) find_hfid_ptr;
195 if (PNODE_FINFO(node->protoNode()) && PNODE_FINFO(node->protoNode())->hfinfo->id == find_hfid->hfid) {
196 find_hfid->node = node;
197 return true;
199 for (int i = 0; i < node->childrenCount(); i++) {
200 // We recurse here, but we're limited by tree depth checks in epan
201 if (foreachFindHfid(node->child(i), find_hfid)) {
202 return true;
205 return false;
208 QModelIndex ProtoTreeModel::findFirstHfid(int hf_id)
210 if (!root_node_ || hf_id < 0) return QModelIndex();
212 struct find_hfid_ find_hfid;
213 find_hfid.hfid = hf_id;
215 if (foreachFindHfid(root_node_, &find_hfid) && find_hfid.node->isValid()) {
216 return indexFromProtoNode(find_hfid.node);
218 return QModelIndex();
221 struct find_field_info_ {
222 field_info *fi;
223 ProtoNode *node;
226 // NOLINTNEXTLINE(misc-no-recursion)
227 bool ProtoTreeModel::foreachFindField(ProtoNode *node, void *find_finfo_ptr)
229 struct find_field_info_ *find_finfo = (struct find_field_info_ *) find_finfo_ptr;
230 if (PNODE_FINFO(node->protoNode()) == find_finfo->fi) {
231 find_finfo->node = node;
232 return true;
234 for (int i = 0; i < node->childrenCount(); i++) {
235 // We recurse here, but we're limited by tree depth checks in epan
236 if (foreachFindField(node->child(i), find_finfo)) {
237 return true;
240 return false;
243 QModelIndex ProtoTreeModel::findFieldInformation(FieldInformation *finfo)
245 if (!root_node_ || !finfo) return QModelIndex();
246 field_info * fi = finfo->fieldInfo();
247 if (!fi) return QModelIndex();
249 struct find_field_info_ find_finfo;
250 find_finfo.fi = fi;
252 if (foreachFindField(root_node_, &find_finfo) && find_finfo.node->isValid()) {
253 return indexFromProtoNode(find_finfo.node);
255 return QModelIndex();