diff options
Diffstat (limited to 'ui/qt/models')
50 files changed, 838 insertions, 409 deletions
diff --git a/ui/qt/models/astringlist_list_model.cpp b/ui/qt/models/astringlist_list_model.cpp index a0b5fc38..c3b3ec05 100644 --- a/ui/qt/models/astringlist_list_model.cpp +++ b/ui/qt/models/astringlist_list_model.cpp @@ -166,7 +166,6 @@ bool AStringListListSortFilterProxyModel::filterAcceptsRow(int sourceRow, const break; case FilterNone: return true; - break; default: compareFunc = AContainsB; break; diff --git a/ui/qt/models/astringlist_list_model.h b/ui/qt/models/astringlist_list_model.h index 70acc97b..f1e396c8 100644 --- a/ui/qt/models/astringlist_list_model.h +++ b/ui/qt/models/astringlist_list_model.h @@ -21,6 +21,7 @@ class AStringListListModel : public QAbstractTableModel { + Q_OBJECT public: explicit AStringListListModel(QObject * parent = Q_NULLPTR); virtual ~AStringListListModel(); diff --git a/ui/qt/models/atap_data_model.cpp b/ui/qt/models/atap_data_model.cpp index b7ff508d..c3a2f840 100644 --- a/ui/qt/models/atap_data_model.cpp +++ b/ui/qt/models/atap_data_model.cpp @@ -7,8 +7,6 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ -#include <glib.h> - #include <epan/tap.h> #include <epan/conversation.h> #include <epan/conversation_table.h> @@ -90,10 +88,12 @@ bool ATapDataModel::hasGeoIPData() while (!coordsFound && row < count) { QModelIndex idx = index(row, 0); - if (_type == ATapDataModel::DATAMODEL_ENDPOINT) - coordsFound = qobject_cast<EndpointDataModel *>(this)->data(idx, ATapDataModel::GEODATA_AVAILABLE).toBool(); - else if (_type == ATapDataModel::DATAMODEL_CONVERSATION) - coordsFound = qobject_cast<ConversationDataModel *>(this)->data(idx, ATapDataModel::GEODATA_AVAILABLE).toBool(); + if (!data(idx, ATapDataModel::ROW_IS_FILTERED).toBool()) { + if (_type == ATapDataModel::DATAMODEL_ENDPOINT) + coordsFound = qobject_cast<EndpointDataModel *>(this)->data(idx, ATapDataModel::GEODATA_AVAILABLE).toBool(); + else if (_type == ATapDataModel::DATAMODEL_CONVERSATION) + coordsFound = qobject_cast<ConversationDataModel *>(this)->data(idx, ATapDataModel::GEODATA_AVAILABLE).toBool(); + } row++; } @@ -585,6 +585,9 @@ void ConversationDataModel::doDataUpdate() int ConversationDataModel::columnCount(const QModelIndex &) const { + if(tap()=="tcp") + return CONV_TCP_EXT_NUM_COLUMNS; + return CONV_NUM_COLUMNS; } @@ -630,6 +633,15 @@ QVariant ConversationDataModel::headerData(int section, Qt::Orientation orientat case CONV_COLUMN_BPS_BA: return tr("Bits/s B " UTF8_RIGHTWARDS_ARROW " A"); break; } + /* Extended conversations columns, e.g. TCP */ + if(tap()=="tcp") { + switch (section) { + case CONV_TCP_EXT_COLUMN_A: + return tr("Flows"); break; + default : + ws_assert_not_reached(); break; + } + } } else if (role == Qt::TextAlignmentRole) { if (section == CONV_COLUMN_SRC_ADDR || section == CONV_COLUMN_DST_ADDR) return Qt::AlignLeft; @@ -701,7 +713,10 @@ QVariant ConversationDataModel::data(const QModelIndex &idx, int role) const return role == Qt::DisplayRole ? formatString((qlonglong)conv_item->tx_bytes + conv_item->rx_bytes) : QVariant((qlonglong)conv_item->tx_bytes + conv_item->rx_bytes); case CONV_COLUMN_CONV_ID: - return (int) conv_item->conv_id; + if(conv_item->conv_id!=CONV_ID_UNSET) { + return (int) conv_item->conv_id; + } + break; case CONV_COLUMN_PACKETS_TOTAL: { qlonglong packets = 0; @@ -722,7 +737,7 @@ QVariant ConversationDataModel::data(const QModelIndex &idx, int role) const /* Qt guarantees that this roundtrip conversion compares equally, * so filtering with equality will work as expected. * XXX: Perhaps the UNFORMATTED_DISPLAYDATA role shoud be split - * into one used for raw data export and comparisions with each + * into one used for raw data export and comparisons with each * other, and another for comparing with filters? */ return role == Qt::DisplayRole ? rounded + "%" : QVariant(rounded.toDouble()); @@ -778,6 +793,18 @@ QVariant ConversationDataModel::data(const QModelIndex &idx, int role) const case CONV_COLUMN_BPS_BA: return bpsCalculated ? (role == Qt::DisplayRole ? gchar_free_to_qstring(format_size((int64_t)bps_ba, FORMAT_SIZE_UNIT_BITS_S, FORMAT_SIZE_PREFIX_SI)) : QVariant((qlonglong)bps_ba)): QVariant(); } + /* Extended conversations columns, e.g. TCP */ + if(tap()=="tcp") { + switch(idx.column()) { + case CONV_TCP_EXT_COLUMN_A: + { + qlonglong flows = (qlonglong)conv_item->ext_tcp.flows; + return role == Qt::DisplayRole ? QString("%L1").arg(flows) : (QVariant)flows; break; + } + default : + ws_assert_not_reached(); break; + } + } } else if (role == Qt::ToolTipRole) { if (idx.column() == CONV_COLUMN_START || idx.column() == CONV_COLUMN_DURATION) return QObject::tr("Bars show the relative timeline for each conversation."); @@ -844,7 +871,11 @@ bool ConversationDataModel::showConversationId(int row) const return false; conv_item_t *conv_item = (conv_item_t *)&g_array_index(storage_, conv_item_t, row); - if (conv_item && (conv_item->ctype == CONVERSATION_TCP || conv_item->ctype == CONVERSATION_UDP)) + if (conv_item && (conv_item->ctype == CONVERSATION_TCP || + conv_item->ctype == CONVERSATION_UDP || + conv_item->ctype == CONVERSATION_IP || + conv_item->ctype == CONVERSATION_IPV6|| + conv_item->ctype == CONVERSATION_ETH)) return true; return false; } diff --git a/ui/qt/models/atap_data_model.h b/ui/qt/models/atap_data_model.h index 38bdbd2f..6ba0b325 100644 --- a/ui/qt/models/atap_data_model.h +++ b/ui/qt/models/atap_data_model.h @@ -12,8 +12,6 @@ #include "config.h" -#include "glib.h" - #include <epan/tap.h> #include <epan/conversation.h> #include <epan/conversation_table.h> @@ -306,6 +304,12 @@ public: CONV_INDEX_COLUMN = CONV_NUM_COLUMNS } conversation_column_type_e; + typedef enum { + CONV_TCP_EXT_COLUMN_A = CONV_INDEX_COLUMN, + CONV_TCP_EXT_NUM_COLUMNS, + CONV_TCP_EXT_INDEX_COLUMN = CONV_TCP_EXT_NUM_COLUMNS + } conversation_tcp_ext_column_type_e; + explicit ConversationDataModel(int protoId, QString filter, QObject *parent = nullptr); int columnCount(const QModelIndex &parent = QModelIndex()) const; diff --git a/ui/qt/models/coloring_rules_delegate.cpp b/ui/qt/models/coloring_rules_delegate.cpp index b86ffa97..58524be1 100644 --- a/ui/qt/models/coloring_rules_delegate.cpp +++ b/ui/qt/models/coloring_rules_delegate.cpp @@ -32,7 +32,7 @@ QWidget* ColoringRulesDelegate::createEditor(QWidget *parent, const QStyleOption return new DisplayFilterEdit(parent); default: - Q_ASSERT(FALSE); + Q_ASSERT(false); return 0; } diff --git a/ui/qt/models/coloring_rules_model.cpp b/ui/qt/models/coloring_rules_model.cpp index dced9c37..29bb7dcf 100644 --- a/ui/qt/models/coloring_rules_model.cpp +++ b/ui/qt/models/coloring_rules_model.cpp @@ -72,7 +72,7 @@ ColoringRuleItem& ColoringRuleItem::operator=(ColoringRuleItem& rhs) // Callback for color_filters_clone. void -color_filter_add_cb(color_filter_t *colorf, gpointer user_data) +color_filter_add_cb(color_filter_t *colorf, void *user_data) { ColoringRulesModel *model = (ColoringRulesModel*)user_data; @@ -149,7 +149,7 @@ void ColoringRulesModel::addColor(bool disabled, QString filter, QColor foregrou bool ColoringRulesModel::importColors(QString filename, QString& err) { bool success = true; - gchar* err_msg = NULL; + char* err_msg = NULL; if (!color_filters_import(filename.toUtf8().constData(), this, &err_msg, color_filter_add_cb)) { err = gchar_free_to_qstring(err_msg); success = false; @@ -162,8 +162,8 @@ bool ColoringRulesModel::exportColors(QString filename, QString& err) { GSList *cfl = createColorFilterList(); bool success = true; - gchar* err_msg = NULL; - if (!color_filters_export(filename.toUtf8().constData(), cfl, FALSE, &err_msg)) { + char* err_msg = NULL; + if (!color_filters_export(filename.toUtf8().constData(), cfl, false, &err_msg)) { err = gchar_free_to_qstring(err_msg); success = false; } @@ -176,7 +176,7 @@ bool ColoringRulesModel::writeColors(QString& err) { GSList *cfl = createColorFilterList(); bool success = true; - gchar* err_msg = NULL; + char* err_msg = NULL; if (!color_filters_apply(conversation_colors_, cfl, &err_msg)) { err = gchar_free_to_qstring(err_msg); success = false; diff --git a/ui/qt/models/coloring_rules_model.h b/ui/qt/models/coloring_rules_model.h index f51a1a30..0df532ef 100644 --- a/ui/qt/models/coloring_rules_model.h +++ b/ui/qt/models/coloring_rules_model.h @@ -14,7 +14,6 @@ #include <config.h> -#include <glib.h> #include <epan/color_filters.h> #include <ui/qt/models/tree_model_helpers.h> diff --git a/ui/qt/models/column_list_model.cpp b/ui/qt/models/column_list_model.cpp index 102ffc31..7613e487 100644 --- a/ui/qt/models/column_list_model.cpp +++ b/ui/qt/models/column_list_model.cpp @@ -13,11 +13,11 @@ #include <ui/qt/widgets/syntax_line_edit.h> #include <ui/qt/utils/wireshark_mime_data.h> -#include <glib.h> #include <epan/column.h> #include <epan/prefs.h> #include <epan/proto.h> #include <ui/preference_utils.h> +#include <ui/recent.h> #include <QLineEdit> #include <QStringList> @@ -31,6 +31,8 @@ struct ListElement int type; int originalType; int occurrence; + int width; + char xalign; bool displayed; bool resolved; }; @@ -65,6 +67,22 @@ ColumnTypeDelegate::ColumnTypeDelegate(QObject * parent) : QStyledItemDelegate(parent) {} +QString ColumnTypeDelegate::alignDesc(char xalign) +{ + switch (xalign) { + case COLUMN_XALIGN_DEFAULT: + return QObject::tr("Default"); + case COLUMN_XALIGN_LEFT: + return QObject::tr("Left"); + case COLUMN_XALIGN_CENTER: + return QObject::tr("Center"); + case COLUMN_XALIGN_RIGHT: + return QObject::tr("Right"); + default: + return QObject::tr("Unknown"); + } +} + QWidget *ColumnTypeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const @@ -92,13 +110,26 @@ QWidget *ColumnTypeDelegate::createEditor(QWidget *parent, ff_editor->setText(index.data().toString()); editor = ff_editor; } - else if (index.column() == ColumnListModel::COL_OCCURRENCE) + else if (index.column() == ColumnListModel::COL_OCCURRENCE || + index.column() == ColumnListModel::COL_WIDTH) { SyntaxLineEdit * sl_editor = new SyntaxLineEdit(parent); connect(sl_editor, &SyntaxLineEdit::textChanged, sl_editor, &SyntaxLineEdit::checkInteger); sl_editor->setText(index.data().toString()); editor = sl_editor; } + else if (index.column() == ColumnListModel::COL_XALIGN) + { + QComboBox *cb_editor = new QComboBox(parent); + + cb_editor->addItem(alignDesc(COLUMN_XALIGN_DEFAULT), QVariant(COLUMN_XALIGN_DEFAULT)); + cb_editor->addItem(alignDesc(COLUMN_XALIGN_LEFT), QVariant(COLUMN_XALIGN_LEFT)); + cb_editor->addItem(alignDesc(COLUMN_XALIGN_CENTER), QVariant(COLUMN_XALIGN_CENTER)); + cb_editor->addItem(alignDesc(COLUMN_XALIGN_RIGHT), QVariant(COLUMN_XALIGN_RIGHT)); + cb_editor->setCurrentIndex(cb_editor->findText(index.data().toString())); + cb_editor->setFrame(false); + editor = cb_editor; + } if (!editor) { editor = QStyledItemDelegate::createEditor(parent, option, index); @@ -111,7 +142,8 @@ void ColumnTypeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QVariant data = index.model()->data(index); - if (index.column() == ColumnListModel::COL_TYPE) + if (index.column() == ColumnListModel::COL_TYPE || + index.column() == ColumnListModel::COL_XALIGN) { QComboBox *comboBox = static_cast<QComboBox*>(editor); comboBox->setCurrentText(data.toString()); @@ -121,7 +153,8 @@ void ColumnTypeDelegate::setEditorData(QWidget *editor, if (qobject_cast<FieldFilterEdit *>(editor)) qobject_cast<FieldFilterEdit *>(editor)->setText(data.toString()); } - else if (index.column() == ColumnListModel::COL_OCCURRENCE) + else if (index.column() == ColumnListModel::COL_OCCURRENCE || + index.column() == ColumnListModel::COL_WIDTH) { if (qobject_cast<SyntaxLineEdit *>(editor)) qobject_cast<SyntaxLineEdit *>(editor)->setText(data.toString()); @@ -136,7 +169,8 @@ void ColumnTypeDelegate::setEditorData(QWidget *editor, void ColumnTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { - if (index.column() == ColumnListModel::COL_TYPE) + if (index.column() == ColumnListModel::COL_TYPE || + index.column() == ColumnListModel::COL_XALIGN) { QComboBox *comboBox = static_cast<QComboBox*>(editor); bool ok = false; @@ -197,6 +231,22 @@ void ColumnTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model } } + else if (index.column() == ColumnListModel::COL_WIDTH) + { + SyntaxLineEdit * sle = qobject_cast<SyntaxLineEdit *>(editor); + bool ok = false; + if (sle) + { + sle->checkInteger(index.data().toString()); + if (sle->syntaxState() == SyntaxLineEdit::Valid) + ok = true; + } + + if (ok) + { + model->setData(index, sle->text(), Qt::EditRole); + } + } else QStyledItemDelegate::setModelData(editor, model, index); } @@ -216,7 +266,7 @@ ColumnListModel::ColumnListModel(QObject * parent): QVariant ColumnListModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (section > ColumnListModel::COL_RESOLVED || orientation != Qt::Horizontal || + if (section > ColumnListModel::COL_XALIGN || orientation != Qt::Horizontal || role != Qt::DisplayRole) return QVariant(); @@ -230,7 +280,7 @@ int ColumnListModel::rowCount(const QModelIndex &/*parent*/) const int ColumnListModel::columnCount(const QModelIndex &/*parent*/) const { - return ColumnListModel::COL_RESOLVED + 1; + return ColumnListModel::COL_XALIGN + 1; } QString ColumnListModel::headerTitle(int section) const @@ -249,6 +299,10 @@ QString ColumnListModel::headerTitle(int section) const return tr("Field Occurrence"); case ColumnListModel::COL_RESOLVED: return tr("Resolved"); + case ColumnListModel::COL_WIDTH: + return tr("Width"); + case ColumnListModel::COL_XALIGN: + return tr("Alignment"); } return QString(); @@ -271,6 +325,9 @@ void ColumnListModel::populate() ne.occurrence = cfmt->custom_occurrence; ne.resolved = cfmt->resolved; + ne.width = recent_get_column_width(nr); + ne.xalign = recent_get_column_xalign(nr); + nr++; store_ << ne; } @@ -298,6 +355,10 @@ QVariant ColumnListModel::data(const QModelIndex &index, int role) const return ne.customFields; case ColumnListModel::COL_OCCURRENCE: return ne.customFields.length() > 0 ? QVariant::fromValue(ne.occurrence) : QVariant(); + case ColumnListModel::COL_WIDTH: + return ne.width; + case ColumnListModel::COL_XALIGN: + return ColumnTypeDelegate::alignDesc(ne.xalign); } } else if (role == Qt::CheckStateRole) @@ -452,6 +513,20 @@ bool ColumnListModel::setData(const QModelIndex &index, const QVariant &value, i { store_[index.row()].resolved = value.toInt() == Qt::Checked ? true : false; } + else if (index.column() == ColumnListModel::COL_WIDTH) + { + bool ok = false; + int val = value.toInt(&ok); + if (ok) + store_[index.row()].width = val; + } + else if (index.column() == ColumnListModel::COL_XALIGN) + { + bool ok = false; + int val = value.toInt(&ok); + if (ok) + store_[index.row()].xalign = static_cast<char>(val); + } if (change) emit dataChanged(index, index); @@ -471,7 +546,7 @@ void ColumnListModel::saveColumns() cfmt->title = qstring_strdup(elem.title); cfmt->visible = elem.displayed; cfmt->fmt = elem.type; - cfmt->resolved = TRUE; + cfmt->resolved = true; if (cfmt->fmt == COL_CUSTOM) { cfmt->custom_fields = qstring_strdup(elem.customFields); @@ -486,6 +561,16 @@ void ColumnListModel::saveColumns() column_prefs_remove_link(prefs.col_list); prefs.col_list = new_col_list; + + recent_free_column_width_info(&recent); + for (int row = 0; row < store_.count(); row++) + { + ListElement elem = store_.at(row); + + recent_insert_column(row); + recent_set_column_width(row, elem.width); + recent_set_column_xalign(row, elem.xalign); + } } void ColumnListModel::addEntry() @@ -499,6 +584,8 @@ void ColumnListModel::addEntry() elem.occurrence = 0; elem.customFields = QString(); elem.resolved = true; + elem.width = -1; + elem.xalign = COLUMN_XALIGN_DEFAULT; store_ << elem; endInsertRows(); } diff --git a/ui/qt/models/column_list_model.h b/ui/qt/models/column_list_model.h index c4739f96..7f59b91c 100644 --- a/ui/qt/models/column_list_model.h +++ b/ui/qt/models/column_list_model.h @@ -35,6 +35,8 @@ class ColumnTypeDelegate : public QStyledItemDelegate public: ColumnTypeDelegate(QObject * parent = Q_NULLPTR); + static QString alignDesc(char xalign); + QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; @@ -59,7 +61,9 @@ public: COL_TYPE, COL_FIELDS, COL_OCCURRENCE, - COL_RESOLVED + COL_RESOLVED, + COL_WIDTH, + COL_XALIGN }; enum { diff --git a/ui/qt/models/decode_as_delegate.cpp b/ui/qt/models/decode_as_delegate.cpp index 3c300a79..c3917928 100644 --- a/ui/qt/models/decode_as_delegate.cpp +++ b/ui/qt/models/decode_as_delegate.cpp @@ -46,11 +46,11 @@ void DecodeAsDelegate::cachePacketProtocols() if (cap_file_ && cap_file_->edt) { wmem_list_frame_t * protos = wmem_list_head(cap_file_->edt->pi.layers); - guint8 curr_layer_num = 1; + uint8_t curr_layer_num = 1; while (protos != NULL) { int proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos)); - const gchar * proto_name = proto_get_protocol_filter_name(proto_id); + const char * proto_name = proto_get_protocol_filter_name(proto_id); for (GList *cur = decode_as_list; cur; cur = cur->next) { decode_as_t *entry = (decode_as_t *) cur->data; if (g_strcmp0(proto_name, entry->name) == 0) { @@ -95,7 +95,7 @@ void DecodeAsDelegate::collectDAProtocols(QSet<QString>& all_protocols, QList<QS //correspond to using a combo box bool DecodeAsDelegate::isSelectorCombo(DecodeAsItem* item) const { - const gchar *proto_name = NULL; + const char *proto_name = NULL; foreach(packet_proto_data_t proto, packet_proto_list_) { @@ -117,7 +117,7 @@ bool DecodeAsDelegate::isSelectorCombo(DecodeAsItem* item) const return false; } -void DecodeAsDelegate::decodeAddProtocol(const gchar *, const gchar *proto_name, gpointer value, gpointer user_data) +void DecodeAsDelegate::decodeAddProtocol(const char *, const char *proto_name, void *value, void *user_data) { QList<dissector_info_t*>* proto_list = (QList<dissector_info_t*>*)user_data; @@ -178,10 +178,10 @@ QWidget* DecodeAsDelegate::createEditor(QWidget *parentWidget, const QStyleOptio case DecodeAsModel::colSelector: { QComboBox *cb_editor = NULL; - const gchar *proto_name = NULL; + const char *proto_name = NULL; bool edt_present = cap_file_ && cap_file_->edt; - gint8 curr_layer_num_saved = edt_present ? cap_file_->edt->pi.curr_layer_num : 0; - QList<guint8> proto_layers; + int8_t curr_layer_num_saved = edt_present ? cap_file_->edt->pi.curr_layer_num : 0; + QList<uint8_t> proto_layers; foreach(packet_proto_data_t proto, packet_proto_list_) { @@ -212,7 +212,7 @@ QWidget* DecodeAsDelegate::createEditor(QWidget *parentWidget, const QStyleOptio cb_editor->addItem(current_value); //get the value(s) from the packet - foreach(guint8 current_layer, proto_layers) { + foreach(uint8_t current_layer, proto_layers) { cap_file_->edt->pi.curr_layer_num = current_layer; for (uint ni = 0; ni < entry->num_items; ni++) { if (entry->values[ni].num_values == 1) { // Skip over multi-value ("both") entries diff --git a/ui/qt/models/decode_as_delegate.h b/ui/qt/models/decode_as_delegate.h index d0457764..d793a85a 100644 --- a/ui/qt/models/decode_as_delegate.h +++ b/ui/qt/models/decode_as_delegate.h @@ -13,7 +13,6 @@ #define DECODE_AS_DELEGATE_H #include <config.h> -#include <glib.h> #include "cfile.h" @@ -23,9 +22,9 @@ #include <ui/qt/models/decode_as_model.h> typedef struct _packet_proto_data_t { - const gchar* proto_name; - const gchar* table_ui_name; - guint8 curr_layer_num; + const char* proto_name; + const char* table_ui_name; + uint8_t curr_layer_num; } packet_proto_data_t; class DecodeAsDelegate : public QStyledItemDelegate @@ -51,7 +50,7 @@ private: void cachePacketProtocols(); bool isSelectorCombo(DecodeAsItem* item) const; - static void decodeAddProtocol(const gchar *table_name, const gchar *proto_name, gpointer value, gpointer user_data); + static void decodeAddProtocol(const char *table_name, const char *proto_name, void *value, void *user_data); capture_file *cap_file_; QList<packet_proto_data_t> packet_proto_list_; diff --git a/ui/qt/models/decode_as_model.cpp b/ui/qt/models/decode_as_model.cpp index 67e98b75..73253c30 100644 --- a/ui/qt/models/decode_as_model.cpp +++ b/ui/qt/models/decode_as_model.cpp @@ -29,7 +29,7 @@ static const char *DEFAULT_TABLE = "tcp.port"; // Arbitrary static const char *DEFAULT_UI_TABLE = "TCP port"; // Arbitrary -DecodeAsItem::DecodeAsItem(const char* table_name, gconstpointer selector) : +DecodeAsItem::DecodeAsItem(const char* table_name, const void *selector) : tableName_(DEFAULT_TABLE), tableUIName_(DEFAULT_UI_TABLE), selectorUint_(0), @@ -45,7 +45,7 @@ DecodeAsItem::DecodeAsItem(const char* table_name, gconstpointer selector) : init(table_name, selector); } -DecodeAsItem::DecodeAsItem(const decode_as_t *entry, gconstpointer selector) : +DecodeAsItem::DecodeAsItem(const decode_as_t *entry, const void *selector) : tableName_(DEFAULT_TABLE), tableUIName_(DEFAULT_UI_TABLE), selectorUint_(0), @@ -65,7 +65,7 @@ DecodeAsItem::~DecodeAsItem() { } -void DecodeAsItem::init(const char* table_name, gconstpointer selector) +void DecodeAsItem::init(const char* table_name, const void *selector) { tableName_ = table_name; tableUIName_ = get_dissector_table_ui_name(tableName_); @@ -74,7 +74,7 @@ void DecodeAsItem::init(const char* table_name, gconstpointer selector) ftenum_t selector_type = get_dissector_table_selector_type(tableName_); if (FT_IS_STRING(selector_type)) { if (selector != NULL) { - default_handle = dissector_get_default_string_handle(tableName_, (const gchar*)selector); + default_handle = dissector_get_default_string_handle(tableName_, (const char*)selector); selectorString_ = QString((const char*)selector); } } else if (FT_IS_UINT(selector_type)) { @@ -241,7 +241,7 @@ QVariant DecodeAsModel::data(const QModelIndex &index, int role) const if (FT_IS_UINT(selector_type)) { return entryString(item->tableName(), GUINT_TO_POINTER(item->selectorUint())); } else if (FT_IS_STRING(selector_type)) { - return entryString(item->tableName(), (gconstpointer)item->selectorString().toUtf8().constData()); + return entryString(item->tableName(), (const void *)item->selectorString().toUtf8().constData()); } else if (selector_type == FT_GUID) { if (item->selectorDCERPC() != NULL) { return item->selectorDCERPC()->ctx_id; @@ -410,12 +410,12 @@ bool DecodeAsModel::insertRows(int row, int count, const QModelIndex &/*parent*/ // the fields for the tables not being present at all. wmem_list_frame_t * protos = wmem_list_tail(cap_file_->edt->pi.layers); - gint8 curr_layer_num_saved = cap_file_->edt->pi.curr_layer_num; - guint8 curr_layer_num = wmem_list_count(cap_file_->edt->pi.layers); + int8_t curr_layer_num_saved = cap_file_->edt->pi.curr_layer_num; + uint8_t curr_layer_num = wmem_list_count(cap_file_->edt->pi.layers); while (protos != NULL && item == nullptr) { int proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos)); - const gchar * proto_name = proto_get_protocol_filter_name(proto_id); + const char * proto_name = proto_get_protocol_filter_name(proto_id); for (GList *cur = decode_as_list; cur; cur = cur->next) { decode_as_t *entry = (decode_as_t *) cur->data; if (g_strcmp0(proto_name, entry->name) == 0) { @@ -428,7 +428,7 @@ bool DecodeAsModel::insertRows(int row, int count, const QModelIndex &/*parent*/ // XXX: What if the Decode As table supports multiple // values, but the first possible one is 0/NULL? cap_file_->edt->pi.curr_layer_num = curr_layer_num; - gpointer selector = entry->values[0].build_values[0](&cap_file_->edt->pi); + void *selector = entry->values[0].build_values[0](&cap_file_->edt->pi); // FT_NONE tables don't need a value if (selector != NULL || selector_type == FT_NONE) { item = new DecodeAsItem(entry, selector); @@ -499,7 +499,7 @@ bool DecodeAsModel::copyRow(int dst_row, int src_row) return true; } -prefs_set_pref_e DecodeAsModel::readDecodeAsEntry(gchar *key, const gchar *value, void *private_data, gboolean) +prefs_set_pref_e DecodeAsModel::readDecodeAsEntry(char *key, const char *value, void *private_data, bool) { DecodeAsModel *model = (DecodeAsModel*)private_data; if (model == NULL) @@ -510,7 +510,7 @@ prefs_set_pref_e DecodeAsModel::readDecodeAsEntry(gchar *key, const gchar *value } /* Parse into table, selector, initial, current */ - gchar **values = g_strsplit_set(value, ",", 4); + char **values = g_strsplit_set(value, ",", 4); DecodeAsItem *item = nullptr; dissector_table_t dissector_table = find_dissector_table(values[0]); @@ -546,7 +546,7 @@ prefs_set_pref_e DecodeAsModel::readDecodeAsEntry(gchar *key, const gchar *value return PREFS_SET_OK; } -bool DecodeAsModel::copyFromProfile(QString filename, const gchar **err) +bool DecodeAsModel::copyFromProfile(QString filename, const char **err) { FILE *fp = ws_fopen(filename.toUtf8().constData(), "r"); @@ -564,7 +564,7 @@ bool DecodeAsModel::copyFromProfile(QString filename, const gchar **err) return true; } -QString DecodeAsModel::entryString(const gchar *table_name, gconstpointer value) +QString DecodeAsModel::entryString(const char *table_name, const void *value) { QString entry_str; ftenum_t selector_type = get_dissector_table_selector_type(table_name); @@ -654,7 +654,7 @@ void DecodeAsModel::setDissectorHandle(const QModelIndex &index, dissector_handl item->setDissectorHandle(dissector_handle); } -void DecodeAsModel::buildChangedList(const gchar *table_name, ftenum_t, gpointer key, gpointer value, gpointer user_data) +void DecodeAsModel::buildChangedList(const char *table_name, ftenum_t, void *key, void *value, void *user_data) { DecodeAsModel *model = (DecodeAsModel*)user_data; if (model == NULL) @@ -669,7 +669,7 @@ void DecodeAsModel::buildChangedList(const gchar *table_name, ftenum_t, gpointer model->decode_as_items_ << item; } -void DecodeAsModel::buildDceRpcChangedList(gpointer data, gpointer user_data) +void DecodeAsModel::buildDceRpcChangedList(void *data, void *user_data) { dissector_table_t sub_dissectors; guid_key guid_val; @@ -690,27 +690,36 @@ void DecodeAsModel::buildDceRpcChangedList(gpointer data, gpointer user_data) model->decode_as_items_ << item; } -typedef QPair<const char *, guint32> UintPair; typedef QPair<const char *, const char *> CharPtrPair; -void DecodeAsModel::gatherChangedEntries(const gchar *table_name, - ftenum_t selector_type, gpointer key, gpointer, gpointer user_data) +void DecodeAsModel::gatherChangedEntries(const char *table_name, + ftenum_t selector_type, void *key, void *value, void *user_data) { DecodeAsModel *model = qobject_cast<DecodeAsModel*>((DecodeAsModel*)user_data); if (model == NULL) return; + dissector_handle_t current = dtbl_entry_get_handle((dtbl_entry_t *)value); + switch (selector_type) { case FT_UINT8: case FT_UINT16: case FT_UINT24: case FT_UINT32: - model->changed_uint_entries_ << UintPair(table_name, GPOINTER_TO_UINT(key)); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + model->changed_uint_entries_.emplaceBack(table_name, GPOINTER_TO_UINT(key), dissector_handle_get_pref_suffix(current)); +#else + model->changed_uint_entries_ << UIntEntry(table_name, GPOINTER_TO_UINT(key), dissector_handle_get_pref_suffix(current)); +#endif break; case FT_NONE: //need to reset dissector table, so this needs to be in a changed list, //might as well be the uint one. - model->changed_uint_entries_ << UintPair(table_name, 0); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + model->changed_uint_entries_.emplaceBack(table_name, 0, ""); +#else + model->changed_uint_entries_ << UIntEntry(table_name, 0, ""); +#endif break; case FT_STRING: @@ -741,20 +750,20 @@ void DecodeAsModel::applyChanges() // If dissector_all_tables_remove_changed existed we could call it // instead. dissector_all_tables_foreach_changed(gatherChangedEntries, this); - foreach (UintPair uint_entry, changed_uint_entries_) { + foreach (const auto &uint_entry, changed_uint_entries_) { /* Set "Decode As preferences" to default values */ - sub_dissectors = find_dissector_table(uint_entry.first); - handle = dissector_get_uint_handle(sub_dissectors, uint_entry.second); + sub_dissectors = find_dissector_table(uint_entry.table); + handle = dissector_get_uint_handle(sub_dissectors, uint_entry.key); if (handle != NULL) { module = prefs_find_module(proto_get_protocol_filter_name(dissector_handle_get_protocol_index(handle))); - pref_value = prefs_find_preference(module, uint_entry.first); + pref_value = prefs_find_preference(module, uint_entry.pref_name); if (pref_value != NULL) { module->prefs_changed_flags |= prefs_get_effect_flags(pref_value); reset_pref(pref_value); } } - dissector_reset_uint(uint_entry.first, uint_entry.second); + dissector_reset_uint(uint_entry.table, uint_entry.key); } changed_uint_entries_.clear(); foreach (CharPtrPair char_ptr_entry, changed_string_entries_) { @@ -775,7 +784,7 @@ void DecodeAsModel::applyChanges() if (!g_strcmp0(decode_as_entry->table_name, item->tableName())) { ftenum_t selector_type = get_dissector_table_selector_type(item->tableName()); - gconstpointer selector_value; + const void * selector_value; QByteArray byteArray; switch (selector_type) { @@ -791,7 +800,7 @@ void DecodeAsModel::applyChanges() case FT_STRINGZPAD: case FT_STRINGZTRUNC: byteArray = item->selectorString().toUtf8(); - selector_value = (gconstpointer) byteArray.constData(); + selector_value = (const void *) byteArray.constData(); break; case FT_NONE: //selector value is ignored, but dissector table needs to happen @@ -799,7 +808,7 @@ void DecodeAsModel::applyChanges() break; case FT_GUID: if (item->selectorDCERPC() != NULL) { - selector_value = (gconstpointer)item->selectorDCERPC(); + selector_value = (const void *)item->selectorDCERPC(); } else { //TODO: Support normal GUID dissector tables selector_value = NULL; @@ -820,7 +829,7 @@ void DecodeAsModel::applyChanges() pref_value = prefs_find_preference(module, decode_as_entry->table_name); if (pref_value != NULL) { module->prefs_changed_flags |= prefs_get_effect_flags(pref_value); - prefs_remove_decode_as_value(pref_value, item->selectorUint(), TRUE); + prefs_remove_decode_as_value(pref_value, item->selectorUint(), true); } } } @@ -833,10 +842,10 @@ void DecodeAsModel::applyChanges() if (item->dissectorHandle() != NULL) { if (FT_IS_UINT(dissector_table_get_type(sub_dissectors))) { module = prefs_find_module(proto_get_protocol_filter_name(dissector_handle_get_protocol_index(item->dissectorHandle()))); - pref_value = prefs_find_preference(module, decode_as_entry->table_name); + pref_value = prefs_find_preference(module, QByteArray(decode_as_entry->table_name).append(dissector_handle_get_pref_suffix(item->dissectorHandle()))); if (pref_value != NULL) { module->prefs_changed_flags |= prefs_get_effect_flags(pref_value); - prefs_add_decode_as_value(pref_value, item->selectorUint(), FALSE); + prefs_add_decode_as_value(pref_value, item->selectorUint(), false); } } } diff --git a/ui/qt/models/decode_as_model.h b/ui/qt/models/decode_as_model.h index cf280965..273827a8 100644 --- a/ui/qt/models/decode_as_model.h +++ b/ui/qt/models/decode_as_model.h @@ -13,7 +13,6 @@ #define DECODE_AS_MODEL_H #include <config.h> -#include <glib.h> #include <QAbstractItemModel> #include <QList> @@ -27,12 +26,12 @@ class DecodeAsItem { public: - DecodeAsItem(const char *table_name = NULL, gconstpointer selector = NULL); - DecodeAsItem(const decode_as_t *entry, gconstpointer selector = NULL); + DecodeAsItem(const char *table_name = NULL, const void *selector = NULL); + DecodeAsItem(const decode_as_t *entry, const void *selector = NULL); virtual ~DecodeAsItem(); - const gchar* tableName() const { return tableName_; } - const gchar* tableUIName() const { return tableUIName_; } + const char* tableName() const { return tableName_; } + const char* tableUIName() const { return tableUIName_; } uint selectorUint() const { return selectorUint_; } QString selectorString() const { return selectorString_; } decode_dcerpc_bind_values_t* selectorDCERPC() const { return selectorDCERPC_; } @@ -46,10 +45,10 @@ public: void updateHandles(); private: - void init(const char *table_name, gconstpointer selector = NULL); + void init(const char *table_name, const void *selector = NULL); - const gchar* tableName_; - const gchar* tableUIName_; + const char* tableName_; + const char* tableUIName_; //save our sanity and not have to worry about memory management //between (lack of) persistent data in GUI and underlying data @@ -70,6 +69,15 @@ public: DecodeAsModel(QObject *parent, capture_file *cf = NULL); virtual ~DecodeAsModel(); + struct UIntEntry { + QByteArray table; + uint32_t key; + QByteArray pref_name; + + UIntEntry(const char* t, uint32_t k, const char* pref_suffix) : + table(t), key(k), pref_name(t) { pref_name.append(pref_suffix); } + }; + enum DecodeAsColumn { colTable = 0, // aka "Field" (or dissector table like "TCP Port") colSelector, // the actual table value (e.g., port number 80) @@ -95,25 +103,25 @@ public: bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); void clearAll(); bool copyRow(int dst_row, int src_row); - bool copyFromProfile(QString filename, const gchar **err); + bool copyFromProfile(QString filename, const char **err); - static QString entryString(const gchar *table_name, gconstpointer value); + static QString entryString(const char *table_name, const void *value); void applyChanges(); protected: - static void buildChangedList(const gchar *table_name, ftenum_t selector_type, - gpointer key, gpointer value, gpointer user_data); - static void buildDceRpcChangedList(gpointer data, gpointer user_data); - static void gatherChangedEntries(const gchar *table_name, ftenum_t selector_type, - gpointer key, gpointer value, gpointer user_data); - static prefs_set_pref_e readDecodeAsEntry(gchar *key, const gchar *value, - void *user_data, gboolean return_range_errors); + static void buildChangedList(const char *table_name, ftenum_t selector_type, + void *key, void *value, void *user_data); + static void buildDceRpcChangedList(void *data, void *user_data); + static void gatherChangedEntries(const char *table_name, ftenum_t selector_type, + void *key, void *value, void *user_data); + static prefs_set_pref_e readDecodeAsEntry(char *key, const char *value, + void *user_data, bool); private: capture_file *cap_file_; QList<DecodeAsItem *> decode_as_items_; - QList<QPair<const char *, guint32> > changed_uint_entries_; + QList<UIntEntry> changed_uint_entries_; QList<QPair<const char *, const char *> > changed_string_entries_; }; diff --git a/ui/qt/models/dissector_tables_model.cpp b/ui/qt/models/dissector_tables_model.cpp index 73c757ec..dcf3dc72 100644 --- a/ui/qt/models/dissector_tables_model.cpp +++ b/ui/qt/models/dissector_tables_model.cpp @@ -179,7 +179,7 @@ QVariant DissectorTablesModel::data(const QModelIndex &index, int role) const return QVariant(); } -static void gatherProtocolDecodes(const char *, ftenum_t selector_type, gpointer key, gpointer value, gpointer item_ptr) +static void gatherProtocolDecodes(const char *, ftenum_t selector_type, void *key, void *value, void *item_ptr) { DissectorTablesItem* pdl_ptr = (DissectorTablesItem*)item_ptr; if (pdl_ptr == NULL) @@ -225,7 +225,7 @@ struct tables_root DissectorTablesItem* string_table; }; -static void gatherTableNames(const char *short_name, const char *table_name, gpointer model_ptr) +static void gatherTableNames(const char *short_name, const char *table_name, void *model_ptr) { struct tables_root* tables = (struct tables_root*)model_ptr; if (model_ptr == NULL) @@ -262,7 +262,7 @@ static void gatherTableNames(const char *short_name, const char *table_name, gpo dissector_table_foreach(short_name, gatherProtocolDecodes, dt_ti); } -static void gatherHeurProtocolDecodes(const char *, struct heur_dtbl_entry *dtbl_entry, gpointer list_ptr) +static void gatherHeurProtocolDecodes(const char *, struct heur_dtbl_entry *dtbl_entry, void *list_ptr) { DissectorTablesItem* hdl_ptr = (DissectorTablesItem*)list_ptr; if (hdl_ptr == NULL) @@ -279,13 +279,18 @@ static void gatherHeurProtocolDecodes(const char *, struct heur_dtbl_entry *dtbl } } -static void gatherHeurTableNames(const char *table_name, heur_dissector_list *list, gpointer heur_tables) +static void gatherHeurTableNames(const char *table_name, heur_dissector_list *list, void *heur_tables) { DissectorTablesItem* table = (DissectorTablesItem*)heur_tables; if (table == NULL) return; - DissectorTablesItem *heur = new DissectorTablesItem(table_name, QString(""), table); + QString desc_name = table_name; + if (list) { + const char *desc = heur_dissector_list_get_description(list); + if (desc) desc_name = desc; + } + DissectorTablesItem *heur = new DissectorTablesItem(desc_name, table_name, table); table->prependChild(heur); if (list) { diff --git a/ui/qt/models/enabled_protocols_model.cpp b/ui/qt/models/enabled_protocols_model.cpp index ecbc47a9..d923d765 100644 --- a/ui/qt/models/enabled_protocols_model.cpp +++ b/ui/qt/models/enabled_protocols_model.cpp @@ -31,7 +31,7 @@ public: virtual ~ProtocolTreeItem() {} protected: - virtual void applyValuePrivate(gboolean value) + virtual void applyValuePrivate(bool value) { if (! proto_can_toggle_protocol(proto_get_id(proto_))) { return; @@ -56,7 +56,7 @@ public: virtual ~HeuristicTreeItem() {} protected: - virtual void applyValuePrivate(gboolean value) + virtual void applyValuePrivate(bool value) { heuristic_table_->enabled = value; } @@ -239,7 +239,6 @@ QVariant EnabledProtocolsModel::data(const QModelIndex &index, int role) const break; case DATA_PROTOCOL_TYPE: return QVariant::fromValue(item->type()); - break; default: break; } @@ -270,7 +269,7 @@ bool EnabledProtocolsModel::setData(const QModelIndex &index, const QVariant &va return true; } -static void addHeuristicItem(gpointer data, gpointer user_data) +static void addHeuristicItem(void *data, void *user_data) { heur_dtbl_entry_t* heur = (heur_dtbl_entry_t*)data; ProtocolTreeItem* protocol_item = (ProtocolTreeItem*)user_data; diff --git a/ui/qt/models/enabled_protocols_model.h b/ui/qt/models/enabled_protocols_model.h index 23b2c1bb..fe6caeab 100644 --- a/ui/qt/models/enabled_protocols_model.h +++ b/ui/qt/models/enabled_protocols_model.h @@ -43,7 +43,7 @@ public: bool applyValue(); protected: - virtual void applyValuePrivate(gboolean value) = 0; + virtual void applyValuePrivate(bool value) = 0; QString name_; QString description_; diff --git a/ui/qt/models/expert_info_model.cpp b/ui/qt/models/expert_info_model.cpp index 017dba3d..24204612 100644 --- a/ui/qt/models/expert_info_model.cpp +++ b/ui/qt/models/expert_info_model.cpp @@ -118,7 +118,7 @@ ExpertPacketItem* ExpertInfoModel::createRootItem() { static const char* rootName = "ROOT"; DIAG_OFF_CAST_AWAY_CONST - static expert_info_t root_expert = { 0, -1, -1, -1, rootName, (gchar*)rootName, NULL }; + static expert_info_t root_expert = { 0, -1, -1, -1, rootName, (char*)rootName, NULL }; DIAG_ON_CAST_AWAY_CONST return new ExpertPacketItem(root_expert, NULL, NULL); @@ -355,8 +355,8 @@ int ExpertInfoModel::columnCount(const QModelIndex&) const void ExpertInfoModel::addExpertInfo(const struct expert_info_s& expert_info) { - QString groupKey = ExpertPacketItem::groupKey(FALSE, expert_info.severity, expert_info.group, QString(expert_info.protocol), expert_info.hf_index); - QString summaryKey = ExpertPacketItem::groupKey(TRUE, expert_info.severity, expert_info.group, QString(expert_info.protocol), expert_info.hf_index); + QString groupKey = ExpertPacketItem::groupKey(false, expert_info.severity, expert_info.group, QString(expert_info.protocol), expert_info.hf_index); + QString summaryKey = ExpertPacketItem::groupKey(true, expert_info.severity, expert_info.group, QString(expert_info.protocol), expert_info.hf_index); ExpertPacketItem* expert_root = root_->child(groupKey); if (expert_root == NULL) { diff --git a/ui/qt/models/export_objects_model.cpp b/ui/qt/models/export_objects_model.cpp index 3cf9ec63..3546db5c 100644 --- a/ui/qt/models/export_objects_model.cpp +++ b/ui/qt/models/export_objects_model.cpp @@ -176,7 +176,7 @@ void ExportObjectModel::saveAllEntries(QString path) if (entry == NULL) continue; - guint count = 0; + unsigned count = 0; QString filename; do { diff --git a/ui/qt/models/fileset_entry_model.cpp b/ui/qt/models/fileset_entry_model.cpp index 8c9f504b..86979e38 100644 --- a/ui/qt/models/fileset_entry_model.cpp +++ b/ui/qt/models/fileset_entry_model.cpp @@ -121,14 +121,13 @@ void FilesetEntryModel::clear() } QString FilesetEntryModel::nameToDate(const char *name) const { + char *date; QString dn; - if (!fileset_filename_match_pattern(name)) + if (fileset_filename_match_pattern(name, NULL, NULL, &date) == FILESET_NO_MATCH) return NULL; - dn = name; - dn.remove(QRegularExpression(".*_")); - dn.truncate(14); + dn = gchar_free_to_qstring(date); dn.insert(4, '-'); dn.insert(7, '-'); dn.insert(10, ' '); diff --git a/ui/qt/models/fileset_entry_model.h b/ui/qt/models/fileset_entry_model.h index aa812b0c..40e6796f 100644 --- a/ui/qt/models/fileset_entry_model.h +++ b/ui/qt/models/fileset_entry_model.h @@ -12,8 +12,6 @@ #include <config.h> -#include <glib.h> - #include <fileset.h> #include <QAbstractItemModel> diff --git a/ui/qt/models/filter_list_model.cpp b/ui/qt/models/filter_list_model.cpp index 3ed25839..c257d6af 100644 --- a/ui/qt/models/filter_list_model.cpp +++ b/ui/qt/models/filter_list_model.cpp @@ -8,8 +8,6 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ -#include <glib.h> - #include <wsutil/filesystem.h> #include <ui/qt/utils/qt_ui_utils.h> @@ -24,11 +22,6 @@ #include <QMimeData> /* - * Old filter file name. - */ -#define FILTER_FILE_NAME "filters" - -/* * Capture filter file name. */ #define CFILTER_FILE_NAME "cfilters" @@ -38,6 +31,11 @@ */ #define DFILTER_FILE_NAME "dfilters" +/* + * Display filter macros file name. + */ +#define DMACROS_FILE_NAME "dmacros" + FilterListModel::FilterListModel(QObject * parent) : QAbstractListModel(parent), type_(FilterListModel::Display) @@ -56,12 +54,17 @@ void FilterListModel::reload() { storage.clear(); - const char * cfile = (type_ == FilterListModel::Capture) ? CFILTER_FILE_NAME : DFILTER_FILE_NAME; + const char *cfile; + + switch (type_) { + case FilterListModel::Capture: cfile = CFILTER_FILE_NAME; break; + case FilterListModel::Display: cfile = DFILTER_FILE_NAME; break; + case FilterListModel::DisplayMacro: cfile = DMACROS_FILE_NAME; break; + default: ws_assert_not_reached(); + } /* Try personal config file first */ - QString fileName = gchar_free_to_qstring(get_persconffile_path(cfile, TRUE)); - if (fileName.length() <= 0 || ! QFileInfo::exists(fileName)) - fileName = gchar_free_to_qstring(get_persconffile_path(FILTER_FILE_NAME, TRUE)); + QString fileName = gchar_free_to_qstring(get_persconffile_path(cfile, true)); if (fileName.length() <= 0 || ! QFileInfo::exists(fileName)) fileName = gchar_free_to_qstring(get_datafile_path(cfile)); if (fileName.length() <= 0 || ! QFileInfo::exists(fileName)) @@ -80,7 +83,7 @@ void FilterListModel::reload() /* Filter out lines that do not contain content: * - Starting with # is a comment * - Does not start with a quoted string - */ + */ if (data.startsWith("#") || ! data.trimmed().startsWith("\"")) continue; @@ -125,10 +128,16 @@ QVariant FilterListModel::headerData(int section, Qt::Orientation orientation, i { switch (section) { case ColumnName: - return tr("Filter Name"); + if (type_ == DisplayMacro) + return tr("Macro Name"); + else + return tr("Filter Name"); break; case ColumnExpression: - return tr("Filter Expression"); + if (type_ == DisplayMacro) + return tr("Macro Expression"); + else + return tr("Filter Expression"); break; } } @@ -230,9 +239,17 @@ void FilterListModel::removeFilter(QModelIndex idx) void FilterListModel::saveList() { - QString filename = (type_ == FilterListModel::Capture) ? CFILTER_FILE_NAME : DFILTER_FILE_NAME; + const char *cfile; + QString filename; + + switch (type_) { + case Capture: cfile = CFILTER_FILE_NAME; break; + case Display: cfile = DFILTER_FILE_NAME; break; + case DisplayMacro: cfile = DMACROS_FILE_NAME; break; + default: ws_assert_not_reached(); + } - filename = QString("%1%2%3").arg(ProfileModel::activeProfilePath()).arg("/").arg(filename); + filename = QString("%1%2%3").arg(ProfileModel::activeProfilePath()).arg("/").arg(cfile); QFile file(filename); if (! file.open(QIODevice::WriteOnly | QIODevice::Text)) diff --git a/ui/qt/models/filter_list_model.h b/ui/qt/models/filter_list_model.h index 4f528d2f..4611eeb9 100644 --- a/ui/qt/models/filter_list_model.h +++ b/ui/qt/models/filter_list_model.h @@ -25,7 +25,8 @@ class FilterListModel : public QAbstractListModel public: enum FilterListType { Display, - Capture + Capture, + DisplayMacro, }; explicit FilterListModel(FilterListType type = FilterListModel::Display, QObject * parent = Q_NULLPTR); diff --git a/ui/qt/models/info_proxy_model.cpp b/ui/qt/models/info_proxy_model.cpp index 7b256b9d..e07027c8 100644 --- a/ui/qt/models/info_proxy_model.cpp +++ b/ui/qt/models/info_proxy_model.cpp @@ -57,7 +57,6 @@ QVariant InfoProxyModel::data (const QModelIndex &index, int role) const { case Qt::DisplayRole: return infos_.at(ifIdx); - break; case Qt::FontRole: QFont font = QIdentityProxyModel::data(index, Qt::FontRole).value<QFont>(); font.setItalic(true); diff --git a/ui/qt/models/interface_sort_filter_model.cpp b/ui/qt/models/interface_sort_filter_model.cpp index 9d9c5dc8..f5d62074 100644 --- a/ui/qt/models/interface_sort_filter_model.cpp +++ b/ui/qt/models/interface_sort_filter_model.cpp @@ -12,8 +12,6 @@ #include <ui/qt/models/interface_tree_cache_model.h> #include <ui/qt/models/interface_sort_filter_model.h> -#include <glib.h> - #include <epan/prefs.h> #include <ui/preference_utils.h> #include <ui/qt/utils/qt_ui_utils.h> @@ -143,10 +141,7 @@ void InterfaceSortFilterModel::resetPreferenceData() } } -#if 0 - // Disabled until bug 13354 is fixed _filterHidden = ! prefs.gui_interfaces_show_hidden; -#endif #ifdef HAVE_PCAP_REMOTE _remoteDisplay = prefs.gui_interfaces_remote_display; #endif @@ -278,15 +273,18 @@ bool InterfaceSortFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex int type = -1; bool hidden = false; - if (dynamic_cast<InterfaceTreeCacheModel*>(sourceModel()) != 0) + InterfaceTreeCacheModel* cacheModel = qobject_cast<InterfaceTreeCacheModel*>(sourceModel()); + InterfaceTreeModel* treeModel = nullptr; + + if (cacheModel != nullptr) { - type = ((InterfaceTreeCacheModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_TYPE).toInt(); - hidden = ((InterfaceTreeCacheModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_HIDDEN, Qt::UserRole).toBool(); + type = cacheModel->getColumnContent(idx, IFTREE_COL_TYPE).toInt(); + hidden = cacheModel->getColumnContent(idx, IFTREE_COL_HIDDEN, Qt::UserRole).toBool(); } - else if (dynamic_cast<InterfaceTreeModel*>(sourceModel()) != 0) + else if ((treeModel = qobject_cast<InterfaceTreeModel*>(sourceModel())) != nullptr) { - type = ((InterfaceTreeModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_TYPE).toInt(); - hidden = ((InterfaceTreeModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_HIDDEN, Qt::UserRole).toBool(); + type = treeModel->getColumnContent(idx, IFTREE_COL_TYPE).toInt(); + hidden = treeModel->getColumnContent(idx, IFTREE_COL_HIDDEN, Qt::UserRole).toBool(); } else return false; @@ -294,24 +292,31 @@ bool InterfaceSortFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex if (hidden && _filterHidden) return false; +#ifdef HAVE_PCAP_REMOTE + bool isRemote = false; + if (cacheModel && cacheModel->isRemote(realIndex)) { + isRemote = true; + } else if (treeModel && treeModel->isRemote(idx)) { + isRemote = true; + } +#endif + if (_filterTypes && ! isInterfaceTypeShown(type)) { #ifdef HAVE_PCAP_REMOTE - /* Remote interfaces have the if type IF_WIRED, therefore would be filtered, if not explicitly checked here */ - if (type != IF_WIRED || ! ((InterfaceTreeModel *)sourceModel())->isRemote(idx)) + /* Remote interfaces have the if type IF_WIRED, therefore would be filtered if not explicitly checked here */ + if (type != IF_WIRED || !isRemote) #endif return false; } #ifdef HAVE_PCAP_REMOTE - if (((InterfaceTreeModel *)sourceModel())->isRemote(idx)) - { - if (! _remoteDisplay) + if (isRemote && !_remoteDisplay) { return false; } #endif -#endif +#endif /* HAVE_LIBPCAP */ return true; } diff --git a/ui/qt/models/interface_sort_filter_model.h b/ui/qt/models/interface_sort_filter_model.h index 5bf69d9d..e3609a81 100644 --- a/ui/qt/models/interface_sort_filter_model.h +++ b/ui/qt/models/interface_sort_filter_model.h @@ -16,8 +16,6 @@ #include <ui/qt/models/interface_tree_model.h> -#include <glib.h> - #include <QSortFilterProxyModel> class InterfaceSortFilterModel : public QSortFilterProxyModel diff --git a/ui/qt/models/interface_tree_cache_model.cpp b/ui/qt/models/interface_tree_cache_model.cpp index cad22b32..6c21d004 100644 --- a/ui/qt/models/interface_tree_cache_model.cpp +++ b/ui/qt/models/interface_tree_cache_model.cpp @@ -32,7 +32,7 @@ InterfaceTreeCacheModel::InterfaceTreeCacheModel(QObject *parent) : sourceModel = new InterfaceTreeModel(parent); QIdentityProxyModel::setSourceModel(sourceModel); - storage = new QMap<int, QMap<InterfaceTreeColumns, QVariant> *>(); + storage = new QMap<int, QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > >(); checkableColumns << IFTREE_COL_HIDDEN << IFTREE_COL_PROMISCUOUSMODE; #ifdef HAVE_PCAP_CREATE @@ -67,8 +67,7 @@ void InterfaceTreeCacheModel::reset(int row) { if (row < 0) { - delete storage; - storage = new QMap<int, QMap<InterfaceTreeColumns, QVariant> *>(); + storage->clear(); } else { @@ -90,7 +89,7 @@ void InterfaceTreeCacheModel::saveNewDevices() interface_t *device = const_cast<interface_t *>(&(*it)); bool useDevice = false; - QMap<InterfaceTreeColumns, QVariant> * dataField = storage->value(idx, 0); + QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > dataField = storage->value(idx, 0); /* When devices are being added, they are added using generic values. So only devices * whose data have been changed should be used from here on out. */ if (dataField != 0) @@ -124,7 +123,6 @@ void InterfaceTreeCacheModel::saveNewDevices() /* All entries of this new devices have been considered */ storage->remove(idx); - delete dataField; } newDevices.clear(); @@ -159,7 +157,7 @@ void InterfaceTreeCacheModel::save() continue; /* Try to load a saved value row for this index */ - QMap<InterfaceTreeColumns, QVariant> * dataField = storage->value(idx, 0); + QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > dataField = storage->value(idx, 0); /* Handle the storing of values for this device here */ if (dataField) @@ -177,7 +175,8 @@ void InterfaceTreeCacheModel::save() if (col == IFTREE_COL_HIDDEN) { - device->hidden = saveValue.toBool(); + /* Hidden is de-selection, therefore inverted logic here */ + device->hidden = (saveValue == Qt::Unchecked); } else if (device->if_info.type == IF_EXTCAP) { @@ -420,12 +419,12 @@ bool InterfaceTreeCacheModel::setData(const QModelIndex &index, const QVariant & { QVariant saveValue = value; - QMap<InterfaceTreeColumns, QVariant> * dataField = 0; + QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > dataField = nullptr; /* obtain the list of already stored changes for this row. If none exist * create a new storage row for this entry */ - if ((dataField = storage->value(row, 0)) == 0) + if ((dataField = storage->value(row, 0)) == nullptr) { - dataField = new QMap<InterfaceTreeColumns, QVariant>(); + dataField = QSharedPointer<QMap<InterfaceTreeColumns, QVariant> >(new QMap<InterfaceTreeColumns, QVariant>); storage->insert(row, dataField); } @@ -452,8 +451,8 @@ QVariant InterfaceTreeCacheModel::data(const QModelIndex &index, int role) const if (((role == Qt::DisplayRole || role == Qt::EditRole) && editableColumns.contains(col)) || (role == Qt::CheckStateRole && checkableColumns.contains(col)) ) { - QMap<InterfaceTreeColumns, QVariant> * dataField = 0; - if ((dataField = storage->value(row, 0)) != 0) + QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > dataField = nullptr; + if ((dataField = storage->value(row, 0)) != nullptr) { if (dataField->contains(col)) { @@ -492,8 +491,8 @@ QVariant InterfaceTreeCacheModel::data(const QModelIndex &index, int role) const col == IFTREE_COL_DESCRIPTION) { - QMap<InterfaceTreeColumns, QVariant> * dataField = 0; - if ((dataField = storage->value(row, 0)) != 0 && + QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > dataField = nullptr; + if ((dataField = storage->value(row, 0)) != nullptr && dataField->contains(IFTREE_COL_PIPE_PATH)) { return dataField->value(IFTREE_COL_PIPE_PATH, QVariant()); @@ -525,6 +524,17 @@ QVariant InterfaceTreeCacheModel::data(const QModelIndex &index, int role) const return QVariant(); } +#ifdef HAVE_PCAP_REMOTE +bool InterfaceTreeCacheModel::isRemote(const QModelIndex &index) const +{ + const interface_t *device = lookup(index); + if (device != nullptr && device->remote_opts.src_type == CAPTURE_IFREMOTE) { + return true; + } + return false; +} +#endif + #ifdef HAVE_LIBPCAP QModelIndex InterfaceTreeCacheModel::index(int row, int column, const QModelIndex &parent) const { diff --git a/ui/qt/models/interface_tree_cache_model.h b/ui/qt/models/interface_tree_cache_model.h index 9b51c10b..1c33081d 100644 --- a/ui/qt/models/interface_tree_cache_model.h +++ b/ui/qt/models/interface_tree_cache_model.h @@ -20,6 +20,8 @@ class InterfaceTreeCacheModel : public QIdentityProxyModel { + Q_OBJECT + public: explicit InterfaceTreeCacheModel(QObject *parent); ~InterfaceTreeCacheModel(); @@ -42,6 +44,10 @@ public: void deleteDevice(const QModelIndex &index); #endif +#ifdef HAVE_PCAP_REMOTE + bool isRemote(const QModelIndex &index) const; +#endif + private: InterfaceTreeModel * sourceModel; @@ -50,7 +56,7 @@ private: void saveNewDevices(); #endif - QMap<int, QMap<InterfaceTreeColumns, QVariant> *> * storage; + QMap<int, QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > > * storage; QList<InterfaceTreeColumns> editableColumns; QList<InterfaceTreeColumns> checkableColumns; diff --git a/ui/qt/models/interface_tree_model.cpp b/ui/qt/models/interface_tree_model.cpp index 547b9010..696937a2 100644 --- a/ui/qt/models/interface_tree_model.cpp +++ b/ui/qt/models/interface_tree_model.cpp @@ -136,7 +136,7 @@ QVariant InterfaceTreeModel::data(const QModelIndex &index, int role) const } else if (col == IFTREE_COL_DESCRIPTION) { - return QString(device->friendly_name); + return QString(device->if_info.friendly_name); } else if (col == IFTREE_COL_DISPLAY_NAME) { @@ -370,7 +370,7 @@ void InterfaceTreeModel::interfaceListChanged() QVariant InterfaceTreeModel::toolTipForInterface(int idx) const { #ifdef HAVE_LIBPCAP - if (! global_capture_opts.all_ifaces || global_capture_opts.all_ifaces->len <= (guint) idx) + if (! global_capture_opts.all_ifaces || global_capture_opts.all_ifaces->len <= (unsigned) idx) return QVariant(); interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, idx); @@ -415,6 +415,12 @@ QVariant InterfaceTreeModel::toolTipForInterface(int idx) const } #ifdef HAVE_LIBPCAP +void InterfaceTreeModel::setCache(if_stat_cache_t *stat_cache) +{ + stopStatistic(); + stat_cache_ = stat_cache; +} + void InterfaceTreeModel::stopStatistic() { if (stat_cache_) @@ -428,7 +434,7 @@ void InterfaceTreeModel::stopStatistic() void InterfaceTreeModel::updateStatistic(unsigned int idx) { #ifdef HAVE_LIBPCAP - if (! global_capture_opts.all_ifaces || global_capture_opts.all_ifaces->len <= (guint) idx) + if (! global_capture_opts.all_ifaces || global_capture_opts.all_ifaces->len <= (unsigned) idx) return; interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, idx); @@ -439,7 +445,11 @@ void InterfaceTreeModel::updateStatistic(unsigned int idx) if (!stat_cache_) { // Start gathering statistics using dumpcap - // We crash (on macOS at least) if we try to do this from ::showEvent. + // + // The stat cache will only properly configure if it has the list + // of interfaces in global_capture_opts->all_ifaces. + // We crash if we try to do this from InterfaceFrame::showEvent, + // because main.cpp calls mainw->show() before capture_opts_init(). stat_cache_ = capture_stat_start(&global_capture_opts); } @@ -530,12 +540,12 @@ bool InterfaceTreeModel::updateSelectedDevices(QItemSelection sourceSelection) { if (! device->selected) selectionHasChanged = true; - device->selected = TRUE; + device->selected = true; global_capture_opts.num_selected++; } else { if (device->selected) selectionHasChanged = true; - device->selected = FALSE; + device->selected = false; } } #else diff --git a/ui/qt/models/interface_tree_model.h b/ui/qt/models/interface_tree_model.h index cdf2ac89..747dc2e0 100644 --- a/ui/qt/models/interface_tree_model.h +++ b/ui/qt/models/interface_tree_model.h @@ -27,19 +27,28 @@ typedef QList<int> PointList; +/* + * When sorting, QSortFilterProxyModel creates its own mapping instead + * of using the QModelIndex mapping with mapToSource to determine which + * column in the proxy model maps to which column in the source. Its own + * mapping is always done in order; this means that it's easier if all + * the Views of this model keep the columns in the same relative order, + * but can omit columns. (If you really need to change the order, + * QHeaderView::swapSections() can be used.) + */ enum InterfaceTreeColumns { - IFTREE_COL_EXTCAP, + IFTREE_COL_EXTCAP, // InterfaceFrame interfaceTree IFTREE_COL_EXTCAP_PATH, - IFTREE_COL_NAME, - IFTREE_COL_DESCRIPTION, - IFTREE_COL_DISPLAY_NAME, - IFTREE_COL_COMMENT, - IFTREE_COL_HIDDEN, + IFTREE_COL_HIDDEN, // ManageInterfaceDialog localView + IFTREE_COL_DISPLAY_NAME, // InterfaceFrame interfaceTree + IFTREE_COL_DESCRIPTION, // ManageInterfaceDialog localView + IFTREE_COL_NAME, // ManageInterfaceDialog localView + IFTREE_COL_COMMENT, // ManageInterfaceDialog localView + IFTREE_COL_STATS, // InterfaceFrame interfaceTree IFTREE_COL_DLT, IFTREE_COL_PROMISCUOUSMODE, IFTREE_COL_TYPE, - IFTREE_COL_STATS, IFTREE_COL_ACTIVE, IFTREE_COL_SNAPLEN, #ifdef CAN_SET_CAPTURE_BUFFER_SIZE @@ -49,7 +58,7 @@ enum InterfaceTreeColumns IFTREE_COL_MONITOR_MODE, #endif IFTREE_COL_CAPTURE_FILTER, - IFTREE_COL_PIPE_PATH, + IFTREE_COL_PIPE_PATH, // ManageInterfaceDialog pipeView IFTREE_COL_MAX /* is not being displayed, it is the definition for the maximum numbers of columns */ }; @@ -68,6 +77,7 @@ public: void updateStatistic(unsigned int row); #ifdef HAVE_LIBPCAP + void setCache(if_stat_cache_t *stat_cache); void stopStatistic(); #endif diff --git a/ui/qt/models/packet_list_model.cpp b/ui/qt/models/packet_list_model.cpp index 8cc00691..9bb81fb5 100644 --- a/ui/qt/models/packet_list_model.cpp +++ b/ui/qt/models/packet_list_model.cpp @@ -8,7 +8,6 @@ */ #include <algorithm> -#include <glib.h> #include <cmath> #include <stdexcept> @@ -55,7 +54,7 @@ class SortAbort : public std::runtime_error static PacketListModel * glbl_plist_model = Q_NULLPTR; static const int reserved_packets_ = 100000; -guint +unsigned packet_list_append(column_info *, frame_data *fdata) { if (!glbl_plist_model) @@ -143,7 +142,7 @@ int PacketListModel::packetNumberToRow(int packet_num) const return number_to_row_.value(packet_num) - 1; } -guint PacketListModel::recreateVisibleRows() +unsigned PacketListModel::recreateVisibleRows() { beginResetModel(); visible_rows_.resize(0); @@ -155,7 +154,7 @@ guint PacketListModel::recreateVisibleRows() if (fdata->passed_dfilter || fdata->ref_time) { visible_rows_ << record; - if (static_cast<guint32>(number_to_row_.size()) <= fdata->num) { + if (static_cast<uint32_t>(number_to_row_.size()) <= fdata->num) { number_to_row_.resize(fdata->num + 10000); } number_to_row_[fdata->num] = static_cast<int>(visible_rows_.count()); @@ -166,7 +165,7 @@ guint PacketListModel::recreateVisibleRows() endInsertRows(); } idle_dissection_row_ = 0; - return static_cast<guint>(visible_rows_.count()); + return static_cast<unsigned>(visible_rows_.count()); } void PacketListModel::clear() { @@ -285,7 +284,7 @@ void PacketListModel::toggleFrameMark(const QModelIndexList &indeces) } } -void PacketListModel::setDisplayedFrameMark(gboolean set) +void PacketListModel::setDisplayedFrameMark(bool set) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) emit layoutAboutToBeChanged(); @@ -334,7 +333,7 @@ void PacketListModel::toggleFrameIgnore(const QModelIndexList &indeces) } } -void PacketListModel::setDisplayedFrameIgnore(gboolean set) +void PacketListModel::setDisplayedFrameIgnore(bool set) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) emit layoutAboutToBeChanged(); @@ -447,7 +446,7 @@ void PacketListModel::addFrameComment(const QModelIndexList &indices, const QByt } } -void PacketListModel::setFrameComment(const QModelIndex &index, const QByteArray &comment, guint c_number) +void PacketListModel::setFrameComment(const QModelIndex &index, const QByteArray &comment, unsigned c_number) { int sectionMax = columnCount() - 1; frame_data *fdata; @@ -492,10 +491,10 @@ void PacketListModel::deleteFrameComments(const QModelIndexList &indices) fdata = record->frameData(); wtap_block_t pkt_block = cf_get_packet_block(cap_file_, fdata); - guint n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT); + unsigned n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT); if (n_comments) { - for (guint i = 0; i < n_comments; i++) { + for (unsigned i = 0; i < n_comments; i++) { wtap_block_remove_nth_option_instance(pkt_block, OPT_COMMENT, 0); } if (!cf_set_modified_block(cap_file_, fdata, pkt_block)) { @@ -522,10 +521,10 @@ void PacketListModel::deleteAllFrameComments() foreach (PacketListRecord *record, physical_rows_) { frame_data *fdata = record->frameData(); wtap_block_t pkt_block = cf_get_packet_block(cap_file_, fdata); - guint n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT); + unsigned n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT); if (n_comments) { - for (guint i = 0; i < n_comments; i++) { + for (unsigned i = 0; i < n_comments; i++) { wtap_block_remove_nth_option_instance(pkt_block, OPT_COMMENT, 0); } cf_set_modified_block(cap_file_, fdata, pkt_block); @@ -557,7 +556,7 @@ int PacketListModel::sort_column_is_numeric_; int PacketListModel::text_sort_column_; Qt::SortOrder PacketListModel::sort_order_; capture_file *PacketListModel::sort_cap_file_; -gboolean PacketListModel::stop_flag_; +bool PacketListModel::stop_flag_; ProgressFrame *PacketListModel::progress_frame_; double PacketListModel::comps_; double PacketListModel::exp_comps_; @@ -579,7 +578,7 @@ void PacketListModel::sort(int column, Qt::SortOrder order) QString col_title = get_column_title(column); - if (text_sort_column_ >= 0 && (guint)visible_rows_.count() > prefs.gui_packet_list_cached_rows_max) { + if (text_sort_column_ >= 0 && (unsigned)visible_rows_.count() > prefs.gui_packet_list_cached_rows_max) { /* Column not based on frame data but by column text that requires * dissection, so to sort in a reasonable amount of time the column * text needs to be cached. @@ -614,7 +613,7 @@ void PacketListModel::sort(int column, Qt::SortOrder order) */ return; } - sort_cap_file_->read_lock = TRUE; + sort_cap_file_->read_lock = true; QString busy_msg; if (!col_title.isEmpty()) { @@ -622,7 +621,7 @@ void PacketListModel::sort(int column, Qt::SortOrder order) } else { busy_msg = tr("Sorting …"); } - stop_flag_ = FALSE; + stop_flag_ = false; comps_ = 0; /* XXX: The expected number of comparisons is O(N log N), but this could * be a pretty significant overestimate of the amount of time it takes, @@ -672,7 +671,7 @@ void PacketListModel::sort(int column, Qt::SortOrder order) disconnect(progress_frame_, &ProgressFrame::stopLoading, this, &PacketListModel::stopSorting); } - sort_cap_file_->read_lock = FALSE; + sort_cap_file_->read_lock = false; if (cap_file_->current_frame) { emit goToPacket(cap_file_->current_frame->num); @@ -681,11 +680,14 @@ void PacketListModel::sort(int column, Qt::SortOrder order) void PacketListModel::stopSorting() { - stop_flag_ = TRUE; + stop_flag_ = true; } bool PacketListModel::isNumericColumn(int column) { + /* XXX - Should this and ui/packet_list_utils.c right_justify_column() + * be the same list of columns? + */ if (column < 0) { return false; } @@ -720,10 +722,19 @@ bool PacketListModel::isNumericColumn(int column) return false; } - guint num_fields = g_slist_length(sort_cap_file_->cinfo.columns[column].col_custom_fields_ids); - for (guint i = 0; i < num_fields; i++) { - guint *field_idx = (guint *) g_slist_nth_data(sort_cap_file_->cinfo.columns[column].col_custom_fields_ids, i); - header_field_info *hfi = proto_registrar_get_nth(*field_idx); + unsigned num_fields = g_slist_length(sort_cap_file_->cinfo.columns[column].col_custom_fields_ids); + col_custom_t *col_custom; + for (unsigned i = 0; i < num_fields; i++) { + col_custom = (col_custom_t *) g_slist_nth_data(sort_cap_file_->cinfo.columns[column].col_custom_fields_ids, i); + if (col_custom->field_id == 0) { + /* XXX - We need some way to check the compiled dfilter's expected + * return type. Best would be to use the actual field values return + * and sort on those (we could skip expensive string conversions + * in the numeric case, see below) + */ + return false; + } + header_field_info *hfi = proto_registrar_get_nth(col_custom->field_id); /* * Reject a field when there is no numeric field type or when: @@ -824,7 +835,7 @@ double PacketListModel::parseNumericColumn(const QString &val, bool *ok) { QByteArray ba = val.toUtf8(); const char *strval = ba.constData(); - gchar *end = NULL; + char *end = NULL; double num = g_ascii_strtod(strval, &end); *ok = strval != end; return num; @@ -871,13 +882,10 @@ QVariant PacketListModel::data(const QModelIndex &d_index, int role) const switch(recent_get_column_xalign(d_index.column())) { case COLUMN_XALIGN_RIGHT: return Qt::AlignRight; - break; case COLUMN_XALIGN_CENTER: return Qt::AlignCenter; - break; case COLUMN_XALIGN_LEFT: return Qt::AlignLeft; - break; case COLUMN_XALIGN_DEFAULT: default: if (right_justify_column(d_index.column(), cap_file_)) { @@ -995,6 +1003,12 @@ void PacketListModel::dissectIdle(bool reset) idle_dissection_timer_->restart(); + if (!cap_file_ || cap_file_->read_lock) { + // File is in use (at worst, being rescanned). Try again later. + QTimer::singleShot(idle_dissection_interval_, this, [=]() { dissectIdle(); }); + return; + } + int first = idle_dissection_row_; while (idle_dissection_timer_->elapsed() < idle_dissection_interval_ && idle_dissection_row_ < physical_rows_.count()) { @@ -1015,7 +1029,7 @@ void PacketListModel::dissectIdle(bool reset) // XXX Pass in cinfo from packet_list_append so that we can fill in // line counts? -gint PacketListModel::appendPacket(frame_data *fdata) +int PacketListModel::appendPacket(frame_data *fdata) { PacketListRecord *record = new PacketListRecord(fdata); qsizetype pos = -1; @@ -1038,17 +1052,19 @@ gint PacketListModel::appendPacket(frame_data *fdata) pos = static_cast<int>( visible_rows_.count() + new_visible_rows_.count() ) - 1; } - return static_cast<gint>(pos); + emit packetAppended(cap_file_, fdata, physical_rows_.size() - 1); + + return static_cast<int>(pos); } -frame_data *PacketListModel::getRowFdata(QModelIndex idx) +frame_data *PacketListModel::getRowFdata(QModelIndex idx) const { if (!idx.isValid()) return Q_NULLPTR; return getRowFdata(idx.row()); } -frame_data *PacketListModel::getRowFdata(int row) { +frame_data *PacketListModel::getRowFdata(int row) const { if (row < 0 || row >= visible_rows_.count()) return NULL; PacketListRecord *record = visible_rows_[row]; @@ -1071,13 +1087,8 @@ void PacketListModel::ensureRowColorized(int row) int PacketListModel::visibleIndexOf(frame_data *fdata) const { - int row = 0; - foreach (PacketListRecord *record, visible_rows_) { - if (record->frameData() == fdata) { - return row; - } - row++; + if (fdata == nullptr) { + return -1; } - - return -1; + return packetNumberToRow(fdata->num); } diff --git a/ui/qt/models/packet_list_model.h b/ui/qt/models/packet_list_model.h index 807d8847..c4a4acf4 100644 --- a/ui/qt/models/packet_list_model.h +++ b/ui/qt/models/packet_list_model.h @@ -14,8 +14,6 @@ #include <stdio.h> -#include <glib.h> - #include <epan/packet.h> #include <QAbstractItemModel> @@ -46,7 +44,7 @@ public: const QModelIndex & = QModelIndex()) const; QModelIndex parent(const QModelIndex &) const; int packetNumberToRow(int packet_num) const; - guint recreateVisibleRows(); + unsigned recreateVisibleRows(); void clear(); int rowCount(const QModelIndex &parent = QModelIndex()) const; @@ -54,9 +52,9 @@ public: QVariant data(const QModelIndex &d_index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - gint appendPacket(frame_data *fdata); - frame_data *getRowFdata(QModelIndex idx); - frame_data *getRowFdata(int row); + int appendPacket(frame_data *fdata); + frame_data *getRowFdata(QModelIndex idx) const; + frame_data *getRowFdata(int row) const; void ensureRowColorized(int row); int visibleIndexOf(frame_data *fdata) const; /** @@ -69,19 +67,20 @@ public: void resetColumns(); void resetColorized(); void toggleFrameMark(const QModelIndexList &indeces); - void setDisplayedFrameMark(gboolean set); + void setDisplayedFrameMark(bool set); void toggleFrameIgnore(const QModelIndexList &indeces); - void setDisplayedFrameIgnore(gboolean set); + void setDisplayedFrameIgnore(bool set); void toggleFrameRefTime(const QModelIndex &rt_index); void unsetAllFrameRefTime(); void addFrameComment(const QModelIndexList &indices, const QByteArray &comment); - void setFrameComment(const QModelIndex &index, const QByteArray &comment, guint c_number); + void setFrameComment(const QModelIndex &index, const QByteArray &comment, unsigned c_number); void deleteFrameComments(const QModelIndexList &indices); void deleteAllFrameComments(); void setMaximumRowHeight(int height); signals: + void packetAppended(capture_file *cap_file, frame_data *fdata, qsizetype row); void goToPacket(int); void maxLineCountChanged(const QModelIndex &ih_index) const; void itemHeightChanged(const QModelIndex &ih_index); @@ -113,7 +112,7 @@ private: static bool recordLessThan(PacketListRecord *r1, PacketListRecord *r2); static double parseNumericColumn(const QString &val, bool *ok); - static gboolean stop_flag_; + static bool stop_flag_; static ProgressFrame *progress_frame_; static double exp_comps_; static double comps_; diff --git a/ui/qt/models/packet_list_record.cpp b/ui/qt/models/packet_list_record.cpp index 9c2c66d1..3cba64d5 100644 --- a/ui/qt/models/packet_list_record.cpp +++ b/ui/qt/models/packet_list_record.cpp @@ -24,7 +24,7 @@ #include <QStringList> -QCache<guint32, QStringList> PacketListRecord::col_text_cache_(500); +QCache<uint32_t, QStringList> PacketListRecord::col_text_cache_(500); QMap<int, int> PacketListRecord::cinfo_column_; unsigned PacketListRecord::rows_color_ver_ = 1; @@ -112,7 +112,7 @@ void PacketListRecord::dissect(capture_file *cap_file, bool dissect_columns, boo // packet_list_store.c:packet_list_dissect_and_cache_record epan_dissect_t edt; column_info *cinfo = NULL; - gboolean create_proto_tree; + bool create_proto_tree; wtap_rec rec; /* Record metadata */ Buffer buf; /* Record data */ @@ -144,7 +144,7 @@ void PacketListRecord::dissect(capture_file *cap_file, bool dissect_columns, boo * error message. */ if (dissect_columns) { - col_fill_in_error(cinfo, fdata_, FALSE, FALSE /* fill_fd_columns */); + col_fill_in_error(cinfo, fdata_, false, false /* fill_fd_columns */); cacheColumnStrings(cinfo); } @@ -175,7 +175,7 @@ void PacketListRecord::dissect(capture_file *cap_file, bool dissect_columns, boo epan_dissect_init(&edt, cap_file->epan, create_proto_tree, - FALSE /* proto_tree_visible */); + false /* proto_tree_visible */); /* Re-color when the coloring rules are changed via the UI. */ if (dissect_color) { @@ -195,7 +195,7 @@ void PacketListRecord::dissect(capture_file *cap_file, bool dissect_columns, boo if (dissect_columns) { /* "Stringify" non frame_data vals */ - epan_dissect_fill_in_columns(&edt, FALSE, FALSE /* fill_fd_columns */); + epan_dissect_fill_in_columns(&edt, false, false /* fill_fd_columns */); cacheColumnStrings(cinfo); } @@ -204,7 +204,8 @@ void PacketListRecord::dissect(capture_file *cap_file, bool dissect_columns, boo color_ver_ = rows_color_ver_; } - struct conversation * conv = find_conversation_pinfo(&edt.pi, 0); + struct conversation * conv = find_conversation_pinfo_ro(&edt.pi, 0); + conv_index_ = ! conv ? 0 : conv->conv_index; epan_dissect_cleanup(&edt); @@ -214,7 +215,7 @@ void PacketListRecord::dissect(capture_file *cap_file, bool dissect_columns, boo void PacketListRecord::cacheColumnStrings(column_info *cinfo) { - // packet_list_store.c:packet_list_change_record(PacketList *packet_list, PacketListRecord *record, gint col, column_info *cinfo) + // packet_list_store.c:packet_list_change_record(PacketList *packet_list, PacketListRecord *record, int col, column_info *cinfo) if (!cinfo) { return; } @@ -230,7 +231,7 @@ void PacketListRecord::cacheColumnStrings(column_info *cinfo) QString col_str; int text_col = cinfo_column_.value(column, -1); if (text_col < 0) { - col_fill_in_frame_data(fdata_, cinfo, column, FALSE); + col_fill_in_frame_data(fdata_, cinfo, column, false); } col_str = QString(get_column_text(cinfo, column)); diff --git a/ui/qt/models/packet_list_record.h b/ui/qt/models/packet_list_record.h index 47aa5621..7bb582fa 100644 --- a/ui/qt/models/packet_list_record.h +++ b/ui/qt/models/packet_list_record.h @@ -12,8 +12,6 @@ #include <config.h> -#include <glib.h> - #include "cfile.h" #include <epan/column.h> @@ -60,7 +58,7 @@ public: private: /** The column text for some columns */ - static QCache<guint32, QStringList> col_text_cache_; + static QCache<uint32_t, QStringList> col_text_cache_; frame_data *fdata_; int lines_; diff --git a/ui/qt/models/pref_delegate.cpp b/ui/qt/models/pref_delegate.cpp index e33bb13f..313c17dc 100644 --- a/ui/qt/models/pref_delegate.cpp +++ b/ui/qt/models/pref_delegate.cpp @@ -66,7 +66,7 @@ void AdvancedPrefDelegate::setEditorData(QWidget *editor, const QModelIndex &ind return; } - Q_ASSERT(FALSE); + Q_ASSERT(false); } void AdvancedPrefDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, @@ -81,5 +81,5 @@ void AdvancedPrefDelegate::setModelData(QWidget *editor, QAbstractItemModel *mod return; } - Q_ASSERT(FALSE); + Q_ASSERT(false); } diff --git a/ui/qt/models/pref_models.cpp b/ui/qt/models/pref_models.cpp index b86230f0..3480a8db 100644 --- a/ui/qt/models/pref_models.cpp +++ b/ui/qt/models/pref_models.cpp @@ -23,10 +23,10 @@ #include <QApplication> // XXX Should we move this to ui/preference_utils? -static GHashTable * pref_ptr_to_pref_ = NULL; +static GHashTable * pref_ptr_to_pref_; pref_t *prefFromPrefPtr(void *pref_ptr) { - return (pref_t *)g_hash_table_lookup(pref_ptr_to_pref_, (gpointer) pref_ptr); + return (pref_t *)g_hash_table_lookup(pref_ptr_to_pref_, (void *) pref_ptr); } static void prefInsertPrefPtr(void * pref_ptr, pref_t * pref) @@ -34,8 +34,8 @@ static void prefInsertPrefPtr(void * pref_ptr, pref_t * pref) if (! pref_ptr_to_pref_) pref_ptr_to_pref_ = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); - gpointer key = (gpointer) pref_ptr; - gpointer val = (gpointer) pref; + void *key = (void *) pref_ptr; + void *val = (void *) pref; /* Already existing entries will be ignored */ if ((void *)g_hash_table_lookup(pref_ptr_to_pref_, key) == NULL) @@ -47,6 +47,7 @@ PrefsItem::PrefsItem(module_t *module, pref_t *pref, PrefsItem* parent) pref_(pref), module_(module), name_(module->name ? module->name : module->parent->name), + help_(QString()), changed_(false) { if (pref_ != NULL) { @@ -59,9 +60,19 @@ PrefsItem::PrefsItem(const QString name, PrefsItem* parent) pref_(NULL), module_(NULL), name_(name), + help_(QString()), changed_(false) { +} +PrefsItem::PrefsItem(PrefsModel::PrefsModelType type, PrefsItem* parent) + : ModelHelperTreeItem<PrefsItem>(parent), + pref_(NULL), + module_(NULL), + name_(PrefsModel::typeToString(type)), + help_(PrefsModel::typeToHelp(type)), + changed_(false) +{ } PrefsItem::~PrefsItem() @@ -113,6 +124,20 @@ QString PrefsItem::getModuleTitle() const return QString(module_->title); } +QString PrefsItem::getModuleHelp() const +{ + if (module_ == nullptr) + return help_; + + module_t *pref_module = module_; + + while (pref_module->help == nullptr && pref_module->parent) { + pref_module = pref_module->parent; + } + + return pref_module->help; +} + void PrefsItem::setChanged(bool changed) { changed_ = changed; @@ -232,8 +257,8 @@ QVariant PrefsModel::data(const QModelIndex &index, int role) const return QVariant(); } -static guint -fill_prefs(module_t *module, gpointer root_ptr) +static unsigned +fill_prefs(module_t *module, void *root_ptr) { PrefsItem* root_item = static_cast<PrefsItem*>(root_ptr); @@ -275,32 +300,32 @@ fill_prefs(module_t *module, gpointer root_ptr) void PrefsModel::populate() { - prefs_modules_foreach_submodules(NULL, fill_prefs, (gpointer)root_); + prefs_modules_foreach_submodules(NULL, fill_prefs, (void *)root_); //Add the "specially handled" preferences PrefsItem *appearance_item, *appearance_subitem, *special_item; - appearance_item = new PrefsItem(typeToString(PrefsModel::Appearance), root_); + appearance_item = new PrefsItem(PrefsModel::Appearance, root_); root_->prependChild(appearance_item); - appearance_subitem = new PrefsItem(typeToString(PrefsModel::Layout), appearance_item); + appearance_subitem = new PrefsItem(PrefsModel::Layout, appearance_item); appearance_item->prependChild(appearance_subitem); - appearance_subitem = new PrefsItem(typeToString(PrefsModel::Columns), appearance_item); + appearance_subitem = new PrefsItem(PrefsModel::Columns, appearance_item); appearance_item->prependChild(appearance_subitem); - appearance_subitem = new PrefsItem(typeToString(PrefsModel::FontAndColors), appearance_item); + appearance_subitem = new PrefsItem(PrefsModel::FontAndColors, appearance_item); appearance_item->prependChild(appearance_subitem); - special_item = new PrefsItem(typeToString(PrefsModel::Capture), root_); + special_item = new PrefsItem(PrefsModel::Capture, root_); root_->prependChild(special_item); - special_item = new PrefsItem(typeToString(PrefsModel::Expert), root_); + special_item = new PrefsItem(PrefsModel::Expert, root_); root_->prependChild(special_item); - special_item = new PrefsItem(typeToString(PrefsModel::FilterButtons), root_); + special_item = new PrefsItem(PrefsModel::FilterButtons, root_); root_->prependChild(special_item); #ifdef HAVE_LIBGNUTLS - special_item = new PrefsItem(typeToString(PrefsModel::RSAKeys), root_); + special_item = new PrefsItem(PrefsModel::RSAKeys, root_); root_->prependChild(special_item); #endif - special_item = new PrefsItem(typeToString(PrefsModel::Advanced), root_); + special_item = new PrefsItem(PrefsModel::Advanced, root_); root_->prependChild(special_item); } @@ -324,6 +349,44 @@ QString PrefsModel::typeToString(int type) return typeStr; } +QString PrefsModel::typeToHelp(int type) +{ + QString helpStr; + + switch(type) + { + case Appearance: + helpStr = QString("ChCustPreferencesSection.html#_appearance"); + break; + case Columns: + helpStr = QString("ChCustPreferencesSection.html#_columns"); + break; + case FontAndColors: + helpStr = QString("ChCustPreferencesSection.html#_font_and_colors"); + break; + case Layout: + helpStr = QString("ChCustPreferencesSection.html#_layout"); + break; + case Capture: + helpStr = QString("ChCustPreferencesSection.html#_capture"); + break; + case Expert: + helpStr = QString("ChCustPreferencesSection.html#ChCustPrefsExpertSection"); + break; + case FilterButtons: + helpStr = QString("ChCustPreferencesSection.html#ChCustFilterButtons"); + break; + case RSAKeys: + helpStr = QString("ChCustPreferencesSection.html#ChCustPrefsRSASection"); + break; + case Advanced: + helpStr = QString("ChCustPreferencesSection.html#_advanced"); + break; + } + + return helpStr; +} + AdvancedPrefsModel::AdvancedPrefsModel(QObject * parent) : QSortFilterProxyModel(parent), filter_(), @@ -470,11 +533,10 @@ bool AdvancedPrefsModel::setData(const QModelIndex &dataindex, const QVariant &v item->setChanged(true); switch (item->getPrefType()) { - case PREF_DECODE_AS_UINT: case PREF_UINT: { bool ok; - guint new_val = value.toString().toUInt(&ok, prefs_get_uint_base(item->getPref())); + unsigned new_val = value.toString().toUInt(&ok, prefs_get_uint_base(item->getPref())); if (ok) prefs_set_uint_value(item->getPref(), new_val, pref_stashed); @@ -487,6 +549,7 @@ bool AdvancedPrefsModel::setData(const QModelIndex &dataindex, const QVariant &v prefs_set_enum_value(item->getPref(), value.toInt(), pref_stashed); break; case PREF_STRING: + case PREF_DISSECTOR: prefs_set_string_value(item->getPref(), value.toString().toStdString().c_str(), pref_stashed); break; case PREF_PASSWORD: @@ -543,7 +606,7 @@ Qt::ItemFlags AdvancedPrefsModel::flags(const QModelIndex &index) const Qt::ItemFlags flags = QAbstractItemModel::flags(index); if (item->getPref() == NULL) { - /* Base modules aren't changable */ + /* Base modules aren't changeable */ flags &= ~(Qt::ItemIsEnabled | Qt::ItemIsSelectable); } else { flags |= Qt::ItemIsEditable; @@ -683,6 +746,8 @@ QVariant ModulePrefsModel::data(const QModelIndex &dataindex, int role) const return sourceModel()->data(modelIndex, role); case ModuleName: return item->getModuleName(); + case ModuleHelp: + return item->getModuleHelp(); default: break; } diff --git a/ui/qt/models/pref_models.h b/ui/qt/models/pref_models.h index 775da0d0..601c7623 100644 --- a/ui/qt/models/pref_models.h +++ b/ui/qt/models/pref_models.h @@ -19,32 +19,7 @@ #include <QSortFilterProxyModel> #include <QTreeView> -class PrefsItem : public ModelHelperTreeItem<PrefsItem> -{ -public: - PrefsItem(module_t *module, pref_t *pref, PrefsItem* parent); - PrefsItem(const QString name, PrefsItem* parent); - virtual ~PrefsItem(); - - QString getName() const {return name_;} - pref_t* getPref() const {return pref_;} - int getPrefType() const; - bool isPrefDefault() const; - QString getPrefTypeName() const; - module_t* getModule() const {return module_;} - QString getModuleName() const; - QString getModuleTitle() const; - void setChanged(bool changed = true); - -private: - pref_t *pref_; - module_t *module_; - QString name_; - //set to true if changed during module manipulation - //Used to determine proper "default" for comparison - bool changed_; -}; - +class PrefsItem; class PrefsModel : public QAbstractItemModel { @@ -83,6 +58,7 @@ public: int columnCount(const QModelIndex &parent = QModelIndex()) const; static QString typeToString(int type); + static QString typeToHelp(int type); private: void populate(); @@ -90,6 +66,35 @@ private: PrefsItem* root_; }; +class PrefsItem : public ModelHelperTreeItem<PrefsItem> +{ +public: + PrefsItem(module_t *module, pref_t *pref, PrefsItem* parent); + PrefsItem(const QString name, PrefsItem* parent); + PrefsItem(PrefsModel::PrefsModelType type, PrefsItem* parent); + virtual ~PrefsItem(); + + QString getName() const {return name_;} + pref_t* getPref() const {return pref_;} + int getPrefType() const; + bool isPrefDefault() const; + QString getPrefTypeName() const; + module_t* getModule() const {return module_;} + QString getModuleName() const; + QString getModuleTitle() const; + QString getModuleHelp() const; + void setChanged(bool changed = true); + +private: + pref_t *pref_; + module_t *module_; + QString name_; + QString help_; + //set to true if changed during module manipulation + //Used to determine proper "default" for comparison + bool changed_; +}; + class AdvancedPrefsModel : public QSortFilterProxyModel { Q_OBJECT @@ -143,7 +148,8 @@ public: }; enum ModulePrefsRoles { - ModuleName = Qt::UserRole + 1 + ModuleName = Qt::UserRole + 1, + ModuleHelp = Qt::UserRole + 2 }; QVariant data(const QModelIndex &index, int role) const; diff --git a/ui/qt/models/profile_model.cpp b/ui/qt/models/profile_model.cpp index 206ef389..ecbcef6b 100644 --- a/ui/qt/models/profile_model.cpp +++ b/ui/qt/models/profile_model.cpp @@ -11,12 +11,13 @@ #include <errno.h> -#include "glib.h" #include "ui/profile.h" #include "ui/recent.h" -#include "wsutil/filesystem.h" #include "epan/prefs.h" +#include "wsutil/filesystem.h" +#include "wsutil/utf8_entities.h" + #include <ui/qt/models/profile_model.h> #include <ui/qt/utils/color_utils.h> @@ -276,6 +277,14 @@ QVariant ProfileModel::dataDisplay(const QModelIndex &index) const return tr("Global"); else return tr("Personal"); + case COL_AUTO_SWITCH_FILTER: + { + if (prof->is_global) { + return QString(UTF8_EM_DASH); + } + return (QString(prof->auto_switch_filter)); + } + default: break; } @@ -426,7 +435,7 @@ QVariant ProfileModel::dataBackgroundRole(const QModelIndex &index) const if (prof->status != PROF_STAT_DEFAULT && ! prof->is_global) { - /* Highlights errorneous line */ + /* Highlights erroneous line */ if (checkInvalid(index) || checkIfDeleted(index) || checkDuplicate(index) || ! checkNameValidity(prof->name)) return ColorUtils::fromColorT(&prefs.gui_text_invalid); @@ -438,6 +447,23 @@ QVariant ProfileModel::dataBackgroundRole(const QModelIndex &index) const return QVariant(); } +QVariant ProfileModel::dataForegroundRole(const QModelIndex &index) const +{ + if (! index.isValid() || profiles_.count() <= index.row()) + return QVariant(); + + profile_def * prof = guard(index.row()); + if (! prof) { + return QVariant(); + } + + if (prof->is_global && index.column() == COL_AUTO_SWITCH_FILTER) { + return ColorUtils::disabledForeground(); + } + + return QVariant(); +} + QVariant ProfileModel::dataToolTipRole(const QModelIndex &idx) const { if (! idx.isValid() || profiles_.count() <= idx.row()) @@ -492,7 +518,7 @@ QVariant ProfileModel::dataPath(const QModelIndex &index) const { case PROF_STAT_DEFAULT: if (!reset_default_) - return gchar_free_to_qstring(get_persconffile_path("", FALSE)); + return gchar_free_to_qstring(get_persconffile_path("", false)); else return tr("Resetting to default"); case PROF_STAT_EXISTS: @@ -537,7 +563,7 @@ QVariant ProfileModel::dataPath(const QModelIndex &index) const QString appendix; /* A global profile is neither deleted or removed, only system provided is allowed as appendix */ - if (profile_exists(prof->reference, TRUE) && prof->from_global) + if (profile_exists(prof->reference, true) && prof->from_global) appendix = tr("system provided"); /* A default model as reference can neither be deleted or renamed, so skip if the reference was one */ else if (! index.data(ProfileModel::DATA_IS_DEFAULT).toBool()) @@ -588,6 +614,8 @@ QVariant ProfileModel::data(const QModelIndex &index, int role) const return dataFontRole(index); case Qt::BackgroundRole: return dataBackgroundRole(index); + case Qt::ForegroundRole: + return dataForegroundRole(index); case Qt::ToolTipRole: return dataToolTipRole(index); case ProfileModel::DATA_STATUS: @@ -612,10 +640,6 @@ QVariant ProfileModel::data(const QModelIndex &index, int role) const } case ProfileModel::DATA_PATH: return dataPath(index); - case ProfileModel::DATA_INDEX_VALUE_IS_URL: - if (index.column() <= ProfileModel::COL_TYPE) - return QVariant::fromValue(false); - return QVariant::fromValue(true); case ProfileModel::DATA_PATH_IS_NOT_DESCRIPTION: if (prof->status == PROF_STAT_NEW || prof->status == PROF_STAT_COPY || (prof->status == PROF_STAT_DEFAULT && reset_default_) @@ -641,6 +665,8 @@ QVariant ProfileModel::headerData(int section, Qt::Orientation orientation, int return tr("Profile"); case COL_TYPE: return tr("Type"); + case COL_AUTO_SWITCH_FILTER: + return tr("Auto Switch Filter"); default: break; } @@ -654,11 +680,18 @@ Qt::ItemFlags ProfileModel::flags(const QModelIndex &index) const Qt::ItemFlags fl = QAbstractTableModel::flags(index); profile_def * prof = guard(index); - if (! prof) + if (! prof) { return fl; + } - if (index.column() == ProfileModel::COL_NAME && prof->status != PROF_STAT_DEFAULT && ! prof->is_global) + if (prof->is_global) { + return fl; + } + + if ((index.column() == ProfileModel::COL_NAME && prof->status != PROF_STAT_DEFAULT) + || (index.column() == ProfileModel::COL_AUTO_SWITCH_FILTER)) { fl |= Qt::ItemIsEditable; + } return fl; } @@ -722,7 +755,7 @@ QModelIndex ProfileModel::addNewProfile(QString name) cnt++; } - add_to_profile_list(newName.toUtf8().constData(), newName.toUtf8().constData(), PROF_STAT_NEW, FALSE, FALSE, FALSE); + add_to_profile_list(newName.toUtf8().constData(), newName.toUtf8().constData(), PROF_STAT_NEW, false, false, false); loadProfiles(); return index(findByName(newName), COL_NAME); @@ -794,7 +827,7 @@ QModelIndex ProfileModel::duplicateEntry(QModelIndex idx, int new_status) new_status = PROF_STAT_NEW; /* add element */ - add_to_profile_list(new_name.toUtf8().constData(), parent.toUtf8().constData(), new_status, FALSE, prof->from_global ? prof->from_global : prof->is_global, FALSE); + add_to_profile_list(new_name.toUtf8().constData(), parent.toUtf8().constData(), new_status, false, prof->from_global ? prof->from_global : prof->is_global, false); /* reload profile list in model */ loadProfiles(); @@ -901,27 +934,41 @@ bool ProfileModel::setData(const QModelIndex &idx, const QVariant &value, int ro { last_set_row_ = -1; - if (role != Qt::EditRole || ! value.isValid() || value.toString().isEmpty()) + if (role != Qt::EditRole || !value.isValid()) { return false; + } + + if (idx.column() == COL_NAME && value.toString().isEmpty()) { + return false; + } QString newValue = value.toString(); profile_def * prof = guard(idx); - if (! prof || prof->status == PROF_STAT_DEFAULT) + + if (!prof) { return false; + } last_set_row_ = idx.row(); - QString current(prof->name); - if (current.compare(newValue) != 0) - { - g_free(prof->name); - prof->name = qstring_strdup(newValue); + if (idx.column() == COL_NAME && prof->status != PROF_STAT_DEFAULT) { + QString current(prof->name); + if (current.compare(newValue) != 0) + { + g_free(prof->name); + prof->name = qstring_strdup(newValue); - if (prof->reference && g_strcmp0(prof->name, prof->reference) == 0 && ! (prof->status == PROF_STAT_NEW || prof->status == PROF_STAT_COPY)) { - prof->status = PROF_STAT_EXISTS; - } else if (prof->status == PROF_STAT_EXISTS) { - prof->status = PROF_STAT_CHANGED; + if (prof->reference && g_strcmp0(prof->name, prof->reference) == 0 && ! (prof->status == PROF_STAT_NEW || prof->status == PROF_STAT_COPY)) { + prof->status = PROF_STAT_EXISTS; + } else if (prof->status == PROF_STAT_EXISTS) { + prof->status = PROF_STAT_CHANGED; + } + emit itemChanged(idx); } + } else if (idx.column() == COL_AUTO_SWITCH_FILTER) { + g_free(prof->auto_switch_filter); + prof->auto_switch_filter = qstring_strdup(newValue); + prof->prefs_changed = true; emit itemChanged(idx); } @@ -1033,7 +1080,7 @@ QFileInfoList ProfileModel::filterProfilePath(QString path, QFileInfoList ent, b return result; } -#ifdef HAVE_MINIZIP +#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG) QStringList ProfileModel::exportFileList(QModelIndexList items) { QStringList result; @@ -1163,7 +1210,7 @@ int ProfileModel::importProfilesFromDir(QString dirname, int * skippedCnt, bool if (success) { count++; - add_to_profile_list(fentry.fileName().toUtf8().constData(), fentry.fileName().toUtf8().constData(), PROF_STAT_NEW, FALSE, FALSE, TRUE); + add_to_profile_list(fentry.fileName().toUtf8().constData(), fentry.fileName().toUtf8().constData(), PROF_STAT_NEW, false, false, true); } else if (! wasEmpty && QFile::exists(profilePath)) { diff --git a/ui/qt/models/profile_model.h b/ui/qt/models/profile_model.h index 16febd70..ff054752 100644 --- a/ui/qt/models/profile_model.h +++ b/ui/qt/models/profile_model.h @@ -11,7 +11,6 @@ #define PROFILE_MODEL_H #include "config.h" -#include "glib.h" #include <ui/profile.h> @@ -59,6 +58,7 @@ public: enum { COL_NAME, COL_TYPE, + COL_AUTO_SWITCH_FILTER, _LAST_ENTRY } columns_; @@ -69,7 +69,6 @@ public: DATA_IS_SELECTED, DATA_PATH, DATA_PATH_IS_NOT_DESCRIPTION, - DATA_INDEX_VALUE_IS_URL } data_values_; // QAbstractItemModel interface @@ -101,7 +100,7 @@ public: bool userProfilesExist() const; -#ifdef HAVE_MINIZIP +#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG) bool exportProfiles(QString filename, QModelIndexList items, QString * err = Q_NULLPTR); int importProfilesFromZip(QString filename, int *skippedCnt = Q_NULLPTR, QStringList *result = Q_NULLPTR); #endif @@ -142,7 +141,7 @@ private: int findByNameAndVisibility(QString name, bool isGlobal = false, bool searchReference = false) const; int findAsReference(QString reference) const; -#ifdef HAVE_MINIZIP +#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG) static bool acceptFile(QString fileName, int fileSize); static QString cleanName(QString fileName); #endif @@ -150,10 +149,11 @@ private: QVariant dataDisplay(const QModelIndex & idx) const; QVariant dataFontRole(const QModelIndex & idx) const; QVariant dataBackgroundRole(const QModelIndex & idx) const; + QVariant dataForegroundRole(const QModelIndex & idx) const; QVariant dataToolTipRole(const QModelIndex & idx) const; QVariant dataPath(const QModelIndex & idx) const; -#ifdef HAVE_MINIZIP +#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG) QStringList exportFileList(QModelIndexList items); #endif bool copyTempToProfile(QString tempPath, QString profilePath, bool *wasEmpty = Q_NULLPTR); diff --git a/ui/qt/models/proto_tree_model.cpp b/ui/qt/models/proto_tree_model.cpp index 3ededffd..fe6f7f95 100644 --- a/ui/qt/models/proto_tree_model.cpp +++ b/ui/qt/models/proto_tree_model.cpp @@ -188,7 +188,8 @@ struct find_hfid_ { ProtoNode *node; }; -bool ProtoTreeModel::foreachFindHfid(ProtoNode *node, gpointer find_hfid_ptr) +// NOLINTNEXTLINE(misc-no-recursion) +bool ProtoTreeModel::foreachFindHfid(ProtoNode *node, void *find_hfid_ptr) { struct find_hfid_ *find_hfid = (struct find_hfid_ *) find_hfid_ptr; if (PNODE_FINFO(node->protoNode()) && PNODE_FINFO(node->protoNode())->hfinfo->id == find_hfid->hfid) { @@ -196,6 +197,7 @@ bool ProtoTreeModel::foreachFindHfid(ProtoNode *node, gpointer find_hfid_ptr) return true; } for (int i = 0; i < node->childrenCount(); i++) { + // We recurse here, but we're limited by tree depth checks in epan if (foreachFindHfid(node->child(i), find_hfid)) { return true; } @@ -221,7 +223,8 @@ struct find_field_info_ { ProtoNode *node; }; -bool ProtoTreeModel::foreachFindField(ProtoNode *node, gpointer find_finfo_ptr) +// NOLINTNEXTLINE(misc-no-recursion) +bool ProtoTreeModel::foreachFindField(ProtoNode *node, void *find_finfo_ptr) { struct find_field_info_ *find_finfo = (struct find_field_info_ *) find_finfo_ptr; if (PNODE_FINFO(node->protoNode()) == find_finfo->fi) { @@ -229,6 +232,7 @@ bool ProtoTreeModel::foreachFindField(ProtoNode *node, gpointer find_finfo_ptr) return true; } for (int i = 0; i < node->childrenCount(); i++) { + // We recurse here, but we're limited by tree depth checks in epan if (foreachFindField(node->child(i), find_finfo)) { return true; } diff --git a/ui/qt/models/proto_tree_model.h b/ui/qt/models/proto_tree_model.h index df7cbba8..12d08fc0 100644 --- a/ui/qt/models/proto_tree_model.h +++ b/ui/qt/models/proto_tree_model.h @@ -41,8 +41,8 @@ public: private: ProtoNode *root_node_; - static bool foreachFindHfid(ProtoNode *node, gpointer find_hfid_ptr); - static bool foreachFindField(ProtoNode *node, gpointer find_finfo_ptr); + static bool foreachFindHfid(ProtoNode *node, void *find_hfid_ptr); + static bool foreachFindField(ProtoNode *node, void *find_finfo_ptr); }; #endif // PROTO_TREE_MODEL_H diff --git a/ui/qt/models/related_packet_delegate.cpp b/ui/qt/models/related_packet_delegate.cpp index 885160f4..bb001adc 100644 --- a/ui/qt/models/related_packet_delegate.cpp +++ b/ui/qt/models/related_packet_delegate.cpp @@ -73,7 +73,7 @@ void RelatedPacketDelegate::paint(QPainter *painter, const QStyleOptionViewItem option_vi.decorationSize.setWidth(em_w); QStyledItemDelegate::paint(painter, option_vi, index); - guint32 setup_frame = 0, last_frame = 0; + uint32_t setup_frame = 0, last_frame = 0; if (conv_) { setup_frame = (int) conv_->setup_frame; last_frame = (int) conv_->last_frame; @@ -339,7 +339,7 @@ void RelatedPacketDelegate::clear() conv_ = NULL; } -void RelatedPacketDelegate::setCurrentFrame(guint32 current_frame) +void RelatedPacketDelegate::setCurrentFrame(uint32_t current_frame) { current_frame_ = current_frame; foreach (ft_framenum_type_t framenum_type, related_frames_) { diff --git a/ui/qt/models/related_packet_delegate.h b/ui/qt/models/related_packet_delegate.h index 927129a0..68250119 100644 --- a/ui/qt/models/related_packet_delegate.h +++ b/ui/qt/models/related_packet_delegate.h @@ -26,7 +26,7 @@ class RelatedPacketDelegate : public QStyledItemDelegate public: RelatedPacketDelegate(QWidget *parent = 0); void clear(); - void setCurrentFrame(guint32 current_frame); + void setCurrentFrame(uint32_t current_frame); void setConversation(struct conversation *conv); public slots: @@ -41,7 +41,7 @@ protected: private: QHash<int, ft_framenum_type_t> related_frames_; struct conversation *conv_; - guint32 current_frame_; + uint32_t current_frame_; void drawArrow(QPainter *painter, const QPoint tail, const QPoint head, int head_size) const; void drawChevrons(QPainter *painter, const QPoint tail, const QPoint head, int head_size) const; diff --git a/ui/qt/models/resolved_addresses_models.cpp b/ui/qt/models/resolved_addresses_models.cpp index 48dd2f09..25557771 100644 --- a/ui/qt/models/resolved_addresses_models.cpp +++ b/ui/qt/models/resolved_addresses_models.cpp @@ -9,8 +9,6 @@ #include <ui/qt/models/resolved_addresses_models.h> -#include <glib.h> - #include "file.h" #include "epan/addr_resolv.h" @@ -20,11 +18,11 @@ extern "C" { static void -serv_port_hash_to_qstringlist(gpointer key, gpointer value, gpointer member_ptr) +serv_port_hash_to_qstringlist(void *key, void *value, void *member_ptr) { PortsModel *model = static_cast<PortsModel *>(member_ptr); serv_port_t *serv_port = (serv_port_t *)value; - guint port = GPOINTER_TO_UINT(key); + unsigned port = GPOINTER_TO_UINT(key); if (serv_port->tcp_name) { QStringList entries; @@ -61,69 +59,73 @@ serv_port_hash_to_qstringlist(gpointer key, gpointer value, gpointer member_ptr) } static void -ipv4_hash_table_resolved_to_list(gpointer, gpointer value, gpointer sl_ptr) +ipv4_hash_table_resolved_to_list(void *, void *value, void *sl_ptr) { QList<QStringList> *hosts = (QList<QStringList> *) sl_ptr; hashipv4_t *ipv4_hash_table_entry = (hashipv4_t *) value; - if ((ipv4_hash_table_entry->flags & NAME_RESOLVED)) { + if ((ipv4_hash_table_entry->flags & (USED_AND_RESOLVED_MASK)) == USED_AND_RESOLVED_MASK) { *hosts << (QStringList() << QString(ipv4_hash_table_entry->ip) << QString(ipv4_hash_table_entry->name)); } } static void -ipv6_hash_table_resolved_to_list(gpointer, gpointer value, gpointer sl_ptr) +ipv6_hash_table_resolved_to_list(void *, void *value, void *sl_ptr) { QList<QStringList> *hosts = (QList<QStringList> *) sl_ptr; hashipv6_t *ipv6_hash_table_entry = (hashipv6_t *) value; - if ((ipv6_hash_table_entry->flags & NAME_RESOLVED)) { + if ((ipv6_hash_table_entry->flags & USED_AND_RESOLVED_MASK) == USED_AND_RESOLVED_MASK) { *hosts << (QStringList() << QString(ipv6_hash_table_entry->ip6) << QString(ipv6_hash_table_entry->name)); } } static void -eth_hash_to_qstringlist(gpointer, gpointer value, gpointer sl_ptr) +eth_hash_to_qstringlist(void *, void *value, void *sl_ptr) { QList<QStringList> *values = (QList<QStringList> *) sl_ptr; hashether_t* tp = (hashether_t*)value; - *values << (QStringList() << QString(get_hash_ether_hexaddr(tp)) << QString(get_hash_ether_resolved_name(tp))); + if (get_hash_ether_used(tp)) { + *values << (QStringList() << QString(get_hash_ether_hexaddr(tp)) << QString(get_hash_ether_resolved_name(tp))); + } } static void -manuf_hash_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr) +manuf_hash_to_qstringlist(void *key, void *value, void *sl_ptr) { QList<QStringList> *values = (QList<QStringList> *) sl_ptr; hashmanuf_t *manuf = (hashmanuf_t*)value; - guint eth_as_guint = GPOINTER_TO_UINT(key); + unsigned eth_as_uint = GPOINTER_TO_UINT(key); - QString entry = QString("%1:%2:%3") - .arg((eth_as_guint >> 16 & 0xff), 2, 16, QChar('0')) - .arg((eth_as_guint >> 8 & 0xff), 2, 16, QChar('0')) - .arg((eth_as_guint & 0xff), 2, 16, QChar('0')); + if (get_hash_manuf_used(manuf)) { + QString entry = QString("%1:%2:%3") + .arg((eth_as_uint >> 16 & 0xff), 2, 16, QChar('0')) + .arg((eth_as_uint >> 8 & 0xff), 2, 16, QChar('0')) + .arg((eth_as_uint & 0xff), 2, 16, QChar('0')); - *values << (QStringList() << entry << QString(get_hash_manuf_resolved_name(manuf))); + *values << (QStringList() << entry << QString(get_hash_manuf_resolved_name(manuf))); + } } static void -wka_hash_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr) +wka_hash_to_qstringlist(void *key, void *value, void *sl_ptr) { QList<QStringList> *values = (QList<QStringList> *) sl_ptr; - gchar *name = (gchar *)value; - guint8 *eth_addr = (guint8*)key; - - QString entry = QString("%1:%2:%3:%4:%5:%6") - .arg(eth_addr[0], 2, 16, QChar('0')) - .arg(eth_addr[1], 2, 16, QChar('0')) - .arg(eth_addr[2], 2, 16, QChar('0')) - .arg(eth_addr[3], 2, 16, QChar('0')) - .arg(eth_addr[4], 2, 16, QChar('0')) - .arg(eth_addr[5], 2, 16, QChar('0')); - - // We should filter on only those actually resolved, not display - // everything in wka - *values << (QStringList() << entry << QString(name)); + hashwka_t *wkahash = (hashwka_t *)value; + uint8_t *eth_addr = (uint8_t*)key; + + if (get_hash_wka_used(wkahash)) { + QString entry = QString("%1:%2:%3:%4:%5:%6") + .arg(eth_addr[0], 2, 16, QChar('0')) + .arg(eth_addr[1], 2, 16, QChar('0')) + .arg(eth_addr[2], 2, 16, QChar('0')) + .arg(eth_addr[3], 2, 16, QChar('0')) + .arg(eth_addr[4], 2, 16, QChar('0')) + .arg(eth_addr[5], 2, 16, QChar('0')); + + *values << (QStringList() << entry << QString(get_hash_wka_resolved_name(wkahash))); + } } } diff --git a/ui/qt/models/resolved_addresses_models.h b/ui/qt/models/resolved_addresses_models.h index 32ca1b15..9a26eb6d 100644 --- a/ui/qt/models/resolved_addresses_models.h +++ b/ui/qt/models/resolved_addresses_models.h @@ -30,6 +30,13 @@ protected: }; +enum PortsModelColumns +{ + PORTS_COL_NAME, + PORTS_COL_PORT, + PORTS_COL_PROTOCOL +}; + class PortsModel : public AStringListListModel { Q_OBJECT diff --git a/ui/qt/models/sparkline_delegate.cpp b/ui/qt/models/sparkline_delegate.cpp index 457c8295..121d8226 100644 --- a/ui/qt/models/sparkline_delegate.cpp +++ b/ui/qt/models/sparkline_delegate.cpp @@ -20,7 +20,7 @@ void SparkLineDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt QList<int> points = qvariant_cast<QList<int> >(index.data(Qt::UserRole)); int max = 1; // We typically draw a sparkline alongside some text. Size our - // drawing area based on an Em width. and a bit of eyballing on + // drawing area based on an Em width. and a bit of eyeballing on // Linux, macOS, and Windows. int em_w = option.fontMetrics.height(); int content_w = option.rect.width() - (em_w / 4); diff --git a/ui/qt/models/uat_delegate.h b/ui/qt/models/uat_delegate.h index e57e533d..f9cfa92d 100644 --- a/ui/qt/models/uat_delegate.h +++ b/ui/qt/models/uat_delegate.h @@ -15,7 +15,6 @@ #define UAT_DELEGATE_H #include <config.h> -#include <glib.h> #include <epan/uat-int.h> #include <QStyledItemDelegate> diff --git a/ui/qt/models/uat_model.cpp b/ui/qt/models/uat_model.cpp index a841ca8c..24b4423c 100644 --- a/ui/qt/models/uat_model.cpp +++ b/ui/qt/models/uat_model.cpp @@ -12,12 +12,23 @@ #include "uat_model.h" #include <epan/to_str.h> +#include <ui/qt/utils/qt_ui_utils.h> +#include <QFont> #include <QBrush> #include <QDebug> +// XXX - The model accesses the uat_t raw data, but if the raw data +// is changed outside the model, e.g. by another model on the same UAT +// or by changing configuration profiles, record_errors and dirty_records +// don't have the proper length, which leads to accessing an illegal list +// index. The preference dialog and configuration profile dialogs are modal, +// which reduces the chance of this, but the I/O Graphs using a UAT invites +// issues. + UatModel::UatModel(QObject *parent, epan_uat *uat) : QAbstractTableModel(parent), - uat_(0) + uat_(0), + applying_(false) { loadUat(uat); } @@ -46,7 +57,14 @@ void UatModel::loadUat(epan_uat * uat) void UatModel::reloadUat() { + // Avoid unnecessarily resetting the model if we're just making + // what's on disk match what we have. + if (applying_) + return; + beginResetModel(); + record_errors.clear(); + dirty_records.clear(); loadUat(uat_); endResetModel(); } @@ -54,16 +72,22 @@ void UatModel::reloadUat() bool UatModel::applyChanges(QString &error) { if (uat_->changed) { - gchar *err = NULL; + char *err = NULL; if (!uat_save(uat_, &err)) { error = QString("Error while saving %1: %2").arg(uat_->name).arg(err); g_free(err); } + applying_ = true; + // XXX - Why does this need to call post_update_cb? post_update_cb + // is for when the uat_t is updated, e.g. after loading a file. + // Saving makes the information on disk match the table records in + // memory, but it shouldn't change the uat_t. if (uat_->post_update_cb) { uat_->post_update_cb(); } + applying_ = false; return true; } @@ -76,7 +100,7 @@ bool UatModel::revertChanges(QString &error) // to avoid calling post_update_cb. Calling uat_clear + uat_load is a lazy // option and might fail (e.g. when the UAT file is removed). if (uat_->changed) { - gchar *err = NULL; + char *err = NULL; uat_clear(uat_); if (!uat_load(uat_, NULL, &err)) { error = QString("Error while loading %1: %2").arg(uat_->name).arg(err); @@ -90,17 +114,19 @@ bool UatModel::revertChanges(QString &error) Qt::ItemFlags UatModel::flags(const QModelIndex &index) const { + Qt::ItemFlags flags = QAbstractTableModel::flags(index); + flags |= Qt::ItemIsDropEnabled; + if (!index.isValid()) - return Qt::ItemFlags(); + return flags; uat_field_t *field = &uat_->fields[index.column()]; - Qt::ItemFlags flags = QAbstractTableModel::flags(index); if (field->mode == PT_TXTMOD_BOOL) { flags |= Qt::ItemIsUserCheckable; } - flags |= Qt::ItemIsEditable; + flags |= Qt::ItemIsEditable | Qt::ItemIsDragEnabled; return flags; } @@ -114,13 +140,13 @@ QVariant UatModel::data(const QModelIndex &index, int role) const uat_field_t *field = &uat_->fields[index.column()]; if (role == Qt::DisplayRole || role == Qt::EditRole) { char *str = NULL; - guint length = 0; + unsigned length = 0; field->cb.tostr(rec, &str, &length, field->cbdata.tostr, field->fld_data); switch (field->mode) { case PT_TXTMOD_HEXBYTES: { - char* temp_str = bytes_to_str(NULL, (const guint8 *) str, length); + char* temp_str = bytes_to_str(NULL, (const uint8_t *) str, length); g_free(str); QString qstr(temp_str); wmem_free(NULL, temp_str); @@ -128,24 +154,24 @@ QVariant UatModel::data(const QModelIndex &index, int role) const } case PT_TXTMOD_BOOL: case PT_TXTMOD_COLOR: + g_free(str); return QVariant(); default: - { - QString qstr(str); - g_free(str); - return qstr; - } + return gchar_free_to_qstring(str); } } if ((role == Qt::CheckStateRole) && (field->mode == PT_TXTMOD_BOOL)) { char *str = NULL; - guint length = 0; + unsigned length = 0; enum Qt::CheckState state = Qt::Unchecked; field->cb.tostr(rec, &str, &length, field->cbdata.tostr, field->fld_data); - if ((g_strcmp0(str, "TRUE") == 0) || - (g_strcmp0(str, "Enabled") == 0)) + // "Enabled" is for backwards compatibility with pre-UAT IO Graphs: + // (Commit 5b3e3ee58748ac1fd9201d2d3facbed1b9b1e800) + if (str && + ((g_ascii_strcasecmp(str, "true") == 0) || + (g_strcmp0(str, "Enabled") == 0))) state = Qt::Checked; g_free(str); @@ -166,12 +192,21 @@ QVariant UatModel::data(const QModelIndex &index, int role) const return QVariant(); } + if (role == Qt::FontRole) { + if (!g_array_index(uat_->valid_data, bool, index.row())) { + QFont font; + font.setItalic(!font.italic()); + return font; + } + return QVariant(); + } + if ((role == Qt::DecorationRole) && (field->mode == PT_TXTMOD_COLOR)) { char *str = NULL; - guint length = 0; + unsigned length = 0; field->cb.tostr(rec, &str, &length, field->cbdata.tostr, field->fld_data); - return QColor(QString(str)); + return QColor(gchar_free_to_qstring(str)); } // expose error message if any. @@ -259,9 +294,9 @@ QModelIndex UatModel::appendEntry(QVariantList rowData) data = rowData[col].toString(); } else { if (rowData[col].toInt() == Qt::Checked) { - data = QString("TRUE"); + data = QString("true"); } else { - data = QString("FALSE"); + data = QString("false"); } } } @@ -281,7 +316,7 @@ QModelIndex UatModel::appendEntry(QVariantList rowData) // postponed until the row (in the view) is not selected anymore checkRow(row); dirty_records.insert(row, true); - uat_->changed = TRUE; + uat_->changed = true; emit endInsertRows(); @@ -316,9 +351,9 @@ bool UatModel::setData(const QModelIndex &index, const QVariant &value, int role field->cb.set(rec, bytes.constData(), (unsigned) bytes.size(), field->cbdata.set, field->fld_data); } else { if (value.toInt() == Qt::Checked) { - field->cb.set(rec, "TRUE", 4, field->cbdata.set, field->fld_data); + field->cb.set(rec, "true", 4, field->cbdata.set, field->fld_data); } else { - field->cb.set(rec, "FALSE", 5, field->cbdata.set, field->fld_data); + field->cb.set(rec, "false", 5, field->cbdata.set, field->fld_data); } } @@ -348,7 +383,7 @@ bool UatModel::setData(const QModelIndex &index, const QVariant &value, int role } uat_update_record(uat_, rec, record_errors[row].isEmpty()); dirty_records[row] = true; - uat_->changed = TRUE; + uat_->changed = true; if (updated_cols.size() > updated_cols.count(index.column())) { // The validation status for other columns were also affected by @@ -388,21 +423,24 @@ bool UatModel::insertRows(int row, int count, const QModelIndex &/*parent*/) // postponed until the row (in the view) is not selected anymore checkRow(row); dirty_records.insert(row, true); - uat_->changed = TRUE; + uat_->changed = true; endInsertRows(); return true; } bool UatModel::removeRows(int row, int count, const QModelIndex &/*parent*/) { - if (count != 1 || row < 0 || row >= rowCount()) + if (row < 0 || count < 0 || row + count > rowCount()) return false; - beginRemoveRows(QModelIndex(), row, row); - uat_remove_record_idx(uat_, row); - record_errors.removeAt(row); - dirty_records.removeAt(row); - uat_->changed = TRUE; + if (count == 0) + return true; + + beginRemoveRows(QModelIndex(), row, row + count - 1); + uat_remove_record_range(uat_, row, count); + record_errors.remove(row, count); + dirty_records.remove(row, count); + uat_->changed = true; endRemoveRows(); return true; } @@ -416,7 +454,7 @@ void UatModel::clearAll() uat_clear(uat_); record_errors.clear(); dirty_records.clear(); - uat_->changed = TRUE; + uat_->changed = true; endResetModel(); } @@ -448,7 +486,7 @@ QModelIndex UatModel::copyRow(QModelIndex original) checkRow(newRow); dirty_records.insert(newRow, true); - // the UAT record has been created, now it is filled with the infromation + // the UAT record has been created, now it is filled with the information const void *src_record = UAT_INDEX_PTR(uat_, original.row()); void *dst_record = UAT_INDEX_PTR(uat_, newRow); // insertRows always initializes the record with empty value. Before copying @@ -462,35 +500,67 @@ QModelIndex UatModel::copyRow(QModelIndex original) /* According to documentation of uat_copy_cb_t memcpy should be used if uat_->copy_cb is NULL */ memcpy(dst_record, src_record, uat_->record_size); } - gboolean src_valid = g_array_index(uat_->valid_data, gboolean, original.row()); + bool src_valid = g_array_index(uat_->valid_data, bool, original.row()); uat_update_record(uat_, dst_record, src_valid); record_errors[newRow] = record_errors[original.row()]; dirty_records[newRow] = true; - uat_->changed = TRUE; + uat_->changed = true; endInsertRows(); return index(newRow, 0, QModelIndex()); } -bool UatModel::moveRow(int src_row, int dst_row) +bool UatModel::moveRowPrivate(int src_row, int dst_row) { - if (src_row < 0 || src_row >= rowCount() || dst_row < 0 || dst_row >= rowCount()) - return false; - - int dst = src_row < dst_row ? dst_row + 1 : dst_row; + if (src_row == dst_row) + return true; - beginMoveRows(QModelIndex(), src_row, src_row, QModelIndex(), dst); uat_move_index(uat_, src_row, dst_row); record_errors.move(src_row, dst_row); dirty_records.move(src_row, dst_row); - uat_->changed = TRUE; - endMoveRows(); + uat_->changed = true; return true; } +bool UatModel::moveRow(int src_row, int dst_row) +{ + return moveRows(QModelIndex(), src_row, 1, QModelIndex(), dst_row); +} + +bool UatModel::moveRows(const QModelIndex &, int sourceRow, int count, const QModelIndex &, int destinationChild) +{ + if (sourceRow < 0 || sourceRow >= rowCount() || destinationChild < 0 || destinationChild >= rowCount() || count < 0) + return false; + + if (count == 0) + return true; + + // beginMoveRows checks this + if (sourceRow <= destinationChild && destinationChild <= sourceRow + count - 1) + return false; + + if (destinationChild < sourceRow) { + if (!beginMoveRows(QModelIndex(), sourceRow, sourceRow + count - 1, QModelIndex(), destinationChild)) { + return false; + } + for (int i = 0; i < count; i++) { + moveRowPrivate(sourceRow + i, destinationChild + i); + } + } else { + if (!beginMoveRows(QModelIndex(), sourceRow, sourceRow + count - 1, QModelIndex(), destinationChild + 1)) { + return false; + } + for (int i = 0; i < count; i++) { + moveRowPrivate(sourceRow, destinationChild); + } + } + endMoveRows(); + return true; +} + bool UatModel::hasErrors() const { for (int i = 0; i < rowCount(); i++) { @@ -513,7 +583,7 @@ bool UatModel::checkField(int row, int col, char **error) const } char *str = NULL; - guint length; + unsigned length; field->cb.tostr(rec, &str, &length, field->cbdata.tostr, field->fld_data); bool ok = field->cb.chk(rec, str, length, field->cbdata.chk, field->fld_data, error); @@ -543,3 +613,20 @@ QList<int> UatModel::checkRow(int row) } return changed; } + +Qt::DropActions UatModel::supportedDropActions() const +{ + return Qt::MoveAction; +} + +bool UatModel::dropMimeData(const QMimeData *, Qt::DropAction, int, int, const QModelIndex &) +{ + // We could implement MimeData using uat_fld_tostr (or a new function + // that just gives the entire string) although it would be nice for + // uat_load_str to be able to load at a specified index, or else have + // a function to produce a UAT record from a string. Or we could use + // something else. However, for now we really just want internal moves. + // Supporting drop actions and rejecting drops still allows our row + // moving view's InternalMove to work. + return false; +} diff --git a/ui/qt/models/uat_model.h b/ui/qt/models/uat_model.h index 5da647a5..a24c938a 100644 --- a/ui/qt/models/uat_model.h +++ b/ui/qt/models/uat_model.h @@ -15,7 +15,6 @@ #define UAT_MODEL_H #include <config.h> -#include <glib.h> #include <QAbstractItemModel> #include <QList> @@ -24,6 +23,7 @@ class UatModel : public QAbstractTableModel { + Q_OBJECT public: UatModel(QObject *parent, uat_t *uat = 0); UatModel(QObject *parent, QString tableName); @@ -43,9 +43,13 @@ public: QModelIndex appendEntry(QVariantList row); QModelIndex copyRow(QModelIndex original); + bool moveRow(int src_row, int dst_row); + bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild); - bool moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild); + //Drag & drop functionality + Qt::DropActions supportedDropActions() const; + bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); void reloadUat(); bool hasErrors() const; @@ -74,9 +78,11 @@ private: bool checkField(int row, int col, char **error) const; QList<int> checkRow(int row); void loadUat(uat_t * uat = 0); + bool moveRowPrivate(int src_row, int dst_row); epan_uat *uat_; - QList<bool> dirty_records; - QList<QMap<int, QString> > record_errors; + bool applying_; + QVector<bool> dirty_records; + QVector<QMap<int, QString> > record_errors; }; #endif // UAT_MODEL_H diff --git a/ui/qt/models/voip_calls_info_model.cpp b/ui/qt/models/voip_calls_info_model.cpp index 23ba46f1..2f6d4f18 100644 --- a/ui/qt/models/voip_calls_info_model.cpp +++ b/ui/qt/models/voip_calls_info_model.cpp @@ -58,7 +58,7 @@ QVariant VoipCallsInfoModel::data(const QModelIndex &index, int role) const call_info->protocol_name : voip_protocol_name[call_info->protocol]; case Duration: { - guint callDuration = nstime_to_sec(&(call_info->stop_fd->abs_ts)) - nstime_to_sec(&(call_info->start_fd->abs_ts)); + unsigned callDuration = nstime_to_sec(&(call_info->stop_fd->abs_ts)) - nstime_to_sec(&(call_info->start_fd->abs_ts)); return QString("%1:%2:%3").arg(callDuration / 3600, 2, 10, QChar('0')).arg((callDuration % 3600) / 60, 2, 10, QChar('0')).arg(callDuration % 60, 2, 10, QChar('0')); } case Packets: @@ -82,14 +82,14 @@ QVariant VoipCallsInfoModel::data(const QModelIndex &index, int role) const case VOIP_H323: { h323_calls_info_t *h323_info = (h323_calls_info_t *)call_info->prot_info; - gboolean flag = FALSE; + bool flag = false; static const QString on_str = tr("On"); static const QString off_str = tr("Off"); if (call_info->call_state == VOIP_CALL_SETUP) { flag = h323_info->is_faststart_Setup; } else { if ((h323_info->is_faststart_Setup) && (h323_info->is_faststart_Proc)) { - flag = TRUE; + flag = true; } } return tr("Tunneling: %1 Fast Start: %2") @@ -202,7 +202,7 @@ void VoipCallsInfoModel::updateCalls(GQueue *callsinfos) // Add new rows cur_call = g_queue_peek_nth_link(callsinfos, rowCount()); - guint extra = g_list_length(cur_call); + unsigned extra = g_list_length(cur_call); if (extra > 0) { beginInsertRows(QModelIndex(), rowCount(), rowCount() + extra - 1); while (cur_call && cur_call->data) { diff --git a/ui/qt/models/voip_calls_info_model.h b/ui/qt/models/voip_calls_info_model.h index 2f8d4007..afb7ebe3 100644 --- a/ui/qt/models/voip_calls_info_model.h +++ b/ui/qt/models/voip_calls_info_model.h @@ -11,7 +11,6 @@ #define VOIP_CALLS_INFO_MODEL_H #include <config.h> -#include <glib.h> #include "ui/voip_calls.h" #include <ui/qt/utils/variant_pointer.h> |