Qt: Byte view recent updates.
authorGerald Combs <gerald@wireshark.org>
Wed, 3 Jan 2018 21:29:55 +0000 (13:29 -0800)
committerRoland Knall <rknall@gmail.com>
Fri, 5 Jan 2018 06:52:13 +0000 (06:52 +0000)
Add a recent.gui_bytes_encoding preference and use it for the byte view
encoding as requested in bug 14044.

The recent.gui_bytes_view preference is an enum, so make it one.

Bug: 14044
Change-Id: Ibc40721c29465aca1940467e41d71e9dd2485e71
Reviewed-on: https://code.wireshark.org/review/25147
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Roland Knall <rknall@gmail.com>
ui/qt/widgets/byte_view_text.cpp
ui/recent.c
ui/recent.h

index 07264771f65554a889fac609bad094e3a907bca5..232ee46f8a4ca791c60c9b1598ab3106bc2372cc 100644 (file)
 #include <QTextLayout>
 
 // To do:
-// - Add recent settings and context menu items to show/hide the offset,
-//   and ASCII/EBCDIC.
+// - Add recent settings and context menu items to show/hide the offset.
 // - Add a UTF-8 and possibly UTF-xx option to the ASCII display.
-// - Add "copy bytes as" context menu items.
 // - Move more common metrics to DataPrinter.
 
 Q_DECLARE_METATYPE(bytes_view_type)
-Q_DECLARE_METATYPE(packet_char_enc)
+Q_DECLARE_METATYPE(bytes_encoding_type)
 Q_DECLARE_METATYPE(DataPrinter::DumpType)
 
 ByteViewText::ByteViewText(const QByteArray &data, packet_char_enc encoding, QWidget *parent) :
@@ -78,47 +76,53 @@ ByteViewText::~ByteViewText()
 
 void ByteViewText::createContextMenu()
 {
-    QActionGroup * format_actions_ = new QActionGroup(this);
     QAction *action;
 
-    QActionGroup * copyEntries = DataPrinter::copyActions(this);
-    ctx_menu_.addActions(copyEntries->actions());
+    QActionGroup * copy_actions = DataPrinter::copyActions(this);
+    ctx_menu_.addActions(copy_actions->actions());
     ctx_menu_.addSeparator();
 
-    action = format_actions_->addAction(tr("Show bytes as hexadecimal"));
+    QActionGroup * format_actions = new QActionGroup(this);
+    action = format_actions->addAction(tr("Show bytes as hexadecimal"));
     action->setData(qVariantFromValue(BYTES_HEX));
     action->setCheckable(true);
     if (recent.gui_bytes_view == BYTES_HEX) {
         action->setChecked(true);
     }
-    action = format_actions_->addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "as bits"));
+    action = format_actions->addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "as bits"));
     action->setData(qVariantFromValue(BYTES_BITS));
     action->setCheckable(true);
     if (recent.gui_bytes_view == BYTES_BITS) {
         action->setChecked(true);
     }
 
-    ctx_menu_.addActions(format_actions_->actions());
-    connect(format_actions_, SIGNAL(triggered(QAction*)), this, SLOT(setHexDisplayFormat(QAction*)));
+    ctx_menu_.addActions(format_actions->actions());
+    connect(format_actions, SIGNAL(triggered(QAction*)), this, SLOT(setHexDisplayFormat(QAction*)));
 
     ctx_menu_.addSeparator();
 
-    QActionGroup * encoding_actions_ = new QActionGroup(this);
-    action = encoding_actions_->addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "as ASCII"));
-    action->setData(qVariantFromValue(PACKET_CHAR_ENC_CHAR_ASCII));
+    QActionGroup * encoding_actions = new QActionGroup(this);
+    action = encoding_actions->addAction(tr("Show text based on packet"));
+    action->setData(qVariantFromValue(BYTES_ENC_FROM_PACKET));
     action->setCheckable(true);
