forked from osmocom/wireshark
Add a Busy status to SyntaxLineEdit.
For CaptureFilterEdit it's possible to have an indeterminate state while we're waiting on name resolution. Add a Busy status to SyntaxLineEdit and set the text color to a mix of the normal foreground and background colors (gray on most platforms). Make the Busy state valid so that we don't have to wait on an annoyingly-long name resolution to start capturing. Update the global capture option filters using the main welcome capture filter when we start a capture instead of when we've finished checking the filter syntax. Connect the CaptureFilterEdit returnPressed signal no matter what so that we can start a capture by pressing return in the welcome screen CaptureFilterEdit. Add a fake resolution timeout to the CaptureFilterSyntaxWorker debug code to make testing the different states easier. Bug: 11950 Change-Id: I0cf01c0fbc0dd8065cdf5a91f1d6b224291b1ce6 Reviewed-on: https://code.wireshark.org/review/13110 Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Gerald Combs <gerald@wireshark.org>
This commit is contained in:
parent
35a79ffebb
commit
0ce9ac4137
|
@ -176,8 +176,8 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
|
||||||
"}"
|
"}"
|
||||||
);
|
);
|
||||||
connect(apply_button_, SIGNAL(clicked()), this, SLOT(applyCaptureFilter()));
|
connect(apply_button_, SIGNAL(clicked()), this, SLOT(applyCaptureFilter()));
|
||||||
connect(this, SIGNAL(returnPressed()), this, SLOT(applyCaptureFilter()));
|
|
||||||
}
|
}
|
||||||
|
connect(this, SIGNAL(returnPressed()), this, SLOT(applyCaptureFilter()));
|
||||||
|
|
||||||
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||||
QSize bksz;
|
QSize bksz;
|
||||||
|
@ -267,11 +267,11 @@ void CaptureFilterEdit::resizeEvent(QResizeEvent *)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureFilterEdit::checkFilter(const QString& text)
|
void CaptureFilterEdit::checkFilter(const QString& filter)
|
||||||
{
|
{
|
||||||
setSyntaxState(Empty);
|
setSyntaxState(Busy);
|
||||||
popFilterSyntaxStatus();
|
popFilterSyntaxStatus();
|
||||||
bool empty = text.isEmpty();
|
bool empty = filter.isEmpty();
|
||||||
|
|
||||||
if (bookmark_button_) {
|
if (bookmark_button_) {
|
||||||
bookmark_button_->setEnabled(false);
|
bookmark_button_->setEnabled(false);
|
||||||
|
@ -286,9 +286,9 @@ void CaptureFilterEdit::checkFilter(const QString& text)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty) {
|
if (empty) {
|
||||||
setFilterSyntaxState(text, Empty, QString());
|
setFilterSyntaxState(filter, Empty, QString());
|
||||||
} else {
|
} else {
|
||||||
syntax_worker_->checkFilter(text);
|
syntax_worker_->checkFilter(filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,8 +306,6 @@ void CaptureFilterEdit::initCaptureFilter()
|
||||||
|
|
||||||
void CaptureFilterEdit::setFilterSyntaxState(QString filter, int state, QString err_msg)
|
void CaptureFilterEdit::setFilterSyntaxState(QString filter, int state, QString err_msg)
|
||||||
{
|
{
|
||||||
bool valid = (state != Invalid);
|
|
||||||
|
|
||||||
if (filter.compare(text()) == 0) { // The user hasn't changed the filter
|
if (filter.compare(text()) == 0) { // The user hasn't changed the filter
|
||||||
setSyntaxState((SyntaxState)state);
|
setSyntaxState((SyntaxState)state);
|
||||||
if (!err_msg.isEmpty()) {
|
if (!err_msg.isEmpty()) {
|
||||||
|
@ -315,43 +313,16 @@ void CaptureFilterEdit::setFilterSyntaxState(QString filter, int state, QString
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBPCAP
|
bool valid = (state != Invalid);
|
||||||
if (syntaxState() != Invalid) {
|
|
||||||
|
if (valid) {
|
||||||
if (bookmark_button_) {
|
if (bookmark_button_) {
|
||||||
bookmark_button_->setEnabled(true);
|
bookmark_button_->setEnabled(true);
|
||||||
}
|
}
|
||||||
if (apply_button_) {
|
if (apply_button_) {
|
||||||
apply_button_->setEnabled(true);
|
apply_button_->setEnabled(true);
|
||||||
}
|
}
|
||||||
valid = true;
|
|
||||||
g_free(global_capture_opts.default_options.cfilter);
|
|
||||||
if (filter.isEmpty()) {
|
|
||||||
global_capture_opts.default_options.cfilter = NULL;
|
|
||||||
} else {
|
|
||||||
global_capture_opts.default_options.cfilter = qstring_strdup(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (global_capture_opts.num_selected > 0) {
|
|
||||||
interface_t device;
|
|
||||||
|
|
||||||
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
|
|
||||||
device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
|
|
||||||
if (!device.selected) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// if (device.active_dlt == -1) {
|
|
||||||
// simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "The link type of interface %s was not specified.", device.name);
|
|
||||||
// continue; /* Programming error: somehow managed to select an "unsupported" entry */
|
|
||||||
// }
|
|
||||||
g_array_remove_index(global_capture_opts.all_ifaces, i);
|
|
||||||
g_free(device.cfilter);
|
|
||||||
device.cfilter = qstring_strdup(filter);
|
|
||||||
g_array_insert_val(global_capture_opts.all_ifaces, i, device);
|
|
||||||
// update_filter_string(device.name, filter_text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif // HAVE_LIBPCAP
|
|
||||||
|
|
||||||
emit captureFilterSyntaxChanged(valid);
|
emit captureFilterSyntaxChanged(valid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ public slots:
|
||||||
private slots:
|
private slots:
|
||||||
void initCaptureFilter();
|
void initCaptureFilter();
|
||||||
void applyCaptureFilter();
|
void applyCaptureFilter();
|
||||||
void checkFilter(const QString &text);
|
void checkFilter(const QString &filter);
|
||||||
void setFilterSyntaxState(QString filter, int state, QString err_msg);
|
void setFilterSyntaxState(QString filter, int state, QString err_msg);
|
||||||
void bookmarkClicked();
|
void bookmarkClicked();
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,10 @@ static QMutex pcap_compile_mtx_;
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#define DEBUG_SYNTAX_CHECK(state1, state2) qDebug() << "CF state" << QThread::currentThreadId() << state1 << "->" << state2 << ":" << filter_text_ << ":" << filter
|
#define DEBUG_SYNTAX_CHECK(state1, state2) qDebug() << "CF state" << QThread::currentThreadId() << state1 << "->" << state2 << ":" << filter_text_ << ":" << filter
|
||||||
|
#define DEBUG_SLEEP_TIME 5000 // ms
|
||||||
#else
|
#else
|
||||||
#define DEBUG_SYNTAX_CHECK(state1, state2)
|
#define DEBUG_SYNTAX_CHECK(state1, state2)
|
||||||
|
#define DEBUG_SLEEP_TIME 0 // ms
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DUMMY_SNAPLENGTH 65535
|
#define DUMMY_SNAPLENGTH 65535
|
||||||
|
@ -102,6 +104,10 @@ void CaptureFilterSyntaxWorker::start() {
|
||||||
pc_err = pcap_compile(pd, &fcode, filter.toUtf8().constData(), 1 /* Do optimize */, 0);
|
pc_err = pcap_compile(pd, &fcode, filter.toUtf8().constData(), 1 /* Do optimize */, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if DEBUG_SLEEP_TIME > 0
|
||||||
|
QThread::msleep(DEBUG_SLEEP_TIME);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (pc_err) {
|
if (pc_err) {
|
||||||
DEBUG_SYNTAX_CHECK("unknown", "known bad");
|
DEBUG_SYNTAX_CHECK("unknown", "known bad");
|
||||||
state = SyntaxLineEdit::Invalid;
|
state = SyntaxLineEdit::Invalid;
|
||||||
|
|
|
@ -204,6 +204,11 @@ InterfaceTree *MainWelcome::getInterfaceTree()
|
||||||
return welcome_ui_->interfaceTree;
|
return welcome_ui_->interfaceTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString MainWelcome::captureFilter()
|
||||||
|
{
|
||||||
|
return welcome_ui_->captureFilterComboBox->currentText();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWelcome::appInitialized()
|
void MainWelcome::appInitialized()
|
||||||
{
|
{
|
||||||
// XXX Add a "check for updates" link?
|
// XXX Add a "check for updates" link?
|
||||||
|
|
|
@ -42,6 +42,7 @@ public:
|
||||||
explicit MainWelcome(QWidget *parent = 0);
|
explicit MainWelcome(QWidget *parent = 0);
|
||||||
virtual ~MainWelcome();
|
virtual ~MainWelcome();
|
||||||
InterfaceTree *getInterfaceTree();
|
InterfaceTree *getInterfaceTree();
|
||||||
|
const QString captureFilter();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent *event);
|
void resizeEvent(QResizeEvent *event);
|
||||||
|
|
|
@ -837,6 +837,36 @@ void MainWindow::startCapture() {
|
||||||
|
|
||||||
/* XXX - we might need to init other pref data as well... */
|
/* XXX - we might need to init other pref data as well... */
|
||||||
|
|
||||||
|
// Set our cfilters.
|
||||||
|
QString capture_filter = main_welcome_->captureFilter();
|
||||||
|
g_free(global_capture_opts.default_options.cfilter);
|
||||||
|
if (capture_filter.isEmpty()) {
|
||||||
|
global_capture_opts.default_options.cfilter = NULL;
|
||||||
|
} else {
|
||||||
|
global_capture_opts.default_options.cfilter = qstring_strdup(capture_filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (global_capture_opts.num_selected > 0) {
|
||||||
|
interface_t device;
|
||||||
|
|
||||||
|
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
|
||||||
|
device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
|
||||||
|
if (!device.selected) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// if (device.active_dlt == -1) {
|
||||||
|
// simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "The link type of interface %s was not specified.", device.name);
|
||||||
|
// continue; /* Programming error: somehow managed to select an "unsupported" entry */
|
||||||
|
// }
|
||||||
|
g_array_remove_index(global_capture_opts.all_ifaces, i);
|
||||||
|
g_free(device.cfilter);
|
||||||
|
device.cfilter = qstring_strdup(capture_filter);
|
||||||
|
g_array_insert_val(global_capture_opts.all_ifaces, i, device);
|
||||||
|
// update_filter_string(device.name, filter_text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* XXX - can this ever happen? */
|
/* XXX - can this ever happen? */
|
||||||
if (cap_session_.state != CAPTURE_STOPPED)
|
if (cap_session_.state != CAPTURE_STOPPED)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -39,6 +39,10 @@
|
||||||
#include <QStringListModel>
|
#include <QStringListModel>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
// To do:
|
||||||
|
// - Add indicator icons for syntax states to make things more clear for
|
||||||
|
// color blind people?
|
||||||
|
|
||||||
const int max_completion_items_ = 20;
|
const int max_completion_items_ = 20;
|
||||||
|
|
||||||
SyntaxLineEdit::SyntaxLineEdit(QWidget *parent) :
|
SyntaxLineEdit::SyntaxLineEdit(QWidget *parent) :
|
||||||
|
@ -46,6 +50,13 @@ SyntaxLineEdit::SyntaxLineEdit(QWidget *parent) :
|
||||||
completer_(NULL),
|
completer_(NULL),
|
||||||
completion_model_(NULL)
|
completion_model_(NULL)
|
||||||
{
|
{
|
||||||
|
// Try to matche QLineEdit's placeholder text color (which sets the
|
||||||
|
// alpha channel to 50%, which doesn't work in style sheets).
|
||||||
|
// Setting the foreground color lets us avoid yet another background
|
||||||
|
// color preference and should hopefully make things easier to
|
||||||
|
// distinguish for color blind folk.
|
||||||
|
busy_fg_ = ColorUtils::alphaBlend(palette().text(), palette().base(), 0.5);
|
||||||
|
|
||||||
setSyntaxState();
|
setSyntaxState();
|
||||||
setMaxLength(std::numeric_limits<quint32>::max());
|
setMaxLength(std::numeric_limits<quint32>::max());
|
||||||
}
|
}
|
||||||
|
@ -75,27 +86,41 @@ void SyntaxLineEdit::setSyntaxState(SyntaxState state) {
|
||||||
syntax_state_ = state;
|
syntax_state_ = state;
|
||||||
state_style_sheet_ = QString(
|
state_style_sheet_ = QString(
|
||||||
"SyntaxLineEdit[syntaxState=\"%1\"] {"
|
"SyntaxLineEdit[syntaxState=\"%1\"] {"
|
||||||
" color: %4;"
|
" color: %5;"
|
||||||
" background-color: %5;"
|
" background-color: %7;"
|
||||||
"}"
|
"}"
|
||||||
|
|
||||||
"SyntaxLineEdit[syntaxState=\"%2\"] {"
|
"SyntaxLineEdit[syntaxState=\"%2\"] {"
|
||||||
" color: %4;"
|
" color: %5;"
|
||||||
" background-color: %6;"
|
" background-color: %8;"
|
||||||
"}"
|
"}"
|
||||||
|
|
||||||
"SyntaxLineEdit[syntaxState=\"%3\"] {"
|
"SyntaxLineEdit[syntaxState=\"%3\"] {"
|
||||||
" color: %4;"
|
" color: %5;"
|
||||||
" background-color: %7;"
|
" background-color: %9;"
|
||||||
|
"}"
|
||||||
|
|
||||||
|
"SyntaxLineEdit[syntaxState=\"%4\"] {"
|
||||||
|
" color: %10;"
|
||||||
|
" background-color: %6;"
|
||||||
"}"
|
"}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// CSS selectors
|
||||||
.arg(Valid)
|
.arg(Valid)
|
||||||
.arg(Invalid)
|
.arg(Invalid)
|
||||||
.arg(Deprecated)
|
.arg(Deprecated)
|
||||||
.arg("palette(text)") // Foreground
|
.arg(Busy)
|
||||||
.arg(ColorUtils::fromColorT(&prefs.gui_text_valid).name()) // Valid
|
|
||||||
.arg(ColorUtils::fromColorT(&prefs.gui_text_invalid).name()) // Invalid
|
// Normal foreground / background
|
||||||
.arg(ColorUtils::fromColorT(&prefs.gui_text_deprecated).name()) // Deprecated
|
.arg("palette(text)")
|
||||||
|
.arg("palette(base)")
|
||||||
|
|
||||||
|
// Special foreground / background
|
||||||
|
.arg(ColorUtils::fromColorT(&prefs.gui_text_valid).name())
|
||||||
|
.arg(ColorUtils::fromColorT(&prefs.gui_text_invalid).name())
|
||||||
|
.arg(ColorUtils::fromColorT(&prefs.gui_text_deprecated).name())
|
||||||
|
.arg(busy_fg_.name())
|
||||||
;
|
;
|
||||||
setStyleSheet(style_sheet_);
|
setStyleSheet(style_sheet_);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ class SyntaxLineEdit : public QLineEdit
|
||||||
Q_ENUMS(SyntaxState)
|
Q_ENUMS(SyntaxState)
|
||||||
public:
|
public:
|
||||||
explicit SyntaxLineEdit(QWidget *parent = 0);
|
explicit SyntaxLineEdit(QWidget *parent = 0);
|
||||||
enum SyntaxState { Empty, Invalid, Deprecated, Valid };
|
enum SyntaxState { Empty, Busy, Invalid, Deprecated, Valid };
|
||||||
|
|
||||||
SyntaxState syntaxState() const { return syntax_state_; }
|
SyntaxState syntaxState() const { return syntax_state_; }
|
||||||
void setSyntaxState(SyntaxState state = Empty);
|
void setSyntaxState(SyntaxState state = Empty);
|
||||||
|
@ -79,6 +79,7 @@ private:
|
||||||
QString deprecated_token_;
|
QString deprecated_token_;
|
||||||
QString syntax_error_message_;
|
QString syntax_error_message_;
|
||||||
QString token_chars_;
|
QString token_chars_;
|
||||||
|
QColor busy_fg_;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void insertFieldCompletion(const QString &completion_text);
|
void insertFieldCompletion(const QString &completion_text);
|
||||||
|
|
Loading…
Reference in New Issue