aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Knall <rknall@gmail.com>2019-10-25 15:29:54 +0200
committerRoland Knall <rknall@gmail.com>2019-10-28 15:08:06 +0000
commit2cccb26bc40dfeb0af8b41582690f72811c750df (patch)
tree85275b53fe0cfffe277def68361f86245bb81806
parentf577d5b3ea0c277bc15168f563a2f2fdd0b87c40 (diff)
Qt: Implement FilterListModel
Change-Id: I365281a709ded644fc8d6ccfce5870a000221a3b Reviewed-on: https://code.wireshark.org/review/34856 Petri-Dish: Roland Knall <rknall@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Roland Knall <rknall@gmail.com>
-rw-r--r--ui/qt/CMakeLists.txt2
-rw-r--r--ui/qt/filter_dialog.cpp169
-rw-r--r--ui/qt/filter_dialog.h28
-rw-r--r--ui/qt/filter_dialog.ui28
-rw-r--r--ui/qt/models/filter_list_model.cpp256
-rw-r--r--ui/qt/models/filter_list_model.h77
6 files changed, 431 insertions, 129 deletions
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index de20413198..b843766756 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -80,6 +80,7 @@ set(WIRESHARK_MODEL_HEADERS
models/expert_info_proxy_model.h
models/export_objects_model.h
models/fileset_entry_model.h
+ models/filter_list_model.h
models/info_proxy_model.h
models/interface_sort_filter_model.h
models/interface_tree_cache_model.h
@@ -308,6 +309,7 @@ set(WIRESHARK_MODEL_SRCS
models/expert_info_proxy_model.cpp
models/export_objects_model.cpp
models/fileset_entry_model.cpp
+ models/filter_list_model.cpp
models/info_proxy_model.cpp
models/interface_sort_filter_model.cpp
models/interface_tree_cache_model.cpp
diff --git a/ui/qt/filter_dialog.cpp b/ui/qt/filter_dialog.cpp
index 98985baa92..cc7e87a3f7 100644
--- a/ui/qt/filter_dialog.cpp
+++ b/ui/qt/filter_dialog.cpp
@@ -23,10 +23,10 @@
#include <QMessageBox>
#include <QThread>
#include <QUrl>
+#include <QSortFilterProxyModel>
#include <ui/qt/utils/qt_ui_utils.h>
#include <ui/qt/widgets/capture_filter_edit.h>
-//#include "capture_filter_syntax_worker.h"
#include <ui/qt/widgets/display_filter_edit.h>
#include "wireshark_application.h"
@@ -41,15 +41,14 @@ enum {
filter_col_
};
-FilterDialog::FilterDialog(QWidget *parent, FilterType filter_type, const QString new_filter) :
+FilterDialog::FilterDialog(QWidget *parent, FilterType filter_type, QString new_filter_) :
GeometryStateDialog(parent),
ui(new Ui::FilterDialog),
filter_type_(filter_type),
-// syntax_worker_(NULL),
- filter_tree_delegate_(new FilterTreeDelegate(this, filter_type)),
- new_filter_(new_filter)
+ filter_tree_delegate_(new FilterTreeDelegate(this, filter_type))
{
ui->setupUi(this);
+
if (parent) loadGeometry(parent->width() * 2 / 3, parent->height() * 2 / 3);
setWindowIcon(wsApp->normalIcon());
@@ -64,30 +63,40 @@ FilterDialog::FilterDialog(QWidget *parent, FilterType filter_type, const QStrin
ui->pathLabel->setAttribute(Qt::WA_MacSmallSize, true);
#endif
+#if 0
ui->filterTreeWidget->setDragEnabled(true);
ui->filterTreeWidget->viewport()->setAcceptDrops(true);
ui->filterTreeWidget->setDropIndicatorShown(true);
ui->filterTreeWidget->setDragDropMode(QAbstractItemView::InternalMove);
+#endif
const gchar * filename = NULL;
+ QString newFilterText;
if (filter_type == CaptureFilter) {
setWindowTitle(wsApp->windowTitleString(tr("Capture Filters")));
filename = CFILTER_FILE_NAME;
-
-// QThread *syntax_thread = new QThread;
-// syntax_worker_ = new CaptureFilterSyntaxWorker;
-// syntax_worker_->moveToThread(syntax_thread);
-// connect(syntax_thread, SIGNAL(started()), syntax_worker_, SLOT(start()));
-// // connect(syntax_thread, SIGNAL(started()), this, SLOT(checkFilter()));
-// connect(syntax_worker_, SIGNAL(syntaxResult(QString, bool, QString)),
-// this, SLOT(setFilterSyntaxState(QString, bool, QString)));
-// connect(syntax_thread, SIGNAL(finished()), syntax_worker_, SLOT(deleteLater()));
-// syntax_thread->start();
+ newFilterText = tr("New capture filter");
+ model_ = new FilterListModel(FilterListModel::Capture, this);
} else {
setWindowTitle(wsApp->windowTitleString(tr("Display Filters")));
filename = DFILTER_FILE_NAME;
+ newFilterText = tr("New display filter");
+ model_ = new FilterListModel(FilterListModel::Display, this);
}
+ if ( new_filter_.length() > 0 )
+ model_->addFilter(newFilterText, new_filter_);
+
+ sortModel_ = new QSortFilterProxyModel(this);
+ sortModel_->setSourceModel(model_);
+ ui->filterTreeView->setModel(sortModel_);
+
+ ui->filterTreeView->setItemDelegate(new FilterTreeDelegate(this, filter_type));
+
+ ui->filterTreeView->resizeColumnToContents(FilterListModel::ColumnName);
+
+ connect( ui->filterTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &FilterDialog::selectionChanged );
+
QString abs_path = gchar_free_to_qstring(get_persconffile_path(filename, TRUE));
if (file_exists(abs_path.toUtf8().constData())) {
ui->pathLabel->setText(abs_path);
@@ -95,8 +104,6 @@ FilterDialog::FilterDialog(QWidget *parent, FilterType filter_type, const QStrin
ui->pathLabel->setToolTip(tr("Open ") + filename);
ui->pathLabel->setEnabled(true);
}
-
- ui->filterTreeWidget->setItemDelegateForColumn(filter_col_, filter_tree_delegate_);
}
FilterDialog::~FilterDialog()
@@ -104,64 +111,28 @@ FilterDialog::~FilterDialog()
delete ui;
}
-void FilterDialog::showEvent(QShowEvent *event)
-{
- ui->filterTreeWidget->clear();
-
- GList *filter_list;
- if (filter_type_ == CaptureFilter) {
- filter_list = get_filter_list_first(CFILTER_LIST);
- } else {
- filter_list = get_filter_list_first(DFILTER_LIST);
- }
- for (GList *fl_item = filter_list; fl_item; fl_item = gxx_list_next(fl_item)) {
- if (!fl_item->data) continue;
- filter_def *fl_data = gxx_list_data(filter_def *, fl_item);
- if (!fl_data->name || !fl_data->strval) continue;
-
- addFilter(fl_data->name, fl_data->strval);
- }
-
- if (!new_filter_.isEmpty()) {
- addFilter(tr("New filter"), new_filter_, true);
- new_filter_.clear();
- }
-
- ui->filterTreeWidget->resizeColumnToContents(name_col_);
- ui->filterTreeWidget->resizeColumnToContents(filter_col_);
-
- QDialog::showEvent(event);
-}
-
void FilterDialog::addFilter(QString name, QString filter, bool start_editing)
{
- QTreeWidgetItem *ti = new QTreeWidgetItem(ui->filterTreeWidget);
- ti->setFlags(ti->flags() | Qt::ItemIsEditable);
- ti->setFlags(ti->flags() & ~(Qt::ItemIsDropEnabled));
- ti->setText(name_col_, name);
- ti->setText(filter_col_, filter);
-
- if (start_editing) {
- ui->filterTreeWidget->setCurrentItem(ti);
- updateWidgets();
- ui->filterTreeWidget->editItem(ti, filter_col_);
+ if ( model_ )
+ {
+ QModelIndex idx = model_->addFilter(name, filter);
+ if ( start_editing )
+ ui->filterTreeView->edit(sortModel_->mapFromSource(idx));
}
}
void FilterDialog::updateWidgets()
{
- int num_selected = ui->filterTreeWidget->selectedItems().count();
+ if ( ! ui->filterTreeView->selectionModel() )
+ return;
+
+ int num_selected = ui->filterTreeView->selectionModel()->selectedRows().count();
ui->copyToolButton->setEnabled(num_selected == 1);
ui->deleteToolButton->setEnabled(num_selected > 0);
}
-//void FilterDialog::setFilterSyntaxState(QString filter, bool valid, QString err_msg)
-//{
-
-//}
-
-void FilterDialog::on_filterTreeWidget_itemSelectionChanged()
+void FilterDialog::selectionChanged(const QItemSelection &/*selected*/, const QItemSelection &/*deselected*/)
{
updateWidgets();
}
@@ -186,36 +157,34 @@ void FilterDialog::on_newToolButton_clicked()
void FilterDialog::on_deleteToolButton_clicked()
{
- QList<QTreeWidgetItem*> selected = ui->filterTreeWidget->selectedItems();
- foreach (QTreeWidgetItem *ti, selected) {
- delete ti;
+ QModelIndexList selected = ui->filterTreeView->selectionModel()->selectedRows();
+ QList<int> rows;
+ foreach ( QModelIndex idx, selected )
+ {
+ QModelIndex original = sortModel_->mapToSource(idx);
+ if ( original.isValid() && ! rows.contains(original.row()) )
+ {
+ rows << original.row();
+ model_->removeFilter(original);
+ }
}
}
void FilterDialog::on_copyToolButton_clicked()
{
- if (!ui->filterTreeWidget->currentItem()) return;
- QTreeWidgetItem *ti = ui->filterTreeWidget->currentItem();
+ QModelIndexList selected = ui->filterTreeView->selectionModel()->selectedRows();
+ if ( selected.count() <= 0 )
+ return;
+
+ int rowNr = selected.at(0).row();
+ QModelIndex row = selected.at(0).sibling(rowNr, FilterListModel::ColumnName);
- addFilter(ti->text(name_col_), ti->text(filter_col_), true);
+ addFilter(row.data().toString(), row.sibling(rowNr, FilterListModel::ColumnExpression).data().toString(), true);
}
void FilterDialog::on_buttonBox_accepted()
{
- filter_list_type_t fl_type = filter_type_ == CaptureFilter ? CFILTER_LIST : DFILTER_LIST;
-
- while (GList *fl_item = get_filter_list_first(fl_type)) {
- remove_from_filter_list(fl_type, fl_item);
- }
-
- QTreeWidgetItemIterator it(ui->filterTreeWidget);
- while (*it) {
- add_to_filter_list(fl_type, (*it)->text(name_col_).toUtf8().constData(),
- (*it)->text(filter_col_).toUtf8().constData());
- ++it;
- }
-
- save_filter_list(fl_type);
+ model_->saveList();
if (filter_type_ == CaptureFilter) {
wsApp->emitAppSignal(WiresharkApplication::CaptureFilterListChanged);
@@ -238,23 +207,41 @@ void FilterDialog::on_buttonBox_helpRequested()
// Delegate for editing capture and display filters.
//
+FilterTreeDelegate::FilterTreeDelegate(QObject *parent, FilterDialog::FilterType filter_type) :
+ QStyledItemDelegate(parent),
+ filter_type_(filter_type)
+{}
+
+
QWidget *FilterTreeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
+ QWidget * w = Q_NULLPTR;
if (index.column() != filter_col_) {
- return QStyledItemDelegate::createEditor(parent, option, index);
+ w = QStyledItemDelegate::createEditor(parent, option, index);
}
-
- QWidget *w;
-
- if (filter_type_ == FilterDialog::CaptureFilter) {
- w = new CaptureFilterEdit(parent, true);
- } else {
- w = new DisplayFilterEdit(parent, DisplayFilterToEnter);
+ else
+ {
+ if (filter_type_ == FilterDialog::CaptureFilter) {
+ w = new CaptureFilterEdit(parent, true);
+ } else {
+ w = new DisplayFilterEdit(parent, DisplayFilterToEnter);
+ }
}
return w;
}
+void FilterTreeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+ if ( ! editor || ! index.isValid() )
+ return;
+
+ QStyledItemDelegate::setEditorData(editor, index);
+
+ if ( qobject_cast<QLineEdit *>(editor) )
+ qobject_cast<QLineEdit *>(editor)->setText(index.data().toString());
+}
+
/*
* Editor modelines
*
diff --git a/ui/qt/filter_dialog.h b/ui/qt/filter_dialog.h
index 323d17ae31..e2dc8fa1e1 100644
--- a/ui/qt/filter_dialog.h
+++ b/ui/qt/filter_dialog.h
@@ -12,7 +12,10 @@
#include "geometry_state_dialog.h"
-//class CaptureFilterSyntaxWorker;
+#include <ui/qt/models/filter_list_model.h>
+
+class QSortFilterProxyModel;
+class QItemSelection;
class FilterTreeDelegate;
namespace Ui {
@@ -28,24 +31,22 @@ public:
explicit FilterDialog(QWidget *parent = 0, FilterType filter_type = CaptureFilter, const QString new_filter = QString());
~FilterDialog();
-protected:
- void showEvent(QShowEvent * event);
-
private:
Ui::FilterDialog *ui;
+ FilterListModel * model_;
+ QSortFilterProxyModel * sortModel_;
+
enum FilterType filter_type_;
-// CaptureFilterSyntaxWorker *syntax_worker_;
FilterTreeDelegate *filter_tree_delegate_;
- QString new_filter_;
void addFilter(QString name, QString filter, bool start_editing = false);
private slots:
void updateWidgets();
-// void setFilterSyntaxState(QString filter, bool valid, QString err_msg);
- void on_filterTreeWidget_itemSelectionChanged();
+ void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+
void on_newToolButton_clicked();
void on_deleteToolButton_clicked();
void on_copyToolButton_clicked();
@@ -66,18 +67,13 @@ class FilterTreeDelegate : public QStyledItemDelegate
Q_OBJECT
public:
- FilterTreeDelegate(QObject *parent, FilterDialog::FilterType filter_type) :
- QStyledItemDelegate(parent),
- filter_type_(filter_type)
- {}
- ~FilterTreeDelegate() {}
+ FilterTreeDelegate(QObject *parent, FilterDialog::FilterType filter_type);
- QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
+ virtual void setEditorData(QWidget *editor, const QModelIndex &index) const override;
private:
FilterDialog::FilterType filter_type_;
-
-private slots:
};
#endif // FILTER_DIALOG_H
diff --git a/ui/qt/filter_dialog.ui b/ui/qt/filter_dialog.ui
index c01a6eff76..4856be13fd 100644
--- a/ui/qt/filter_dialog.ui
+++ b/ui/qt/filter_dialog.ui
@@ -15,29 +15,13 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QTreeWidget" name="filterTreeWidget">
- <property name="selectionMode">
- <enum>QAbstractItemView::ExtendedSelection</enum>
+ <widget class="QTreeView" name="filterTreeView">
+ <property name="sortingEnabled">
+ <bool>true</bool>
</property>
- <property name="textElideMode">
- <enum>Qt::ElideMiddle</enum>
- </property>
- <property name="indentation">
- <number>0</number>
- </property>
- <property name="rootIsDecorated">
- <bool>false</bool>
- </property>
- <column>
- <property name="text">
- <string>Name</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Filter</string>
- </property>
- </column>
+ <attribute name="headerShowSortIndicator" stdset="0">
+ <bool>true</bool>
+ </attribute>
</widget>
</item>
<item>
diff --git a/ui/qt/models/filter_list_model.cpp b/ui/qt/models/filter_list_model.cpp
new file mode 100644
index 0000000000..ba75128b56
--- /dev/null
+++ b/ui/qt/models/filter_list_model.cpp
@@ -0,0 +1,256 @@
+/* filter_list_model.cpp
+ * Model for all filter types
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <glib.h>
+
+#include <wsutil/filesystem.h>
+
+#include <ui/qt/utils/qt_ui_utils.h>
+#include <ui/qt/models/filter_list_model.h>
+#include <ui/qt/models/profile_model.h>
+
+#include <QFile>
+#include <QTextStream>
+#include <QRegExp>
+#include <QDir>
+
+/*
+ * Old filter file name.
+ */
+#define FILTER_FILE_NAME "filters"
+
+/*
+ * Capture filter file name.
+ */
+#define CFILTER_FILE_NAME "cfilters"
+
+/*
+ * Display filter file name.
+ */
+#define DFILTER_FILE_NAME "dfilters"
+
+FilterListModel::FilterListModel(QObject * parent) :
+ QAbstractListModel(parent),
+ type_(FilterListModel::Display)
+{
+ reload();
+}
+
+FilterListModel::FilterListModel(FilterListModel::FilterListType type, QObject * parent) :
+ QAbstractListModel(parent),
+ type_(type)
+{
+ reload();
+}
+
+void FilterListModel::reload()
+{
+ QFile file;
+
+ storage.clear();
+
+ /* Try personal config file first */
+ file.setFileName(qstring_strdup(get_persconffile_path(FilterListModel::Capture ? CFILTER_FILE_NAME : DFILTER_FILE_NAME, TRUE)));
+ /* Try personal old-style config file next */
+ if ( ! file.exists() )
+ file.setFileName(qstring_strdup(get_persconffile_path(FILTER_FILE_NAME, TRUE)));
+ /* Last but not least, try the global file */
+ if ( ! file.exists() )
+ file.setFileName(qstring_strdup(get_datafile_path(FilterListModel::Capture ? CFILTER_FILE_NAME : DFILTER_FILE_NAME)));
+
+ /* Still can use the model, just have to start from an empty set */
+ if ( ! file.exists() || ! file.open(QIODevice::ReadOnly | QIODevice::Text) )
+ return;
+
+ QTextStream in(&file);
+ QRegExp rx("\\s*\\\"(.*)\\\"\\s(.*)");
+ while (!in.atEnd())
+ {
+ QString line = in.readLine().trimmed();
+ if ( line.startsWith("#") || line.indexOf("\"") <= -1 )
+ continue;
+
+ rx.indexIn(line);
+ QStringList groups = rx.capturedTexts();
+ if ( groups.count() != 3 )
+ continue;
+ addFilter(groups.at(1), groups.at(2));
+ }
+}
+
+void FilterListModel::setFilterType(FilterListModel::FilterListType type)
+{
+ type_ = type;
+ reload();
+}
+
+FilterListModel::FilterListType FilterListModel::filterType() const
+{
+ return type_;
+}
+
+int FilterListModel::rowCount(const QModelIndex &/* parent */) const
+{
+ return storage.count();
+}
+
+int FilterListModel::columnCount(const QModelIndex &/* parent */) const
+{
+ return 2;
+}
+
+QVariant FilterListModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if ( section >= columnCount() || section < 0 || orientation != Qt::Horizontal )
+ return QVariant();
+
+ if ( role == Qt::DisplayRole )
+ {
+ switch ( section ) {
+ case ColumnName:
+ return tr("Filter Name");
+ break;
+ case ColumnExpression:
+ return tr("Filter Expression");
+ break;
+ }
+ }
+
+ return QVariant();
+}
+
+QVariant FilterListModel::data(const QModelIndex &index, int role) const
+{
+ if ( ! index.isValid() || index.row() >= rowCount() )
+ return QVariant();
+
+ QStringList row = storage.at(index.row()).split("\n");
+ if ( role == Qt::DisplayRole )
+ return row.at(index.column());
+
+ return QVariant();
+}
+
+bool FilterListModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if ( ! index.isValid() || index.row() >= rowCount() || role != Qt::EditRole )
+ return false;
+
+ QStringList row = storage.at(index.row()).split("\n");
+ if ( row.count() <= index.column() )
+ return false;
+
+ row[index.column()] = value.toString();
+ storage[index.row()] = row.join("\n");
+
+ return true;
+}
+
+Qt::ItemFlags FilterListModel::flags(const QModelIndex &index) const
+{
+ Qt::ItemFlags fl = QAbstractListModel::flags(index);
+ if ( ! index.isValid() || index.row() >= rowCount() )
+ return fl;
+
+ QStringList row = storage.at(index.row()).split("\n");
+
+ fl |= Qt::ItemIsEditable;
+
+ return fl;
+}
+QModelIndex FilterListModel::addFilter(QString name, QString expression)
+{
+ if ( name.length() == 0 || expression.length() == 0 )
+ return QModelIndex();
+
+ beginInsertRows(QModelIndex(), rowCount(), rowCount());
+ storage << QString("%1\n%2").arg(name).arg(expression);
+ endInsertRows();
+
+ return index(rowCount() - 1, 0);
+}
+
+QModelIndex FilterListModel::findByName(QString name)
+{
+ if ( name.length() == 0 )
+ return QModelIndex();
+
+ for ( int cnt = 0; cnt < rowCount(); cnt++ )
+ {
+ if ( storage.at(cnt).startsWith(QString("%1\n").arg(name)) )
+ return index(cnt, 0);
+ }
+
+ return QModelIndex();
+}
+
+QModelIndex FilterListModel::findByExpression(QString expression)
+{
+ if ( expression.length() == 0 )
+ return QModelIndex();
+
+ for ( int cnt = 0; cnt < rowCount(); cnt++ )
+ {
+ if ( storage.at(cnt).endsWith(QString("\n%1").arg(expression)) )
+ return index(cnt, 0);
+ }
+
+ return QModelIndex();
+}
+
+void FilterListModel::removeFilter(QModelIndex idx)
+{
+ if ( ! idx.isValid() || idx.row() >= rowCount() )
+ return;
+
+ beginRemoveRows(QModelIndex(), idx.row(), idx.row());
+ storage.removeAt(idx.row());
+ endRemoveRows();
+}
+
+void FilterListModel::saveList()
+{
+ QString filename = FilterListModel::Capture ? CFILTER_FILE_NAME : DFILTER_FILE_NAME;
+
+ filename = QString("%1%2%3").arg(ProfileModel::activeProfilePath()).arg(QDir::separator()).arg(filename);
+ QFile file(filename);
+
+ if ( ! file.open(QIODevice::WriteOnly | QIODevice::Text) )
+ return;
+
+ QTextStream out(&file);
+ for ( int row = 0; row < rowCount(); row++ )
+ {
+ QString line = QString("\"%1\"").arg(index(row, ColumnName).data().toString().replace("\\", "\\\\").replace("\"", "\\\""));
+ line.append(QString(" %1").arg(index(row, ColumnExpression).data().toString()));
+
+#ifdef _WIN32
+ line = line.append("\r\n");
+#else
+ line = line.append("\n");
+#endif
+ out << line;
+ }
+
+ file.close();
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local Variables:
+ * c-basic-offset: 2
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=2 tabstop=8 expandtab:
+ * :indentSize=2:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/models/filter_list_model.h b/ui/qt/models/filter_list_model.h
new file mode 100644
index 0000000000..8050609a72
--- /dev/null
+++ b/ui/qt/models/filter_list_model.h
@@ -0,0 +1,77 @@
+/* filter_list_model.h
+ * Model for all filter types
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef FILTER_LIST_MODEL_h
+#define FILTER_LIST_MODEL_h
+
+#include <config.h>
+
+#include <QAbstractListModel>
+#include <QList>
+#include <QStringList>
+
+class FilterListModel : public QAbstractListModel
+{
+
+public:
+ enum FilterListType {
+ Display,
+ Capture
+ };
+
+ explicit FilterListModel(FilterListType type = FilterListModel::Display, QObject * parent = Q_NULLPTR);
+ explicit FilterListModel(QObject * parent = Q_NULLPTR);
+
+ enum {
+ ColumnName,
+ ColumnExpression
+ };
+
+ void setFilterType(FilterListModel::FilterListType type);
+ FilterListModel::FilterListType filterType() const;
+
+ QModelIndex findByName(QString name);
+ QModelIndex findByExpression(QString expression);
+
+ QModelIndex addFilter(QString name, QString expression);
+ void removeFilter(QModelIndex idx);
+
+ void saveList();
+
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
+
+private:
+
+ FilterListModel::FilterListType type_;
+
+ QStringList storage;
+
+ void reload();
+};
+
+#endif // FILTER_LIST_MODEL_h
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */