summaryrefslogtreecommitdiff
path: root/ui/qt/byte_view_text.cpp
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2012-10-30 19:21:24 +0000
committerGerald Combs <gerald@wireshark.org>2012-10-30 19:21:24 +0000
commit0a28fb8f6a354aa9a446b6bf70733c305534e074 (patch)
treea075f90a96240ec13bbb5b15135e4f81cb9c75f3 /ui/qt/byte_view_text.cpp
parent27b5d556cb53bee24e20a9bb5862189ee2e55a61 (diff)
downloadwireshark-0a28fb8f6a354aa9a446b6bf70733c305534e074.tar.gz
Update the Qt byte view widget to reflect the recent changes in the GTK+
byte view. Move the packet_char_enc enum from packet.h to frame_data.h. Make the encoding flag a packet_char_enc and make it one bit. Get rid of the "cfile" global in a few places. C++-ize some of the font code. Clean up some variable names. svn path=/trunk/; revision=45838
Diffstat (limited to 'ui/qt/byte_view_text.cpp')
-rw-r--r--ui/qt/byte_view_text.cpp838
1 files changed, 297 insertions, 541 deletions
diff --git a/ui/qt/byte_view_text.cpp b/ui/qt/byte_view_text.cpp
index ba814e0966..fca655ed47 100644
--- a/ui/qt/byte_view_text.cpp
+++ b/ui/qt/byte_view_text.cpp
@@ -21,11 +21,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "monospace_font.h"
#include "byte_view_text.h"
#include <epan/charsets.h>
+#include "wireshark_application.h"
#include <QTextCursor>
#include <QApplication>
#include <QMouseEvent>
@@ -33,579 +33,334 @@
// XXX - Use KHexEdit instead?
// http://api.kde.org/4.x-api/kdelibs-apidocs/interfaces/khexedit/html/index.html
-ByteViewText::ByteViewText(QWidget *parent, tvbuff_t *tvb, proto_tree *tree, QTreeWidget *protoTree, unsigned int encoding) :
- QTextEdit(parent)
+ByteViewText::ByteViewText(QWidget *parent, tvbuff_t *tvb, proto_tree *tree, QTreeWidget *tree_widget, packet_char_enc encoding) :
+ QTextEdit(parent),
+ tvb_(tvb),
+ proto_tree_(tree),
+ tree_widget_(tree_widget),
+ max_width_(0),
+ bold_highlight_(false),
+ encoding_(encoding),
+ format_(BYTES_HEX),
+ per_line_(16),
+ offset_width_(4)
{
setReadOnly(true);
setLineWrapMode(QTextEdit::NoWrap);
- setCurrentFont(get_monospace_font());
+ setState(StateNormal);
+}
- m_tvb = tvb;
- m_tree = tree;
- m_protoTree = protoTree;
- m_encoding = encoding;
- m_start = m_len = 0;
+void ByteViewText::setEncoding(packet_char_enc encoding)
+{
+ encoding_ = encoding;
+}
-// m_background = textBackgroundColor();
-// m_foreground = textColor();
+bool ByteViewText::hasDataSource(tvbuff_t *ds_tvb) {
+ if (ds_tvb != NULL && ds_tvb == tvb_)
+ return true;
+ return false;
+}
-// g_log(NULL, G_LOG_LEVEL_DEBUG, "fg %d %d %d bg %d %d %d",
-// m_foreground.red(), m_foreground.green(), m_foreground.blue(),
-// m_background.red(), m_background.green(), m_background.blue()
-// );
+void ByteViewText::setProtocolHighlight(int start, int end)
+{
+ p_start_ = start;
+ p_end_ = end;
+}
- hexPrintCommon();
+void ByteViewText::setFieldHighlight(int start, int end, guint32 mask, int mask_le)
+{
+ Q_UNUSED(mask);
+ Q_UNUSED(mask_le);
+ f_start_ = start;
+ f_end_ = end;
}
-#define MAX_OFFSET_LEN 8 /* max length of hex offset of bytes */
-#define BYTES_PER_LINE 16 /* max byte values in a line */
-#define BITS_PER_LINE 8 /* max bit values in a line */
+void ByteViewText::setFieldAppendixHighlight(int start, int end)
+{
+ fa_start_ = start;
+ fa_end_ = end;
+}
+
+void ByteViewText::render()
+{
+ int length;
+
+ if (!tvb_) {
+ clear();
+ return;
+ }
+
+ setUpdatesEnabled(false);
+ clear();
+
+ length = tvb_length(tvb_);
+ for (int off = 0; off < length; off += per_line_) {
+ lineCommon(off);
+ }
+
+ if (f_start_ != -1 && f_end_ != -1) {
+ scrollToByte(f_start_);
+ } else if (p_start_ != -1 && p_end_ != -1) {
+ scrollToByte(p_start_);
+ }
+
+ setUpdatesEnabled(true);
+}
+
+// Private
+
#define BYTE_VIEW_SEP 8 /* insert a space every BYTE_VIEW_SEP bytes */
-#define HEX_DUMP_LEN (BYTES_PER_LINE*3 + 1)
-/* max number of characters hex dump takes -
- 2 digits plus trailing blank
- plus separator between first and
- second 8 digits */
-#define DATA_DUMP_LEN (HEX_DUMP_LEN + 2 + BYTES_PER_LINE)
-/* number of characters those bytes take;
- 3 characters per byte of hex dump,
- 2 blanks separating hex from ASCII,
- 1 character per byte of ASCII dump */
-#define MAX_LINE_LEN (MAX_OFFSET_LEN + 2 + DATA_DUMP_LEN)
-/* number of characters per line;
- offset, 2 blanks separating offset
- from data dump, data dump */
-#define MAX_LINES 100
-#define MAX_LINES_LEN (MAX_LINES*MAX_LINE_LEN)
-
-// Copied from packet_hex_print_common
-void
-ByteViewText::hexPrintCommon()
+
+void ByteViewText::lineCommon(const int org_off)
{
- int i = 0, j, k = 0, len;
- const guint8 *pd;
- QString line;
- static guchar hexchars[16] = {
+ static const guchar hexchars[16] = {
'0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
-// static const guint8 bitmask[8] = {
-// 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
- guchar c = '\0';
-
-// progdlg_t *progbar = NULL;
-// float progbar_val;
-// gboolean progbar_stop_flag;
-// GTimeVal progbar_start_time;
-// gchar progbar_status_str[100];
-// int progbar_nextstep;
-// int progbar_quantum;
-
- setPlainText("");
- // Replaces get_byte_view_data_and_length().
- if (!m_tvb)
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+ const guint8 *pd;
+ int len;
+
+ highlight_state state;
+
+ QString str;
+
+ int off;
+ guchar c;
+ int byten;
+ int j;
+
+ g_assert(org_off >= 0);
+
+ if (!tvb_)
return;
- len = tvb_length(m_tvb);
- pd = tvb_get_ptr(m_tvb, 0, -1);
-
- /*
- * How many of the leading digits of the offset will we supply?
- * We always supply at least 4 digits, but if the maximum offset
- * won't fit in 4 digits, we use as many digits as will be needed.
- */
- if (((len - 1) & 0xF0000000) != 0)
- m_useDigits = 8; /* need all 8 digits */
- else if (((len - 1) & 0x0F000000) != 0)
- m_useDigits = 7; /* need 7 digits */
- else if (((len - 1) & 0x00F00000) != 0)
- m_useDigits = 6; /* need 6 digits */
- else if (((len - 1) & 0x000F0000) != 0)
- m_useDigits = 5; /* need 5 digits */
- else
- m_useDigits = 4; /* we'll supply 4 digits */
-
- /* Update the progress bar when it gets to this value. */
-// if (len > MIN_PACKET_LENGTH){
-// progbar_nextstep = 0;
-// }else{
-// /* If length =< MIN_PACKET_LENGTH
-// * there is no need to calculate the progress
-// */
-// progbar_nextstep = len+1;
-// }
-
-// /* When we reach the value that triggers a progress bar update,
-// bump that value by this amount. */
-// progbar_quantum = len/N_PROGBAR_UPDATES;
-// /* Progress so far. */
-// progbar_val = 0.0f;
-
-// progbar_stop_flag = FALSE;
-// g_get_current_time(&progbar_start_time);
-
- while (i < len) {
- /* Create the progress bar if necessary.
- We check on every iteration of the loop, so that it takes no
- longer than the standard time to create it (otherwise, for a
- large packet, we might take considerably longer than that standard
- time in order to get to the next progress bar step). */
-// if ((progbar == NULL) && (len > MIN_PACKET_LENGTH))
-// progbar = delayed_create_progress_dlg("Processing", "Packet Details",
-// TRUE,
-// &progbar_stop_flag,
-// &progbar_start_time,
-// progbar_val);
-
- /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
- when we update it, we have to run the GTK+ main loop to get it
- to repaint what's pending, and doing so may involve an "ioctl()"
- to see if there's any pending input from an X server, and doing
- that for every packet can be costly, especially on a big file. */
-// if (i >= progbar_nextstep) {
-
-// if (progbar != NULL) {
-// /* let's not divide by zero. I should never be started
-// * with count == 0, so let's assert that
-// */
-// g_assert(len > 0);
-// progbar_val = (gfloat) i / len;
-// g_snprintf(progbar_status_str, sizeof(progbar_status_str),
-// "%4u of %u bytes", i, len);
-// update_progress_dlg(progbar, progbar_val, progbar_status_str);
-// }
-
-// progbar_nextstep += progbar_quantum;
-// }
-
-// if (progbar_stop_flag) {
-// /* Well, the user decided to abort the operation. Just stop,
-// and arrange to return TRUE to our caller, so they know it
-// was stopped explicitly. */
-// break;
-// }
-
- /* Print the line number */
- j = m_useDigits;
- do {
- j--;
- c = (i >> (j*4)) & 0xF;
- line += hexchars[c];
- } while (j != 0);
- line += " ";
-
- j = i;
-// switch (recent.gui_bytes_view) {
-// case BYTES_HEX:
- k = i + BYTES_PER_LINE;
-// break;
-// case BYTES_BITS:
-// k = i + BITS_PER_LINE;
-// break;
-// default:
-// g_assert_not_reached();
-// }
- /* Print the hex bit */
- while (i < k) {
- if (i < len) {
-// switch (recent.gui_bytes_view) {
-// case BYTES_HEX:
- line += hexchars[(pd[i] & 0xf0) >> 4];
- line += hexchars[pd[i] & 0x0f];
-// break;
-// case BYTES_BITS:
-// for (b = 0; b < 8; b++) {
-// line += (pd[i] & bitmask[b]) ? '1' : '0';
-// }
-// break;
-// default:
-// g_assert_not_reached();
-// }
- } else {
-// switch (recent.gui_bytes_view) {
-// case BYTES_HEX:
- line += " ";
-// break;
-// case BYTES_BITS:
-// for (b = 0; b < 8; b++) {
-// line += ' ';
-// }
-// break;
-// default:
-// g_assert_not_reached();
-// }
- }
- i++;
- /* Inter byte space if not at end of line */
- if (i < k) {
- line += ' ';
+ len = tvb_length(tvb_);
+ pd = tvb_get_ptr(tvb_, 0, -1);
+
+ state = StateNormal;
+ setState(state);
+
+ /* Print the line number */
+ str += QString("%1 ").arg(org_off, offset_width_, 16, QChar('0'));
+
+ /* Print the hex bit */
+ for (byten = 0, off = org_off; byten < per_line_; byten++) {
+ highlight_state state_cur = StateNormal;
+ bool add_space = byten > 0;
+
+ if ((off >= f_start_ && off < f_end_) || (off >= fa_start_ && off < fa_end_)) {
+ state_cur = StateField;
+ } else if (off >= p_start_ && off < p_end_) {
+ state_cur = StateProtocol;
+ }
+
+ if (state_cur != state) {
+ if (state != StateField && add_space) {
+ add_space = false;
+ str += ' ';
/* insert a space every BYTE_VIEW_SEP bytes */
- if( ( i % BYTE_VIEW_SEP ) == 0 ) {
- line += ' ';
- }
+ if ((off % BYTE_VIEW_SEP) == 0)
+ str += ' ';
}
- }
- /* Print some space at the end of the line */
- line += " ";
+ if (flushBytes(str) < 0)
+ return;
+ setState(state_cur);
+ state = state_cur;
+ }
- /* Print the ASCII bit */
- i = j;
+ if (add_space) {
+ str += ' ';
+ /* insert a space every BYTE_VIEW_SEP bytes */
+ if ((off % BYTE_VIEW_SEP) == 0)
+ str += ' ';
+ }
- while (i < k) {
- if (i < len) {
- if (m_encoding == PACKET_CHAR_ENC_CHAR_ASCII) {
- c = pd[i];
- }
- else if (m_encoding == PACKET_CHAR_ENC_CHAR_EBCDIC) {
- c = EBCDIC_to_ASCII1(pd[i]);
- }
- else {
- g_assert_not_reached();
- }
- line += isascii(c) && isprint(c) ? c : '.';
- } else {
- line += ' ';
+ if (off < len) {
+ switch (format_) {
+ case BYTES_HEX:
+ str += hexchars[(pd[off] & 0xf0) >> 4];
+ str += hexchars[pd[off] & 0x0f];
+ break;
+ case BYTES_BITS:
+ /* XXX, bitmask */
+ for (j = 7; j >= 0; j--)
+ str += (pd[off] & (1 << j)) ? '1' : '0';
+ break;
}
- i++;
- if (i < k) {
- /* insert a space every BYTE_VIEW_SEP bytes */
- if( ( i % BYTE_VIEW_SEP ) == 0 ) {
- line += ' ';
- }
+ } else {
+ switch (format_) {
+ case BYTES_HEX:
+ str += " ";
+ break;
+ case BYTES_BITS:
+ str += " ";
+ break;
}
}
- line += '\n';
- if (line.length() >= (MAX_LINES_LEN - MAX_LINE_LEN)) {
- append(line);
- line.clear();
- }
+ off++;
}
-// /* We're done printing the packets; destroy the progress bar if
-// it was created. */
-// if (progbar != NULL)
-// destroy_progress_dlg(progbar);
-
- if (line.length()) {
- append(line);
+ if (state != StateNormal) {
+ if (flushBytes(str) < 0)
+ return;
+ setState(StateNormal);
+ state = StateNormal;
}
-}
-bool ByteViewText::hasDataSource(tvbuff_t *ds_tvb) {
- if (ds_tvb != NULL && ds_tvb == m_tvb)
- return true;
- return false;
-}
+ /* Print some space at the end of the line */
+ str += " ";
-// Copied from packet_hex_apply_reverse_tag
-void ByteViewText::highlight(int bstart, int blen, bool is_root) {
- m_start = bstart;
-// m_len = blen;
+ /* Print the ASCII bit */
+ for (byten = 0, off = org_off; byten < per_line_; byten++) {
+ highlight_state state_cur = StateNormal;
+ bool add_space = byten > 0;
-// g_log(NULL, G_LOG_LEVEL_DEBUG, "hl %d %d %d %d", start, len, m_foreground.color().red(), m_background.color().red());
- QTextCursor cursor(textCursor());
- QTextCharFormat format = cursor.charFormat();
+ if ((off >= f_start_ && off < f_end_) || (off >= fa_start_ && off < fa_end_)) {
+ state_cur = StateField;
+ } else if (off >= p_start_ && off < p_end_) {
+ state_cur = StateProtocol;
+ }
- QPalette pal = QApplication::palette();
+ if (state_cur != state) {
+ if (state != StateField && add_space) {
+ add_space = false;
+ /* insert a space every BYTE_VIEW_SEP bytes */
+ if ((off % BYTE_VIEW_SEP) == 0)
+ str += ' ';
+ }
- if (is_root) {
- cursor.movePosition(QTextCursor::Start);
- cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
- format.setForeground(pal.text());
- format.setBackground(pal.base());
- cursor.setCharFormat(format);
- }
+ if (flushBytes(str) < 0)
+ return;
+ setState(state_cur);
+ state = state_cur;
+ }
- // XXX - We should probably use the same colors as the packet list and proto tree selections.
- // It isn't obvious how to fetch these.
- format.setForeground(is_root ? pal.text() : pal.base());
- format.setBackground(is_root ? pal.alternateBase() : pal.text());
+ if (add_space) {
+ /* insert a space every BYTE_VIEW_SEP bytes */
+ if ((off % BYTE_VIEW_SEP) == 0)
+ str += ' ';
+ }
- int bend = bstart + blen;
- int per_line = 0;
- int per_one = 0;
-// int bits_per_one = 0;
- int hex_offset, ascii_offset;
+ if (off < len) {
+ c = (encoding_ == PACKET_CHAR_ENC_CHAR_EBCDIC) ?
+ EBCDIC_to_ASCII1(pd[off]) :
+ pd[off];
- int start_line, start_line_pos;
- int stop_line, stop_line_pos;
+ str += isprint(c) ? c : '.';
+ } else
+ str += ' ';
- if (bstart == -1 || blen == -1)
- return;
+ off++;
+ }
-// /* Display with inverse video ? */
-// if (prefs.gui_hex_dump_highlight_style)
-// revstyle = "reverse";
-// else
-// revstyle = "bold";
-
-// switch (recent.gui_bytes_view) {
-// case BYTES_HEX:
- per_line = BYTES_PER_LINE;
- per_one = 2+1; /* "ff " */
-// bits_per_one = 4;
-// break;
-// case BYTES_BITS:
-// per_line = BITS_PER_LINE;
-// per_one = 8+1; /* "10101010 " */
-// bits_per_one = 1;
-// break;
-// default:
-// g_assert_not_reached();
-// }
-
- start_line = bstart / per_line;
- start_line_pos = bstart % per_line;
-
- stop_line = bend / per_line;
- stop_line_pos = bend % per_line;
-
-#define hex_fix(pos) hex_offset + (pos * per_one) + (pos / BYTE_VIEW_SEP) - (pos == per_line)
-#define ascii_fix(pos) pos + (pos / BYTE_VIEW_SEP) - (pos == per_line)
-
- hex_offset = m_useDigits + 2;
- ascii_offset = hex_fix(per_line) + 2;
-
- cursor.setPosition(0);
- cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, start_line);
-
-// if (mask == 0x00) {
- while (start_line <= stop_line) {
- int line_pos_end = (start_line == stop_line) ? stop_line_pos : per_line;
-// int first_block_adjust = (recent.gui_bytes_view == BYTES_HEX) ? (line_pos_end == per_line/2) : 0;
- int first_block_adjust = line_pos_end == per_line/2;
-
- if (start_line_pos == line_pos_end) break;
-
- // Should we just jump to absolute offsets instead?
- /* bits/hex */
- int cursor_start = hex_fix(start_line_pos);
- int cursor_len = hex_fix(line_pos_end) - cursor_start - 1 - first_block_adjust;
- cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, cursor_start);
- cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, cursor_len);
- cursor.setCharFormat(format);
- cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, ascii_offset - cursor_start - cursor_len);
-
- /* ascii */
- cursor_start = ascii_fix(start_line_pos);
- cursor_len = ascii_fix(line_pos_end) - cursor_start - first_block_adjust;
- cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, cursor_start);
- cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, cursor_len);
- cursor.setCharFormat(format);
-
- start_line_pos = 0;
- start_line++;
- // You are encouraged to make carriage return and line feed sound
- // effects as you read the next two lines.
- cursor.movePosition(QTextCursor::StartOfLine);
- cursor.movePosition(QTextCursor::Down);
- }
+ if (str.length() > 0) {
+ if (flushBytes(str) < 0)
+ return;
+ }
-// } else if (mask_le) { /* LSB of mask first (little-endian) */
-// while (start_line <= stop_line) {
-// int line_pos_end = (start_line == stop_line) ? stop_line_pos : per_line;
-// int line_pos = start_line_pos;
-
-// while (line_pos < line_pos_end) {
-// int lop = 8 / bits_per_one;
-// int mask_per_one = (1 << bits_per_one) - 1;
-// int ascii_on = 0;
-
-// while (lop--) {
-// if ((mask & mask_per_one)) {
-// /* bits/hex */
-// gtk_text_buffer_get_iter_at_line_index(buf, &i_start, start_line, hex_fix(line_pos)+lop);
-// gtk_text_buffer_get_iter_at_line_index(buf, &i_stop, start_line, hex_fix(line_pos)+lop+1);
-// gtk_text_buffer_apply_tag(buf, revstyle_tag, &i_start, &i_stop);
-
-// ascii_on = 1;
-// }
-// mask >>= bits_per_one;
-// }
-
-// /* at least one bit of ascii was one -> turn ascii on */
-// if (ascii_on) {
-// /* ascii */
-// gtk_text_buffer_get_iter_at_line_index(buf, &i_start, start_line, ascii_fix(line_pos));
-// gtk_text_buffer_get_iter_at_line_index(buf, &i_stop, start_line, ascii_fix(line_pos)+1);
-// gtk_text_buffer_apply_tag(buf, revstyle_tag, &i_start, &i_stop);
-// }
-
-// if (!mask)
-// goto xend;
-
-// line_pos++;
-// }
-
-// start_line_pos = 0;
-// start_line++;
-// }
-// } else { /* mask starting from end (big-endian) */
-// while (start_line <= stop_line) {
-// int line_pos_start = (start_line == stop_line) ? start_line_pos : 0;
-// int line_pos = stop_line_pos-1;
-
-// while (line_pos >= line_pos_start) {
-// int lop = 8 / bits_per_one;
-// int mask_per_one = (1 << bits_per_one) - 1;
-// int ascii_on = 0;
-
-// while (lop--) {
-// if ((mask & mask_per_one)) {
-// /* bits/hex */
-// gtk_text_buffer_get_iter_at_line_index(buf, &i_start, stop_line, hex_fix(line_pos)+lop);
-// gtk_text_buffer_get_iter_at_line_index(buf, &i_stop, stop_line, hex_fix(line_pos)+lop+1);
-// gtk_text_buffer_apply_tag(buf, revstyle_tag, &i_start, &i_stop);
-
-// ascii_on = 1;
-// }
-// mask >>= bits_per_one;
-// }
-
-// /* at least one bit of ascii was one -> turn ascii on */
-// if (ascii_on) {
-// /* ascii */
-// gtk_text_buffer_get_iter_at_line_index(buf, &i_start, stop_line, ascii_fix(line_pos));
-// gtk_text_buffer_get_iter_at_line_index(buf, &i_stop, stop_line, ascii_fix(line_pos)+1);
-// gtk_text_buffer_apply_tag(buf, revstyle_tag, &i_start, &i_stop);
-// }
-
-// if (!mask)
-// goto xend;
-
-// line_pos--;
-// }
-
-// stop_line_pos = per_line;
-// stop_line--;
-// }
-// }
-//xend:
-
-#undef hex_fix
-#undef ascii_fix
+ if (state != StateNormal) {
+ setState(StateNormal);
+ /* state = StateNormal; */
+ }
+ append("");
}
-// XXX - Copied from main_proto_draw.c
-/* Which byte the offset is referring to. Associates
- * whitespace with the preceding digits. */
-static int
-byte_num(int offset, int start_point)
+void ByteViewText::setState(ByteViewText::highlight_state state)
{
- return (offset - start_point) / 3;
+ QPalette pal = wsApp->palette();
+
+ moveCursor(QTextCursor::End);
+ setCurrentFont(wsApp->monospaceFont());
+ setTextColor(pal.text().color());
+ setTextBackgroundColor(pal.base().color());
+
+ switch (state) {
+ case StateProtocol:
+ setTextBackgroundColor(pal.alternateBase().color());
+ break;
+ case StateField:
+ if (bold_highlight_) {
+ setCurrentFont(wsApp->monospaceFont(true));
+ } else {
+ setTextColor(pal.base().color());
+ setTextBackgroundColor(pal.text().color());
+ }
+ break;
+ default:
+ break;
+ }
}
-// XXX - Copied from main_proto_draw.c
-//static int
-//bit_num(int offset, int start_point)
-//{
-// return (offset - start_point) / 9;
-//}
+int ByteViewText::flushBytes(QString &str)
+{
+ if (str.length() < 1) return 0;
+
+ insertPlainText(str);
+ str.clear();
+ return str.length();
+}
-// XXX - Copied from main_proto_draw.c
-static int
-hex_view_get_byte(guint ndigits, int row, int column)
+void ByteViewText::scrollToByte(int byte)
{
- int byte;
- int digits_start_1;
- int digits_end_1;
- int digits_start_2;
- int digits_end_2;
- int text_start_1;
- int text_end_1;
- int text_start_2;
- int text_end_2;
-
- /*
- * The column of the first hex digit in the first half.
- * That starts after "ndigits" digits of offset and two
- * separating blanks.
- */
- digits_start_1 = ndigits + 2;
-
- /*
- * The column of the last hex digit in the first half.
- * There are BYTES_PER_LINE/2 bytes displayed in the first
- * half; there are 2 characters per byte, plus a separating
- * blank after all but the last byte's characters.
- */
- digits_end_1 = digits_start_1 + (BYTES_PER_LINE/2)*2 +
- (BYTES_PER_LINE/2 - 1);
-
- /*
- * The column of the first hex digit in the second half.
- * Add 2 for the 2 separating blanks between the halves.
- */
- digits_start_2 = digits_end_1 + 2;
-
- /*
- * The column of the last hex digit in the second half.
- * Add the same value we used to get "digits_end_1" from
- * "digits_start_1".
- */
- digits_end_2 = digits_start_2 + (BYTES_PER_LINE/2)*2 +
- (BYTES_PER_LINE/2 - 1);
-
- /*
- * The column of the first "text dump" character in the first half.
- * Add 3 for the 3 separating blanks between the hex and text dump.
- */
- text_start_1 = digits_end_2 + 3;
-
- /*
- * The column of the last "text dump" character in the first half.
- * There are BYTES_PER_LINE/2 bytes displayed in the first
- * half; there is 1 character per byte.
- *
- * Then subtract 1 to get the last column of the first half
- * rather than the first column after the first half.
- */
- text_end_1 = text_start_1 + BYTES_PER_LINE/2 - 1;
-
- /*
- * The column of the first "text dump" character in the second half.
- * Add back the 1 to get the first column after the first half,
- * and then add 1 for the separating blank between the halves.
- */
- text_start_2 = text_end_1 + 2;
-
- /*
- * The column of the last "text dump" character in second half.
- * Add the same value we used to get "text_end_1" from
- * "text_start_1".
- */
- text_end_2 = text_start_2 + BYTES_PER_LINE/2 - 1;
-
- /* Given the column and row, determine which byte offset
- * the user clicked on. */
- if (column >= digits_start_1 && column <= digits_end_1) {
- byte = byte_num(column, digits_start_1);
- if (byte == -1) {
- return byte;
- }
- }
- else if (column >= digits_start_2 && column <= digits_end_2) {
- byte = byte_num(column, digits_start_2);
- if (byte == -1) {
- return byte;
- }
- byte += 8;
- }
- else if (column >= text_start_1 && column <= text_end_1) {
- byte = column - text_start_1;
- }
- else if (column >= text_start_2 && column <= text_end_2) {
- byte = 8 + column - text_start_2;
- }
- else {
- /* The user didn't select a hex digit or
- * text-dump character. */
+ QTextCursor cursor(textCursor());
+
+ cursor.movePosition(QTextCursor::Start);
+ cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, byte / per_line_);
+ setTextCursor(cursor);
+}
+
+int ByteViewText::byteFromRowCol(int row, int col)
+{
+ /* hex_pos_byte array generated with hex_view_get_byte(0, 0, 0...70) */
+ static const int hex_pos_byte[70] = {
+ -1, -1,
+ 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
+ 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7,
+ -1,
+ 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11,
+ 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15,
+ -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ -1,
+ 8, 9, 10, 11, 12, 13, 14, 15
+ };
+
+ /* bits_pos_byte array generated with bit_view_get_byte(0, 0, 0...84) */
+ static const int bits_pos_byte[84] = {
+ -1, -1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7
+ };
+
+ int off_col = 1;
+ int off_row;
+
+ off_row = row * per_line_;
+
+ if (/* char_x < 0 || */ col < offset_width_)
return -1;
+ col -= offset_width_;
+
+ switch (format_) {
+ case BYTES_BITS:
+ g_return_val_if_fail(col >= 0 && col < (int) G_N_ELEMENTS(bits_pos_byte), -1);
+ off_col = bits_pos_byte[col];
+ break;
+
+ case BYTES_HEX:
+ g_return_val_if_fail(col >= 0 && col < (int) G_N_ELEMENTS(hex_pos_byte), -1);
+ off_col = hex_pos_byte[col];
+ break;
}
- /* Add the number of bytes from the previous rows. */
- byte += row * BYTES_PER_LINE;
+ if (col == -1)
+ return -1;
- return byte;
+ return off_row + off_col;
}
void ByteViewText::mousePressEvent (QMouseEvent * event) {
@@ -614,26 +369,27 @@ void ByteViewText::mousePressEvent (QMouseEvent * event) {
QTextCursor cursor(cursorForPosition(event->pos()));
field_info *fi;
- byte = hex_view_get_byte(m_useDigits, cursor.blockNumber(), cursor.columnNumber());
- fi = proto_find_field_from_offset(m_tree, byte, m_tvb);
- g_log(NULL, G_LOG_LEVEL_DEBUG, "byte %d fi %p", byte, fi);
-
- if (fi && m_protoTree) {
- // XXX - This should probably be a ProtoTree method.
- QTreeWidgetItemIterator iter(m_protoTree);
- while (*iter) {
- if (fi == (*iter)->data(0, Qt::UserRole).value<field_info *>()) {
- g_log(NULL, G_LOG_LEVEL_DEBUG, "found %p", fi);
- m_protoTree->setCurrentItem((*iter));
- }
+ byte = byteFromRowCol(cursor.blockNumber(), cursor.columnNumber());
+ if (byte >= 0) {
+ fi = proto_find_field_from_offset(proto_tree_, byte, tvb_);
+
+ if (fi && tree_widget_) {
+ // XXX - This should probably be a ProtoTree method.
+ QTreeWidgetItemIterator iter(tree_widget_);
+ while (*iter) {
+ if (fi == (*iter)->data(0, Qt::UserRole).value<field_info *>()) {
+ tree_widget_->setCurrentItem((*iter));
+ }
- iter++;
+ iter++;
+ }
}
}
}
QWidget::mousePressEvent (event);
}
+
/*
* Editor modelines
*