summaryrefslogtreecommitdiff
path: root/ui/qt/column_preferences_frame.cpp
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2013-01-23 19:04:36 +0000
committerGerald Combs <gerald@wireshark.org>2013-01-23 19:04:36 +0000
commit21e66f0c6f38d20dc4ac3968324fff0959113b14 (patch)
treee801135c51e407d67516e1969c1ef788af48292e /ui/qt/column_preferences_frame.cpp
parentd59e9cf574976b1e9849f5c35be1fd2abdf8ed6d (diff)
downloadwireshark-21e66f0c6f38d20dc4ac3968324fff0959113b14.tar.gz
Add column preferences.
svn path=/trunk/; revision=47231
Diffstat (limited to 'ui/qt/column_preferences_frame.cpp')
-rw-r--r--ui/qt/column_preferences_frame.cpp440
1 files changed, 440 insertions, 0 deletions
diff --git a/ui/qt/column_preferences_frame.cpp b/ui/qt/column_preferences_frame.cpp
new file mode 100644
index 0000000000..ebfdbdce30
--- /dev/null
+++ b/ui/qt/column_preferences_frame.cpp
@@ -0,0 +1,440 @@
+/* column_preferences_frame.cpp
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * 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/column_info.h>
+#include <epan/column.h>
+#include <epan/prefs.h>
+#include <epan/proto.h>
+
+#include <ui/preference_utils.h>
+
+#include "column_preferences_frame.h"
+#include "ui_column_preferences_frame.h"
+#include "syntax_line_edit.h"
+#include "wireshark_application.h"
+
+#include <QTreeWidgetItemIterator>
+#include <QLineEdit>
+#include <QKeyEvent>
+
+#include <QDebug>
+
+const int visible_col_ = 0;
+const int title_col_ = 1;
+const int type_col_ = 2;
+const int custom_field_col_ = 3;
+const int custom_occurrence_col_ = 4;
+
+ColumnPreferencesFrame::ColumnPreferencesFrame(QWidget *parent) :
+ QFrame(parent),
+ ui(new Ui::ColumnPreferencesFrame),
+ cur_line_edit_(NULL),
+ cur_combo_box_(NULL)
+{
+ ui->setupUi(this);
+
+ int one_em = ui->columnTreeWidget->fontMetrics().height();
+ ui->columnTreeWidget->setColumnWidth(3, one_em * 10);
+ ui->columnTreeWidget->setColumnWidth(4, one_em * 5);
+
+ ui->columnTreeWidget->setMinimumWidth(one_em * 20);
+ ui->columnTreeWidget->setMinimumHeight(one_em * 12);
+
+ ui->columnTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+ ui->columnTreeWidget->setDragEnabled(true);
+ ui->columnTreeWidget->viewport()->setAcceptDrops(true);
+ ui->columnTreeWidget->setDropIndicatorShown(true);
+ ui->columnTreeWidget->setDragDropMode(QAbstractItemView::InternalMove);
+
+ updateWidgets();
+}
+
+ColumnPreferencesFrame::~ColumnPreferencesFrame()
+{
+ delete ui;
+}
+
+void ColumnPreferencesFrame::unstash()
+{
+ GList *new_col_list = NULL;
+ bool changed = false;
+
+ QTreeWidgetItemIterator it(ui->columnTreeWidget);
+ while (*it) {
+ fmt_data *cfmt = g_new0(fmt_data, 1);
+ cfmt->visible = (*it)->checkState(visible_col_) == Qt::Checked ? TRUE : FALSE;
+ cfmt->title = g_strdup((*it)->text(title_col_).toUtf8().constData());
+ cfmt->fmt = (*it)->data(type_col_, Qt::UserRole).value<int>();
+ if (cfmt->fmt == COL_CUSTOM) {
+ bool ok;
+ int occurrence = (*it)->text(custom_occurrence_col_).toInt(&ok);
+ cfmt->custom_field = g_strdup((*it)->text(custom_field_col_).toUtf8().constData());
+ cfmt->custom_occurrence = ok ? occurrence : 0;
+ }
+
+ if (prefs.col_list == NULL) {
+ changed = true;
+ } else {
+ fmt_data *old_cfmt = (fmt_data *) prefs.col_list->data;
+ if (!old_cfmt ||
+ g_strcmp0(old_cfmt->title, cfmt->title) != 0 ||
+ old_cfmt->fmt != cfmt->fmt ||
+ old_cfmt->visible != cfmt->visible ||
+ (old_cfmt->fmt == COL_CUSTOM && (
+ g_strcmp0(old_cfmt->custom_field, cfmt->custom_field) != 0 ||
+ old_cfmt->custom_occurrence != cfmt->custom_occurrence))) {
+ changed = true;
+ }
+ column_prefs_remove_link(prefs.col_list);
+ }
+
+ new_col_list = g_list_append(new_col_list, cfmt);
+ ++it;
+ }
+
+ while (prefs.col_list) {
+ changed = true;
+ column_prefs_remove_link(prefs.col_list);
+ }
+ prefs.col_list = new_col_list;
+
+ if (changed) {
+ wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged);
+ }
+}
+
+void ColumnPreferencesFrame::showEvent(QShowEvent *evt)
+{
+ Q_UNUSED(evt);
+}
+
+void ColumnPreferencesFrame::keyPressEvent(QKeyEvent *evt)
+{
+ if (cur_line_edit_ && cur_line_edit_->hasFocus()) {
+ int new_idx = COL_CUSTOM;
+ switch (evt->key()) {
+ case Qt::Key_Escape:
+ cur_line_edit_->setText(saved_col_string_);
+ new_idx = saved_combo_idx_;
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ switch (cur_column_) {
+ case title_col_:
+ columnTitleEditingFinished();
+ break;
+ case custom_field_col_:
+ customFieldEditingFinished();
+ columnTypeCurrentIndexChanged(new_idx);
+ break;
+ case custom_occurrence_col_:
+ customOccurrenceEditingFinished();
+ columnTypeCurrentIndexChanged(new_idx);
+ 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
+ columnTypeCurrentIndexChanged(cur_combo_box_->currentIndex());
+ delete cur_combo_box_;
+ return;
+ default:
+ break;
+ }
+ }
+ QFrame::keyPressEvent(evt);
+}
+
+void ColumnPreferencesFrame::addColumn(bool visible, const char *title, int fmt, const char *custom_field, int custom_occurrence)
+{
+ QTreeWidgetItem *item = new QTreeWidgetItem(ui->columnTreeWidget);
+
+ item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
+ item->setFlags(item->flags() & ~(Qt::ItemIsDropEnabled));
+ item->setCheckState(visible_col_, visible ? Qt::Checked : Qt::Unchecked);
+ item->setText(title_col_, title);
+ item->setText(type_col_, col_format_desc(fmt));
+ item->setData(type_col_, Qt::UserRole, QVariant(fmt));
+ if (fmt == COL_CUSTOM) {
+ item->setText(custom_field_col_, custom_field);
+ item->setText(custom_occurrence_col_, QString::number(custom_occurrence));
+ }
+}
+
+void ColumnPreferencesFrame::updateWidgets()
+{
+ ui->columnTreeWidget->clear();
+
+ for (GList *cur = g_list_first(prefs.col_list); cur != NULL && cur->data != NULL; cur = cur->next) {
+ fmt_data *cfmt = (fmt_data *) cur->data;
+ addColumn(cfmt->visible, cfmt->title, cfmt->fmt, cfmt->custom_field, cfmt->custom_occurrence);
+ }
+
+ ui->columnTreeWidget->resizeColumnToContents(visible_col_);
+ ui->columnTreeWidget->resizeColumnToContents(title_col_);
+ ui->columnTreeWidget->resizeColumnToContents(type_col_);
+}
+
+
+void ColumnPreferencesFrame::on_columnTreeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
+{
+ ui->deleteToolButton->setEnabled(current ? true : false);
+
+ if (previous && ui->columnTreeWidget->itemWidget(previous, title_col_)) {
+ ui->columnTreeWidget->removeItemWidget(previous, title_col_);
+ }
+ if (previous && ui->columnTreeWidget->itemWidget(previous, type_col_)) {
+ ui->columnTreeWidget->removeItemWidget(previous, type_col_);
+ previous->setText(type_col_, col_format_desc(previous->data(type_col_, Qt::UserRole).toInt()));
+ }
+ if (previous && ui->columnTreeWidget->itemWidget(previous, custom_field_col_)) {
+ ui->columnTreeWidget->removeItemWidget(previous, custom_field_col_);
+ }
+ if (previous && ui->columnTreeWidget->itemWidget(previous, custom_occurrence_col_)) {
+ ui->columnTreeWidget->removeItemWidget(previous, custom_occurrence_col_);
+ }
+}
+
+void ColumnPreferencesFrame::on_columnTreeWidget_itemActivated(QTreeWidgetItem *item, int column)
+{
+ if (!item || cur_line_edit_ || cur_combo_box_) return;
+
+ QWidget *editor = NULL;
+ cur_column_ = column;
+ saved_combo_idx_ = item->data(type_col_, Qt::UserRole).toInt();
+
+ switch (column) {
+ case title_col_:
+ {
+ cur_line_edit_ = new QLineEdit();
+ cur_column_ = column;
+ saved_col_string_ = item->text(title_col_);
+ connect(cur_line_edit_, SIGNAL(editingFinished()), this, SLOT(columnTitleEditingFinished()));
+ editor = cur_line_edit_;
+ break;
+ }
+ case type_col_:
+ {
+ cur_combo_box_ = new QComboBox();
+ for (int i = 0; i < NUM_COL_FMTS; i++) {
+ cur_combo_box_->addItem(col_format_desc(i), QVariant(i));
+ if (i == saved_combo_idx_) {
+ cur_combo_box_->setCurrentIndex(i);
+ }
+ }
+ connect(cur_combo_box_, SIGNAL(currentIndexChanged(int)), this, SLOT(columnTypeCurrentIndexChanged(int)));
+ editor = cur_combo_box_;
+ break;
+ }
+ case custom_field_col_:
+ {
+ SyntaxLineEdit *syntax_edit = new SyntaxLineEdit();
+ saved_col_string_ = item->text(custom_field_col_);
+ connect(syntax_edit, SIGNAL(textChanged(QString)),
+ this, SLOT(customFieldTextChanged(QString)));
+ connect(syntax_edit, SIGNAL(editingFinished()), this, SLOT(customFieldEditingFinished()));
+ editor = cur_line_edit_ = syntax_edit;
+
+ saved_combo_idx_ = item->data(type_col_, Qt::UserRole).toInt();
+ item->setText(type_col_, col_format_desc(COL_CUSTOM));
+ item->setData(type_col_, Qt::UserRole, QVariant(COL_CUSTOM));
+ break;
+ }
+ case custom_occurrence_col_:
+ {
+ SyntaxLineEdit *syntax_edit = new SyntaxLineEdit();
+ saved_col_string_ = item->text(custom_occurrence_col_);
+ connect(syntax_edit, SIGNAL(textChanged(QString)),
+ this, SLOT(customOccurrenceTextChanged(QString)));
+ connect(syntax_edit, SIGNAL(editingFinished()), this, SLOT(customOccurrenceEditingFinished()));
+ editor = cur_line_edit_ = syntax_edit;
+
+ saved_combo_idx_ = item->data(type_col_, Qt::UserRole).toInt();
+ item->setText(type_col_, col_format_desc(COL_CUSTOM));
+ item->setData(type_col_, Qt::UserRole, QVariant(COL_CUSTOM));
+ break;
+ }
+ default:
+ return;
+ }
+
+ if (cur_line_edit_) {
+ cur_line_edit_->setText(saved_col_string_);
+ cur_line_edit_->selectAll();
+ connect(cur_line_edit_, SIGNAL(destroyed()), this, SLOT(lineEditDestroyed()));
+ }
+ if (cur_combo_box_) {
+ connect(cur_combo_box_, SIGNAL(destroyed()), this, SLOT(comboDestroyed()));
+ }
+ 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(cur_column_, "");
+ edit_frame->setLayout(hb);
+ ui->columnTreeWidget->setItemWidget(item, cur_column_, edit_frame);
+ editor->setFocus();
+ }
+}
+
+void ColumnPreferencesFrame::lineEditDestroyed()
+{
+ cur_line_edit_ = NULL;
+}
+
+void ColumnPreferencesFrame::comboDestroyed()
+{
+ cur_combo_box_ = NULL;
+}
+
+void ColumnPreferencesFrame::columnTitleEditingFinished()
+{
+ QTreeWidgetItem *item = ui->columnTreeWidget->currentItem();
+ if (!cur_line_edit_ || !item) return;
+
+ item->setText(title_col_, cur_line_edit_->text());
+ ui->columnTreeWidget->removeItemWidget(item, title_col_);
+}
+
+void ColumnPreferencesFrame::columnTypeCurrentIndexChanged(int index)
+{
+ QTreeWidgetItem *item = ui->columnTreeWidget->currentItem();
+ if (!item || index < 0) return;
+
+ item->setData(type_col_, Qt::UserRole, QVariant(index));
+ item->setText(type_col_, col_format_desc(index));
+
+ if (index != COL_CUSTOM) {
+ item->setText(custom_field_col_, "");
+ item->setText(custom_occurrence_col_, "");
+ }
+}
+
+void ColumnPreferencesFrame::customFieldTextChanged(QString)
+{
+ SyntaxLineEdit *syntax_edit = qobject_cast<SyntaxLineEdit *>(cur_line_edit_);
+ QTreeWidgetItem *item = ui->columnTreeWidget->currentItem();
+ if (!syntax_edit || !item) return;
+
+ dfilter_t *dfp = NULL;
+ const char *field_text = syntax_edit->text().toUtf8().constData();
+ if (strlen(field_text) < 1) {
+ syntax_edit->setSyntaxState(SyntaxLineEdit::Empty);
+ } else if (proto_check_field_name(field_text) != 0 || !dfilter_compile(field_text, &dfp)) {
+ syntax_edit->setSyntaxState(SyntaxLineEdit::Invalid);
+ } else {
+ syntax_edit->setSyntaxState(SyntaxLineEdit::Valid);
+ }
+ dfilter_free(dfp);
+}
+
+void ColumnPreferencesFrame::customFieldEditingFinished()
+{
+ QTreeWidgetItem *item = ui->columnTreeWidget->currentItem();
+ if (!cur_line_edit_ || !item) return;
+
+ item->setText(custom_field_col_, cur_line_edit_->text());
+ ui->columnTreeWidget->removeItemWidget(item, custom_field_col_);
+}
+
+void ColumnPreferencesFrame::customOccurrenceTextChanged(QString)
+{
+ SyntaxLineEdit *syntax_edit = qobject_cast<SyntaxLineEdit *>(cur_line_edit_);
+ QTreeWidgetItem *item = ui->columnTreeWidget->currentItem();
+ if (!syntax_edit || !item) return;
+
+ if (syntax_edit->text().isEmpty()) {
+ syntax_edit->setSyntaxState(SyntaxLineEdit::Empty);
+ } else {
+ bool ok;
+ syntax_edit->text().toInt(&ok);
+ if (ok) {
+ syntax_edit->setSyntaxState(SyntaxLineEdit::Valid);
+ } else {
+ syntax_edit->setSyntaxState(SyntaxLineEdit::Invalid);
+ }
+ }
+}
+
+void ColumnPreferencesFrame::customOccurrenceEditingFinished()
+{
+ QTreeWidgetItem *item = ui->columnTreeWidget->currentItem();
+ if (!cur_line_edit_ || !item) return;
+
+ item->setText(custom_occurrence_col_, cur_line_edit_->text());
+ ui->columnTreeWidget->removeItemWidget(item, custom_occurrence_col_);
+}
+
+void ColumnPreferencesFrame::on_newToolButton_clicked()
+{
+ addColumn(true, "New Column", COL_NUMBER, NULL, 0);
+}
+
+void ColumnPreferencesFrame::on_deleteToolButton_clicked()
+{
+ QTreeWidgetItem *item = ui->columnTreeWidget->currentItem();
+ if (item) {
+ ui->columnTreeWidget->invisibleRootItem()->removeChild(item);
+ }
+}
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */