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
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
),
22 bool ExpertInfoProxyModel::lessThan(const QModelIndex
&source_left
, const QModelIndex
&source_right
) const
24 ExpertPacketItem
*left_item
,
26 QString leftStr
, rightStr
;
27 bool checkPacketNumber
= false;
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());
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;
49 compare_ret
= left_item
->summary().compare(right_item
->summary());
55 checkPacketNumber
= true;
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"));
65 checkPacketNumber
= true;
67 case colProxyProtocol
:
68 compare_ret
= QString::compare(left_item
->protocol(), right_item
->protocol(), Qt::CaseInsensitive
);
74 checkPacketNumber
= true;
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
;
97 case Qt::BackgroundRole
:
99 source_index
= mapToSource(proxy_index
);
101 // only color base row
102 if (!source_index
.isValid() || source_index
.parent().isValid())
105 ExpertPacketItem
* item
= static_cast<ExpertPacketItem
*>(source_index
.internalPointer());
109 // provide background color for groups
110 switch(item
->severity()) {
112 return QBrush(ColorUtils::expert_color_comment
);
114 return QBrush(ColorUtils::expert_color_chat
);
116 return QBrush(ColorUtils::expert_color_note
);
118 return QBrush(ColorUtils::expert_color_warn
);
120 return QBrush(ColorUtils::expert_color_error
);
124 case Qt::ForegroundRole
:
126 source_index
= mapToSource(proxy_index
);
128 // only color base row
129 if (!source_index
.isValid() || source_index
.parent().isValid())
132 ExpertPacketItem
* item
= static_cast<ExpertPacketItem
*>(source_index
.internalPointer());
136 // provide foreground color for groups
137 switch(item
->severity()) {
143 return QBrush(ColorUtils::expert_color_foreground
);
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
;
156 return Qt::AlignRight
;
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
);
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
);
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
)
189 if (filterAcceptItem(*child_item
))
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
)
211 return tr("Severity");
212 case colProxySummary
:
213 return tr("Summary");
216 case colProxyProtocol
:
217 return tr("Protocol");
227 int ExpertInfoProxyModel::columnCount(const QModelIndex
&) const
232 bool ExpertInfoProxyModel::filterAcceptItem(ExpertPacketItem
& item
) const
234 if (hidden_severities_
.contains(item
.severity()))
237 if (!textFilter_
.isEmpty()) {
238 QRegularExpression
regex(textFilter_
, QRegularExpression::CaseInsensitiveOption
|
239 QRegularExpression::UseUnicodePropertiesOption
);
240 if (! regex
.isValid())
243 if (item
.protocol().contains(regex
))
246 if (item
.summary().contains(regex
))
249 if (item
.colInfo().contains(regex
))
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());
265 return filterAcceptItem(*item
);
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
)
279 hidden_severities_
<< severity
;
283 hidden_severities_
.removeOne(severity
);
289 void ExpertInfoProxyModel::setSummaryFilter(const QString
&filter
)
291 textFilter_
= filter
;