diff options
author | Gerald Combs <gerald@wireshark.org> | 2013-01-14 22:21:11 +0000 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 2013-01-14 22:21:11 +0000 |
commit | b82f42d8cf43db14a13a8a064873884fafc2deb1 (patch) | |
tree | f7ce35ae6689e002b80b30b3c485bfa8f0cace43 /ui/qt | |
parent | 21f9ab573dc775eafd64e8408cc647bf1cb7eedb (diff) | |
download | wireshark-b82f42d8cf43db14a13a8a064873884fafc2deb1.tar.gz wireshark-b82f42d8cf43db14a13a8a064873884fafc2deb1.tar.bz2 wireshark-b82f42d8cf43db14a13a8a064873884fafc2deb1.zip |
When the user is editing text or selecting from a combo box, don't
immediately close the dialog if he or she presses the escape or enter
keys. Revert the value if the user presses escape. Properly handle the
base for uint preferences. Fix a NULL pointer dereference.
Add a gchar_free_to_qstring utility routine which creates a QString from
a g_malloced string and frees it.
svn path=/trunk/; revision=47083
Diffstat (limited to 'ui/qt')
-rw-r--r-- | ui/qt/preferences_dialog.cpp | 144 | ||||
-rw-r--r-- | ui/qt/preferences_dialog.h | 9 | ||||
-rw-r--r-- | ui/qt/qt_ui_utils.cpp | 6 | ||||
-rw-r--r-- | ui/qt/qt_ui_utils.h | 11 |
4 files changed, 128 insertions, 42 deletions
diff --git a/ui/qt/preferences_dialog.cpp b/ui/qt/preferences_dialog.cpp index 495f71b4bd..8f96ffee6a 100644 --- a/ui/qt/preferences_dialog.cpp +++ b/ui/qt/preferences_dialog.cpp @@ -28,15 +28,18 @@ #include <epan/prefs-int.h> #include "syntax_line_edit.h" +#include "qt_ui_utils.h" + #include <QTreeWidgetItemIterator> #include <QFrame> #include <QHBoxLayout> #include <QSpacerItem> #include <QLineEdit> -#include <QComboBox> #include <QFileDialog> #include <QColorDialog> #include <QMessageBox> +#include <QPushButton> +#include <QKeyEvent> #include <QDebug> Q_DECLARE_METATYPE(pref_t *) @@ -65,24 +68,22 @@ fill_advanced_prefs(module_t *module, gpointer root_ptr) pref_t *pref = (pref_t *) pref_l->data; if (pref->type == PREF_OBSOLETE || pref->type == PREF_STATIC_TEXT) continue; + const char *type_name = prefs_pref_type_name(pref); if (!type_name) continue; QTreeWidgetItem *item = new QTreeWidgetItem(); QString full_name = QString(module->name ? module->name : module->parent->name) + "." + pref->name; - char *type_desc = prefs_pref_type_description(pref); - char * default_value = prefs_pref_to_str(pref, true); + QString type_desc = gchar_free_to_qstring(prefs_pref_type_description(pref)); + QString default_value = gchar_free_to_qstring(prefs_pref_to_str(pref, true)); item->setData(0, Qt::UserRole, qVariantFromValue(pref)); item->setText(0, full_name); item->setToolTip(0, QString("<span>%1</span>").arg(pref->description)); item->setText(2, type_name); 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(default_value); - + item->setToolTip(3, QString("<span>%1</span>").arg( + default_value.isEmpty() ? default_value : "Default value is empty")); tl_children << item; } tl_item->addChildren(tl_children); @@ -93,7 +94,6 @@ fill_advanced_prefs(module_t *module, gpointer root_ptr) return 0; } - } // extern "C" const int appearance_item_ = 0; @@ -103,7 +103,9 @@ const int advanced_item_ = 6; PreferencesDialog::PreferencesDialog(QWidget *parent) : QDialog(parent), - pd_ui_(new Ui::PreferencesDialog) + pd_ui_(new Ui::PreferencesDialog), + cur_line_edit_(NULL), + cur_combo_box_(NULL) { pd_ui_->setupUi(this); QTreeWidgetItem tmp_item; // Adding pre-populated top-level items is much faster @@ -154,12 +156,56 @@ void PreferencesDialog::showEvent(QShowEvent *evt) pd_ui_->advancedTree->resizeColumnToContents(3); } +void PreferencesDialog::keyPressEvent(QKeyEvent *evt) +{ + if (cur_line_edit_ && cur_line_edit_->hasFocus()) { + switch (evt->key()) { + case Qt::Key_Escape: + cur_line_edit_->setText(saved_string_pref_); + case Qt::Key_Enter: + case Qt::Key_Return: + switch (cur_pref_type_) { + case PREF_UINT: + uintPrefEditingFinished(); + break; + case PREF_STRING: + stringPrefEditingFinished(); + break; + case PREF_RANGE: + rangePrefEditingFinished(); + break; + default: + break; + } + + delete cur_line_edit_; + return; + default: + break; + } + } else if (cur_combo_box_ && cur_combo_box_->hasFocus()) { + switch (evt->key()) { + case Qt::Key_Escape: + cur_combo_box_->setCurrentIndex(saved_combo_idx_); + case Qt::Key_Enter: + case Qt::Key_Return: + // XXX The combo box eats enter and return + enumPrefCurrentIndexChanged(cur_combo_box_->currentIndex()); + delete cur_combo_box_; + return; + default: + break; + } + } + QDialog::keyPressEvent(evt); +} + 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); + QString cur_value = gchar_free_to_qstring(prefs_pref_to_str(pref, false)).remove(QRegExp("\n\t")); bool is_changed = false; QFont font = item.font(0); @@ -179,8 +225,7 @@ void PreferencesDialog::updateItem(QTreeWidgetItem &item) 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); + item.setText(3, cur_value); } void PreferencesDialog::on_prefsTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) @@ -242,7 +287,7 @@ void PreferencesDialog::on_advancedTree_currentItemChanged(QTreeWidgetItem *curr void PreferencesDialog::on_advancedTree_itemActivated(QTreeWidgetItem *item, int column) { pref_t *pref = item->data(0, Qt::UserRole).value<pref_t *>(); - if (!pref) return; + if (!pref || cur_line_edit_ || cur_combo_box_) return; if (column < 3) { reset_pref(pref); @@ -253,11 +298,11 @@ void PreferencesDialog::on_advancedTree_itemActivated(QTreeWidgetItem *item, int 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; + cur_line_edit_ = new QLineEdit(); +// cur_line_edit_->setInputMask("0000000009;"); + saved_string_pref_ = QString::number(*pref->varp.uint, pref->info.base); + connect(cur_line_edit_, SIGNAL(editingFinished()), this, SLOT(uintPrefEditingFinished())); + editor = cur_line_edit_; break; } case PREF_BOOL: @@ -266,23 +311,24 @@ void PreferencesDialog::on_advancedTree_itemActivated(QTreeWidgetItem *item, int break; case PREF_ENUM: { - QComboBox *combo = new QComboBox(); + cur_combo_box_ = 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)); + cur_combo_box_->addItem(ev->description, QVariant(ev->value)); if (*pref->varp.enump == ev->value) - combo->setCurrentIndex(combo->count() - 1); + cur_combo_box_->setCurrentIndex(cur_combo_box_->count() - 1); } - connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(enumPrefCurrentIndexChanged(int))); - editor = combo; + saved_combo_idx_ = cur_combo_box_->currentIndex(); + connect(cur_combo_box_, SIGNAL(currentIndexChanged(int)), this, SLOT(enumPrefCurrentIndexChanged(int))); + editor = cur_combo_box_; 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; + cur_line_edit_ = new QLineEdit(); + saved_string_pref_ = *pref->varp.string; + connect(cur_line_edit_, SIGNAL(editingFinished()), this, SLOT(stringPrefEditingFinished())); + editor = cur_line_edit_; break; } case PREF_FILENAME: @@ -301,12 +347,11 @@ void PreferencesDialog::on_advancedTree_itemActivated(QTreeWidgetItem *item, int { SyntaxLineEdit *syntax_edit = new SyntaxLineEdit(); char *cur_val = prefs_pref_to_str(pref, FALSE); + saved_string_pref_ = gchar_free_to_qstring(cur_val); 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; + editor = cur_line_edit_ = syntax_edit; break; } case PREF_COLOR: @@ -333,6 +378,14 @@ void PreferencesDialog::on_advancedTree_itemActivated(QTreeWidgetItem *item, int default: break; } + cur_pref_type_ = pref->type; + if (cur_line_edit_) { + cur_line_edit_->setText(saved_string_pref_); + connect(cur_line_edit_, SIGNAL(destroyed()), this, SLOT(lineEditPrefDestroyed())); + } + if (cur_combo_box_) { + connect(cur_combo_box_, SIGNAL(destroyed()), this, SLOT(enumPrefDestroyed())); + } if (editor) { QFrame *edit_frame = new QFrame(); QHBoxLayout *hb = new QHBoxLayout(); @@ -355,52 +408,59 @@ void PreferencesDialog::on_advancedTree_itemActivated(QTreeWidgetItem *item, int } } +void PreferencesDialog::lineEditPrefDestroyed() +{ + cur_line_edit_ = NULL; +} + +void PreferencesDialog::enumPrefDestroyed() +{ + cur_combo_box_ = NULL; +} + void PreferencesDialog::uintPrefEditingFinished() { - QLineEdit *line_edit = qobject_cast<QLineEdit *>(QObject::sender()); QTreeWidgetItem *item = pd_ui_->advancedTree->currentItem(); - if (!line_edit || !item) return; + if (!cur_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(); + *pref->varp.uint = cur_line_edit_->text().toUInt(NULL, pref->info.base); 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; + if (!cur_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 + *pref->varp.enump = cur_combo_box_->itemData(index, Qt::UserRole).toInt(); +// pd_ui_->advancedTree->removeItemWidget(item, 3); updateItem(*item); } void PreferencesDialog::stringPrefEditingFinished() { - QLineEdit *line_edit = qobject_cast<QLineEdit *>(QObject::sender()); QTreeWidgetItem *item = pd_ui_->advancedTree->currentItem(); - if (!line_edit || !item) return; + if (!cur_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()); + *pref->varp.string = g_strdup(cur_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()); + SyntaxLineEdit *syntax_edit = qobject_cast<SyntaxLineEdit *>(cur_line_edit_); QTreeWidgetItem *item = pd_ui_->advancedTree->currentItem(); if (!syntax_edit || !item) return; diff --git a/ui/qt/preferences_dialog.h b/ui/qt/preferences_dialog.h index 981378ea17..b00b60d4a1 100644 --- a/ui/qt/preferences_dialog.h +++ b/ui/qt/preferences_dialog.h @@ -35,6 +35,7 @@ #include <QDialog> #include <QTreeWidgetItem> +#include <QComboBox> namespace Ui { class PreferencesDialog; @@ -50,17 +51,25 @@ public: protected: void showEvent(QShowEvent *evt); + void keyPressEvent(QKeyEvent *evt); private: void updateItem(QTreeWidgetItem &item); Ui::PreferencesDialog *pd_ui_; + int cur_pref_type_; + QLineEdit *cur_line_edit_; + QString saved_string_pref_; + QComboBox *cur_combo_box_; + int saved_combo_idx_; // QHash<pref_t *, QTreeWidgetItem *> pref_item_hash_; private slots: void on_prefsTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); void on_advancedSearchLineEdit_textEdited(const QString &search_str); void on_advancedTree_itemActivated(QTreeWidgetItem *item, int column); + void lineEditPrefDestroyed(); + void enumPrefDestroyed(); void uintPrefEditingFinished(); void enumPrefCurrentIndexChanged(int index); void stringPrefEditingFinished(); diff --git a/ui/qt/qt_ui_utils.cpp b/ui/qt/qt_ui_utils.cpp index 7c997be420..d2c27e8728 100644 --- a/ui/qt/qt_ui_utils.cpp +++ b/ui/qt/qt_ui_utils.cpp @@ -164,6 +164,12 @@ format_size_flags_e operator|(format_size_flags_e lhs, format_size_flags_e rhs) return (format_size_flags_e) ((int)lhs| (int)rhs); } +QString gchar_free_to_qstring(gchar *glib_string) { + QString *qt_string = new QString(glib_string); + g_free(glib_string); + return *qt_string; +} + /* * Editor modelines * diff --git a/ui/qt/qt_ui_utils.h b/ui/qt/qt_ui_utils.h index 5b2edd8e46..6d995fb9b2 100644 --- a/ui/qt/qt_ui_utils.h +++ b/ui/qt/qt_ui_utils.h @@ -34,6 +34,8 @@ #include <glib.h> #include <epan/timestamp.h> +#include <QString> + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -73,6 +75,15 @@ extern gboolean main_do_quit(void); } #endif /* __cplusplus */ +/** Transfer ownership of a GLib character string to a newly constructed QString + * + * @param glib_string A string allocated with g_malloc() or NULL. Will be + * freed. + * + * @return a QString instance created from the input string. + */ +QString gchar_free_to_qstring(gchar *glib_string); + #endif /* __QT_UI_UTILS__H__ */ |