| File: | builds/wireshark/wireshark/ui/qt/models/supported_protocols_model.cpp |
| Warning: | line 185, column 5 Potential leak of memory pointed to by 'fieldItem' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* supported_protocols_model.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 <QSortFilterProxyModel> | |||
| 11 | #include <QStringList> | |||
| 12 | #include <QPalette> | |||
| 13 | #include <QApplication> | |||
| 14 | #include <QBrush> | |||
| 15 | #include <QRegularExpression> | |||
| 16 | ||||
| 17 | #include <ui/qt/models/supported_protocols_model.h> | |||
| 18 | ||||
| 19 | SupportedProtocolsItem::SupportedProtocolsItem(protocol_t* proto, const char *name, const char* filter, ftenum_t ftype, const char* descr, SupportedProtocolsItem* parent) | |||
| 20 | : ModelHelperTreeItem<SupportedProtocolsItem>(parent), | |||
| 21 | proto_(proto), | |||
| 22 | name_(name), | |||
| 23 | filter_(filter), | |||
| 24 | ftype_(ftype), | |||
| 25 | descr_(descr) | |||
| 26 | { | |||
| 27 | } | |||
| 28 | ||||
| 29 | SupportedProtocolsItem::~SupportedProtocolsItem() | |||
| 30 | { | |||
| 31 | } | |||
| 32 | ||||
| 33 | ||||
| 34 | SupportedProtocolsModel::SupportedProtocolsModel(QObject *parent) : | |||
| 35 | QAbstractItemModel(parent), | |||
| 36 | root_(new SupportedProtocolsItem(NULL__null, NULL__null, NULL__null, FT_NONE, NULL__null, NULL__null)), | |||
| 37 | field_count_(0) | |||
| 38 | { | |||
| 39 | } | |||
| 40 | ||||
| 41 | SupportedProtocolsModel::~SupportedProtocolsModel() | |||
| 42 | { | |||
| 43 | delete root_; | |||
| 44 | } | |||
| 45 | ||||
| 46 | int SupportedProtocolsModel::rowCount(const QModelIndex &parent) const | |||
| 47 | { | |||
| 48 | SupportedProtocolsItem *parent_item; | |||
| 49 | if (parent.column() > 0) | |||
| 50 | return 0; | |||
| 51 | ||||
| 52 | if (!parent.isValid()) | |||
| 53 | parent_item = root_; | |||
| 54 | else | |||
| 55 | parent_item = static_cast<SupportedProtocolsItem*>(parent.internalPointer()); | |||
| 56 | ||||
| 57 | if (parent_item == NULL__null) | |||
| 58 | return 0; | |||
| 59 | ||||
| 60 | return parent_item->childCount(); | |||
| 61 | } | |||
| 62 | ||||
| 63 | int SupportedProtocolsModel::columnCount(const QModelIndex&) const | |||
| 64 | { | |||
| 65 | return colLast; | |||
| 66 | } | |||
| 67 | ||||
| 68 | QVariant SupportedProtocolsModel::headerData(int section, Qt::Orientation orientation, int role) const | |||
| 69 | { | |||
| 70 | if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { | |||
| 71 | ||||
| 72 | switch ((enum SupportedProtocolsColumn)section) { | |||
| 73 | case colName: | |||
| 74 | return tr("Name"); | |||
| 75 | case colFilter: | |||
| 76 | return tr("Filter"); | |||
| 77 | case colType: | |||
| 78 | return tr("Type"); | |||
| 79 | case colDescription: | |||
| 80 | return tr("Description"); | |||
| 81 | default: | |||
| 82 | break; | |||
| 83 | } | |||
| 84 | } | |||
| 85 | return QVariant(); | |||
| 86 | } | |||
| 87 | ||||
| 88 | QModelIndex SupportedProtocolsModel::parent(const QModelIndex& index) const | |||
| 89 | { | |||
| 90 | if (!index.isValid()) | |||
| 91 | return QModelIndex(); | |||
| 92 | ||||
| 93 | SupportedProtocolsItem* item = static_cast<SupportedProtocolsItem*>(index.internalPointer()); | |||
| 94 | if (item != NULL__null) { | |||
| 95 | SupportedProtocolsItem* parent_item = item->parentItem(); | |||
| 96 | if (parent_item != NULL__null) { | |||
| 97 | if (parent_item == root_) | |||
| 98 | return QModelIndex(); | |||
| 99 | ||||
| 100 | return createIndex(parent_item->row(), 0, parent_item); | |||
| 101 | } | |||
| 102 | } | |||
| 103 | ||||
| 104 | return QModelIndex(); | |||
| 105 | } | |||
| 106 | ||||
| 107 | QModelIndex SupportedProtocolsModel::index(int row, int column, const QModelIndex& parent) const | |||
| 108 | { | |||
| 109 | if (!hasIndex(row, column, parent)) | |||
| 110 | return QModelIndex(); | |||
| 111 | ||||
| 112 | SupportedProtocolsItem *parent_item, *child_item; | |||
| 113 | ||||
| 114 | if (!parent.isValid()) | |||
| 115 | parent_item = root_; | |||
| 116 | else | |||
| 117 | parent_item = static_cast<SupportedProtocolsItem*>(parent.internalPointer()); | |||
| 118 | ||||
| 119 | Q_ASSERT(parent_item)((parent_item) ? static_cast<void>(0) : qt_assert("parent_item" , "ui/qt/models/supported_protocols_model.cpp", 119)); | |||
| 120 | ||||
| 121 | child_item = parent_item->child(row); | |||
| 122 | if (child_item) { | |||
| 123 | return createIndex(row, column, child_item); | |||
| 124 | } | |||
| 125 | ||||
| 126 | return QModelIndex(); | |||
| 127 | } | |||
| 128 | ||||
| 129 | QVariant SupportedProtocolsModel::data(const QModelIndex &index, int role) const | |||
| 130 | { | |||
| 131 | if (!index.isValid() || role != Qt::DisplayRole) | |||
| 132 | return QVariant(); | |||
| 133 | ||||
| 134 | SupportedProtocolsItem* item = static_cast<SupportedProtocolsItem*>(index.internalPointer()); | |||
| 135 | if (item == NULL__null) | |||
| 136 | return QVariant(); | |||
| 137 | ||||
| 138 | switch ((enum SupportedProtocolsColumn)index.column()) { | |||
| 139 | case colName: | |||
| 140 | return item->name(); | |||
| 141 | case colFilter: | |||
| 142 | return item->filter(); | |||
| 143 | case colType: | |||
| 144 | if (index.parent().isValid()) | |||
| 145 | return QString(ftype_pretty_name(item->type())); | |||
| 146 | ||||
| 147 | return QVariant(); | |||
| 148 | case colDescription: | |||
| 149 | return item->description(); | |||
| 150 | default: | |||
| 151 | break; | |||
| 152 | } | |||
| 153 | ||||
| 154 | return QVariant(); | |||
| 155 | } | |||
| 156 | ||||
| 157 | void SupportedProtocolsModel::populate() | |||
| 158 | { | |||
| 159 | void *proto_cookie; | |||
| 160 | void *field_cookie; | |||
| 161 | ||||
| 162 | beginResetModel(); | |||
| 163 | ||||
| 164 | SupportedProtocolsItem *protoItem, *fieldItem; | |||
| 165 | protocol_t *protocol; | |||
| 166 | ||||
| 167 | for (int proto_id = proto_get_first_protocol(&proto_cookie); proto_id != -1; | |||
| ||||
| 168 | proto_id = proto_get_next_protocol(&proto_cookie)) { | |||
| 169 | ||||
| 170 | protocol = find_protocol_by_id(proto_id); | |||
| 171 | protoItem = new SupportedProtocolsItem(protocol, proto_get_protocol_short_name(protocol), proto_get_protocol_filter_name(proto_id), FT_PROTOCOL, proto_get_protocol_long_name(protocol), root_); | |||
| 172 | root_->prependChild(protoItem); | |||
| 173 | ||||
| 174 | for (header_field_info *hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo != NULL__null; | |||
| 175 | hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie)) { | |||
| 176 | if (hfinfo->same_name_prev_id != -1) | |||
| 177 | continue; | |||
| 178 | ||||
| 179 | fieldItem = new SupportedProtocolsItem(protocol, hfinfo->name, hfinfo->abbrev, hfinfo->type, hfinfo->blurb, protoItem); | |||
| 180 | protoItem->prependChild(fieldItem); | |||
| 181 | field_count_++; | |||
| 182 | } | |||
| 183 | } | |||
| 184 | ||||
| 185 | endResetModel(); | |||
| ||||
| 186 | } | |||
| 187 | ||||
| 188 | ||||
| 189 | ||||
| 190 | SupportedProtocolsProxyModel::SupportedProtocolsProxyModel(QObject * parent) | |||
| 191 | : QSortFilterProxyModel(parent), | |||
| 192 | filter_() | |||
| 193 | { | |||
| 194 | } | |||
| 195 | ||||
| 196 | bool SupportedProtocolsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const | |||
| 197 | { | |||
| 198 | //Use SupportedProtocolsItem directly for better performance | |||
| 199 | SupportedProtocolsItem* left_item = static_cast<SupportedProtocolsItem*>(left.internalPointer()); | |||
| 200 | SupportedProtocolsItem* right_item = static_cast<SupportedProtocolsItem*>(right.internalPointer()); | |||
| 201 | ||||
| 202 | if ((left_item != NULL__null) && (right_item != NULL__null)) { | |||
| 203 | int compare_ret = QString::compare(left_item->name(), right_item->name(), Qt::CaseInsensitive); | |||
| 204 | if (compare_ret < 0) | |||
| 205 | return true; | |||
| 206 | } | |||
| 207 | ||||
| 208 | return false; | |||
| 209 | } | |||
| 210 | ||||
| 211 | bool SupportedProtocolsProxyModel::filterAcceptItem(SupportedProtocolsItem& item) const | |||
| 212 | { | |||
| 213 | QRegularExpression regex(filter_, QRegularExpression::CaseInsensitiveOption); | |||
| 214 | if (! regex.isValid()) | |||
| 215 | return false; | |||
| 216 | ||||
| 217 | if (item.name().contains(regex)) | |||
| 218 | return true; | |||
| 219 | ||||
| 220 | if (item.filter().contains(regex)) | |||
| 221 | return true; | |||
| 222 | ||||
| 223 | if (item.description().contains(regex)) | |||
| 224 | return true; | |||
| 225 | ||||
| 226 | return false; | |||
| 227 | } | |||
| 228 | ||||
| 229 | bool SupportedProtocolsProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const | |||
| 230 | { | |||
| 231 | QModelIndex nameIdx = sourceModel()->index(sourceRow, SupportedProtocolsModel::colName, sourceParent); | |||
| 232 | SupportedProtocolsItem* item = static_cast<SupportedProtocolsItem*>(nameIdx.internalPointer()); | |||
| 233 | if (item == NULL__null) | |||
| 234 | return true; | |||
| 235 | ||||
| 236 | if (!filter_.isEmpty()) { | |||
| 237 | if (filterAcceptItem(*item)) | |||
| 238 | return true; | |||
| 239 | ||||
| 240 | if (!nameIdx.parent().isValid()) | |||
| 241 | { | |||
| 242 | SupportedProtocolsItem* child_item; | |||
| 243 | for (int row = 0; row < item->childCount(); row++) | |||
| 244 | { | |||
| 245 | child_item = item->child(row); | |||
| 246 | if ((child_item != NULL__null) && (filterAcceptItem(*child_item))) | |||
| 247 | return true; | |||
| 248 | } | |||
| 249 | } | |||
| 250 | ||||
| 251 | return false; | |||
| 252 | } | |||
| 253 | ||||
| 254 | return true; | |||
| 255 | } | |||
| 256 | ||||
| 257 | void SupportedProtocolsProxyModel::setFilter(const QString& filter) | |||
| 258 | { | |||
| 259 | #if QT_VERSION((6<<16)|(4<<8)|(2)) >= QT_VERSION_CHECK(6, 9, 0)((6<<16)|(9<<8)|(0)) | |||
| 260 | beginFilterChange(); | |||
| 261 | #endif | |||
| 262 | filter_ = filter; | |||
| 263 | #if QT_VERSION((6<<16)|(4<<8)|(2)) >= QT_VERSION_CHECK(6, 10, 0)((6<<16)|(10<<8)|(0)) | |||
| 264 | endFilterChange(QSortFilterProxyModel::Direction::Rows); | |||
| 265 | #else | |||
| 266 | invalidateFilter(); | |||
| 267 | #endif | |||
| 268 | } |