-    if (encoding_ == PACKET_CHAR_ENC_CHAR_ASCII) {
+    if (recent.gui_bytes_encoding == BYTES_ENC_FROM_PACKET) {
         action->setChecked(true);
     }
-    action = encoding_actions_->addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "as EBCDIC"));
-    action->setData(qVariantFromValue(PACKET_CHAR_ENC_CHAR_EBCDIC));
+    action = encoding_actions->addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "as ASCII"));
+    action->setData(qVariantFromValue(BYTES_ENC_ASCII));
     action->setCheckable(true);
-    if (encoding_ == PACKET_CHAR_ENC_CHAR_EBCDIC) {
+    if (recent.gui_bytes_encoding == BYTES_ENC_ASCII) {
+        action->setChecked(true);
+    }
+    action = encoding_actions->addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "as EBCDIC"));
+    action->setData(qVariantFromValue(BYTES_ENC_EBCDIC));
+    action->setCheckable(true);
+    if (recent.gui_bytes_encoding == BYTES_ENC_EBCDIC) {
         action->setChecked(true);
     }
 
-    ctx_menu_.addActions(encoding_actions_->actions());
-    connect(encoding_actions_, SIGNAL(triggered(QAction*)), this, SLOT(setCharacterEncoding(QAction*)));
+    ctx_menu_.addActions(encoding_actions->actions());
+    connect(encoding_actions, SIGNAL(triggered(QAction*)), this, SLOT(setCharacterEncoding(QAction*)));
 }
 
 bool ByteViewText::isEmpty() const
