From 1426c44281c2b266d7159340f7e75afc56141b18 Mon Sep 17 00:00:00 2001 From: Roland Knall Date: Wed, 21 Jun 2017 17:19:36 -0400 Subject: Qt: Context menu for toolbar filter buttons Adds a context menu for the toolbar filter buttons, which allows for opening the preference for the filter buttons, as well as direct edit, removal and disable functionality Change-Id: I5f2d132737c77804cf22834574dfe3c02f85fbdf Reviewed-on: https://code.wireshark.org/review/22327 Petri-Dish: Anders Broman Tested-by: Petri Dish Buildbot Reviewed-by: Roland Knall --- ui/qt/filter_expression_frame.cpp | 67 ++++++++++++++++++++++++++++++++---- ui/qt/filter_expression_frame.h | 4 +++ ui/qt/main_window.cpp | 4 +++ ui/qt/main_window.h | 6 ++++ ui/qt/main_window_slots.cpp | 71 +++++++++++++++++++++++++++++++++++++++ ui/qt/uat_model.cpp | 31 ++++++++++++++++- ui/qt/uat_model.h | 6 +++- 7 files changed, 180 insertions(+), 9 deletions(-) diff --git a/ui/qt/filter_expression_frame.cpp b/ui/qt/filter_expression_frame.cpp index 72e2ecf282..e1c22a6eb0 100644 --- a/ui/qt/filter_expression_frame.cpp +++ b/ui/qt/filter_expression_frame.cpp @@ -26,6 +26,8 @@ #include #include +#include + #include // To do: @@ -42,6 +44,8 @@ FilterExpressionFrame::FilterExpressionFrame(QWidget *parent) : w->setAttribute(Qt::WA_MacSmallSize, true); } #endif + + editExpression_ = -1; } FilterExpressionFrame::~FilterExpressionFrame() @@ -56,9 +60,36 @@ void FilterExpressionFrame::addExpression(const QString filter_text) return; } + editExpression_ = -1; ui->displayFilterLineEdit->setText(filter_text); } +void FilterExpressionFrame::editExpression(int exprIdx) +{ + if (isVisible()) + { + ui->labelLineEdit->clear(); + ui->displayFilterLineEdit->clear(); + ui->commentLineEdit->clear(); + editExpression_ = -1; + } + + UatModel * uatModel = new UatModel(this, "Display expressions"); + if ( ! uatModel->index(exprIdx, 1).isValid() ) + return; + + editExpression_ = exprIdx; + + ui->labelLineEdit->setText(uatModel->data(uatModel->index(exprIdx, 1), Qt::DisplayRole).toString()); + ui->displayFilterLineEdit->setText(uatModel->data(uatModel->index(exprIdx, 2), Qt::DisplayRole).toString()); + ui->commentLineEdit->setText(uatModel->data(uatModel->index(exprIdx, 3), Qt::DisplayRole).toString()); + + delete(uatModel); + + if (! isVisible()) + animatedShow(); +} + void FilterExpressionFrame::showEvent(QShowEvent *event) { ui->labelLineEdit->setFocus(); @@ -69,11 +100,10 @@ void FilterExpressionFrame::showEvent(QShowEvent *event) void FilterExpressionFrame::updateWidgets() { - bool ok_enable = false; + bool ok_enable = true; - if (!ui->labelLineEdit->text().isEmpty()) { - ok_enable = true; - } + if (ui->labelLineEdit->text().isEmpty() || ui->displayFilterLineEdit->text().isEmpty()) + ok_enable = false; ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ok_enable); } @@ -89,6 +119,11 @@ void FilterExpressionFrame::on_labelLineEdit_textChanged(const QString) updateWidgets(); } +void FilterExpressionFrame::on_displayFilterLineEdit_textChanged(const QString) +{ + updateWidgets(); +} + void FilterExpressionFrame::on_buttonBox_accepted() { gchar* err = NULL; @@ -96,15 +131,31 @@ void FilterExpressionFrame::on_buttonBox_accepted() QByteArray expr_ba = ui->displayFilterLineEdit->text().toUtf8(); QByteArray comment_ba = ui->commentLineEdit->text().toUtf8(); - if ( ui->labelLineEdit->text().length() == 0 ) + if ( ui->labelLineEdit->text().length() == 0 || ui->displayFilterLineEdit->text().length() == 0 ) + return; + + if ( ! ui->displayFilterLineEdit->checkFilter() ) return; - filter_expression_new(label_ba.constData(), expr_ba.constData(), comment_ba.constData(), TRUE); + if ( editExpression_ >= 0 ) + { + UatModel * uatModel = new UatModel(this, "Display expressions"); + if ( ! uatModel->index(editExpression_, 1).isValid() ) + return; + + uatModel->setData(uatModel->index(editExpression_, 1), QVariant::fromValue(label_ba)); + uatModel->setData(uatModel->index(editExpression_, 2), QVariant::fromValue(expr_ba)); + uatModel->setData(uatModel->index(editExpression_, 3), QVariant::fromValue(comment_ba)); + } + else + { + filter_expression_new(label_ba.constData(), expr_ba.constData(), comment_ba.constData(), TRUE); + } + uat_save(uat_get_table_by_name("Display expressions"), &err); on_buttonBox_rejected(); emit filterExpressionsChanged(); - uat_save(uat_get_table_by_name("Display expressions"), &err); g_free(err); } @@ -112,6 +163,8 @@ void FilterExpressionFrame::on_buttonBox_rejected() { ui->labelLineEdit->clear(); ui->displayFilterLineEdit->clear(); + ui->commentLineEdit->clear(); + editExpression_ = -1; animatedHide(); } diff --git a/ui/qt/filter_expression_frame.h b/ui/qt/filter_expression_frame.h index 2d65f9a596..63293bc241 100644 --- a/ui/qt/filter_expression_frame.h +++ b/ui/qt/filter_expression_frame.h @@ -38,6 +38,7 @@ public: ~FilterExpressionFrame(); void addExpression(const QString filter_text); + void editExpression(int exprIdx); signals: void showPreferencesDialog(PreferencesDialog::PreferencesPane start_pane); @@ -49,10 +50,13 @@ protected: private: Ui::FilterExpressionFrame *ui; + int editExpression_; + private slots: void updateWidgets(); void on_filterExpressionPreferencesPushButton_clicked(); void on_labelLineEdit_textChanged(const QString); + void on_displayFilterLineEdit_textChanged(const QString); void on_buttonBox_accepted(); void on_buttonBox_rejected(); }; diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp index dbbf0576ee..5d7ac14741 100644 --- a/ui/qt/main_window.cpp +++ b/ui/qt/main_window.cpp @@ -462,6 +462,10 @@ MainWindow::MainWindow(QWidget *parent) : // https://bugreports.qt.io/browse/QTBUG-2472 filter_expression_toolbar_ = new QToolBar(); filter_expression_toolbar_->setStyleSheet("QToolBar { background: none; border: none; }"); + filter_expression_toolbar_->setContextMenuPolicy(Qt::CustomContextMenu); + connect(filter_expression_toolbar_, SIGNAL(customContextMenuRequested(QPoint)), + this, SLOT(filterToolbarCustomMenuHandler(QPoint))); + main_ui_->displayFilterToolBar->addWidget(filter_expression_toolbar_); wireless_frame_ = new WirelessFrame(this); diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h index a3509219e6..55e3407add 100644 --- a/ui/qt/main_window.h +++ b/ui/qt/main_window.h @@ -345,6 +345,12 @@ private slots: QMenu * searchSubMenu(QString objectName); void activatePluginIFToolbar(bool); + void filterToolbarCustomMenuHandler(const QPoint& globalPos); + void filterToolbarShowPreferences(); + void filterToolbarEditFilter(); + void filterToolbarDisableFilter(); + void filterToolbarRemoveFilter(); + void startInterfaceCapture(bool valid, const QString capture_filter); void applyGlobalCommandLineOptions(); diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index a6abdb4956..d5b87758e7 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -4041,6 +4041,77 @@ void MainWindow::activatePluginIFToolbar(bool) } } +void MainWindow::filterToolbarCustomMenuHandler(const QPoint& pos) +{ + QAction * filterAction = filter_expression_toolbar_->actionAt(pos); + if ( ! filterAction ) + return; + + QMenu * filterMenu = new QMenu(this); + + QAction *actFilter = filterMenu->addAction(tr("Filter Preferences...")); + connect(actFilter, SIGNAL(triggered()), this, SLOT(filterToolbarShowPreferences())); + actFilter->setData(filterAction->data()); + filterMenu->addSeparator(); + QAction * actEdit = filterMenu->addAction(tr("Edit Filter")); + connect(actEdit, SIGNAL(triggered()), this, SLOT(filterToolbarEditFilter())); + actEdit->setData(filterAction->data()); + QAction * actDisable = filterMenu->addAction(tr("Disable Filter")); + connect(actDisable, SIGNAL(triggered()), this, SLOT(filterToolbarDisableFilter())); + actDisable->setData(filterAction->data()); + QAction * actRemove = filterMenu->addAction(tr("Remove Filter")); + connect(actRemove, SIGNAL(triggered()), this, SLOT(filterToolbarRemoveFilter())); + actRemove->setData(filterAction->data()); + + filterMenu->exec(filter_expression_toolbar_->mapToGlobal(pos)); +} + +void MainWindow::filterToolbarShowPreferences() +{ + emit showPreferencesDialog(PreferencesDialog::ppFilterExpressions); +} + +void MainWindow::filterToolbarEditFilter() +{ + UatModel * uatModel = new UatModel(this, "Display expressions"); + + QModelIndex rowIndex = uatModel->findRowForColumnContent(((QAction *)sender())->data(), 2); + if ( rowIndex.isValid() ) + main_ui_->filterExpressionFrame->editExpression(rowIndex.row()); + + delete uatModel; +} + +void MainWindow::filterToolbarDisableFilter() +{ + gchar* err = NULL; + UatModel * uatModel = new UatModel(this, "Display expressions"); + + QModelIndex rowIndex = uatModel->findRowForColumnContent(((QAction *)sender())->data(), 2); + if ( rowIndex.isValid() ) { + uatModel->setData(uatModel->index(rowIndex.row(), 0), QVariant::fromValue(false)); + + uat_save(uat_get_table_by_name("Display expressions"), &err); + g_free(err); + filterExpressionsChanged(); + } +} + +void MainWindow::filterToolbarRemoveFilter() +{ + gchar* err = NULL; + UatModel * uatModel = new UatModel(this, "Display expressions"); + + QModelIndex rowIndex = uatModel->findRowForColumnContent(((QAction *)sender())->data(), 2); + if ( rowIndex.isValid() ) { + uatModel->removeRow(rowIndex.row()); + + uat_save(uat_get_table_by_name("Display expressions"), &err); + g_free(err); + filterExpressionsChanged(); + } +} + #ifdef _MSC_VER #pragma warning(pop) #endif diff --git a/ui/qt/uat_model.cpp b/ui/qt/uat_model.cpp index c5310f3a07..fe56a18441 100644 --- a/ui/qt/uat_model.cpp +++ b/ui/qt/uat_model.cpp @@ -29,8 +29,22 @@ UatModel::UatModel(QObject *parent, epan_uat *uat) : QAbstractTableModel(parent), - uat_(uat) + uat_(0) { + loadUat(uat); +} + +UatModel::UatModel(QObject * parent, QString tableName) : + QAbstractTableModel(parent), + uat_(0) +{ + loadUat(uat_get_table_by_name(tableName.toStdString().c_str())); +} + +void UatModel::loadUat(epan_uat * uat) +{ + uat_ = uat; + dirty_records.reserve(uat_->raw_data->len); // Validate existing data such that they can be marked as invalid if necessary. record_errors.reserve(uat_->raw_data->len); @@ -124,6 +138,21 @@ QVariant UatModel::data(const QModelIndex &index, int role) const return QVariant(); } +QModelIndex UatModel::findRowForColumnContent(QVariant columnContent, int columnToCheckAgainst, int role) +{ + if (! columnContent.isValid()) + return QModelIndex(); + + for(int i = 0; i < rowCount(); i++) + { + QVariant r_expr = data(index(i, columnToCheckAgainst), role); + if ( r_expr == columnContent ) + return index(i, columnToCheckAgainst); + } + + return QModelIndex(); +} + QVariant UatModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole || orientation != Qt::Horizontal) diff --git a/ui/qt/uat_model.h b/ui/qt/uat_model.h index 36e79ebf83..c52646d7c3 100644 --- a/ui/qt/uat_model.h +++ b/ui/qt/uat_model.h @@ -38,7 +38,8 @@ class UatModel : public QAbstractTableModel Q_OBJECT public: - UatModel(QObject *parent = 0, epan_uat *uat = 0); + UatModel(QObject *parent, uat_t *uat = 0); + UatModel(QObject *parent, QString tableName); Qt::ItemFlags flags(const QModelIndex &index) const; QVariant data(const QModelIndex &index, int role) const; @@ -55,9 +56,12 @@ public: bool copyRow(int dst_row, int src_row); bool hasErrors() const; + QModelIndex findRowForColumnContent(QVariant columnContent, int columnToCheckAgainst, int role = Qt::DisplayRole); + private: bool checkField(int row, int col, char **error) const; QList checkRow(int row); + void loadUat(uat_t * uat = 0); epan_uat *uat_; QList dirty_records; -- cgit v1.2.1