1 /* preferences_dialog.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "preferences_dialog.h"
23 #include <ui_preferences_dialog.h>
25 #include "module_preferences_scroll_area.h"
29 #include "caputils/capture-wpcap.h"
31 #endif /* HAVE_LIBPCAP */
33 #include <epan/prefs-int.h>
34 #include <epan/decode_as.h>
35 #include <ui/language.h>
36 #include <ui/preference_utils.h>
37 #include <ui/simple_dialog.h>
38 #include <main_window.h>
40 #include "syntax_line_edit.h"
41 #include "qt_ui_utils.h"
42 #include "uat_dialog.h"
43 #include "wireshark_application.h"
45 #include <QColorDialog>
47 #include <QFileDialog>
49 #include <QHBoxLayout>
52 #include <QMessageBox>
53 #include <QSpacerItem>
54 #include <QTreeWidgetItemIterator>
56 Q_DECLARE_METATYPE(ModulePreferencesScrollArea *)
57 Q_DECLARE_METATYPE(pref_t *)
58 Q_DECLARE_METATYPE(QStackedWidget *)
60 // XXX Should we move this to ui/preference_utils?
61 static QHash<void *, pref_t *> pref_ptr_to_pref_;
62 pref_t *prefFromPrefPtr(void *pref_ptr)
64 return pref_ptr_to_pref_[pref_ptr];
80 stacked_role_ = Qt::UserRole + 1, // pd_ui_->stackedWidget
81 module_name_role_, // QString
82 mpsa_role_ // QWidget *
85 class AdvancedPrefTreeWidgetItem : public QTreeWidgetItem
88 AdvancedPrefTreeWidgetItem(pref_t *pref, module_t *module) :
89 QTreeWidgetItem (advanced_type_),
93 pref_t *pref() { return pref_; }
94 void updatePref() { emitDataChanged(); }
96 virtual QVariant data(int column, int role) const {
97 bool is_default = prefs_pref_is_default(pref_);
103 QString full_name = QString(module_->name ? module_->name : module_->parent->name);
104 full_name += QString(".%1").arg(pref_->name);
107 case adv_status_col_:
108 if ((pref_->type == PREF_UAT && (pref_->gui == GUI_ALL || pref_->gui == GUI_QT))|| pref_->type == PREF_CUSTOM) {
109 return QObject::tr("Unknown");
110 } else if (is_default) {
111 return QObject::tr("Default");
113 return QObject::tr("Changed");
116 return QString(prefs_pref_type_name(pref_));
119 QString cur_value = gchar_free_to_qstring(prefs_pref_to_str(pref_, pref_stashed)).remove(QRegExp("\n\t"));
126 case Qt::ToolTipRole:
129 return QString("<span>%1</span>").arg(pref_->description);
130 case adv_status_col_:
131 return QObject::tr("Has this preference been changed?");
134 QString type_desc = gchar_free_to_qstring(prefs_pref_type_description(pref_));
135 return QString("<span>%1</span>").arg(type_desc);
139 QString default_value = gchar_free_to_qstring(prefs_pref_to_str(pref_, pref_stashed));
140 return QString("<span>%1</span>").arg(
141 default_value.isEmpty() ? default_value : QObject::tr("Default value is empty"));
148 if (!is_default && treeWidget()) {
149 QFont font = treeWidget()->font();
157 return QTreeWidgetItem::data(column, role);
165 class ModulePrefTreeWidgetItem : public QTreeWidgetItem
168 ModulePrefTreeWidgetItem(QTreeWidgetItem *parent, module_t *module) :
169 QTreeWidgetItem (parent, module_type_),
173 void ensureModulePreferencesScrollArea(QStackedWidget *sw) {
175 * We create pages for interior nodes even if they don't have
176 * preferences, so that we at least have something to show
177 * if the user clicks on them, even if it's empty.
180 /* Scrolled window */
182 mpsa_ = new ModulePreferencesScrollArea(module_);
183 if (sw->indexOf(mpsa_) < 0) sw->addWidget(mpsa_);
187 virtual QVariant data(int column, int role) const {
190 case Qt::DisplayRole:
191 return QString(module_->title);
192 case module_name_role_:
193 return QString (module_->name);
195 return qVariantFromValue(mpsa_);
200 return QTreeWidgetItem::data(column, role);
209 // Callbacks prefs routines
212 fill_advanced_prefs(module_t *module, gpointer root_ptr)
214 QTreeWidgetItem *root_item = static_cast<QTreeWidgetItem *>(root_ptr);
216 if (!module || !root_item) return 1;
218 if (module->numprefs < 1 && !prefs_module_has_submodules(module)) return 0;
220 QString module_title = module->title;
222 QTreeWidgetItem *tl_item = new QTreeWidgetItem(root_item);
223 tl_item->setText(0, module_title);
224 tl_item->setToolTip(0, QString("<span>%1</span>").arg(module->description));
225 tl_item->setFirstColumnSpanned(true);
226 Qt::ItemFlags item_flags = tl_item->flags();
227 item_flags &= ~(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
228 tl_item->setFlags(item_flags);
231 QList<QTreeWidgetItem *>tl_children;
232 for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = g_list_next(pref_l)) {
233 pref_t *pref = (pref_t *) pref_l->data;
235 if (pref->type == PREF_OBSOLETE || pref->type == PREF_STATIC_TEXT) continue;
237 const char *type_name = prefs_pref_type_name(pref);
238 if (!type_name) continue;
240 pref_stash(pref, NULL);
242 AdvancedPrefTreeWidgetItem *item = new AdvancedPrefTreeWidgetItem(pref, module);
245 // .uat is a void * so it wins the "useful key value" prize.
246 if (pref->varp.uat) {
247 pref_ptr_to_pref_[pref->varp.uat] = pref;
250 tl_item->addChildren(tl_children);
252 if(prefs_module_has_submodules(module))
253 return prefs_modules_foreach_submodules(module, fill_advanced_prefs, tl_item);
259 pref_exists(pref_t *, gpointer)
265 fill_module_prefs(module_t *module, gpointer ti_ptr)
267 QTreeWidgetItem *item = static_cast<QTreeWidgetItem *>(ti_ptr);
271 QStackedWidget *stacked_widget = item->data(0, stacked_role_).value<QStackedWidget *>();
273 if (!stacked_widget) return 0;
275 if (!module->use_gui) {
276 /* This module uses its own GUI interface to modify its
277 * preferences, so ignore it
283 * Is this module an interior node, with modules underneath it?
285 if (!prefs_module_has_submodules(module)) {
288 * Does it have any preferences (other than possibly obsolete ones)?
290 if (prefs_pref_foreach(module, pref_exists, NULL) == 0) {
292 * No. Don't put the module into the preferences window,
293 * as there's nothing to show.
295 * XXX - we should do the same for interior ndes; if the module
296 * has no non-obsolete preferences *and* nothing under it has
297 * non-obsolete preferences, don't put it into the window.
304 * Add this module to the tree.
306 ModulePrefTreeWidgetItem *new_mpti = new ModulePrefTreeWidgetItem(item, module);
307 new_mpti->setData(0, stacked_role_, item->data(0, stacked_role_));
310 * Is this an interior node?
312 if (prefs_module_has_submodules(module)) {
314 * Yes. Walk the subtree and attach stuff to it.
316 prefs_modules_foreach_submodules(module, fill_module_prefs, (gpointer) new_mpti);
323 module_prefs_unstash(module_t *module, gpointer data)
325 gboolean *must_redissect_p = (gboolean *)data;
326 pref_unstash_data_t unstashed_data;
328 unstashed_data.handle_decode_as = TRUE;
330 module->prefs_changed = FALSE; /* assume none of them changed */
331 for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = g_list_next(pref_l)) {
332 pref_t *pref = (pref_t *) pref_l->data;
334 if (pref->type == PREF_OBSOLETE || pref->type == PREF_STATIC_TEXT) continue;
336 unstashed_data.module = module;
337 pref_unstash(pref, &unstashed_data);
340 /* If any of them changed, indicate that we must redissect and refilter
341 the current capture (if we have one), as the preference change
342 could cause packets to be dissected differently. */
343 if (module->prefs_changed)
344 *must_redissect_p = TRUE;
346 if(prefs_module_has_submodules(module))
347 return prefs_modules_foreach_submodules(module, module_prefs_unstash, data);
349 return 0; /* Keep unstashing. */
353 module_prefs_clean_stash(module_t *module, gpointer)
355 for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = g_list_next(pref_l)) {
356 pref_t *pref = (pref_t *) pref_l->data;
358 if (pref->type == PREF_OBSOLETE || pref->type == PREF_STATIC_TEXT) continue;
360 pref_clean_stash(pref, NULL);
363 if(prefs_module_has_submodules(module))
364 return prefs_modules_foreach_submodules(module, module_prefs_clean_stash, NULL);
366 return 0; /* Keep cleaning modules */
371 // Preference tree items
372 const int appearance_item_ = 0;
373 const int capture_item_ = 1;
375 PreferencesDialog::PreferencesDialog(QWidget *parent) :
376 GeometryStateDialog(parent),
377 pd_ui_(new Ui::PreferencesDialog),
379 cur_line_edit_(NULL),
380 cur_combo_box_(NULL),
383 QTreeWidgetItem tmp_item; // Adding pre-populated top-level items is much faster
384 prefs_modules_foreach_submodules(NULL, fill_advanced_prefs, (gpointer) &tmp_item);
386 // Some classes depend on pref_ptr_to_pref_ so this MUST be called after
387 // fill_advanced_prefs.
388 pd_ui_->setupUi(this);
391 setWindowTitle(wsApp->windowTitleString(tr("Preferences")));
392 pd_ui_->advancedTree->invisibleRootItem()->addChildren(tmp_item.takeChildren());
394 pd_ui_->splitter->setStretchFactor(0, 1);
395 pd_ui_->splitter->setStretchFactor(1, 5);
397 pd_ui_->prefsTree->invisibleRootItem()->child(appearance_item_)->setExpanded(true);
399 bool disable_capture = true;
402 /* Is WPcap loaded? */
405 disable_capture = false;
409 #endif /* HAVE_LIBPCAP */
410 pd_ui_->prefsTree->invisibleRootItem()->child(capture_item_)->setDisabled(disable_capture);
412 // PreferencesPane, prefsTree, and stackedWidget must all correspond to each other.
413 // This may not be the best way to go about enforcing that.
414 QTreeWidgetItem *item = pd_ui_->prefsTree->topLevelItem(0);
415 item->setSelected(true);
416 pd_ui_->stackedWidget->setCurrentIndex(0);
417 for (int i = 0; i < pd_ui_->stackedWidget->count() && item; i++) {
418 item->setData(0, mpsa_role_, qVariantFromValue(pd_ui_->stackedWidget->widget(i)));
419 item = pd_ui_->prefsTree->itemBelow(item);
421 item = pd_ui_->prefsTree->topLevelItem(0);
422 prefs_pane_to_item_[ppAppearance] = item;
423 prefs_pane_to_item_[ppLayout] = item->child(0);
424 prefs_pane_to_item_[ppColumn] = item->child(1);
425 prefs_pane_to_item_[ppFontAndColor] = item->child(2);
426 prefs_pane_to_item_[ppCapture] = pd_ui_->prefsTree->topLevelItem(1);
427 prefs_pane_to_item_[ppFilterExpressions] = pd_ui_->prefsTree->topLevelItem(2);
429 // Printing prefs don't apply here.
430 module_t *print_module = prefs_find_module("print");
431 if (print_module) print_module->use_gui = FALSE;
433 // We called takeChildren above so this shouldn't be necessary.
434 while (tmp_item.childCount() > 0) {
435 tmp_item.removeChild(tmp_item.child(0));
437 tmp_item.setData(0, stacked_role_, qVariantFromValue(pd_ui_->stackedWidget));
438 prefs_modules_foreach_submodules(NULL, fill_module_prefs, (gpointer) &tmp_item);
439 pd_ui_->prefsTree->invisibleRootItem()->insertChildren(
440 pd_ui_->prefsTree->invisibleRootItem()->childCount() - 1, tmp_item.takeChildren());
443 PreferencesDialog::~PreferencesDialog()
446 prefs_modules_foreach_submodules(NULL, module_prefs_clean_stash, NULL);
449 void PreferencesDialog::setPane(PreferencesDialog::PreferencesPane start_pane)
451 if (prefs_pane_to_item_.contains(start_pane)) {
452 pd_ui_->prefsTree->setCurrentItem(prefs_pane_to_item_[start_pane]);
456 // Only valid for ModulePrefTreeWidgetItems.
457 void PreferencesDialog::setPane(const QString module_name)
459 QTreeWidgetItemIterator pref_it(pd_ui_->prefsTree);
461 if ((*pref_it)->type() == module_type_) {
462 ModulePrefTreeWidgetItem *mp_ti = dynamic_cast<ModulePrefTreeWidgetItem *>(*pref_it);
463 // Ensure that the module's scroll area exists and that it's in the
466 QString mpsa_name = (*pref_it)->data(0, module_name_role_).toString();
467 if (mpsa_name == module_name) {
468 mp_ti->ensureModulePreferencesScrollArea(pd_ui_->stackedWidget);
469 QWidget *mpsa = (*pref_it)->data(0, mpsa_role_).value<QWidget *>();
471 pd_ui_->prefsTree->setCurrentItem((*pref_it));
481 void PreferencesDialog::showEvent(QShowEvent *)
483 QStyleOption style_opt;
484 int new_prefs_tree_width = pd_ui_->prefsTree->style()->subElementRect(QStyle::SE_TreeViewDisclosureItem, &style_opt).left();
485 QList<int> sizes = pd_ui_->splitter->sizes();
488 new_prefs_tree_width *= 2;
490 pd_ui_->prefsTree->resizeColumnToContents(0);
491 new_prefs_tree_width += pd_ui_->prefsTree->columnWidth(0);
492 pd_ui_->prefsTree->setMinimumWidth(new_prefs_tree_width);
493 sizes[1] += sizes[0] - new_prefs_tree_width;
494 sizes[0] = new_prefs_tree_width;
495 pd_ui_->splitter->setSizes(sizes);
496 pd_ui_->splitter->setStretchFactor(0, 1);
498 pd_ui_->advancedTree->expandAll();
499 pd_ui_->advancedTree->setSortingEnabled(true);
500 pd_ui_->advancedTree->sortByColumn(0, Qt::AscendingOrder);
502 int one_em = fontMetrics().height();
503 pd_ui_->advancedTree->setColumnWidth(adv_name_col_, one_em * 12); // Don't let long items widen things too much
504 pd_ui_->advancedTree->resizeColumnToContents(adv_status_col_);
505 pd_ui_->advancedTree->resizeColumnToContents(adv_type_col_);
506 pd_ui_->advancedTree->setColumnWidth(adv_value_col_, one_em * 30);
509 void PreferencesDialog::keyPressEvent(QKeyEvent *evt)
511 if (cur_line_edit_ && cur_line_edit_->hasFocus()) {
512 switch (evt->key()) {
514 cur_line_edit_->setText(saved_string_pref_);
518 switch (cur_pref_type_) {
520 uintPrefEditingFinished();
523 stringPrefEditingFinished();
526 rangePrefEditingFinished();
532 delete cur_line_edit_;
537 } else if (cur_combo_box_ && cur_combo_box_->hasFocus()) {
538 switch (evt->key()) {
540 cur_combo_box_->setCurrentIndex(saved_combo_idx_);
544 // XXX The combo box eats enter and return
545 enumPrefCurrentIndexChanged(cur_combo_box_->currentIndex());
546 delete cur_combo_box_;
552 QDialog::keyPressEvent(evt);
555 void PreferencesDialog::on_prefsTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *)
557 if (!current) return;
558 QWidget *new_item = NULL;
560 // "current" might be a QTreeWidgetItem from our .ui file, e.g. "Columns"
561 // or a ModulePrefTreeWidgetItem created by fill_module_prefs, e.g. a
562 // protocol preference. If it's the latter, ensure that the module's
563 // scroll area exists and that it's in the widget stack.
564 if (current->type() == module_type_) {
565 ModulePrefTreeWidgetItem *mp_ti = dynamic_cast<ModulePrefTreeWidgetItem *>(current);
566 if (mp_ti) mp_ti->ensureModulePreferencesScrollArea(pd_ui_->stackedWidget);
569 new_item = current->data(0, mpsa_role_).value<QWidget *>();
570 g_assert(new_item != NULL);
571 pd_ui_->stackedWidget->setCurrentWidget(new_item);
574 void PreferencesDialog::on_advancedSearchLineEdit_textEdited(const QString &search_re)
576 QTreeWidgetItemIterator branch_it(pd_ui_->advancedTree);
577 QRegExp regex(search_re, Qt::CaseInsensitive);
579 // Hide or show everything
581 (*branch_it)->setHidden(!search_re.isEmpty());
584 if (search_re.isEmpty()) return;
586 // Hide or show each item, showing its parents if needed
587 QTreeWidgetItemIterator pref_it(pd_ui_->advancedTree);
591 if ((*pref_it)->type() == advanced_type_) {
593 if ((*pref_it)->text(0).contains(regex) ||
594 (*pref_it)->toolTip(0).contains(regex)) {
598 (*pref_it)->setHidden(hidden);
600 QTreeWidgetItem *parent = (*pref_it)->parent();
602 parent->setHidden(false);
603 parent = parent->parent();
611 void PreferencesDialog::on_advancedTree_currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *previous)
613 if (previous && pd_ui_->advancedTree->itemWidget(previous, 3)) {
614 pd_ui_->advancedTree->removeItemWidget(previous, 3);
618 void PreferencesDialog::on_advancedTree_itemActivated(QTreeWidgetItem *item, int column)
620 AdvancedPrefTreeWidgetItem *adv_ti;
623 if (item->type() == advanced_type_) {
624 adv_ti = dynamic_cast<AdvancedPrefTreeWidgetItem *>(item);
625 if (adv_ti) pref = adv_ti->pref();
628 if (!pref || cur_line_edit_ || cur_combo_box_) return;
630 if (column < 3) { // Reset to default
631 reset_stashed_pref(pref);
632 adv_ti->updatePref();
634 QWidget *editor = NULL;
636 switch (pref->type) {
637 case PREF_DECODE_AS_UINT:
639 cur_line_edit_ = new QLineEdit();
640 // cur_line_edit_->setInputMask("0000000009;");
641 saved_string_pref_ = QString::number(pref->stashed_val.uint, pref->info.base);
642 connect(cur_line_edit_, SIGNAL(editingFinished()), this, SLOT(uintPrefEditingFinished()));
643 editor = cur_line_edit_;
648 cur_line_edit_ = new QLineEdit();
649 // cur_line_edit_->setInputMask("0000000009;");
650 saved_string_pref_ = QString::number(pref->stashed_val.uint, pref->info.base);
651 connect(cur_line_edit_, SIGNAL(editingFinished()), this, SLOT(uintPrefEditingFinished()));
652 editor = cur_line_edit_;
656 pref->stashed_val.boolval = !pref->stashed_val.boolval;
657 adv_ti->updatePref();
661 cur_combo_box_ = new QComboBox();
662 const enum_val_t *ev;
663 for (ev = pref->info.enum_info.enumvals; ev && ev->description; ev++) {
664 cur_combo_box_->addItem(ev->description, QVariant(ev->value));
665 if (pref->stashed_val.enumval == ev->value)
666 cur_combo_box_->setCurrentIndex(cur_combo_box_->count() - 1);
668 saved_combo_idx_ = cur_combo_box_->currentIndex();
669 connect(cur_combo_box_, SIGNAL(currentIndexChanged(int)), this, SLOT(enumPrefCurrentIndexChanged(int)));
670 editor = cur_combo_box_;
675 cur_line_edit_ = new QLineEdit();
676 saved_string_pref_ = pref->stashed_val.string;
677 connect(cur_line_edit_, SIGNAL(editingFinished()), this, SLOT(stringPrefEditingFinished()));
678 editor = cur_line_edit_;
686 if (pref->type == PREF_FILENAME) {
687 filename = QFileDialog::getSaveFileName(this, wsApp->windowTitleString(pref->title),
688 pref->stashed_val.string);
690 filename = QFileDialog::getExistingDirectory(this, wsApp->windowTitleString(pref->title),
691 pref->stashed_val.string);
693 if (!filename.isEmpty()) {
694 g_free((void *)pref->stashed_val.string);
695 pref->stashed_val.string = qstring_strdup(QDir::toNativeSeparators(filename));
696 adv_ti->updatePref();
700 case PREF_DECODE_AS_RANGE:
703 SyntaxLineEdit *syntax_edit = new SyntaxLineEdit();
704 char *cur_val = prefs_pref_to_str(pref, pref_stashed);
705 saved_string_pref_ = gchar_free_to_qstring(cur_val);
706 connect(syntax_edit, SIGNAL(textChanged(QString)),
707 this, SLOT(rangePrefTextChanged(QString)));
708 connect(syntax_edit, SIGNAL(editingFinished()), this, SLOT(rangePrefEditingFinished()));
709 editor = cur_line_edit_ = syntax_edit;
714 QColorDialog color_dlg;
716 color_dlg.setCurrentColor(QColor(
717 pref->stashed_val.color.red >> 8,
718 pref->stashed_val.color.green >> 8,
719 pref->stashed_val.color.blue >> 8
721 if (color_dlg.exec() == QDialog::Accepted) {
722 QColor cc = color_dlg.currentColor();
723 pref->stashed_val.color.red = cc.red() << 8 | cc.red();
724 pref->stashed_val.color.green = cc.green() << 8 | cc.green();
725 pref->stashed_val.color.blue = cc.blue() << 8 | cc.blue();
726 adv_ti->updatePref();
732 if (pref->gui == GUI_ALL || pref->gui == GUI_QT) {
733 UatDialog uat_dlg(this, pref->varp.uat);
741 cur_pref_type_ = pref->type;
742 if (cur_line_edit_) {
743 cur_line_edit_->setText(saved_string_pref_);
744 cur_line_edit_->selectAll();
745 connect(cur_line_edit_, SIGNAL(destroyed()), this, SLOT(lineEditPrefDestroyed()));
747 if (cur_combo_box_) {
748 connect(cur_combo_box_, SIGNAL(destroyed()), this, SLOT(enumPrefDestroyed()));
751 QFrame *edit_frame = new QFrame();
752 QHBoxLayout *hb = new QHBoxLayout();
753 QSpacerItem *spacer = new QSpacerItem(5, 10);
755 hb->addWidget(editor, 0);
756 hb->addSpacerItem(spacer);
757 hb->setStretch(1, 1);
758 hb->setContentsMargins(0, 0, 0, 0);
760 edit_frame->setLineWidth(0);
761 edit_frame->setFrameStyle(QFrame::NoFrame);
762 // The documentation suggests setting autoFillbackground. That looks silly
763 // so we clear the item text instead.
764 item->setText(3, "");
765 edit_frame->setLayout(hb);
766 pd_ui_->advancedTree->setItemWidget(item, 3, edit_frame);
772 void PreferencesDialog::lineEditPrefDestroyed()
774 cur_line_edit_ = NULL;
777 void PreferencesDialog::enumPrefDestroyed()
779 cur_combo_box_ = NULL;
782 void PreferencesDialog::uintPrefEditingFinished()
784 AdvancedPrefTreeWidgetItem *adv_ti = dynamic_cast<AdvancedPrefTreeWidgetItem *>(pd_ui_->advancedTree->currentItem());
785 if (!cur_line_edit_ || !adv_ti) return;
787 pref_t *pref = adv_ti->pref();
791 guint new_val = cur_line_edit_->text().toUInt(&ok, pref->info.base);
793 if (ok) pref->stashed_val.uint = new_val;
794 pd_ui_->advancedTree->removeItemWidget(adv_ti, 3);
795 adv_ti->updatePref();
798 void PreferencesDialog::enumPrefCurrentIndexChanged(int index)
800 AdvancedPrefTreeWidgetItem *adv_ti = dynamic_cast<AdvancedPrefTreeWidgetItem *>(pd_ui_->advancedTree->currentItem());
801 if (!cur_combo_box_ || !adv_ti || index < 0) return;
803 pref_t *pref = adv_ti->pref();
806 pref->stashed_val.enumval = cur_combo_box_->itemData(index).toInt();
807 adv_ti->updatePref();
810 void PreferencesDialog::stringPrefEditingFinished()
812 AdvancedPrefTreeWidgetItem *adv_ti = dynamic_cast<AdvancedPrefTreeWidgetItem *>(pd_ui_->advancedTree->currentItem());
813 if (!cur_line_edit_ || !adv_ti) return;
815 pref_t *pref = adv_ti->pref();
818 g_free((void *)pref->stashed_val.string);
819 pref->stashed_val.string = qstring_strdup(cur_line_edit_->text());
820 pd_ui_->advancedTree->removeItemWidget(adv_ti, 3);
821 adv_ti->updatePref();
824 void PreferencesDialog::rangePrefTextChanged(const QString &text)
826 SyntaxLineEdit *syntax_edit = qobject_cast<SyntaxLineEdit *>(cur_line_edit_);
827 AdvancedPrefTreeWidgetItem *adv_ti = dynamic_cast<AdvancedPrefTreeWidgetItem *>(pd_ui_->advancedTree->currentItem());
828 if (!syntax_edit || !adv_ti) return;
830 pref_t *pref = adv_ti->pref();
833 if (text.isEmpty()) {
834 syntax_edit->setSyntaxState(SyntaxLineEdit::Empty);
837 convert_ret_t ret = range_convert_str(NULL, &newrange, text.toUtf8().constData(), pref->info.max_value);
839 if (ret == CVT_NO_ERROR) {
840 syntax_edit->setSyntaxState(SyntaxLineEdit::Valid);
842 syntax_edit->setSyntaxState(SyntaxLineEdit::Invalid);
844 wmem_free(NULL, newrange);
848 void PreferencesDialog::rangePrefEditingFinished()
850 SyntaxLineEdit *syntax_edit = qobject_cast<SyntaxLineEdit *>(QObject::sender());
851 AdvancedPrefTreeWidgetItem *adv_ti = dynamic_cast<AdvancedPrefTreeWidgetItem *>(pd_ui_->advancedTree->currentItem());
852 if (!syntax_edit || !adv_ti) return;
854 pref_t *pref = adv_ti->pref();
857 prefs_set_stashed_range_value(pref, syntax_edit->text().toUtf8().constData());
858 pd_ui_->advancedTree->removeItemWidget(adv_ti, 3);
859 adv_ti->updatePref();
862 void PreferencesDialog::on_buttonBox_accepted()
865 gboolean must_redissect = FALSE;
867 // XXX - We should validate preferences as the user changes them, not here.
868 // XXX - We're also too enthusiastic about setting must_redissect.
869 // if (!prefs_main_fetch_all(parent_w, &must_redissect))
870 // return; /* Errors in some preference setting - already reported */
871 prefs_modules_foreach_submodules(NULL, module_prefs_unstash, (gpointer) &must_redissect);
873 pd_ui_->columnFrame->unstash();
874 pd_ui_->filterExpressonsFrame->unstash();
877 if (save_decode_as_entries(&err) < 0)
879 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err);
883 write_language_prefs();
884 wsApp->loadLanguage(QString(language));
888 * Load the Wireshark decryption keys (just set) and save
889 * the changes to the adapters' registry
891 //airpcap_load_decryption_keys(airpcap_if_list);
894 // gtk/prefs_dlg.c:prefs_main_apply_all
896 * Apply the protocol preferences first - "gui_prefs_apply()" could
897 * cause redissection, and we have to make sure the protocol
898 * preference changes have been fully applied.
902 /* Fill in capture options with values from the preferences */
903 prefs_to_capture_opts();
906 // prefs_airpcap_update();
909 wsApp->setMonospaceFont(prefs.gui_qt_font_name);
911 if (must_redissect) {
912 /* Redissect all the packets, and re-evaluate the display filter. */
913 wsApp->queueAppSignal(WiresharkApplication::PacketDissectionChanged);
915 wsApp->queueAppSignal(WiresharkApplication::PreferencesChanged);
918 void PreferencesDialog::on_buttonBox_helpRequested()
920 wsApp->helpTopicAction(HELP_PREFERENCES_DIALOG);
929 * indent-tabs-mode: nil
932 * ex: set shiftwidth=4 tabstop=8 expandtab:
933 * :indentSize=4:tabSize=8:noTabs=true: