aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2015-02-04 16:36:19 -0800
committerGerald Combs <gerald@wireshark.org>2015-02-07 00:30:30 +0000
commitc8cad99515eeac25faf6ea84795ce6b5fa4afebb (patch)
treeec72051d71ac3caf9331690a6f34d6255a876576
parentb3f3dd8d82d9b651f34886a3293056c612958aa2 (diff)
Qt: Add the Coloring Rules dialog.
Merge in the old ColorDialog which was a placeholder for color_filter_add_cb. Change-Id: I48d188509f480b8514122b4011ac9d8790fcca10 Reviewed-on: https://code.wireshark.org/review/6996 Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Gerald Combs <gerald@wireshark.org>
-rw-r--r--color_filters.c14
-rw-r--r--color_filters.h13
-rw-r--r--ui/qt/CMakeLists.txt7
-rw-r--r--ui/qt/Makefile.am2
-rw-r--r--ui/qt/Makefile.common6
-rw-r--r--ui/qt/Wireshark.pro5
-rw-r--r--ui/qt/color_dialog.cpp65
-rw-r--r--ui/qt/color_dialog.h52
-rw-r--r--ui/qt/color_utils.cpp10
-rw-r--r--ui/qt/color_utils.h1
-rw-r--r--ui/qt/coloring_rules_dialog.cpp440
-rw-r--r--ui/qt/coloring_rules_dialog.h108
-rw-r--r--ui/qt/coloring_rules_dialog.ui209
-rw-r--r--ui/qt/io_graph_dialog.ui6
-rw-r--r--ui/qt/main_window.h1
-rw-r--r--ui/qt/main_window.ui21
-rw-r--r--ui/qt/main_window_slots.cpp8
-rw-r--r--ui/qt/packet_list.cpp6
-rw-r--r--ui/qt/packet_list.h1
19 files changed, 824 insertions, 151 deletions
diff --git a/color_filters.c b/color_filters.c
index 869a6e506d..b9a0429333 100644
--- a/color_filters.c
+++ b/color_filters.c
@@ -76,15 +76,12 @@ color_filter_new(const gchar *name, /* The name of the filter to create
{
color_filter_t *colorf;
- colorf = (color_filter_t *)g_malloc(sizeof (color_filter_t));
+ colorf = (color_filter_t *)g_malloc0(sizeof (color_filter_t));
colorf->filter_name = g_strdup(name);
colorf->filter_text = g_strdup(filter_string);
colorf->bg_color = *bg_color;
colorf->fg_color = *fg_color;
colorf->disabled = disabled;
- colorf->c_colorfilter = NULL;
- colorf->color_edit_dlg_info = NULL;
- colorf->selected = FALSE;
return colorf;
}
@@ -119,7 +116,6 @@ color_filters_add_tmp(GSList **cfl)
BLUE_COMPONENT(cval) );
colorf = color_filter_new(name, NULL, &bg_color, &fg_color, TRUE);
colorf->filter_text = g_strdup("frame");
- colorf->c_colorfilter = NULL;
*cfl = g_slist_append(*cfl, colorf);
g_free(name);
@@ -683,7 +679,7 @@ color_filters_read_globals(gpointer user_data)
/* read filters from some other filter file (import) */
gboolean
-color_filters_import(gchar *path, gpointer user_data)
+color_filters_import(const gchar *path, const gpointer user_data)
{
FILE *f;
gboolean ret;
@@ -731,7 +727,7 @@ write_filter(gpointer filter_arg, gpointer data_arg)
/* save filters in a filter file */
static gboolean
-write_filters_file(GSList *cfl, FILE *f, gboolean only_selected)
+write_filters_file(const GSList *cfl, FILE *f, gboolean only_selected)
{
struct write_filter_data data;
@@ -739,7 +735,7 @@ write_filters_file(GSList *cfl, FILE *f, gboolean only_selected)
data.only_selected = only_selected;
fprintf(f,"# DO NOT EDIT THIS FILE! It was created by Wireshark\n");
- g_slist_foreach(cfl, write_filter, &data);
+ g_slist_foreach((GSList *) cfl, write_filter, &data);
return TRUE;
}
@@ -777,7 +773,7 @@ color_filters_write(GSList *cfl)
/* save filters in some other filter file (export) */
gboolean
-color_filters_export(gchar *path, GSList *cfl, gboolean only_marked)
+color_filters_export(const gchar *path, const GSList *cfl, gboolean only_marked)
{
FILE *f;
diff --git a/color_filters.h b/color_filters.h
index e8262d85b4..7fe8068011 100644
--- a/color_filters.h
+++ b/color_filters.h
@@ -40,13 +40,13 @@ typedef struct _color_filter {
color_t bg_color; /* background color for packets that match */
color_t fg_color; /* foreground color for packets that match */
gboolean disabled; /* set if the filter is disabled */
- gboolean selected; /* set if the filter is selected in the color dialog box */
+ gboolean selected; /* set if the filter is selected in the color dialog box. GTK+ only. */
/* only used inside of color_filters.c */
struct epan_dfilter *c_colorfilter; /* compiled filter expression */
/* only used outside of color_filters.c (beside init) */
- void *color_edit_dlg_info; /* if filter is being edited, ptr to req'd info */
+ void *color_edit_dlg_info; /* if filter is being edited, ptr to req'd info. GTK+ only. */
} color_filter_t;
@@ -120,7 +120,7 @@ void color_filters_clone(gpointer user_data);
* @param user_data will be returned by each call to to color_filter_add_cb()
* @return TRUE, if read succeeded
*/
-gboolean color_filters_import(gchar *path, gpointer user_data);
+gboolean color_filters_import(const gchar *path, const gpointer user_data);
/** Read filters from the global filter file (not the users file).
*
@@ -160,9 +160,7 @@ gboolean color_filters_write(GSList *cfl);
* @param only_selected TRUE if only the selected filters should be saved
* @return TRUE, if write succeeded
*/
-gboolean color_filters_export(gchar *path, GSList *cfl, gboolean only_selected);
-
-
+gboolean color_filters_export(const gchar *path, const GSList *cfl, gboolean only_selected);
/** Create a new color filter (g_malloc'ed).
*
@@ -183,9 +181,6 @@ color_filter_t *color_filter_new(
*/
void color_filter_delete(color_filter_t *colorf);
-
-
-
/** Delete a filter list including all entries.
*
* @param cfl the filter list to delete
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index 0de0e9550f..abd33f61fa 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -35,8 +35,8 @@ set(WIRESHARK_QT_HEADERS
capture_info_dialog.h
capture_interfaces_dialog.h
capture_preferences_frame.h
- color_dialog.h
color_utils.h
+ coloring_rules_dialog.h
column_preferences_frame.h
column_editor_frame.h
compiled_filter_output.h
@@ -135,9 +135,9 @@ set(WIRESHARK_QT_SRC
capture_filter_syntax_worker.cpp
capture_info_dialog.cpp
capture_interfaces_dialog.cpp
- color_dialog.cpp
- color_utils.cpp
capture_preferences_frame.cpp
+ color_utils.cpp
+ coloring_rules_dialog.cpp
column_preferences_frame.cpp
column_editor_frame.cpp
compiled_filter_output.cpp
@@ -237,6 +237,7 @@ set(WIRESHARK_QT_UI
capture_file_properties_dialog.ui
capture_interfaces_dialog.ui
capture_preferences_frame.ui
+ coloring_rules_dialog.ui
column_preferences_frame.ui
column_editor_frame.ui
compiled_filter_output.ui
diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am
index cf17a2f4f3..725cf9fbbd 100644
--- a/ui/qt/Makefile.am
+++ b/ui/qt/Makefile.am
@@ -128,6 +128,8 @@ capture_interfaces_dialog.cpp capture_interfaces_dialog.h: ui_capture_interfaces
capture_preferences_frame.cpp capture_preferences_frame.h: ui_capture_preferences_frame.h
+coloring_rules_dialog.cpp coloring_rules_dialog.h: ui_coloring_rules_dialog.h
+
column_editor_frame.cpp column_editor_frame.h: ui_column_editor_frame.h
column_preferences_frame.cpp column_preferences_frame.h: ui_column_preferences_frame.h
diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common
index e7e5927cc7..8106e88821 100644
--- a/ui/qt/Makefile.common
+++ b/ui/qt/Makefile.common
@@ -33,6 +33,7 @@ NODIST_GENERATED_HEADER_FILES = \
ui_capture_file_properties_dialog.h \
ui_capture_interfaces_dialog.h \
ui_capture_preferences_frame.h \
+ ui_coloring_rules_dialog.h \
ui_column_preferences_frame.h \
ui_column_editor_frame.h \
ui_compiled_filter_output.h \
@@ -128,7 +129,7 @@ MOC_HDRS = \
capture_info_dialog.h \
capture_interfaces_dialog.h \
capture_preferences_frame.h \
- color_dialog.h \
+ coloring_rules_dialog.h \
color_utils.h \
column_preferences_frame.h \
column_editor_frame.h \
@@ -211,6 +212,7 @@ UI_FILES = \
capture_file_properties_dialog.ui \
capture_interfaces_dialog.ui \
capture_preferences_frame.ui \
+ coloring_rules_dialog.ui \
column_preferences_frame.ui \
column_editor_frame.ui \
compiled_filter_output.ui \
@@ -329,8 +331,8 @@ WIRESHARK_QT_SRC = \
capture_info_dialog.cpp \
capture_interfaces_dialog.cpp \
capture_preferences_frame.cpp \
- color_dialog.cpp \
color_utils.cpp \
+ coloring_rules_dialog.cpp \
column_preferences_frame.cpp \
column_editor_frame.cpp \
compiled_filter_output.cpp \
diff --git a/ui/qt/Wireshark.pro b/ui/qt/Wireshark.pro
index bb5c21390b..fedcd03719 100644
--- a/ui/qt/Wireshark.pro
+++ b/ui/qt/Wireshark.pro
@@ -209,6 +209,7 @@ FORMS += \
capture_file_properties_dialog.ui \
capture_interfaces_dialog.ui \
capture_preferences_frame.ui \
+ coloring_rules_dialog.ui \
column_preferences_frame.ui \
column_editor_frame.ui \
compiled_filter_output.ui \
@@ -264,6 +265,7 @@ HEADERS += $$HEADERS_WS_C \
capture_file_properties_dialog.h \
capture_interfaces_dialog.h \
capture_preferences_frame.h \
+ coloring_rules_dialog.h \
column_preferences_frame.h \
column_editor_frame.h \
compiled_filter_output.h \
@@ -558,7 +560,6 @@ HEADERS += \
capture_filter_edit.h \
capture_filter_syntax_worker.h \
capture_info_dialog.h \
- color_dialog.h \
color_utils.h \
display_filter_combo.h \
display_filter_edit.h \
@@ -605,8 +606,8 @@ SOURCES += \
capture_info_dialog.cpp \
capture_interfaces_dialog.cpp \
capture_preferences_frame.cpp \
- color_dialog.cpp \
color_utils.cpp \
+ coloring_rules_dialog.cpp \
column_preferences_frame.cpp \
column_editor_frame.cpp \
compiled_filter_output.cpp \
diff --git a/ui/qt/color_dialog.cpp b/ui/qt/color_dialog.cpp
deleted file mode 100644
index 0342ba8bf9..0000000000
--- a/ui/qt/color_dialog.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* color_dialog.cpp
- *
- * 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_dialog.h"
-
-#include <epan/packet.h>
-#include <epan/dfilter/dfilter.h>
-#include <epan/prefs.h>
-
-#include "color.h"
-#include "color_filters.h"
-
-/* a new color filter was read in from a filter file */
-void
-color_filter_add_cb(color_filter_t *colorf, gpointer user_data)
-{
- Q_UNUSED(colorf);
- Q_UNUSED(user_data);
- g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: color_filter_add_cb");
-// GtkWidget *color_filters = user_data;
-
-// add_filter_to_list(colorf, color_filters);
-
-// gtk_widget_grab_focus(color_filters);
-}
-
-ColorDialog::ColorDialog(QWidget *parent) :
- QDialog(parent)
-{
-}
-
-/*
- * 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:
- */
diff --git a/ui/qt/color_dialog.h b/ui/qt/color_dialog.h
deleted file mode 100644
index 347e52d5b9..0000000000
--- a/ui/qt/color_dialog.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* color_dialog.h
- *
- * 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.
- */
-
-#ifndef COLOR_DIALOG_H
-#define COLOR_DIALOG_H
-
-#include <QDialog>
-
-class ColorDialog : public QDialog
-{
- Q_OBJECT
-public:
- explicit ColorDialog(QWidget *parent = 0);
-
-signals:
-
-public slots:
-
-};
-
-#endif // COLOR_DIALOG_H
-
-/*
- * 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:
- */
diff --git a/ui/qt/color_utils.cpp b/ui/qt/color_utils.cpp
index 4210d29734..e6d7f31082 100644
--- a/ui/qt/color_utils.cpp
+++ b/ui/qt/color_utils.cpp
@@ -60,6 +60,16 @@ QColor ColorUtils::fromColorT(color_t color)
return fromColorT(&color);
}
+const color_t ColorUtils::toColorT(const QColor color)
+{
+ color_t colort;
+ colort.red = (color.red() << 8) | color.red();
+ colort.green = (color.green() << 8) | color.green();
+ colort.blue = (color.blue() << 8) | color.blue();
+
+ return colort;
+}
+
QRgb ColorUtils::alphaBlend(const QColor &color1, const QColor &color2, qreal alpha)
{
alpha = qBound(0.0, alpha, 1.0);
diff --git a/ui/qt/color_utils.h b/ui/qt/color_utils.h
index abbd4497a2..aa74adcfaf 100644
--- a/ui/qt/color_utils.h
+++ b/ui/qt/color_utils.h
@@ -40,6 +40,7 @@ public:
static QColor fromColorT(color_t *color);
static QColor fromColorT(color_t color);
+ static const color_t toColorT(const QColor color);
static QRgb alphaBlend(const QColor &color1, const QColor &color2, qreal alpha);
static QRgb alphaBlend(const QBrush &brush1, const QBrush &brush2, qreal alpha);
diff --git a/ui/qt/coloring_rules_dialog.cpp b/ui/qt/coloring_rules_dialog.cpp
new file mode 100644
index 0000000000..054394bf6a
--- /dev/null
+++ b/ui/qt/coloring_rules_dialog.cpp
@@ -0,0 +1,440 @@
+/* coloring_rules_dialog.cpp
+ *
+ * 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 "coloring_rules_dialog.h"
+#include "ui_coloring_rules_dialog.h"
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "color.h"
+#include "color_filters.h"
+
+#include "ui/utf8_entities.h"
+
+#include "color_utils.h"
+#include "display_filter_combo.h"
+#include "syntax_line_edit.h"
+#include "wireshark_application.h"
+
+#include <QColorDialog>
+#include <QDir>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QPushButton>
+#include <QTreeWidgetItemIterator>
+
+/*
+ * @file Coloring Rules dialog
+ *
+ * Coloring rule editor for the current profile.
+ */
+
+// Callback for color_filters_clone.
+void
+color_filter_add_cb(color_filter_t *colorf, gpointer user_data)
+{
+ ColoringRulesDialog *coloring_rules_dialog = static_cast<ColoringRulesDialog*>(user_data);
+
+ if (!coloring_rules_dialog) return;
+ coloring_rules_dialog->addColor(colorf);
+}
+
+enum {
+ name_col_ = 0,
+ filter_col_
+};
+
+const QString new_rule_name_ = QObject::tr("New coloring rule");
+
+ColoringRulesDialog::ColoringRulesDialog(QWidget *parent, QString add_filter) :
+ QDialog(parent),
+ ui(new Ui::ColoringRulesDialog),
+ conversation_colors_(NULL)
+{
+ ui->setupUi(this);
+ setWindowTitle(wsApp->windowTitleString(tr("Coloring Rules")));
+
+ // XXX Use recent settings instead
+ resize(parent->width() * 2 / 3, parent->height() * 4 / 5);
+
+ ui->coloringRulesTreeWidget->setDragEnabled(true);
+ ui->coloringRulesTreeWidget->viewport()->setAcceptDrops(true);
+ ui->coloringRulesTreeWidget->setDropIndicatorShown(true);
+ ui->coloringRulesTreeWidget->setDragDropMode(QAbstractItemView::InternalMove);
+
+ color_filters_clone(this);
+
+ for (int i = 0; i < ui->coloringRulesTreeWidget->columnCount(); i++) {
+ ui->coloringRulesTreeWidget->setItemDelegateForColumn(i, &coloring_rules_tree_delegate_);
+ ui->coloringRulesTreeWidget->resizeColumnToContents(i);
+ }
+ coloring_rules_tree_delegate_.setTree(ui->coloringRulesTreeWidget);
+
+ if (!add_filter.isEmpty()) {
+ addColoringRule(false, new_rule_name_, add_filter,
+ palette().color(QPalette::Text),
+ palette().color(QPalette::Base),
+ true);
+ }
+
+ connect(ui->coloringRulesTreeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
+ this, SLOT(updateWidgets()));
+
+ import_button_ = ui->buttonBox->addButton(tr("Import" UTF8_HORIZONTAL_ELLIPSIS), QDialogButtonBox::ApplyRole);
+ import_button_->setToolTip(tr("Select a file and add its filters to the end of the list."));
+ export_button_ = ui->buttonBox->addButton(tr("Export" UTF8_HORIZONTAL_ELLIPSIS), QDialogButtonBox::ApplyRole);
+ export_button_->setToolTip(tr("Save filters in a file."));
+
+ updateWidgets();
+}
+
+ColoringRulesDialog::~ColoringRulesDialog()
+{
+ delete ui;
+ color_filter_list_delete(&conversation_colors_);
+}
+
+void ColoringRulesDialog::addColor(_color_filter *colorf)
+{
+ if (!colorf) return;
+
+ if(strstr(colorf->filter_name, CONVERSATION_COLOR_PREFIX) != NULL) {
+ conversation_colors_ = g_slist_append(conversation_colors_, colorf);
+ } else {
+ addColoringRule(colorf->disabled, colorf->filter_name, colorf->filter_text,
+ ColorUtils::fromColorT(colorf->fg_color),
+ ColorUtils::fromColorT(colorf->bg_color));
+ }
+}
+
+void ColoringRulesDialog::showEvent(QShowEvent *)
+{
+ ui->fGPushButton->setFixedHeight(ui->copyToolButton->geometry().height());
+ ui->bGPushButton->setFixedHeight(ui->copyToolButton->geometry().height());
+}
+
+void ColoringRulesDialog::updateWidgets()
+{
+ QString hint = "<small><i>";
+ int num_selected = ui->coloringRulesTreeWidget->selectedItems().count();
+
+ if (num_selected == 1) {
+ QTreeWidgetItem *ti = ui->coloringRulesTreeWidget->currentItem();
+ QString color_button_ss =
+ "QPushButton {"
+ " border: 1px solid palette(Dark);"
+ " padding-left: %1px;"
+ " padding-right: %1px;"
+ " color: %2;"
+ " background-color: %3;"
+ "}";
+ int one_em = fontMetrics().height();
+ QString fg_color = ti->foreground(0).color().name();
+ QString bg_color = ti->background(0).color().name();
+ ui->fGPushButton->setStyleSheet(color_button_ss.arg(one_em).arg(bg_color).arg(fg_color));
+ ui->bGPushButton->setStyleSheet(color_button_ss.arg(one_em).arg(fg_color).arg(bg_color));
+ }
+
+
+ ui->copyToolButton->setEnabled(num_selected == 1);
+ ui->deleteToolButton->setEnabled(num_selected > 0);
+ ui->fGPushButton->setVisible(num_selected == 1);
+ ui->bGPushButton->setVisible(num_selected == 1);
+
+ QString error_text;
+ QTreeWidgetItemIterator iter(ui->coloringRulesTreeWidget);
+ bool enable_save = true;
+
+ while (*iter) {
+ QTreeWidgetItem *item = (*iter);
+ if (item->text(name_col_).contains("@")) {
+ error_text = tr("the \"@\" symbol will be ignored.");
+ }
+
+ QString display_filter = item->text(filter_col_);
+ if (!display_filter.isEmpty()) {
+ dfilter_t *dfilter;
+ bool status;
+ gchar *err_msg;
+ status = dfilter_compile(display_filter.toUtf8().constData(), &dfilter, &err_msg);
+ dfilter_free(dfilter);
+ if (!status) {
+ if (!error_text.isEmpty()) error_text += " ";
+ error_text += err_msg;
+ g_free(err_msg);
+ enable_save = false;
+ }
+ }
+
+ if (!error_text.isEmpty()) {
+ error_text.prepend(QString("%1: ").arg(item->text(name_col_)));
+ break;
+ }
+ iter++;
+ }
+
+ if (error_text.isEmpty()) {
+ hint += tr("Double click to edit. Drag to move.");
+ } else {
+ hint += error_text;
+ }
+ hint += "</i></small>";
+ ui->hintLabel->setText(hint);
+
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(enable_save);
+}
+
+GSList *ColoringRulesDialog::createColorFilterList()
+{
+ GSList *cfl = NULL;
+ QTreeWidgetItemIterator iter(ui->coloringRulesTreeWidget);
+
+ while (*iter) {
+ QTreeWidgetItem *item = (*iter);
+ color_t fg = ColorUtils::toColorT(item->foreground(0).color());
+ color_t bg = ColorUtils::toColorT(item->background(0).color());
+ color_filter_t *colorf = color_filter_new(item->text(name_col_).toUtf8().constData(),
+ item->text(filter_col_).toUtf8().constData(),
+ &bg, &fg, item->checkState(0) == Qt::Unchecked);
+ cfl = g_slist_append(cfl, colorf);
+ ++iter;
+ }
+ return cfl;
+}
+
+void ColoringRulesDialog::on_coloringRulesTreeWidget_itemSelectionChanged()
+{
+ updateWidgets();
+}
+
+void ColoringRulesDialog::changeColor(bool foreground)
+{
+ if (!ui->coloringRulesTreeWidget->currentItem()) return;
+
+ QTreeWidgetItem *ti = ui->coloringRulesTreeWidget->currentItem();
+ QColorDialog color_dlg;
+
+ color_dlg.setCurrentColor(foreground ?
+ ti->foreground(0).color() : ti->background(0).color());
+ if (color_dlg.exec() == QDialog::Accepted) {
+ QColor cc = color_dlg.currentColor();
+ if (foreground) {
+ for (int i = 0; i < ui->coloringRulesTreeWidget->columnCount(); i++) {
+ ti->setForeground(i, cc);
+ }
+ } else {
+ for (int i = 0; i < ui->coloringRulesTreeWidget->columnCount(); i++) {
+ ti->setBackground(i, cc);
+ }
+ }
+ updateWidgets();
+ }
+
+}
+
+void ColoringRulesDialog::on_fGPushButton_clicked()
+{
+ changeColor();
+}
+
+void ColoringRulesDialog::on_bGPushButton_clicked()
+{
+ changeColor(false);
+}
+
+void ColoringRulesDialog::addColoringRule(bool disabled, QString name, QString filter, QColor foreground, QColor background, bool start_editing)
+{
+ QTreeWidgetItem *ti = new QTreeWidgetItem(ui->coloringRulesTreeWidget);
+
+ ti->setFlags(ti->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsEditable);
+ ti->setCheckState(name_col_, disabled ? Qt::Unchecked : Qt::Checked);
+ ti->setText(name_col_, name);
+ ti->setText(filter_col_, filter);
+
+ for (int i = 0; i < ui->coloringRulesTreeWidget->columnCount(); i++) {
+ ti->setForeground(i, foreground);
+ ti->setBackground(i, background);
+ }
+
+ ui->coloringRulesTreeWidget->addTopLevelItem(ti);
+
+ if (start_editing) {
+ ui->coloringRulesTreeWidget->setCurrentItem(ti);
+ updateWidgets();
+ ui->coloringRulesTreeWidget->editItem(ti, filter_col_);
+ }
+}
+
+void ColoringRulesDialog::on_newToolButton_clicked()
+{
+ addColoringRule(false, new_rule_name_, QString(), palette().color(QPalette::Text),
+ palette().color(QPalette::Base), true);
+}
+
+void ColoringRulesDialog::on_deleteToolButton_clicked()
+{
+ QList<QTreeWidgetItem*> selected = ui->coloringRulesTreeWidget->selectedItems();
+ foreach (QTreeWidgetItem *ti, selected) {
+ delete ti;
+ }
+}
+
+void ColoringRulesDialog::on_copyToolButton_clicked()
+{
+ if (!ui->coloringRulesTreeWidget->currentItem()) return;
+ QTreeWidgetItem *ti = ui->coloringRulesTreeWidget->currentItem();
+
+ addColoringRule(ti->checkState(0) == Qt::Unchecked, ti->text(name_col_),
+ ti->text(filter_col_), ti->foreground(0).color(),
+ ti->background(0).color(), true);
+}
+
+void ColoringRulesDialog::on_buttonBox_clicked(QAbstractButton *button)
+{
+ if (button == import_button_) {
+ QString file_name = QFileDialog::getOpenFileName(this, wsApp->windowTitleString(tr("Import Coloring Rules")),
+ wsApp->lastOpenDir().path());
+ color_filters_import(file_name.toUtf8().constData(), this);
+ } else if (button == export_button_) {
+ int num_items = ui->coloringRulesTreeWidget->selectedItems().count();
+
+ if (num_items < 1) {
+ num_items = ui->coloringRulesTreeWidget->topLevelItemCount();
+ }
+
+ if (num_items < 1) return;
+
+ QString caption = wsApp->windowTitleString(tr("Export %1 Coloring Rules").arg(num_items));
+ QString file_name = QFileDialog::getSaveFileName(this, caption,
+ wsApp->lastOpenDir().path());
+ if (!file_name.isEmpty()) {
+ GSList *cfl = createColorFilterList();
+ color_filters_export(file_name.toUtf8().constData(), cfl, FALSE);
+ color_filter_list_delete(&cfl);
+ }
+ }
+}
+
+void ColoringRulesDialog::on_buttonBox_accepted()
+{
+ GSList *cfl = createColorFilterList();
+ if (prefs.unknown_colorfilters) {
+ QMessageBox mb;
+ mb.setText(tr("Your coloring rules file contains unknown rules"));
+ mb.setInformativeText(tr("Wireshark doesn't recognize one or more of your coloring rules. "
+ "Saving will discard them."));
+ mb.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel);
+ mb.setDefaultButton(QMessageBox::Save);
+
+ int result = mb.exec();
+ if (result != QMessageBox::Save) return;
+ }
+ color_filters_apply(conversation_colors_, cfl);
+ if (!color_filters_write(cfl)) {
+ QMessageBox::warning(this, tr("Unable to save coloring rules"), g_strerror(errno));
+ }
+ color_filter_list_delete(&cfl);
+}
+
+void ColoringRulesDialog::on_buttonBox_helpRequested()
+{
+ wsApp->helpTopicAction(HELP_COLORING_RULES_DIALOG);
+}
+
+
+//
+// ColoringRulesTreeDelegate
+// Delegate for editing coloring rule names and filters.
+//
+
+QWidget *ColoringRulesTreeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ Q_UNUSED(option);
+ QWidget *w = NULL;
+
+ QTreeWidgetItem *ti = tree_->topLevelItem(index.row());
+ if (!ti) return NULL;
+
+ switch (index.column()) {
+ case name_col_:
+ {
+ SyntaxLineEdit *sle = new SyntaxLineEdit(parent);
+ connect(sle, SIGNAL(textChanged(QString)), this, SLOT(ruleNameChanged(QString)));
+ sle->setText(ti->text(name_col_));
+ w = (QWidget*) sle;
+ }
+ break;
+
+ case filter_col_:
+ {
+ SyntaxLineEdit *dfe = new SyntaxLineEdit(parent);
+ connect(dfe, SIGNAL(textChanged(QString)), dfe, SLOT(checkDisplayFilter(QString)));
+ connect(dfe, SIGNAL(textChanged(QString)), this, SLOT(ruleFilterChanged(QString)));
+ dfe->setText(ti->text(filter_col_));
+ w = (QWidget*) dfe;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return w;
+}
+
+void ColoringRulesTreeDelegate::ruleNameChanged(const QString name)
+{
+ SyntaxLineEdit *name_edit = qobject_cast<SyntaxLineEdit*>(QObject::sender());
+ if (!name_edit) return;
+
+ if (name.isEmpty()) {
+ name_edit->setSyntaxState(SyntaxLineEdit::Empty);
+ } else if (name.contains("@")) {
+ name_edit->setSyntaxState(SyntaxLineEdit::Invalid);
+ } else {
+ name_edit->setSyntaxState(SyntaxLineEdit::Valid);
+ }
+
+ if (tree_->currentItem()) {
+ tree_->currentItem()->setText(name_col_, name);
+ }
+}
+
+void ColoringRulesTreeDelegate::ruleFilterChanged(const QString filter)
+{
+ if (tree_->currentItem()) {
+ tree_->currentItem()->setText(filter_col_, filter);
+ }
+}
+
+/*
+ * 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:
+ */
diff --git a/ui/qt/coloring_rules_dialog.h b/ui/qt/coloring_rules_dialog.h
new file mode 100644
index 0000000000..737c31daca
--- /dev/null
+++ b/ui/qt/coloring_rules_dialog.h
@@ -0,0 +1,108 @@
+/* coloring_rules_dialog.h
+ *
+ * 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.
+ */
+
+#ifndef COLORING_RULES_DIALOG_H
+#define COLORING_RULES_DIALOG_H
+
+#include <QDialog>
+
+class QAbstractButton;
+class QTreeWidget;
+
+struct _color_filter;
+struct _GSList; // This is a completely and toltally safe forward declaration, right?
+
+namespace Ui {
+class ColoringRulesDialog;
+}
+
+#include <QStyledItemDelegate>
+
+class ColoringRulesTreeDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ ColoringRulesTreeDelegate(QObject *parent = 0) : QStyledItemDelegate(parent) {}
+ ~ColoringRulesTreeDelegate() {}
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ void setTree(QTreeWidget* tree) { tree_ = tree; }
+
+private:
+ QTreeWidget* tree_;
+
+private slots:
+ void ruleNameChanged(const QString name);
+ void ruleFilterChanged(const QString filter);
+};
+
+class ColoringRulesDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit ColoringRulesDialog(QWidget *parent = 0, QString add_filter = QString());
+ ~ColoringRulesDialog();
+
+ void addColor(struct _color_filter *colorf);
+
+protected:
+ void showEvent(QShowEvent *);
+
+private slots:
+ void updateWidgets();
+ struct _GSList *createColorFilterList();
+ void on_coloringRulesTreeWidget_itemSelectionChanged();
+ void on_fGPushButton_clicked();
+ void on_bGPushButton_clicked();
+ void on_newToolButton_clicked();
+ void on_deleteToolButton_clicked();
+ void on_copyToolButton_clicked();
+ void on_buttonBox_clicked(QAbstractButton *button);
+ void on_buttonBox_accepted();
+ void on_buttonBox_helpRequested();
+
+private:
+ Ui::ColoringRulesDialog *ui;
+ QPushButton *import_button_;
+ QPushButton *export_button_;
+ ColoringRulesTreeDelegate coloring_rules_tree_delegate_;
+ struct _GSList *conversation_colors_;
+
+ void addColoringRule(bool disabled, QString name, QString filter, QColor foreground, QColor background, bool start_editing = false);
+ void changeColor(bool foreground = true);
+};
+
+#endif // COLORING_RULES_DIALOG_H
+
+/*
+ * 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:
+ */
diff --git a/ui/qt/coloring_rules_dialog.ui b/ui/qt/coloring_rules_dialog.ui
new file mode 100644
index 0000000000..8f94b7e7a6
--- /dev/null
+++ b/ui/qt/coloring_rules_dialog.ui
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ColoringRulesDialog</class>
+ <widget class="QDialog" name="ColoringRulesDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>650</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTreeWidget" name="coloringRulesTreeWidget">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <property name="itemsExpandable">
+ <bool>false</bool>
+ </property>
+ <property name="expandsOnDoubleClick">
+ <bool>false</bool>
+ </property>
+ <column>
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Filter</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="hintLabel">
+ <property name="text">
+ <string>&lt;small&gt;&lt;i&gt;A hint.&lt;/i&gt;&lt;/small&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0,0,1">
+ <item>
+ <widget class="QToolButton" name="newToolButton">
+ <property name="toolTip">
+ <string>Add a new coloring rule.</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../../image/toolbar.qrc">
+ <normaloff>:/stock/plus-8.png</normaloff>:/stock/plus-8.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="deleteToolButton">
+ <property name="toolTip">
+ <string>Delete this coloring rule.</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../../image/toolbar.qrc">
+ <normaloff>:/stock/minus-8.png</normaloff>:/stock/minus-8.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="copyToolButton">
+ <property name="toolTip">
+ <string>Duplicate this coloring rule.</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../../image/toolbar.qrc">
+ <normaloff>:/stock/copy-8.png</normaloff>:/stock/copy-8.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="fGPushButton">
+ <property name="toolTip">
+ <string>Set the foreground color for this rule.</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">QPushButton { border: 1px solid palette(Dark); }</string>
+ </property>
+ <property name="text">
+ <string>Foreground</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="bGPushButton">
+ <property name="toolTip">
+ <string>Set the background color for this rule.</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">QPushButton { border: 1px solid palette(Dark); }</string>
+ </property>
+ <property name="text">
+ <string>Background</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../../image/toolbar.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ColoringRulesDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>ColoringRulesDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/ui/qt/io_graph_dialog.ui b/ui/qt/io_graph_dialog.ui
index b9468f6b42..e51e23ada6 100644
--- a/ui/qt/io_graph_dialog.ui
+++ b/ui/qt/io_graph_dialog.ui
@@ -109,7 +109,7 @@
<item>
<widget class="QToolButton" name="newToolButton">
<property name="toolTip">
- <string>Change the dissection behavior for a protocol.</string>
+ <string>Add a new graph.</string>
</property>
<property name="text">
<string/>
@@ -123,7 +123,7 @@
<item>
<widget class="QToolButton" name="deleteToolButton">
<property name="toolTip">
- <string>Remove this dissection behavior.</string>
+ <string>Remove this graph.</string>
</property>
<property name="icon">
<iconset resource="../../image/toolbar.qrc">
@@ -134,7 +134,7 @@
<item>
<widget class="QToolButton" name="copyToolButton">
<property name="toolTip">
- <string>Copy this dissection behavior.</string>
+ <string>Duplicate this graph.</string>
</property>
<property name="text">
<string/>
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index 68715457bf..3bdc9e4158 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -314,6 +314,7 @@ private slots:
void on_actionViewZoomOut_triggered();
void on_actionViewNormalSize_triggered();
void on_actionViewColorizePacketList_triggered(bool checked);
+ void on_actionViewColoringRules_triggered();
void on_actionViewResizeColumns_triggered();
void on_actionViewReload_triggered();
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index 4bb733876a..b2f945dd27 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -291,6 +291,7 @@
<addaction name="actionViewCollapseAll"/>
<addaction name="separator"/>
<addaction name="actionViewColorizePacketList"/>
+ <addaction name="actionViewColoringRules"/>
<addaction name="separator"/>
<addaction name="actionViewResizeColumns"/>
<addaction name="separator"/>
@@ -2246,10 +2247,24 @@
<string>RTP Streams</string>
</property>
</action>
+ <action name="actionViewColoringRules">
+ <property name="text">
+ <string>&amp;Coloring Rules...</string>
+ </property>
+ <property name="toolTip">
+ <string>Edit the packet list coloring rules.</string>
+ </property>
+ </action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
+ <class>AccordionFrame</class>
+ <extends>QFrame</extends>
+ <header>accordion_frame.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
<class>MainStatusBar</class>
<extends>QStatusBar</extends>
<header>main_status_bar.h</header>
@@ -2266,12 +2281,6 @@
<header>search_frame.h</header>
</customwidget>
<customwidget>
- <class>AccordionFrame</class>
- <extends>QFrame</extends>
- <header>accordion_frame.h</header>
- <container>1</container>
- </customwidget>
- <customwidget>
<class>ColumnEditorFrame</class>
<extends>QFrame</extends>
<header>column_editor_frame.h</header>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 9d56954383..b80478a584 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -73,6 +73,7 @@
#include "capture_file_dialog.h"
#include "capture_file_properties_dialog.h"
+#include "coloring_rules_dialog.h"
#include "conversation_dialog.h"
#include "decode_as_dialog.h"
#include "endpoint_dialog.h"
@@ -1986,6 +1987,13 @@ void MainWindow::on_actionViewColorizePacketList_triggered(bool checked) {
packet_list_->update();
}
+void MainWindow::on_actionViewColoringRules_triggered()
+{
+ ColoringRulesDialog coloring_rules_dialog(this);
+
+ coloring_rules_dialog.exec();
+}
+
void MainWindow::on_actionViewResizeColumns_triggered()
{
for (int col = 0; col < packet_list_->packetListModel()->columnCount(); col++) {
diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp
index 6b465186a1..a11353563e 100644
--- a/ui/qt/packet_list.cpp
+++ b/ui/qt/packet_list.cpp
@@ -643,6 +643,12 @@ void PacketList::redrawVisiblePackets() {
header()->update();
}
+void PacketList::recolorPackets()
+{
+ packet_list_model_->resetColorized();
+ redrawVisiblePackets();
+}
+
void PacketList::freeze()
{
setUpdatesEnabled(false);
diff --git a/ui/qt/packet_list.h b/ui/qt/packet_list.h
index 8886abaff3..f4368f7f11 100644
--- a/ui/qt/packet_list.h
+++ b/ui/qt/packet_list.h
@@ -63,6 +63,7 @@ public:
QString packetComment();
void setPacketComment(QString new_comment);
QString allPacketComments();
+ void recolorPackets();
protected:
void showEvent (QShowEvent *event);