aboutsummaryrefslogtreecommitdiffstats
path: root/ui/qt/preferences_dialog.cpp
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2013-01-07 19:13:03 +0000
committerGerald Combs <gerald@wireshark.org>2013-01-07 19:13:03 +0000
commit0fa6a4c4216bf3c1e5e19d007893b8494e1860d0 (patch)
tree4623d8fe653f56522126acddc781e705060d27ab /ui/qt/preferences_dialog.cpp
parentb671f8dbd6b6a2ae62ac0a5459930eb7c86979a3 (diff)
Allow editing via the advanced preferences tree. Double-clicking an
item's name, status, or type resets it to its default value. Double-clicking the item's value lets you edit it. Implement the advanced search field. (Clicking OK and Cancel still doesn't yet do anything.) Note that we could probably use a prefs_register_{uint16|port}_preference routine for 16-bit values. Make reset_pref public. Update some names and descriptions. svn path=/trunk/; revision=46986
Diffstat (limited to 'ui/qt/preferences_dialog.cpp')
-rw-r--r--ui/qt/preferences_dialog.cpp390
1 files changed, 333 insertions, 57 deletions
diff --git a/ui/qt/preferences_dialog.cpp b/ui/qt/preferences_dialog.cpp
index 1e12a5a560..495f71b4bd 100644
--- a/ui/qt/preferences_dialog.cpp
+++ b/ui/qt/preferences_dialog.cpp
@@ -21,22 +21,26 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "config.h"
-
-#include <glib.h>
-
-#include "color.h"
-#include "packet-range.h"
-
-#include <epan/prefs.h>
-#include <epan/prefs-int.h>
-
#include "preferences_dialog.h"
#include "ui_preferences_dialog.h"
+#include "wireshark_application.h"
+
+#include <epan/prefs-int.h>
+#include "syntax_line_edit.h"
+#include <QTreeWidgetItemIterator>
+#include <QFrame>
+#include <QHBoxLayout>
+#include <QSpacerItem>
+#include <QLineEdit>
+#include <QComboBox>
+#include <QFileDialog>
+#include <QColorDialog>
#include <QMessageBox>
#include <QDebug>
+Q_DECLARE_METATYPE(pref_t *)
+
extern "C" {
// Callbacks prefs routines
@@ -49,15 +53,11 @@ fill_advanced_prefs(module_t *module, gpointer root_ptr)
if (module->numprefs < 1 && !prefs_module_has_submodules(module)) return 0;
- QString module_title;
-// if (module->parent == NULL)
- module_title = module->title;
-// else
-// module_title = QString(module->parent->title) +": "+ module->title;
+ QString module_title = module->title;
QTreeWidgetItem *tl_item = new QTreeWidgetItem(root_item);
tl_item->setText(0, module_title);
- tl_item->setToolTip(0, module->description);
+ tl_item->setToolTip(0, QString("<span>%1</span>").arg(module->description));
tl_item->setFirstColumnSpanned(true);
QList<QTreeWidgetItem *>tl_children;
@@ -70,43 +70,19 @@ fill_advanced_prefs(module_t *module, gpointer root_ptr)
QTreeWidgetItem *item = new QTreeWidgetItem();
QString full_name = QString(module->name ? module->name : module->parent->name) + "." + pref->name;
- QFont font = item->font(0);
char *type_desc = prefs_pref_type_description(pref);
- char *cur_value = prefs_pref_to_str(pref, false);
- char *default_value = prefs_pref_to_str(pref, true);
- bool is_default = false;
- bool is_editable = true;
-
- if (pref->type == PREF_UAT) {
- is_editable = false;
- } else {
- if (prefs_pref_is_default(pref)) is_default = true;
- }
+ char * default_value = prefs_pref_to_str(pref, true);
+ item->setData(0, Qt::UserRole, qVariantFromValue(pref));
item->setText(0, full_name);
- item->setToolTip(0, pref->description);
- item->setText(1, is_default ? "Default" : "Changed");
- item->setToolTip(1, "Has this value been changed?");
+ item->setToolTip(0, QString("<span>%1</span>").arg(pref->description));
item->setText(2, type_name);
- item->setToolTip(2, type_desc);
- item->setText(3, QString(cur_value).replace(QRegExp("\n\t"), " "));
- item->setToolTip(3, QString("Default: ") + default_value);
+ item->setToolTip(2, QString("<span>%1</span>").arg(type_desc));
+ item->setToolTip(3, QString("<span>%1</span>").arg(strlen(default_value) < 1 ? "Default value is empty" : default_value));
+
g_free(type_desc);
- g_free(cur_value);
g_free(default_value);
- font.setBold(!is_default);
-
- if (!is_editable) {
- item->setFlags(item->flags() ^ Qt::ItemIsEnabled);
- }
- font.setItalic(!is_editable);
- item->setFont(0, font);
-
- item->setFont(0, font);
- item->setFont(1, font);
- item->setFont(2, font);
- item->setFont(3, font);
tl_children << item;
}
tl_item->addChildren(tl_children);
@@ -130,25 +106,24 @@ PreferencesDialog::PreferencesDialog(QWidget *parent) :
pd_ui_(new Ui::PreferencesDialog)
{
pd_ui_->setupUi(this);
- QTreeWidgetItem tmp_item;
+ QTreeWidgetItem tmp_item; // Adding pre-populated top-level items is much faster
- pd_ui_->advancedTree->setUpdatesEnabled(false);
prefs_modules_foreach_submodules(NULL, fill_advanced_prefs, (gpointer) &tmp_item);
+
pd_ui_->advancedTree->invisibleRootItem()->addChildren(tmp_item.takeChildren());
- pd_ui_->advancedTree->expandAll();
- pd_ui_->advancedTree->setSortingEnabled(true);
- pd_ui_->advancedTree->sortByColumn(0, Qt::AscendingOrder);
- pd_ui_->advancedTree->setColumnWidth(0, pd_ui_->advancedTree->width() * 2 / 5);
- pd_ui_->advancedTree->resizeColumnToContents(1);
- pd_ui_->advancedTree->resizeColumnToContents(2);
- pd_ui_->advancedTree->setColumnWidth(3, pd_ui_->advancedTree->width() * 3 / 5);
- pd_ui_->advancedTree->setUpdatesEnabled(true);
+ QTreeWidgetItemIterator pref_it(pd_ui_->advancedTree, QTreeWidgetItemIterator::NoChildren);
+ while (*pref_it) {
+// pref_t *pref = (*pref_it)->data(0, Qt::UserRole).value<pref_t *>();
+ updateItem(*(*pref_it));
+// if (pref) pref_item_hash_[pref] = (*pref_it);
+ ++pref_it;
+ }
pd_ui_->splitter->setStretchFactor(0, 1);
pd_ui_->splitter->setStretchFactor(1, 5);
pd_ui_->prefsTree->invisibleRootItem()->child(appearance_item_)->setExpanded(true);
- pd_ui_->prefsTree->invisibleRootItem()->child(advanced_item_)->setSelected(true);
+ pd_ui_->prefsTree->setCurrentItem(pd_ui_->prefsTree->invisibleRootItem()->child(advanced_item_));
}
PreferencesDialog::~PreferencesDialog()
@@ -169,6 +144,307 @@ void PreferencesDialog::showEvent(QShowEvent *evt)
sizes[0] = new_prefs_tree_width;
pd_ui_->splitter->setSizes(sizes);
pd_ui_->splitter->setStretchFactor(0, 0);
+
+ pd_ui_->advancedTree->expandAll();
+ pd_ui_->advancedTree->setSortingEnabled(true);
+ pd_ui_->advancedTree->sortByColumn(0, Qt::AscendingOrder);
+ pd_ui_->advancedTree->setColumnWidth(0, pd_ui_->stackedWidget->width() / 2); // Don't let long items widen things too much
+ pd_ui_->advancedTree->resizeColumnToContents(1);
+ pd_ui_->advancedTree->resizeColumnToContents(2);
+ pd_ui_->advancedTree->resizeColumnToContents(3);
+}
+
+void PreferencesDialog::updateItem(QTreeWidgetItem &item)
+{
+ pref_t *pref = item.data(0, Qt::UserRole).value<pref_t *>();
+ if (!pref) return;
+
+ char *cur_value = prefs_pref_to_str(pref, false);
+ bool is_changed = false;
+ QFont font = item.font(0);
+
+ if (pref->type == PREF_UAT) {
+ item.setText(1, "Unknown");
+ } else if (prefs_pref_is_default(pref)) {
+ item.setText(1, "Default");
+ } else {
+ item.setText(1, "Changed");
+ is_changed = true;
+ }
+ font.setBold(is_changed);
+ item.setFont(0, font);
+ item.setFont(0, font);
+ item.setFont(1, font);
+ item.setFont(2, font);
+ item.setFont(3, font);
+
+ item.setToolTip(1, "Has this value been changed?");
+ item.setText(3, QString(cur_value).remove(QRegExp("\n\t")));
+ g_free(cur_value);
+}
+
+void PreferencesDialog::on_prefsTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
+{
+ Q_UNUSED(previous)
+ QString frame_name = current->text(0).remove(" ").toLower().append("Frame");
+ QFrame *frame = pd_ui_->stackedWidget->findChild<QFrame *>(frame_name);
+ if (frame) {
+ pd_ui_->stackedWidget->setCurrentWidget(frame);
+ }
+}
+
+void PreferencesDialog::on_advancedSearchLineEdit_textEdited(const QString &search_str)
+{
+ // Hide or show each branch
+ QTreeWidgetItemIterator branch_it(pd_ui_->advancedTree);
+ while (*branch_it) {
+ if ((*branch_it)->data(0, Qt::UserRole).value<pref_t *>() == NULL) {
+ (*branch_it)->setHidden(!search_str.isEmpty());
+ }
+ ++branch_it;
+ }
+
+ // Hide or show each item, showing its parents if needed
+ QTreeWidgetItemIterator pref_it(pd_ui_->advancedTree);
+ while (*pref_it) {
+ bool hidden = true;
+
+ if ((*pref_it)->data(0, Qt::UserRole).value<pref_t *>()) {
+ QTreeWidgetItem *parent = (*pref_it)->parent();
+
+ if (search_str.isEmpty() ||
+ (*pref_it)->text(0).contains(search_str, Qt::CaseInsensitive) ||
+ (*pref_it)->toolTip(0).contains(search_str, Qt::CaseInsensitive)) {
+ hidden = false;
+ }
+
+ (*pref_it)->setHidden(hidden);
+ if (!hidden) {
+ while (parent) {
+ parent->setHidden(false);
+ parent = parent->parent();
+ }
+ }
+ }
+ ++pref_it;
+ }
+}
+
+void PreferencesDialog::on_advancedTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
+{
+ Q_UNUSED(current);
+
+ if (previous && pd_ui_->advancedTree->itemWidget(previous, 3)) {
+ pd_ui_->advancedTree->removeItemWidget(previous, 3);
+ }
+}
+
+void PreferencesDialog::on_advancedTree_itemActivated(QTreeWidgetItem *item, int column)
+{
+ pref_t *pref = item->data(0, Qt::UserRole).value<pref_t *>();
+ if (!pref) return;
+
+ if (column < 3) {
+ reset_pref(pref);
+ updateItem(*item);
+ } else {
+ QWidget *editor = NULL;
+
+ switch (pref->type) {
+ case PREF_UINT:
+ {
+ QLineEdit *line_edit = new QLineEdit();
+ line_edit->setInputMask("0000000009;");
+ line_edit->setText(*pref->varp.string);
+ connect(line_edit, SIGNAL(editingFinished()), this, SLOT(uintPrefEditingFinished()));
+ editor = line_edit;
+ break;
+ }
+ case PREF_BOOL:
+ *pref->varp.boolp = !*pref->varp.boolp;
+ updateItem(*item);
+ break;
+ case PREF_ENUM:
+ {
+ QComboBox *combo = new QComboBox();
+ const enum_val_t *ev;
+ for (ev = pref->info.enum_info.enumvals; ev && ev->description; ev++) {
+ combo->addItem(ev->description, QVariant(ev->value));
+ if (*pref->varp.enump == ev->value)
+ combo->setCurrentIndex(combo->count() - 1);
+ }
+ connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(enumPrefCurrentIndexChanged(int)));
+ editor = combo;
+ break;
+ }
+ case PREF_STRING:
+ {
+ QLineEdit *line_edit = new QLineEdit();
+ line_edit->setText(*pref->varp.string);
+ connect(line_edit, SIGNAL(editingFinished()), this, SLOT(stringPrefEditingFinished()));
+ editor = line_edit;
+ break;
+ }
+ case PREF_FILENAME:
+ {
+ QString filename = QFileDialog::getSaveFileName(this,
+ QString("Wireshark: ") + pref->description,
+ *pref->varp.string);
+ if (!filename.isEmpty()) {
+ g_free((void *)*pref->varp.string);
+ *pref->varp.string = g_strdup(filename.toUtf8().constData());
+ updateItem(*item);
+ }
+ break;
+ }
+ case PREF_RANGE:
+ {
+ SyntaxLineEdit *syntax_edit = new SyntaxLineEdit();
+ char *cur_val = prefs_pref_to_str(pref, FALSE);
+ connect(syntax_edit, SIGNAL(textChanged(QString)),
+ this, SLOT(rangePrefTextChanged(QString)));
+ connect(syntax_edit, SIGNAL(editingFinished()), this, SLOT(rangePrefEditingFinished()));
+ syntax_edit->setText(cur_val);
+ g_free(cur_val);
+ editor = syntax_edit;
+ break;
+ }
+ case PREF_COLOR:
+ {
+ QColorDialog color_dlg;
+
+ color_dlg.setCurrentColor(QColor(
+ pref->varp.color->red >> 8,
+ pref->varp.color->green >> 8,
+ pref->varp.color->blue >> 8
+ ));
+ if (color_dlg.exec() == QDialog::Accepted) {
+ QColor cc = color_dlg.currentColor();
+ pref->varp.color->red = cc.red() << 8 | cc.red();
+ pref->varp.color->green = cc.green() << 8 | cc.green();
+ pref->varp.color->blue = cc.blue() << 8 | cc.blue();
+ updateItem(*item);
+ }
+ break;
+ }
+ case PREF_UAT:
+ qDebug() << "FIX open uat dialog" << item->text(column);
+ break;
+ default:
+ break;
+ }
+ if (editor) {
+ QFrame *edit_frame = new QFrame();
+ QHBoxLayout *hb = new QHBoxLayout();
+ QSpacerItem *spacer = new QSpacerItem(5, 10);
+
+ hb->addWidget(editor, 0);
+ hb->addSpacerItem(spacer);
+ hb->setStretch(1, 1);
+ hb->setContentsMargins(0, 0, 0, 0);
+
+ edit_frame->setLineWidth(0);
+ edit_frame->setFrameStyle(QFrame::NoFrame);
+ // The documentation suggests setting autoFillbackground. That looks silly
+ // so we clear the item text instead.
+ item->setText(3, "");
+ edit_frame->setLayout(hb);
+ pd_ui_->advancedTree->setItemWidget(item, 3, edit_frame);
+ editor->setFocus();
+ }
+ }
+}
+
+void PreferencesDialog::uintPrefEditingFinished()
+{
+ QLineEdit *line_edit = qobject_cast<QLineEdit *>(QObject::sender());
+ QTreeWidgetItem *item = pd_ui_->advancedTree->currentItem();
+ if (!line_edit || !item) return;
+
+ pref_t *pref = item->data(0, Qt::UserRole).value<pref_t *>();
+ if (!pref) return;
+
+ *pref->varp.uint = line_edit->text().toUInt();
+ pd_ui_->advancedTree->removeItemWidget(item, 3);
+ updateItem(*item);
+}
+
+void PreferencesDialog::enumPrefCurrentIndexChanged(int index)
+{
+ QComboBox *combo_box = qobject_cast<QComboBox *>(QObject::sender());
+ QTreeWidgetItem *item = pd_ui_->advancedTree->currentItem();
+ if (!combo_box || !item || index < 0) return;
+
+ pref_t *pref = item->data(0, Qt::UserRole).value<pref_t *>();
+ if (!pref) return;
+
+ *pref->varp.enump = combo_box->itemData(index, Qt::UserRole).toInt();
+// pd_ui_->advancedTree->removeItemWidget(item, 3); // Crashes
+ updateItem(*item);
+}
+
+void PreferencesDialog::stringPrefEditingFinished()
+{
+ QLineEdit *line_edit = qobject_cast<QLineEdit *>(QObject::sender());
+ QTreeWidgetItem *item = pd_ui_->advancedTree->currentItem();
+ if (!line_edit || !item) return;
+
+ pref_t *pref = item->data(0, Qt::UserRole).value<pref_t *>();
+ if (!pref) return;
+
+ g_free((void *)*pref->varp.string);
+ *pref->varp.string = g_strdup(line_edit->text().toUtf8().constData());
+ pd_ui_->advancedTree->removeItemWidget(item, 3);
+ updateItem(*item);
+}
+
+void PreferencesDialog::rangePrefTextChanged(const QString &text)
+{
+ SyntaxLineEdit *syntax_edit = qobject_cast<SyntaxLineEdit *>(QObject::sender());
+ QTreeWidgetItem *item = pd_ui_->advancedTree->currentItem();
+ if (!syntax_edit || !item) return;
+
+ pref_t *pref = item->data(0, Qt::UserRole).value<pref_t *>();
+ if (!pref) return;
+
+ if (text.isEmpty()) {
+ syntax_edit->setSyntaxState(SyntaxLineEdit::Empty);
+ } else {
+ range_t *newrange;
+ convert_ret_t ret = range_convert_str(&newrange, text.toUtf8().constData(), pref->info.max_value);
+
+ if (ret == CVT_NO_ERROR) {
+ syntax_edit->setSyntaxState(SyntaxLineEdit::Valid);
+ g_free(newrange);
+ } else {
+ syntax_edit->setSyntaxState(SyntaxLineEdit::Invalid);
+ }
+ }
+}
+
+void PreferencesDialog::rangePrefEditingFinished()
+{
+ SyntaxLineEdit *syntax_edit = qobject_cast<SyntaxLineEdit *>(QObject::sender());
+ QTreeWidgetItem *item = pd_ui_->advancedTree->currentItem();
+ if (!syntax_edit || !item) return;
+
+ pref_t *pref = item->data(0, Qt::UserRole).value<pref_t *>();
+ if (!pref) return;
+
+ range_t *newrange;
+ convert_ret_t ret = range_convert_str(&newrange, syntax_edit->text().toUtf8().constData(), pref->info.max_value);
+
+ if (ret == CVT_NO_ERROR) {
+ g_free(*pref->varp.range);
+ *pref->varp.range = newrange;
+ }
+ pd_ui_->advancedTree->removeItemWidget(item, 3);
+ updateItem(*item);
+}
+
+void PreferencesDialog::on_buttonBox_helpRequested()
+{
+ wsApp->helpTopicAction(HELP_PREFERENCES_DIALOG);
}
/*