HACK: 1. try to match RowsetProperties
[wireshark-wip.git] / ui / qt / preferences_dialog.cpp
blobb4317e0fb2401d14ea4a384440eaa3f4ae6373b8
1 /* preferences_dialog.cpp
3 * $Id$
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "preferences_dialog.h"
25 #include "ui_preferences_dialog.h"
27 #include "module_preferences_scroll_area.h"
28 #include "wireshark_application.h"
30 #ifdef HAVE_LIBPCAP
31 #ifdef _WIN32
32 #include "capture-wpcap.h"
33 #endif /* _WIN32 */
34 #endif /* HAVE_LIBPCAP */
36 #include <epan/prefs-int.h>
38 #include <ui/preference_utils.h>
40 #include "module_preferences_scroll_area.h"
41 #include "syntax_line_edit.h"
42 #include "qt_ui_utils.h"
43 #include "uat_dialog.h"
45 #include <QColorDialog>
46 #include <QFileDialog>
47 #include <QFrame>
48 #include <QHBoxLayout>
49 #include <QKeyEvent>
50 #include <QLineEdit>
51 #include <QMessageBox>
52 #include <QSpacerItem>
53 #include <QTreeWidgetItemIterator>
55 #include <QDebug>
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];
67 extern "C" {
68 // Callbacks prefs routines
70 static guint
71 pref_exists(pref_t *pref, gpointer user_data)
73 Q_UNUSED(pref)
74 Q_UNUSED(user_data)
75 return 1;
78 static guint
79 module_prefs_show(module_t *module, gpointer ti_ptr)
81 QTreeWidgetItem *item = static_cast<QTreeWidgetItem *>(ti_ptr);
83 if (!item) return 0;
85 QStackedWidget *stacked_widget = item->data(0, Qt::UserRole).value<QStackedWidget *>();
87 if (!stacked_widget) return 0;
89 if (!module->use_gui) {
90 /* This module uses its own GUI interface to modify its
91 * preferences, so ignore it
93 return 0;
97 * Is this module an interior node, with modules underneath it?
99 if (!prefs_module_has_submodules(module)) {
101 * No.
102 * Does it have any preferences (other than possibly obsolete ones)?
104 if (prefs_pref_foreach(module, pref_exists, NULL) == 0) {
106 * No. Don't put the module into the preferences window,
107 * as there's nothing to show.
109 * XXX - we should do the same for interior ndes; if the module
110 * has no non-obsolete preferences *and* nothing under it has
111 * non-obsolete preferences, don't put it into the window.
113 return 0;
118 * Add this module to the tree.
120 QTreeWidgetItem *new_item = new QTreeWidgetItem(item);
121 new_item->setText(0, module->title);
122 new_item->setData(0, Qt::UserRole, item->data(0, Qt::UserRole));
125 * Is this an interior node?
127 if (prefs_module_has_submodules(module)) {
129 * Yes. Walk the subtree and attach stuff to it.
131 prefs_modules_foreach_submodules(module, module_prefs_show, (gpointer) new_item);
135 * We create pages for interior nodes even if they don't have
136 * preferences, so that we at least have something to show
137 * if the user clicks on them, even if it's empty.
140 /* Scrolled window */
141 ModulePreferencesScrollArea *mpsa = new ModulePreferencesScrollArea(module);
143 // /* Associate this module with the page's frame. */
144 // g_object_set_data(G_OBJECT(frame), E_PAGE_MODULE_KEY, module);
146 /* Add the page to the notebook */
147 stacked_widget->addWidget(mpsa);
149 /* Attach the page to the tree item */
150 new_item->setData(0, Qt::UserRole, qVariantFromValue(qobject_cast<QWidget *>(mpsa)));
152 return 0;
155 static guint
156 fill_advanced_prefs(module_t *module, gpointer root_ptr)
158 QTreeWidgetItem *root_item = static_cast<QTreeWidgetItem *>(root_ptr);
160 if (!module || !root_item) return 1;
162 if (module->numprefs < 1 && !prefs_module_has_submodules(module)) return 0;
164 QString module_title = module->title;
166 QTreeWidgetItem *tl_item = new QTreeWidgetItem(root_item);
167 tl_item->setText(0, module_title);
168 tl_item->setToolTip(0, QString("<span>%1</span>").arg(module->description));
169 tl_item->setFirstColumnSpanned(true);
171 QList<QTreeWidgetItem *>tl_children;
172 for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = g_list_next(pref_l)) {
173 pref_t *pref = (pref_t *) pref_l->data;
175 if (pref->type == PREF_OBSOLETE || pref->type == PREF_STATIC_TEXT) continue;
177 const char *type_name = prefs_pref_type_name(pref);
178 if (!type_name) continue;
180 pref_stash(pref, NULL);
182 QTreeWidgetItem *item = new QTreeWidgetItem();
183 QString full_name = QString(module->name ? module->name : module->parent->name) + "." + pref->name;
184 QString type_desc = gchar_free_to_qstring(prefs_pref_type_description(pref));
185 QString default_value = gchar_free_to_qstring(prefs_pref_to_str(pref, pref_stashed));
187 item->setData(0, Qt::UserRole, qVariantFromValue(pref));
188 item->setText(0, full_name);
189 item->setToolTip(0, QString("<span>%1</span>").arg(pref->description));
190 item->setToolTip(1, QObject::tr("Has this preference been changed?"));
191 item->setText(2, type_name);
192 item->setToolTip(2, QString("<span>%1</span>").arg(type_desc));
193 item->setToolTip(3, QString("<span>%1</span>").arg(
194 default_value.isEmpty() ? default_value : QObject::tr("Default value is empty")));
195 tl_children << item;
197 // .uat is a void * so it wins the "useful key value" prize.
198 if (pref->varp.uat) {
199 pref_ptr_to_pref_[pref->varp.uat] = pref;
202 tl_item->addChildren(tl_children);
204 if(prefs_module_has_submodules(module))
205 return prefs_modules_foreach_submodules(module, fill_advanced_prefs, tl_item);
207 return 0;
210 static guint
211 module_prefs_unstash(module_t *module, gpointer data)
213 gboolean *must_redissect_p = (gboolean *)data;
215 module->prefs_changed = FALSE; /* assume none of them changed */
216 for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = g_list_next(pref_l)) {
217 pref_t *pref = (pref_t *) pref_l->data;
219 if (pref->type == PREF_OBSOLETE || pref->type == PREF_STATIC_TEXT) continue;
221 pref_unstash(pref, &module->prefs_changed);
224 /* If any of them changed, indicate that we must redissect and refilter
225 the current capture (if we have one), as the preference change
226 could cause packets to be dissected differently. */
227 if (module->prefs_changed)
228 *must_redissect_p = TRUE;
230 if(prefs_module_has_submodules(module))
231 return prefs_modules_foreach_submodules(module, module_prefs_unstash, data);
233 return 0; /* Keep unstashing. */
236 static guint
237 module_prefs_clean_stash(module_t *module, gpointer unused)
239 Q_UNUSED(unused);
241 for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = g_list_next(pref_l)) {
242 pref_t *pref = (pref_t *) pref_l->data;
244 if (pref->type == PREF_OBSOLETE || pref->type == PREF_STATIC_TEXT) continue;
246 pref_clean_stash(pref, NULL);
249 if(prefs_module_has_submodules(module))
250 return prefs_modules_foreach_submodules(module, module_prefs_clean_stash, NULL);
252 return 0; /* Keep cleaning modules */
255 } // extern "C"
257 // Preference tree items
258 const int appearance_item_ = 0;
259 const int capture_item_ = 1;
261 // We store the saved and current preference values in the "Advanced" tree columns
262 const int pref_ptr_col_ = 0;
264 PreferencesDialog::PreferencesDialog(QWidget *parent) :
265 QDialog(parent),
266 pd_ui_(new Ui::PreferencesDialog),
267 cur_line_edit_(NULL),
268 cur_combo_box_(NULL)
270 QTreeWidgetItem tmp_item; // Adding pre-populated top-level items is much faster
271 prefs_modules_foreach_submodules(NULL, fill_advanced_prefs, (gpointer) &tmp_item);
273 // Some classes depend on pref_ptr_to_pref_ so this MUST be called after
274 // fill_advanced_prefs.
275 pd_ui_->setupUi(this);
276 pd_ui_->advancedTree->invisibleRootItem()->addChildren(tmp_item.takeChildren());
277 QTreeWidgetItemIterator pref_it(pd_ui_->advancedTree, QTreeWidgetItemIterator::NoChildren);
278 while (*pref_it) {
279 updateItem(*(*pref_it));
280 ++pref_it;
282 qDebug() << "FIX: Auto-size each preference pane.";
284 pd_ui_->splitter->setStretchFactor(0, 1);
285 pd_ui_->splitter->setStretchFactor(1, 5);
287 pd_ui_->prefsTree->invisibleRootItem()->child(appearance_item_)->setExpanded(true);
288 pd_ui_->prefsTree->setCurrentItem(pd_ui_->prefsTree->invisibleRootItem()->child(appearance_item_));
290 bool disable_capture = true;
291 #ifdef HAVE_LIBPCAP
292 #ifdef _WIN32
293 /* Is WPcap loaded? */
294 if (has_wpcap) {
295 #endif /* _WIN32 */
296 disable_capture = false;
297 #ifdef _WIN32
299 #endif /* _WIN32 */
300 #endif /* HAVE_LIBPCAP */
301 pd_ui_->prefsTree->invisibleRootItem()->child(capture_item_)->setDisabled(disable_capture);
303 // This assumes that the prefs tree and stacked widget contents exactly
304 // correspond to each other.
305 QTreeWidgetItem *item = pd_ui_->prefsTree->itemAt(0,0);
306 item->setSelected(true);
307 pd_ui_->stackedWidget->setCurrentIndex(0);
308 for (int i = 0; i < pd_ui_->stackedWidget->count() && item; i++) {
309 item->setData(0, Qt::UserRole, qVariantFromValue(pd_ui_->stackedWidget->widget(i)));
310 item = pd_ui_->prefsTree->itemBelow(item);
313 // Printing prefs don't apply here.
314 module_t *print_module = prefs_find_module("print");
315 if (print_module) print_module->use_gui = FALSE;
317 // We called takeChildren above so this shouldn't be necessary.
318 while (tmp_item.childCount() > 0) {
319 tmp_item.removeChild(tmp_item.child(0));
321 tmp_item.setData(0, Qt::UserRole, qVariantFromValue(pd_ui_->stackedWidget));
322 prefs_modules_foreach_submodules(NULL, module_prefs_show, (gpointer) &tmp_item);
323 pd_ui_->prefsTree->invisibleRootItem()->insertChildren(
324 pd_ui_->prefsTree->invisibleRootItem()->childCount() - 1, tmp_item.takeChildren());
327 PreferencesDialog::~PreferencesDialog()
329 delete pd_ui_;
330 prefs_modules_foreach_submodules(NULL, module_prefs_clean_stash, NULL);
333 void PreferencesDialog::showEvent(QShowEvent *evt)
335 Q_UNUSED(evt);
336 QStyleOption style_opt;
337 int new_prefs_tree_width = pd_ui_->prefsTree->style()->subElementRect(QStyle::SE_TreeViewDisclosureItem, &style_opt).left();
338 QList<int> sizes = pd_ui_->splitter->sizes();
340 #ifdef Q_OS_WIN
341 new_prefs_tree_width *= 2;
342 #endif
343 pd_ui_->prefsTree->resizeColumnToContents(0);
344 new_prefs_tree_width += pd_ui_->prefsTree->columnWidth(0);
345 pd_ui_->prefsTree->setMinimumWidth(new_prefs_tree_width);
346 sizes[1] += sizes[0] - new_prefs_tree_width;
347 sizes[0] = new_prefs_tree_width;
348 pd_ui_->splitter->setSizes(sizes);
349 pd_ui_->splitter->setStretchFactor(0, 0);
351 pd_ui_->advancedTree->expandAll();
352 pd_ui_->advancedTree->setSortingEnabled(true);
353 pd_ui_->advancedTree->sortByColumn(0, Qt::AscendingOrder);
354 pd_ui_->advancedTree->setColumnWidth(0, pd_ui_->stackedWidget->width() / 2); // Don't let long items widen things too much
355 pd_ui_->advancedTree->resizeColumnToContents(1);
356 pd_ui_->advancedTree->resizeColumnToContents(2);
357 pd_ui_->advancedTree->resizeColumnToContents(3);
360 void PreferencesDialog::keyPressEvent(QKeyEvent *evt)
362 if (cur_line_edit_ && cur_line_edit_->hasFocus()) {
363 switch (evt->key()) {
364 case Qt::Key_Escape:
365 cur_line_edit_->setText(saved_string_pref_);
366 case Qt::Key_Enter:
367 case Qt::Key_Return:
368 switch (cur_pref_type_) {
369 case PREF_UINT:
370 uintPrefEditingFinished();
371 break;
372 case PREF_STRING:
373 stringPrefEditingFinished();
374 break;
375 case PREF_RANGE:
376 rangePrefEditingFinished();
377 break;
378 default:
379 break;
382 delete cur_line_edit_;
383 return;
384 default:
385 break;
387 } else if (cur_combo_box_ && cur_combo_box_->hasFocus()) {
388 switch (evt->key()) {
389 case Qt::Key_Escape:
390 cur_combo_box_->setCurrentIndex(saved_combo_idx_);
391 case Qt::Key_Enter:
392 case Qt::Key_Return:
393 // XXX The combo box eats enter and return
394 enumPrefCurrentIndexChanged(cur_combo_box_->currentIndex());
395 delete cur_combo_box_;
396 return;
397 default:
398 break;
401 QDialog::keyPressEvent(evt);
404 // Copied from prefs.c:prefs_pref_is_default. We may want to move this to
405 // prefs.c as well.
406 bool PreferencesDialog::stashedPrefIsDefault(pref_t *pref)
408 if (!pref) return false;
410 switch (pref->type) {
412 case PREF_UINT:
413 if (pref->default_val.uint == pref->stashed_val.uint)
414 return true;
415 break;
417 case PREF_BOOL:
418 if (pref->default_val.boolval == pref->stashed_val.boolval)
419 return true;
420 break;
422 case PREF_ENUM:
423 if (pref->default_val.enumval == pref->stashed_val.enumval)
424 return true;
425 break;
427 case PREF_STRING:
428 case PREF_FILENAME:
429 case PREF_DIRNAME:
430 if (!(g_strcmp0(pref->default_val.string, pref->stashed_val.string)))
431 return true;
432 break;
434 case PREF_RANGE:
436 if ((ranges_are_equal(pref->default_val.range, pref->stashed_val.range)))
437 return true;
438 break;
441 case PREF_COLOR:
443 if ((pref->default_val.color.red == pref->stashed_val.color.red) &&
444 (pref->default_val.color.green == pref->stashed_val.color.green) &&
445 (pref->default_val.color.blue == pref->stashed_val.color.blue))
446 return true;
447 break;
450 case PREF_CUSTOM:
451 case PREF_OBSOLETE:
452 case PREF_STATIC_TEXT:
453 case PREF_UAT:
454 return false;
455 break;
457 return false;
461 void PreferencesDialog::updateItem(QTreeWidgetItem &item)
463 pref_t *pref = item.data(pref_ptr_col_, Qt::UserRole).value<pref_t *>();
464 if (!pref) return;
466 QString cur_value = gchar_free_to_qstring(prefs_pref_to_str(pref, pref_stashed)).remove(QRegExp("\n\t"));
467 bool is_changed = false;
468 QFont font = item.font(0);
470 if (pref->type == PREF_UAT || pref->type == PREF_CUSTOM) {
471 item.setText(1, tr("Unknown"));
472 } else if (stashedPrefIsDefault(pref)) {
473 item.setText(1, tr("Default"));
474 } else {
475 item.setText(1, tr("Changed"));
476 is_changed = true;
478 font.setBold(is_changed);
479 item.setFont(0, font);
480 item.setFont(0, font);
481 item.setFont(1, font);
482 item.setFont(2, font);
483 item.setFont(3, font);
485 item.setText(3, cur_value);
488 void PreferencesDialog::on_prefsTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
490 Q_UNUSED(previous)
492 if (!current) return;
493 QWidget *new_item = current->data(0, Qt::UserRole).value<QWidget *>();
494 if (new_item) {
495 pd_ui_->stackedWidget->setCurrentWidget(new_item);
496 if (new_item == pd_ui_->advancedFrame) {
497 QTreeWidgetItemIterator it(pd_ui_->advancedTree, QTreeWidgetItemIterator::NoChildren);
498 while (*it) {
499 updateItem(*(*it));
500 ++it;
506 void PreferencesDialog::on_advancedSearchLineEdit_textEdited(const QString &search_str)
508 // Hide or show each branch
509 QTreeWidgetItemIterator branch_it(pd_ui_->advancedTree);
510 while (*branch_it) {
511 if ((*branch_it)->data(pref_ptr_col_, Qt::UserRole).value<pref_t *>() == NULL) {
512 (*branch_it)->setHidden(!search_str.isEmpty());
514 ++branch_it;
517 // Hide or show each item, showing its parents if needed
518 QTreeWidgetItemIterator pref_it(pd_ui_->advancedTree);
519 while (*pref_it) {
520 bool hidden = true;
522 if ((*pref_it)->data(pref_ptr_col_, Qt::UserRole).value<pref_t *>()) {
523 QTreeWidgetItem *parent = (*pref_it)->parent();
525 if (search_str.isEmpty() ||
526 (*pref_it)->text(0).contains(search_str, Qt::CaseInsensitive) ||
527 (*pref_it)->toolTip(0).contains(search_str, Qt::CaseInsensitive)) {
528 hidden = false;
531 (*pref_it)->setHidden(hidden);
532 if (!hidden) {
533 while (parent) {
534 parent->setHidden(false);
535 parent = parent->parent();
539 ++pref_it;
543 void PreferencesDialog::on_advancedTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
545 Q_UNUSED(current);
547 if (previous && pd_ui_->advancedTree->itemWidget(previous, 3)) {
548 pd_ui_->advancedTree->removeItemWidget(previous, 3);
552 void PreferencesDialog::on_advancedTree_itemActivated(QTreeWidgetItem *item, int column)
554 pref_t *pref = item->data(pref_ptr_col_, Qt::UserRole).value<pref_t *>();
555 if (!pref || cur_line_edit_ || cur_combo_box_) return;
557 if (column < 3) { // Reset to default
558 reset_stashed_pref(pref);
559 updateItem(*item);
560 } else {
561 QWidget *editor = NULL;
563 switch (pref->type) {
564 case PREF_UINT:
566 cur_line_edit_ = new QLineEdit();
567 // cur_line_edit_->setInputMask("0000000009;");
568 saved_string_pref_ = QString::number(pref->stashed_val.uint, pref->info.base);
569 connect(cur_line_edit_, SIGNAL(editingFinished()), this, SLOT(uintPrefEditingFinished()));
570 editor = cur_line_edit_;
571 break;
573 case PREF_BOOL:
574 pref->stashed_val.boolval = !pref->stashed_val.boolval;
575 updateItem(*item);
576 break;
577 case PREF_ENUM:
579 cur_combo_box_ = new QComboBox();
580 const enum_val_t *ev;
581 for (ev = pref->info.enum_info.enumvals; ev && ev->description; ev++) {
582 cur_combo_box_->addItem(ev->description, QVariant(ev->value));
583 if (pref->stashed_val.enumval == ev->value)
584 cur_combo_box_->setCurrentIndex(cur_combo_box_->count() - 1);
586 saved_combo_idx_ = cur_combo_box_->currentIndex();
587 connect(cur_combo_box_, SIGNAL(currentIndexChanged(int)), this, SLOT(enumPrefCurrentIndexChanged(int)));
588 editor = cur_combo_box_;
589 break;
591 case PREF_STRING:
593 cur_line_edit_ = new QLineEdit();
594 saved_string_pref_ = pref->stashed_val.string;
595 connect(cur_line_edit_, SIGNAL(editingFinished()), this, SLOT(stringPrefEditingFinished()));
596 editor = cur_line_edit_;
597 break;
599 case PREF_FILENAME:
600 case PREF_DIRNAME:
602 QString filename;
604 if (pref->type == PREF_FILENAME) {
605 filename = QFileDialog::getSaveFileName(this,
606 QString(tr("Wireshark: ")) + pref->description,
607 pref->stashed_val.string);
608 } else {
609 filename = QFileDialog::getExistingDirectory(this,
610 QString(tr("Wireshark: ")) + pref->description,
611 pref->stashed_val.string);
613 if (!filename.isEmpty()) {
614 g_free((void *)pref->stashed_val.string);
615 pref->stashed_val.string = qstring_strdup(filename);
616 updateItem(*item);
618 break;
620 case PREF_RANGE:
622 SyntaxLineEdit *syntax_edit = new SyntaxLineEdit();
623 char *cur_val = prefs_pref_to_str(pref, pref_stashed);
624 saved_string_pref_ = gchar_free_to_qstring(cur_val);
625 connect(syntax_edit, SIGNAL(textChanged(QString)),
626 this, SLOT(rangePrefTextChanged(QString)));
627 connect(syntax_edit, SIGNAL(editingFinished()), this, SLOT(rangePrefEditingFinished()));
628 editor = cur_line_edit_ = syntax_edit;
629 break;
631 case PREF_COLOR:
633 QColorDialog color_dlg;
635 color_dlg.setCurrentColor(QColor(
636 pref->stashed_val.color.red >> 8,
637 pref->stashed_val.color.green >> 8,
638 pref->stashed_val.color.blue >> 8
640 if (color_dlg.exec() == QDialog::Accepted) {
641 QColor cc = color_dlg.currentColor();
642 pref->stashed_val.color.red = cc.red() << 8 | cc.red();
643 pref->stashed_val.color.green = cc.green() << 8 | cc.green();
644 pref->stashed_val.color.blue = cc.blue() << 8 | cc.blue();
645 updateItem(*item);
647 break;
649 case PREF_UAT:
651 UatDialog uat_dlg(this, pref->varp.uat);
652 uat_dlg.exec();
653 break;
655 default:
656 break;
658 cur_pref_type_ = pref->type;
659 if (cur_line_edit_) {
660 cur_line_edit_->setText(saved_string_pref_);
661 cur_line_edit_->selectAll();
662 connect(cur_line_edit_, SIGNAL(destroyed()), this, SLOT(lineEditPrefDestroyed()));
664 if (cur_combo_box_) {
665 connect(cur_combo_box_, SIGNAL(destroyed()), this, SLOT(enumPrefDestroyed()));
667 if (editor) {
668 QFrame *edit_frame = new QFrame();
669 QHBoxLayout *hb = new QHBoxLayout();
670 QSpacerItem *spacer = new QSpacerItem(5, 10);
672 hb->addWidget(editor, 0);
673 hb->addSpacerItem(spacer);
674 hb->setStretch(1, 1);
675 hb->setContentsMargins(0, 0, 0, 0);
677 edit_frame->setLineWidth(0);
678 edit_frame->setFrameStyle(QFrame::NoFrame);
679 // The documentation suggests setting autoFillbackground. That looks silly
680 // so we clear the item text instead.
681 item->setText(3, "");
682 edit_frame->setLayout(hb);
683 pd_ui_->advancedTree->setItemWidget(item, 3, edit_frame);
684 editor->setFocus();
689 void PreferencesDialog::lineEditPrefDestroyed()
691 cur_line_edit_ = NULL;
694 void PreferencesDialog::enumPrefDestroyed()
696 cur_combo_box_ = NULL;
699 void PreferencesDialog::uintPrefEditingFinished()
701 QTreeWidgetItem *item = pd_ui_->advancedTree->currentItem();
702 if (!cur_line_edit_ || !item) return;
704 pref_t *pref = item->data(pref_ptr_col_, Qt::UserRole).value<pref_t *>();
705 if (!pref) return;
707 bool ok;
708 guint new_val = cur_line_edit_->text().toUInt(&ok, pref->info.base);
710 if (ok) pref->stashed_val.uint = new_val;
711 pd_ui_->advancedTree->removeItemWidget(item, 3);
712 updateItem(*item);
715 void PreferencesDialog::enumPrefCurrentIndexChanged(int index)
717 QTreeWidgetItem *item = pd_ui_->advancedTree->currentItem();
718 if (!cur_combo_box_ || !item || index < 0) return;
720 pref_t *pref = item->data(pref_ptr_col_, Qt::UserRole).value<pref_t *>();
721 if (!pref) return;
723 pref->stashed_val.enumval = cur_combo_box_->itemData(index).toInt();
724 updateItem(*item);
727 void PreferencesDialog::stringPrefEditingFinished()
729 QTreeWidgetItem *item = pd_ui_->advancedTree->currentItem();
730 if (!cur_line_edit_ || !item) return;
732 pref_t *pref = item->data(pref_ptr_col_, Qt::UserRole).value<pref_t *>();
733 if (!pref) return;
735 g_free((void *)pref->stashed_val.string);
736 pref->stashed_val.string = qstring_strdup(cur_line_edit_->text());
737 pd_ui_->advancedTree->removeItemWidget(item, 3);
738 updateItem(*item);
741 void PreferencesDialog::rangePrefTextChanged(const QString &text)
743 SyntaxLineEdit *syntax_edit = qobject_cast<SyntaxLineEdit *>(cur_line_edit_);
744 QTreeWidgetItem *item = pd_ui_->advancedTree->currentItem();
745 if (!syntax_edit || !item) return;
747 pref_t *pref = item->data(pref_ptr_col_, Qt::UserRole).value<pref_t *>();
748 if (!pref) return;
750 if (text.isEmpty()) {
751 syntax_edit->setSyntaxState(SyntaxLineEdit::Empty);
752 } else {
753 range_t *newrange;
754 convert_ret_t ret = range_convert_str(&newrange, text.toUtf8().constData(), pref->info.max_value);
756 if (ret == CVT_NO_ERROR) {
757 syntax_edit->setSyntaxState(SyntaxLineEdit::Valid);
758 g_free(newrange);
759 } else {
760 syntax_edit->setSyntaxState(SyntaxLineEdit::Invalid);
765 void PreferencesDialog::rangePrefEditingFinished()
767 SyntaxLineEdit *syntax_edit = qobject_cast<SyntaxLineEdit *>(QObject::sender());
768 QTreeWidgetItem *item = pd_ui_->advancedTree->currentItem();
769 if (!syntax_edit || !item) return;
771 pref_t *pref = item->data(pref_ptr_col_, Qt::UserRole).value<pref_t *>();
772 if (!pref) return;
774 range_t *newrange;
775 convert_ret_t ret = range_convert_str(&newrange, syntax_edit->text().toUtf8().constData(), pref->info.max_value);
777 if (ret == CVT_NO_ERROR) {
778 g_free(pref->stashed_val.range);
779 pref->stashed_val.range = newrange;
781 pd_ui_->advancedTree->removeItemWidget(item, 3);
782 updateItem(*item);
785 void PreferencesDialog::on_buttonBox_accepted()
787 gboolean must_redissect = FALSE;
789 // XXX - We should validate preferences as the user changes them, not here.
790 // if (!prefs_main_fetch_all(parent_w, &must_redissect))
791 // return; /* Errors in some preference setting - already reported */
792 prefs_modules_foreach_submodules(NULL, module_prefs_unstash, (gpointer) &must_redissect);
794 pd_ui_->columnFrame->unstash();
795 pd_ui_->filterExpressonsFrame->unstash();
797 prefs_main_write();
799 #ifdef HAVE_AIRPCAP
801 * Load the Wireshark decryption keys (just set) and save
802 * the changes to the adapters' registry
804 //airpcap_load_decryption_keys(airpcap_if_list);
805 #endif
807 /* Fill in capture options with values from the preferences */
808 prefs_to_capture_opts();
810 #ifdef HAVE_AIRPCAP
811 // prefs_airpcap_update();
812 #endif
814 wsApp->setMonospaceFont(prefs.gui_qt_font_name);
815 wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
817 /* Now destroy the "Preferences" dialog. */
818 // window_destroy(GTK_WIDGET(parent_w));
820 if (must_redissect) {
821 /* Redissect all the packets, and re-evaluate the display filter. */
822 wsApp->emitAppSignal(WiresharkApplication::PacketDissectionChanged);
826 void PreferencesDialog::on_buttonBox_helpRequested()
828 wsApp->helpTopicAction(HELP_PREFERENCES_DIALOG);
832 * Editor modelines
834 * Local Variables:
835 * c-basic-offset: 4
836 * tab-width: 8
837 * indent-tabs-mode: nil
838 * End:
840 * ex: set shiftwidth=4 tabstop=8 expandtab:
841 * :indentSize=4:tabSize=8:noTabs=true: