1 /* preference_editor_frame.h
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include <epan/prefs.h>
13 #include <epan/prefs-int.h>
14 #include <epan/decode_as.h>
16 #include <ui/preference_utils.h>
17 #include <ui/simple_dialog.h>
19 #include "preference_editor_frame.h"
20 #include <ui_preference_editor_frame.h>
22 #include <ui/qt/utils/qt_ui_utils.h>
23 #include <ui/qt/widgets/wireshark_file_dialog.h>
24 #include <wsutil/utf8_entities.h>
26 #include "main_application.h"
28 #include <QPushButton>
30 #include <QRegularExpression>
32 PreferenceEditorFrame::PreferenceEditorFrame(QWidget
*parent
) :
33 AccordionFrame(parent
),
34 ui(new Ui::PreferenceEditorFrame
),
44 foreach (QWidget
*w
, findChildren
<QWidget
*>()) {
45 w
->setAttribute(Qt::WA_MacSmallSize
, true);
49 connect(ui
->preferenceBrowseButton
, &QPushButton::clicked
, this, &PreferenceEditorFrame::browsePushButtonClicked
);
51 // Disconnect textChanged signal for DissectorSyntaxLineEdit.
52 disconnect(ui
->preferenceLineEdit
, &DissectorSyntaxLineEdit::textChanged
, NULL
, NULL
);
55 PreferenceEditorFrame::~PreferenceEditorFrame()
60 void PreferenceEditorFrame::editPreference(preference
*pref
, pref_module
*module
)
65 if (!pref
|| !module
) {
70 ui
->modulePreferencesToolButton
->setText(tr("Open %1 preferences…").arg(module_
->title
));
72 pref_stash(pref_
, NULL
);
73 ui
->preferenceTitleLabel
->setText(QStringLiteral("%1:").arg(prefs_get_title(pref
)));
75 // Convert the pref description from plain text to rich text.
76 QString description
= html_escape(prefs_get_description(pref
));
77 description
.replace('\n', "<br>");
78 QString tooltip
= QStringLiteral("<span>%1</span>").arg(description
);
79 ui
->preferenceTitleLabel
->setToolTip(tooltip
);
80 ui
->preferenceLineEdit
->setToolTip(tooltip
);
82 ui
->preferenceLineEdit
->clear();
83 ui
->preferenceLineEdit
->setSyntaxState(SyntaxLineEdit::Empty
);
85 // Disconnect previous textChanged signal.
86 disconnect(ui
->preferenceLineEdit
, &SyntaxLineEdit::textChanged
, this, NULL
);
89 bool browse_button
= false;
91 switch (prefs_get_type(pref_
)) {
93 connect(ui
->preferenceLineEdit
, &SyntaxLineEdit::textChanged
,
94 this, &PreferenceEditorFrame::uintLineEditTextEdited
);
97 case PREF_SAVE_FILENAME
:
98 case PREF_OPEN_FILENAME
:
100 browse_button
= true;
105 connect(ui
->preferenceLineEdit
, &SyntaxLineEdit::textChanged
,
106 this, &PreferenceEditorFrame::stringLineEditTextEdited
);
110 case PREF_DECODE_AS_RANGE
:
111 connect(ui
->preferenceLineEdit
, &SyntaxLineEdit::textChanged
,
112 this, &PreferenceEditorFrame::rangeLineEditTextEdited
);
120 // Enable completion only for display filter search.
121 if (prefs_get_type(pref_
) == PREF_DISSECTOR
) {
122 ui
->preferenceLineEdit
->allowCompletion(true);
123 ui
->preferenceLineEdit
->updateDissectorNames();
124 ui
->preferenceLineEdit
->setDefaultPlaceholderText();
126 ui
->preferenceLineEdit
->allowCompletion(false);
127 ui
->preferenceLineEdit
->setPlaceholderText("");
130 ui
->preferenceLineEdit
->setText(gchar_free_to_qstring(prefs_pref_to_str(pref_
, pref_stashed
)).remove(QRegularExpression("\n\t")));
131 ui
->preferenceBrowseButton
->setHidden(!browse_button
);
136 void PreferenceEditorFrame::uintLineEditTextEdited(const QString
&new_str
)
138 if (new_str
.isEmpty()) {
139 new_uint_
= prefs_get_uint_value(pref_
, pref_stashed
);
140 ui
->preferenceLineEdit
->setSyntaxState(SyntaxLineEdit::Empty
);
141 ui
->buttonBox
->button(QDialogButtonBox::Ok
)->setEnabled(true);
146 uint new_uint
= new_str
.toUInt(&ok
, 0);
148 new_uint_
= new_uint
;
149 ui
->preferenceLineEdit
->setSyntaxState(SyntaxLineEdit::Valid
);
151 new_uint_
= prefs_get_uint_value(pref_
, pref_stashed
);
152 ui
->preferenceLineEdit
->setSyntaxState(SyntaxLineEdit::Invalid
);
154 ui
->buttonBox
->button(QDialogButtonBox::Ok
)->setEnabled(ok
);
157 void PreferenceEditorFrame::stringLineEditTextEdited(const QString
&new_str
)
162 if (prefs_get_type(pref_
) == PREF_DISSECTOR
) {
163 ui
->preferenceLineEdit
->checkDissectorName(new_str_
);
164 ok
= (ui
->preferenceLineEdit
->syntaxState() != SyntaxLineEdit::Invalid
);
167 ui
->buttonBox
->button(QDialogButtonBox::Ok
)->setEnabled(ok
);
170 void PreferenceEditorFrame::browsePushButtonClicked()
172 QString caption
= mainApp
->windowTitleString(prefs_get_title(pref_
));
173 QString dir
= prefs_get_string_value(pref_
, pref_stashed
);
176 switch (prefs_get_type(pref_
)) {
177 case PREF_SAVE_FILENAME
:
178 filename
= WiresharkFileDialog::getSaveFileName(this, caption
, dir
);
180 case PREF_OPEN_FILENAME
:
181 filename
= WiresharkFileDialog::getOpenFileName(this, caption
, dir
);
184 filename
= WiresharkFileDialog::getExistingDirectory(this, caption
, dir
);
188 if (!filename
.isEmpty()) {
189 ui
->preferenceLineEdit
->setText(filename
);
193 void PreferenceEditorFrame::rangeLineEditTextEdited(const QString
&new_str
)
195 range_t
*new_range
= NULL
;
197 convert_ret_t ret
= range_convert_str(NULL
, &new_range
, new_str
.toUtf8().constData(), prefs_get_max_value(pref_
));
198 wmem_free(NULL
, new_range_
);
199 new_range_
= new_range
;
201 if (ret
== CVT_NO_ERROR
) {
202 if (new_str
.isEmpty()) {
203 ui
->preferenceLineEdit
->setSyntaxState(SyntaxLineEdit::Empty
);
205 ui
->preferenceLineEdit
->setSyntaxState(SyntaxLineEdit::Valid
);
208 ui
->preferenceLineEdit
->setSyntaxState(SyntaxLineEdit::Invalid
);
211 ui
->buttonBox
->button(QDialogButtonBox::Ok
)->setEnabled(ret
== CVT_NO_ERROR
);
214 void PreferenceEditorFrame::showEvent(QShowEvent
*event
)
216 ui
->preferenceLineEdit
->setFocus();
217 ui
->preferenceLineEdit
->selectAll();
219 AccordionFrame::showEvent(event
);
222 void PreferenceEditorFrame::on_modulePreferencesToolButton_clicked()
225 emit
showProtocolPreferences(module_
->name
);
227 on_buttonBox_rejected();
230 void PreferenceEditorFrame::on_preferenceLineEdit_returnPressed()
232 if (ui
->buttonBox
->button(QDialogButtonBox::Ok
)->isEnabled()) {
233 on_buttonBox_accepted();
237 void PreferenceEditorFrame::on_buttonBox_accepted()
239 unsigned int changed_flags
= 0;
240 unsigned int apply
= 0;
241 switch(prefs_get_type(pref_
)) {
243 apply
= prefs_set_uint_value(pref_
, new_uint_
, pref_stashed
);
246 case PREF_SAVE_FILENAME
:
247 case PREF_OPEN_FILENAME
:
250 apply
= prefs_set_string_value(pref_
, new_str_
.toStdString().c_str(), pref_stashed
);
253 apply
= prefs_set_password_value(pref_
, new_str_
.toStdString().c_str(), pref_stashed
);
256 case PREF_DECODE_AS_RANGE
:
257 apply
= prefs_set_range_value(pref_
, new_range_
, pref_stashed
);
263 if (apply
&& module_
) {
264 changed_flags
= module_
->prefs_changed_flags
;
265 pref_unstash_data_t unstashed_data
;
267 unstashed_data
.module
= module_
;
268 unstashed_data
.handle_decode_as
= true;
270 pref_unstash(pref_
, &unstashed_data
);
271 prefs_apply(module_
);
275 if (save_decode_as_entries(&err
) < 0)
277 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "%s", err
);
281 on_buttonBox_rejected();
282 // Emit signals once UI is hidden
284 if (changed_flags
& PREF_EFFECT_FIELDS
) {
285 mainApp
->emitAppSignal(MainApplication::FieldsChanged
);
287 mainApp
->emitAppSignal(MainApplication::PacketDissectionChanged
);
288 mainApp
->emitAppSignal(MainApplication::PreferencesChanged
);
292 void PreferenceEditorFrame::on_buttonBox_rejected()
296 wmem_free(NULL
, new_range_
);
301 void PreferenceEditorFrame::keyPressEvent(QKeyEvent
*event
)
303 if (pref_
&& module_
&& (event
->modifiers() == Qt::NoModifier
)) {
304 if (event
->key() == Qt::Key_Escape
) {
305 on_buttonBox_rejected();
306 } else if (event
->key() == Qt::Key_Enter
|| event
->key() == Qt::Key_Return
) {
307 if (ui
->buttonBox
->button(QDialogButtonBox::Ok
)->isEnabled()) {
308 on_buttonBox_accepted();
309 } else if (ui
->preferenceLineEdit
->syntaxState() == SyntaxLineEdit::Invalid
) {
310 mainApp
->pushStatus(MainApplication::FilterSyntax
, tr("Invalid value."));
315 AccordionFrame::keyPressEvent(event
);