@@ -351,6 +355,8 @@ void ByteViewText::drawLine(QPainter *painter, const int offset, const int row_y
         bool in_non_printable = false;
         int np_start = 0;
         int np_len = 0;
+        guchar c;
+
         for (int tvb_pos = offset; tvb_pos <= max_tvb_pos; tvb_pos++) {
             /* insert a space every separator_interval_ bytes */
             if ((tvb_pos != offset) && ((tvb_pos % separator_interval_) == 0)) {
@@ -360,9 +366,11 @@ void ByteViewText::drawLine(QPainter *painter, const int offset, const int row_y
                 }
             }
 
-            guchar c = (encoding_ == PACKET_CHAR_ENC_CHAR_EBCDIC) ?
-                        EBCDIC_to_ASCII1(data_[tvb_pos]) :
-                        data_[tvb_pos];
+            if (recent.gui_bytes_encoding != BYTES_ENC_EBCDIC && encoding_ == PACKET_CHAR_ENC_CHAR_ASCII) {
+                c = data_[tvb_pos];
+            } else {
+                c = EBCDIC_to_ASCII1(data_[tvb_pos]);
+            }
 
             if (g_ascii_isprint(c)) {
                 line += c;
@@ -614,7 +622,7 @@ void ByteViewText::setCharacterEncoding(QAction *action)
         return;
     }
 
-    encoding_ = action->data().value<packet_char_enc>();
+    recent.gui_bytes_encoding = action->data().value<bytes_encoding_type>();
     viewport()->update();
 }
 
index 35ec2785f658937180670c1c2070a9b7d6c5e729..11a6f96008984d6daa429630b5674a6e69a9ff7e 100644 (file)
@@ -44,6 +44,7 @@
 #define RECENT_GUI_SECONDS_FORMAT             "gui.seconds_format"
 #define RECENT_GUI_ZOOM_LEVEL                 "gui.zoom_level"
 #define RECENT_GUI_BYTES_VIEW                 "gui.bytes_view"
+#define RECENT_GUI_BYTES_ENCODING             "gui.bytes_encoding"
 #define RECENT_GUI_GEOMETRY_MAIN_X            "gui.geometry_main_x"
 #define RECENT_GUI_GEOMETRY_MAIN_Y            "gui.geometry_main_y"
 #define RECENT_GUI_GTK_GEOMETRY_MAIN_X        "gui.gtk.geometry_main_x"
@@ -108,6 +109,19 @@ static const value_string ts_seconds_values[] = {
     { 0, NULL }
 };
 
+static const value_string bytes_view_type_values[] = {
+    { BYTES_HEX,    "HEX"  },
+    { BYTES_BITS,   "BITS" },
+    { 0, NULL }
+};
+
+static const value_string bytes_encoding_type_values[] = {
+    { BYTES_ENC_FROM_PACKET,    "FROM_PACKET"  },
+    { BYTES_ENC_ASCII,          "ASCII"  },
+    { BYTES_ENC_EBCDIC,         "EBCDIC"  },
+    { 0, NULL }
+};
+
 static void
 free_col_width_data(gpointer data, gpointer user_data _U_)
 {
@@ -824,11 +838,14 @@ write_profile_recent(void)
     fprintf(rf, RECENT_GUI_ZOOM_LEVEL ": %d\n",
             recent.gui_zoom_level);
 
-    fprintf(rf, "\n# Bytes view.\n");
-    fprintf(rf, "# A decimal number.\n");
-    fprintf(rf, RECENT_GUI_BYTES_VIEW ": %d\n",
+    write_recent_enum(rf, "Bytes view display type",
+            RECENT_GUI_BYTES_VIEW, bytes_view_type_values,
             recent.gui_bytes_view);
 
+    write_recent_enum(rf, "Bytes view text encoding",
+            RECENT_GUI_BYTES_ENCODING, bytes_encoding_type_values,
+            recent.gui_bytes_encoding);
+
     fprintf(rf, "\n# Main window upper (or leftmost) pane size.\n");
     fprintf(rf, "# Decimal number.\n");
     if (recent.gui_geometry_main_upper_pane != 0) {
@@ -1027,10 +1044,11 @@ read_set_recent_pair_static(gchar *key, const gchar *value,
             return PREFS_SET_SYNTAX_ERR;      /* number was bad */
         recent.gui_zoom_level = (gint)num;
     } else if (strcmp(key, RECENT_GUI_BYTES_VIEW) == 0) {
-        num = strtol(value, &p, 0);
-        if (p == value || *p != '\0')
-            return PREFS_SET_SYNTAX_ERR;      /* number was bad */
-        recent.gui_bytes_view = (bytes_view_type)num;
+        recent.gui_bytes_view =
+            (bytes_view_type)str_to_val(value, bytes_view_type_values, BYTES_HEX);
+    } else if (strcmp(key, RECENT_GUI_BYTES_ENCODING) == 0) {
+        recent.gui_bytes_encoding =
+            (bytes_encoding_type)str_to_val(value, bytes_encoding_type_values, BYTES_ENC_FROM_PACKET);
     } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED) == 0) {
         parse_recent_boolean(value, &recent.gui_geometry_main_maximized);
     } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE) == 0) {
@@ -1284,6 +1302,7 @@ recent_read_profile_static(char **rf_path_return, int *rf_errno_return)
     recent.gui_seconds_format        = TS_SECONDS_DEFAULT;
     recent.gui_zoom_level            = 0;
     recent.gui_bytes_view            = BYTES_HEX;
+    recent.gui_bytes_encoding        = BYTES_ENC_FROM_PACKET;
 
     /* pane size of zero will autodetect */
     recent.gui_geometry_main_upper_pane   = 0;
index 5ee7e14f9c28ab91e50a8afc5633724c7de38f35..05cfd9077b45a43b8d92107931ab6cb0eafe147a 100644 (file)
@@ -56,6 +56,12 @@ typedef enum {
     BYTES_BITS
 } bytes_view_type;
 
+typedef enum {
+    BYTES_ENC_FROM_PACKET, // frame_data packet_char_enc
+    BYTES_ENC_ASCII,
+    BYTES_ENC_EBCDIC
+} bytes_encoding_type;
+
 /** Recent settings. */
 typedef struct recent_settings_tag {
     gboolean    main_toolbar_show;
@@ -72,6 +78,7 @@ typedef struct recent_settings_tag {
     ts_seconds_type gui_seconds_format;
     gint        gui_zoom_level;
     bytes_view_type gui_bytes_view;
+    bytes_encoding_type gui_bytes_encoding;
 
     gint        gui_geometry_main_x;
     gint        gui_geometry_main_y;