prefs: Add prefs_register_dissector_preference()
Use this preference to get color code validation and autocompletion for string preferences used for configuring a dissector name.
This commit is contained in:
parent
92546a4a66
commit
2f1392169a
|
@ -3268,6 +3268,10 @@ dissector_handle_get_protocol_index(const dissector_handle_t handle)
|
|||
GList*
|
||||
get_dissector_names(void)
|
||||
{
|
||||
if (!registered_dissectors) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_hash_table_get_keys(registered_dissectors);
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,8 @@ struct pref_custom_cbs {
|
|||
*/
|
||||
#define PREF_PROTO_TCP_SNDAMB_ENUM (1u << 16)
|
||||
|
||||
#define PREF_DISSECTOR (1u << 17) /* like string, but with dissector name syntax check */
|
||||
|
||||
/* read_prefs_file: read in a generic config file and do a callback to */
|
||||
/* pref_set_pair_fct() for every key/value pair found */
|
||||
/**
|
||||
|
|
34
epan/prefs.c
34
epan/prefs.c
|
@ -333,6 +333,7 @@ free_pref(gpointer data, gpointer user_data _U_)
|
|||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_PASSWORD:
|
||||
case PREF_DISSECTOR:
|
||||
free_string_like_preference(pref);
|
||||
break;
|
||||
case PREF_RANGE:
|
||||
|
@ -1969,6 +1970,19 @@ DIAG_OFF(cast-qual)
|
|||
DIAG_ON(cast-qual)
|
||||
}
|
||||
|
||||
/*
|
||||
* Register a preference with a dissector name.
|
||||
*/
|
||||
void
|
||||
prefs_register_dissector_preference(module_t *module, const char *name,
|
||||
const char *title, const char *description,
|
||||
const char **var)
|
||||
{
|
||||
DIAG_OFF(cast-qual)
|
||||
register_string_like_preference(module, name, title, description,
|
||||
(char **)var, PREF_DISSECTOR, NULL, FALSE);
|
||||
DIAG_ON(cast-qual)
|
||||
}
|
||||
|
||||
gboolean prefs_add_decode_as_value(pref_t *pref, guint value, gboolean replace)
|
||||
{
|
||||
|
@ -2091,6 +2105,7 @@ pref_stash(pref_t *pref, gpointer unused _U_)
|
|||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_PASSWORD:
|
||||
case PREF_DISSECTOR:
|
||||
g_free(pref->stashed_val.string);
|
||||
pref->stashed_val.string = g_strdup(*pref->varp.string);
|
||||
break;
|
||||
|
@ -2194,6 +2209,7 @@ pref_unstash(pref_t *pref, gpointer unstash_data_p)
|
|||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_PASSWORD:
|
||||
case PREF_DISSECTOR:
|
||||
if (strcmp(*pref->varp.string, pref->stashed_val.string) != 0) {
|
||||
unstash_data->module->prefs_changed_flags |= prefs_get_effect_flags(pref);
|
||||
g_free(*pref->varp.string);
|
||||
|
@ -2301,6 +2317,7 @@ reset_stashed_pref(pref_t *pref) {
|
|||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_PASSWORD:
|
||||
case PREF_DISSECTOR:
|
||||
g_free(pref->stashed_val.string);
|
||||
pref->stashed_val.string = g_strdup(pref->default_val.string);
|
||||
break;
|
||||
|
@ -2353,6 +2370,7 @@ pref_clean_stash(pref_t *pref, gpointer unused _U_)
|
|||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_PASSWORD:
|
||||
case PREF_DISSECTOR:
|
||||
if (pref->stashed_val.string != NULL) {
|
||||
g_free(pref->stashed_val.string);
|
||||
pref->stashed_val.string = NULL;
|
||||
|
@ -4357,6 +4375,7 @@ reset_pref(pref_t *pref)
|
|||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_PASSWORD:
|
||||
case PREF_DISSECTOR:
|
||||
reset_string_like_preference(pref);
|
||||
break;
|
||||
|
||||
|
@ -6136,6 +6155,7 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
|
|||
case PREF_SAVE_FILENAME:
|
||||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_DISSECTOR:
|
||||
containing_module->prefs_changed_flags |= prefs_set_string_value(pref, value, pref_current);
|
||||
break;
|
||||
|
||||
|
@ -6339,6 +6359,10 @@ prefs_pref_type_name(pref_t *pref)
|
|||
case PREF_PASSWORD:
|
||||
type_name = "Password";
|
||||
break;
|
||||
|
||||
case PREF_DISSECTOR:
|
||||
type_name = "Dissector";
|
||||
break;
|
||||
}
|
||||
return type_name;
|
||||
}
|
||||
|
@ -6490,6 +6514,10 @@ prefs_pref_type_description(pref_t *pref)
|
|||
type_desc = "Password (never stored on disk)";
|
||||
break;
|
||||
|
||||
case PREF_DISSECTOR:
|
||||
type_desc = "A dissector name";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -6537,6 +6565,7 @@ prefs_pref_is_default(pref_t *pref)
|
|||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_PASSWORD:
|
||||
case PREF_DISSECTOR:
|
||||
if (!(g_strcmp0(pref->default_val.string, *pref->varp.string)))
|
||||
return TRUE;
|
||||
break;
|
||||
|
@ -6656,6 +6685,8 @@ prefs_pref_to_str(pref_t *pref, pref_source_t source) {
|
|||
case PREF_SAVE_FILENAME:
|
||||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_PASSWORD:
|
||||
case PREF_DISSECTOR:
|
||||
return g_strdup(*(const char **) valp);
|
||||
|
||||
case PREF_DECODE_AS_RANGE:
|
||||
|
@ -6692,9 +6723,6 @@ prefs_pref_to_str(pref_t *pref, pref_source_t source) {
|
|||
break;
|
||||
}
|
||||
|
||||
case PREF_PASSWORD:
|
||||
return g_strdup(*(const char **) valp);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
24
epan/prefs.h
24
epan/prefs.h
|
@ -762,6 +762,30 @@ void prefs_register_decode_as_range_preference(module_t *module, const char *nam
|
|||
WS_DLL_PUBLIC void prefs_register_password_preference(module_t *module, const char *name,
|
||||
const char *title, const char *description, const char **var);
|
||||
|
||||
/**
|
||||
* Register a preference with a dissector name.
|
||||
* @param module the preferences module returned by prefs_register_protocol() or
|
||||
* prefs_register_protocol_subtree()
|
||||
* @param name the preference's identifier. This is appended to the name of the
|
||||
* protocol, with a "." between them, to create a unique identifier.
|
||||
* The identifier should not include the protocol name, as the name in
|
||||
* the preference file will already have it. Make sure that
|
||||
* only lower-case ASCII letters, numbers, underscores and
|
||||
* dots appear in the preference name.
|
||||
* @param title Field's title in the preferences dialog
|
||||
* @param description description to include in the preferences file
|
||||
* and shown as tooltip in the GUI, or NULL
|
||||
* @param var pointer to the storage location that is updated when the
|
||||
* field is changed in the preference dialog box. Note that
|
||||
* with string preferences the given pointer is overwritten
|
||||
* with a pointer to a new copy of the string during the
|
||||
* preference registration. The passed-in string may be
|
||||
* freed, but you must keep another pointer to the string
|
||||
* in order to free it
|
||||
*/
|
||||
WS_DLL_PUBLIC void prefs_register_dissector_preference(module_t *module, const char *name,
|
||||
const char *title, const char *description, const char **var);
|
||||
|
||||
/**
|
||||
* Register a preference that used to be supported but no longer is.
|
||||
*
|
||||
|
|
|
@ -180,6 +180,7 @@ WSLUA_FUNCTION wslua_get_preference(lua_State *L) {
|
|||
case PREF_SAVE_FILENAME:
|
||||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_DISSECTOR:
|
||||
{
|
||||
const gchar *string_value = prefs_get_string_value(pref, pref_current);
|
||||
lua_pushstring(L,string_value);
|
||||
|
@ -256,6 +257,7 @@ WSLUA_FUNCTION wslua_set_preference(lua_State *L) {
|
|||
case PREF_SAVE_FILENAME:
|
||||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_DISSECTOR:
|
||||
{
|
||||
const gchar *string_value = luaL_checkstring(L,WSLUA_ARG_set_preference_VALUE);
|
||||
changed = prefs_set_string_value(pref, string_value, pref_current);
|
||||
|
|
|
@ -5190,6 +5190,7 @@ sharkd_session_process_dumpconf_cb(pref_t *pref, gpointer d)
|
|||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_PASSWORD:
|
||||
case PREF_DISSECTOR:
|
||||
sharkd_json_value_string("s", prefs_get_string_value(pref, pref_current));
|
||||
break;
|
||||
|
||||
|
@ -5293,7 +5294,7 @@ sharkd_session_process_dumpconf_mod_cb(module_t *module, gpointer d)
|
|||
* (o) u - preference value (for PREF_UINT, PREF_DECODE_AS_UINT)
|
||||
* (o) ub - preference value suggested base for display (for PREF_UINT, PREF_DECODE_AS_UINT) and if different than 10
|
||||
* (o) b - preference value (only for PREF_BOOL) (1 true, 0 false)
|
||||
* (o) s - preference value (for PREF_STRING, PREF_SAVE_FILENAME, PREF_OPEN_FILENAME, PREF_DIRNAME, PREF_PASSWORD)
|
||||
* (o) s - preference value (for PREF_STRING, PREF_SAVE_FILENAME, PREF_OPEN_FILENAME, PREF_DIRNAME, PREF_PASSWORD, PREF_DISSECTOR)
|
||||
* (o) e - preference possible values (only for PREF_ENUM)
|
||||
* (o) r - preference value (for PREF_RANGE, PREF_DECODE_AS_RANGE)
|
||||
* (o) t - preference value (only for PREF_UAT)
|
||||
|
|
|
@ -93,7 +93,7 @@ prefs_store_ext_helper(const char * module_name, const char *pref_name, const ch
|
|||
if (!pref)
|
||||
return 0;
|
||||
|
||||
if (prefs_get_type(pref) == PREF_STRING )
|
||||
if (prefs_get_type(pref) == PREF_STRING || prefs_get_type(pref) == PREF_DISSECTOR)
|
||||
{
|
||||
pref_changed |= prefs_set_string_value(pref, pref_value, pref_stashed);
|
||||
if ( !pref_changed || prefs_get_string_value(pref, pref_stashed) != 0 )
|
||||
|
|
|
@ -80,6 +80,7 @@ public:
|
|||
};
|
||||
REGISTER_PREFERENCE_TYPE(PREF_STRING, StringPreference)
|
||||
REGISTER_PREFERENCE_TYPE(PREF_CUSTOM, StringPreference)
|
||||
REGISTER_PREFERENCE_TYPE(PREF_DISSECTOR, StringPreference)
|
||||
|
||||
class PasswordPreference : public StringPreference
|
||||
{
|
||||
|
|
|
@ -487,6 +487,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:
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "module_preferences_scroll_area.h"
|
||||
#include <ui_module_preferences_scroll_area.h>
|
||||
#include <ui/qt/widgets/syntax_line_edit.h>
|
||||
#include <ui/qt/widgets/dissector_syntax_line_edit.h>
|
||||
#include "ui/qt/widgets/wireshark_file_dialog.h"
|
||||
#include <ui/qt/utils/qt_ui_utils.h>
|
||||
#include "uat_dialog.h"
|
||||
|
@ -171,6 +172,21 @@ pref_show(pref_t *pref, gpointer user_data)
|
|||
vb->addLayout(hb);
|
||||
break;
|
||||
}
|
||||
case PREF_DISSECTOR:
|
||||
{
|
||||
QHBoxLayout *hb = new QHBoxLayout();
|
||||
QLabel *label = new QLabel(prefs_get_title(pref));
|
||||
label->setToolTip(tooltip);
|
||||
hb->addWidget(label);
|
||||
QLineEdit *string_le = new DissectorSyntaxLineEdit();
|
||||
string_le->setToolTip(tooltip);
|
||||
string_le->setProperty(pref_prop_, VariantPointer<pref_t>::asQVariant(pref));
|
||||
string_le->setMinimumWidth(string_le->fontMetrics().height() * 20);
|
||||
hb->addWidget(string_le);
|
||||
hb->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum));
|
||||
vb->addLayout(hb);
|
||||
break;
|
||||
}
|
||||
case PREF_DECODE_AS_RANGE:
|
||||
case PREF_RANGE:
|
||||
{
|
||||
|
@ -333,6 +349,7 @@ ModulePreferencesScrollArea::ModulePreferencesScrollArea(module_t *module, QWidg
|
|||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_PASSWORD:
|
||||
case PREF_DISSECTOR:
|
||||
connect(le, &QLineEdit::textEdited, this, &ModulePreferencesScrollArea::stringLineEditTextEdited);
|
||||
break;
|
||||
case PREF_RANGE:
|
||||
|
|
|
@ -80,7 +80,14 @@ void PreferenceEditorFrame::editPreference(preference *pref, pref_module *module
|
|||
|
||||
ui->preferenceLineEdit->clear();
|
||||
ui->preferenceLineEdit->setSyntaxState(SyntaxLineEdit::Empty);
|
||||
disconnect(ui->preferenceLineEdit, 0, 0, 0);
|
||||
|
||||
// Disconnect previous textChanged signals.
|
||||
disconnect(ui->preferenceLineEdit, &SyntaxLineEdit::textChanged,
|
||||
this, &PreferenceEditorFrame::uintLineEditTextEdited);
|
||||
disconnect(ui->preferenceLineEdit, &SyntaxLineEdit::textChanged,
|
||||
this, &PreferenceEditorFrame::stringLineEditTextEdited);
|
||||
disconnect(ui->preferenceLineEdit, &SyntaxLineEdit::textChanged,
|
||||
this, &PreferenceEditorFrame::rangeLineEditTextEdited);
|
||||
|
||||
bool show = false;
|
||||
bool browse_button = false;
|
||||
|
@ -99,6 +106,7 @@ void PreferenceEditorFrame::editPreference(preference *pref, pref_module *module
|
|||
// Fallthrough
|
||||
case PREF_STRING:
|
||||
case PREF_PASSWORD:
|
||||
case PREF_DISSECTOR:
|
||||
connect(ui->preferenceLineEdit, &SyntaxLineEdit::textChanged,
|
||||
this, &PreferenceEditorFrame::stringLineEditTextEdited);
|
||||
show = true;
|
||||
|
@ -114,6 +122,16 @@ void PreferenceEditorFrame::editPreference(preference *pref, pref_module *module
|
|||
}
|
||||
|
||||
if (show) {
|
||||
// Enable completion only for display filter search.
|
||||
if (prefs_get_type(pref_) == PREF_DISSECTOR) {
|
||||
ui->preferenceLineEdit->allowCompletion(true);
|
||||
ui->preferenceLineEdit->updateDissectorNames();
|
||||
ui->preferenceLineEdit->setDefaultPlaceholderText();
|
||||
} else {
|
||||
ui->preferenceLineEdit->allowCompletion(false);
|
||||
ui->preferenceLineEdit->setPlaceholderText("");
|
||||
}
|
||||
|
||||
ui->preferenceLineEdit->setText(gchar_free_to_qstring(prefs_pref_to_str(pref_, pref_stashed)).remove(QRegularExpression("\n\t")));
|
||||
ui->preferenceBrowseButton->setHidden(!browse_button);
|
||||
animatedShow();
|
||||
|
@ -143,8 +161,15 @@ void PreferenceEditorFrame::uintLineEditTextEdited(const QString &new_str)
|
|||
|
||||
void PreferenceEditorFrame::stringLineEditTextEdited(const QString &new_str)
|
||||
{
|
||||
bool ok = true;
|
||||
new_str_ = new_str;
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
|
||||
if (prefs_get_type(pref_) == PREF_DISSECTOR) {
|
||||
ui->preferenceLineEdit->checkDissectorName(new_str_);
|
||||
ok = (ui->preferenceLineEdit->syntaxState() != SyntaxLineEdit::Invalid);
|
||||
}
|
||||
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ok);
|
||||
}
|
||||
|
||||
void PreferenceEditorFrame::browsePushButtonClicked()
|
||||
|
@ -227,6 +252,7 @@ void PreferenceEditorFrame::on_buttonBox_accepted()
|
|||
case PREF_SAVE_FILENAME:
|
||||
case PREF_OPEN_FILENAME:
|
||||
case PREF_DIRNAME:
|
||||
case PREF_DISSECTOR:
|
||||
apply = prefs_set_string_value(pref_, new_str_.toStdString().c_str(), pref_stashed);
|
||||
break;
|
||||
case PREF_PASSWORD:
|
||||
|
@ -280,7 +306,7 @@ void PreferenceEditorFrame::on_buttonBox_rejected()
|
|||
|
||||
void PreferenceEditorFrame::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (event->modifiers() == Qt::NoModifier) {
|
||||
if (pref_ && module_ && (event->modifiers() == Qt::NoModifier)) {
|
||||
if (event->key() == Qt::Key_Escape) {
|
||||
on_buttonBox_rejected();
|
||||
} else if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="SyntaxLineEdit" name="preferenceLineEdit">
|
||||
<widget class="DissectorSyntaxLineEdit" name="preferenceLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
|
@ -106,9 +106,9 @@
|
|||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>SyntaxLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>widgets/syntax_line_edit.h</header>
|
||||
<class>DissectorSyntaxLineEdit</class>
|
||||
<extends>SyntaxLineEdit</extends>
|
||||
<header>widgets/dissector_syntax_line_edit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
|
|
|
@ -270,6 +270,7 @@ void ProtocolPreferencesMenu::addMenuItem(preference *pref)
|
|||
case PREF_DECODE_AS_UINT:
|
||||
case PREF_DECODE_AS_RANGE:
|
||||
case PREF_PASSWORD:
|
||||
case PREF_DISSECTOR:
|
||||
{
|
||||
EditorPreferenceAction *epa = new EditorPreferenceAction(pref, this);
|
||||
addAction(epa);
|
||||
|
|
|
@ -38,6 +38,15 @@ DissectorSyntaxLineEdit::DissectorSyntaxLineEdit(QWidget *parent) :
|
|||
setCompleter(new QCompleter(completion_model_, this));
|
||||
setCompletionTokenChars(fld_abbrev_chars_);
|
||||
|
||||
updateDissectorNames();
|
||||
setDefaultPlaceholderText();
|
||||
|
||||
connect(this, &DissectorSyntaxLineEdit::textChanged, this,
|
||||
static_cast<void (DissectorSyntaxLineEdit::*)(const QString &)>(&DissectorSyntaxLineEdit::checkDissectorName));
|
||||
}
|
||||
|
||||
void DissectorSyntaxLineEdit::updateDissectorNames()
|
||||
{
|
||||
GList *dissector_names = get_dissector_names();
|
||||
QStringList dissector_list;
|
||||
for (GList* l = dissector_names; l != NULL; l = l->next) {
|
||||
|
@ -46,10 +55,6 @@ DissectorSyntaxLineEdit::DissectorSyntaxLineEdit(QWidget *parent) :
|
|||
g_list_free(dissector_names);
|
||||
dissector_list.sort();
|
||||
completion_model_->setStringList(dissector_list);
|
||||
setDefaultPlaceholderText();
|
||||
|
||||
connect(this, &DissectorSyntaxLineEdit::textChanged, this,
|
||||
static_cast<void (DissectorSyntaxLineEdit::*)(const QString &)>(&DissectorSyntaxLineEdit::checkDissectorName));
|
||||
}
|
||||
|
||||
void DissectorSyntaxLineEdit::setDefaultPlaceholderText()
|
||||
|
|
|
@ -20,19 +20,22 @@ class DissectorSyntaxLineEdit : public SyntaxLineEdit
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit DissectorSyntaxLineEdit(QWidget *parent = 0);
|
||||
void updateDissectorNames();
|
||||
void setDefaultPlaceholderText();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) { completionKeyPressEvent(event); }
|
||||
void focusInEvent(QFocusEvent *event) { completionFocusInEvent(event); }
|
||||
|
||||
private slots:
|
||||
public slots:
|
||||
void checkDissectorName(const QString &dissector);
|
||||
|
||||
private slots:
|
||||
void changeEvent(QEvent* event);
|
||||
|
||||
private:
|
||||
QString placeholder_text_;
|
||||
|
||||
void setDefaultPlaceholderText();
|
||||
void buildCompletionList(const QString &field_word, const QString &preamble);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue