update epan/dissectors/pidl/drsuapi/drsuapi.idl from samba
[wireshark-sm.git] / ui / qt / models / expert_info_proxy_model.cpp
blob35544168af6a872a7bd3d39b9e75eeead1f75786
1 /* expert_info_model.cpp
2 * Data model for Expert Info tap data.
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include <ui/qt/models/expert_info_model.h>
12 #include <ui/qt/models/expert_info_proxy_model.h>
13 #include <ui/qt/utils/color_utils.h>
15 #include <QRegularExpression>
17 ExpertInfoProxyModel::ExpertInfoProxyModel(QObject *parent) : QSortFilterProxyModel(parent),
18 severityMode_(Group)
22 bool ExpertInfoProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
24 ExpertPacketItem *left_item,
25 *right_item;
26 QString leftStr, rightStr;
27 bool checkPacketNumber = false;
28 int compare_ret;
30 if (source_left.parent().isValid() && source_right.parent().isValid()) {
31 left_item = static_cast<ExpertPacketItem*>(source_left.parent().internalPointer());
32 right_item = static_cast<ExpertPacketItem*>(source_right.parent().internalPointer());
33 } else {
34 left_item = static_cast<ExpertPacketItem*>(source_left.internalPointer());
35 right_item = static_cast<ExpertPacketItem*>(source_right.internalPointer());
38 if ((left_item != NULL) && (right_item != NULL)) {
39 switch (source_left.column())
41 case colProxySeverity:
42 if (left_item->severity() != right_item->severity()) {
43 return (left_item->severity() < right_item->severity());
46 checkPacketNumber = true;
47 break;
48 case colProxySummary:
49 compare_ret = left_item->summary().compare(right_item->summary());
50 if (compare_ret < 0)
51 return true;
52 if (compare_ret > 0)
53 return false;
55 checkPacketNumber = true;
56 break;
57 case colProxyGroup:
58 compare_ret = QString::compare(val_to_str_const(left_item->group(), expert_group_vals, "Unknown"),
59 val_to_str_const(right_item->group(), expert_group_vals, "Unknown"));
60 if (compare_ret < 0)
61 return true;
62 if (compare_ret > 0)
63 return false;
65 checkPacketNumber = true;
66 break;
67 case colProxyProtocol:
68 compare_ret = QString::compare(left_item->protocol(), right_item->protocol(), Qt::CaseInsensitive);
69 if (compare_ret < 0)
70 return true;
71 if (compare_ret > 0)
72 return false;
74 checkPacketNumber = true;
75 break;
76 case colProxyCount:
77 break;
78 default:
79 break;
82 if (checkPacketNumber) {
83 return (left_item->packetNum() < right_item->packetNum());
87 // fallback to string cmp on other fields
88 return QSortFilterProxyModel::lessThan(source_left, source_right);
91 QVariant ExpertInfoProxyModel::data(const QModelIndex &proxy_index, int role) const
93 QModelIndex source_index;
95 switch (role)
97 case Qt::BackgroundRole:
99 source_index = mapToSource(proxy_index);
101 // only color base row
102 if (!source_index.isValid() || source_index.parent().isValid())
103 return QVariant();
105 ExpertPacketItem* item = static_cast<ExpertPacketItem*>(source_index.internalPointer());
106 if (item == NULL)
107 return QVariant();
109 // provide background color for groups
110 switch(item->severity()) {
111 case(PI_COMMENT):
112 return QBrush(ColorUtils::expert_color_comment);
113 case(PI_CHAT):
114 return QBrush(ColorUtils::expert_color_chat);
115 case(PI_NOTE):
116 return QBrush(ColorUtils::expert_color_note);
117 case(PI_WARN):
118 return QBrush(ColorUtils::expert_color_warn);
119 case(PI_ERROR):
120 return QBrush(ColorUtils::expert_color_error);
123 break;
124 case Qt::ForegroundRole:
126 source_index = mapToSource(proxy_index);
128 // only color base row
129 if (!source_index.isValid() || source_index.parent().isValid())
130 return QVariant();
132 ExpertPacketItem* item = static_cast<ExpertPacketItem*>(source_index.internalPointer());
133 if (item == NULL)
134 return QVariant();
136 // provide foreground color for groups
137 switch(item->severity()) {
138 case(PI_COMMENT):
139 case(PI_CHAT):
140 case(PI_NOTE):
141 case(PI_WARN):
142 case(PI_ERROR):
143 return QBrush(ColorUtils::expert_color_foreground);
146 break;
147 case Qt::TextAlignmentRole:
148 switch (proxy_index.column())
150 case colProxySeverity:
151 //packet number should be right aligned
152 if (source_index.parent().isValid())
153 return Qt::AlignRight;
154 break;
155 case colProxyCount:
156 return Qt::AlignRight;
157 default:
158 break;
160 return Qt::AlignLeft;
162 case Qt::DisplayRole:
163 source_index = mapToSource(proxy_index);
165 switch (proxy_index.column())
167 case colProxySeverity:
168 if (source_index.parent().isValid())
169 return sourceModel()->data(source_index.sibling(source_index.row(), ExpertInfoModel::colPacket), role);
171 return sourceModel()->data(source_index.sibling(source_index.row(), ExpertInfoModel::colSeverity), role);
172 case colProxySummary:
173 return sourceModel()->data(source_index.sibling(source_index.row(), ExpertInfoModel::colSummary), role);
174 case colProxyGroup:
175 return sourceModel()->data(source_index.sibling(source_index.row(), ExpertInfoModel::colGroup), role);
176 case colProxyProtocol:
177 return sourceModel()->data(source_index.sibling(source_index.row(), ExpertInfoModel::colProtocol), role);
178 case colProxyCount:
179 //only show counts for parent
180 if (!source_index.parent().isValid()) {
181 //because of potential filtering, count is computed manually
182 unsigned int count = 0;
183 ExpertPacketItem *child_item,
184 *item = static_cast<ExpertPacketItem*>(source_index.internalPointer());
185 for (int row = 0; row < item->childCount(); row++) {
186 child_item = item->child(row);
187 if (child_item == NULL)
188 continue;
189 if (filterAcceptItem(*child_item))
190 count++;
193 return count;
196 break;
199 return QSortFilterProxyModel::data(proxy_index, role);
202 QVariant ExpertInfoProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
204 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
206 switch ((enum ExpertProxyColumn)section) {
207 case colProxySeverity:
208 if (severityMode_ == Packet)
209 return tr("Packet");
210 else
211 return tr("Severity");
212 case colProxySummary:
213 return tr("Summary");
214 case colProxyGroup:
215 return tr("Group");
216 case colProxyProtocol:
217 return tr("Protocol");
218 case colProxyCount:
219 return tr("Count");
220 default:
221 break;
224 return QVariant();
227 int ExpertInfoProxyModel::columnCount(const QModelIndex&) const
229 return colProxyLast;
232 bool ExpertInfoProxyModel::filterAcceptItem(ExpertPacketItem& item) const
234 if (hidden_severities_.contains(item.severity()))
235 return false;
237 if (!textFilter_.isEmpty()) {
238 QRegularExpression regex(textFilter_, QRegularExpression::CaseInsensitiveOption |
239 QRegularExpression::UseUnicodePropertiesOption);
240 if (! regex.isValid())
241 return false;
243 if (item.protocol().contains(regex))
244 return true;
246 if (item.summary().contains(regex))
247 return true;
249 if (item.colInfo().contains(regex))
250 return true;
252 return false;
255 return true;
258 bool ExpertInfoProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
260 QModelIndex severityIdx = sourceModel()->index(sourceRow, ExpertInfoModel::colSeverity, sourceParent);
261 ExpertPacketItem* item = static_cast<ExpertPacketItem*>(severityIdx.internalPointer());
262 if (item == NULL)
263 return true;
265 return filterAcceptItem(*item);
268 //GUI helpers
269 void ExpertInfoProxyModel::setSeverityMode(enum SeverityMode mode)
271 severityMode_ = mode;
272 emit headerDataChanged(Qt::Vertical, 0, 1);
275 void ExpertInfoProxyModel::setSeverityFilter(int severity, bool hide)
277 if (hide)
279 hidden_severities_ << severity;
281 else
283 hidden_severities_.removeOne(severity);
286 invalidateFilter();
289 void ExpertInfoProxyModel::setSummaryFilter(const QString &filter)
291 textFilter_ = filter;
292 invalidateFilter();