diff options
author | Gerald Combs <gerald@wireshark.org> | 2018-01-16 16:41:36 -0800 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2018-01-17 11:37:49 +0000 |
commit | d1254247b7db596cc3863652e2093f7d0e79d402 (patch) | |
tree | 4ae18cdbf7f065a86f31f06dba993b614766a709 | |
parent | 34381ed20c7e1005dec1e13ab90edd736238f2d7 (diff) |
Qt: ByteViewText hover fixes & updates.
Add back field highlighting during hover.
Instead of marking hovered bytes using an underline+overline, draw a
border rect.
Change-Id: I574dd074cfa021ac0dec3cdea6c5f9b0b4da6d0e
Reviewed-on: https://code.wireshark.org/review/25348
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r-- | ui/qt/byte_view_tab.cpp | 35 | ||||
-rw-r--r-- | ui/qt/byte_view_tab.h | 6 | ||||
-rw-r--r-- | ui/qt/widgets/byte_view_text.cpp | 61 | ||||
-rw-r--r-- | ui/qt/widgets/byte_view_text.h | 4 |
4 files changed, 77 insertions, 29 deletions
diff --git a/ui/qt/byte_view_tab.cpp b/ui/qt/byte_view_tab.cpp index 56b8d748cf..7d54c8433f 100644 --- a/ui/qt/byte_view_tab.cpp +++ b/ui/qt/byte_view_tab.cpp @@ -43,8 +43,7 @@ ByteViewTab::ByteViewTab(QWidget *parent) : QTabWidget(parent), - cap_file_(0), - curSelected(0) + cap_file_(0) { setAccessibleName(tr("Packet bytes")); setTabPosition(QTabWidget::South); @@ -130,7 +129,9 @@ void ByteViewTab::byteViewTextHovered(int idx) field_info * fi = proto_find_field_from_offset(tree, idx, tvb); if ( fi ) { - emit fieldHighlight(new FieldInformation(fi, this)); + FieldInformation finfo(fi, this); + highlightedFieldChanged(&finfo); + emit fieldHighlight(&finfo); return; } } @@ -151,7 +152,8 @@ void ByteViewTab::byteViewTextMarked(int idx) field_info * fi = proto_find_field_from_offset(tree, idx, tvb); if ( fi ) { - emit fieldSelected(new FieldInformation(fi, this)); + FieldInformation finfo(fi, this); + emit fieldSelected(&finfo); return; } } @@ -251,7 +253,6 @@ void ByteViewTab::selectedFrameChanged(int frameNum) void ByteViewTab::selectedFieldChanged(FieldInformation *selected) { - ByteViewText * byte_view_text = 0; if (selected) { @@ -286,8 +287,30 @@ void ByteViewTab::selectedFieldChanged(FieldInformation *selected) byte_view_text->markAppendix(selected->appendix().start, selected->appendix().length); } } +} + +void ByteViewTab::highlightedFieldChanged(FieldInformation *highlighted) +{ + ByteViewText * byte_view_text = qobject_cast<ByteViewText *>(currentWidget()); + if (!highlighted || !byte_view_text) { + return; + } + + int f_start = -1, f_length = -1; + + if (cap_file_->search_in_progress && (cap_file_->hex || (cap_file_->string && cap_file_->packet_data))) { + // In the hex view, only highlight the target bytes or string. The entire + // field can then be displayed by clicking on any of the bytes in the field. + f_start = cap_file_->search_pos - cap_file_->search_len + 1; + f_length = (int) cap_file_->search_len; + } else { + f_start = highlighted->position().start; + f_length = highlighted->position().length; + } - curSelected = selected; + byte_view_text->markField(f_start, f_length, false); + byte_view_text->markProtocol(-1, -1); + byte_view_text->markAppendix(-1, -1); } void ByteViewTab::setCaptureFile(capture_file *cf) diff --git a/ui/qt/byte_view_tab.h b/ui/qt/byte_view_tab.h index a0e8903ace..4187a3bc1d 100644 --- a/ui/qt/byte_view_tab.h +++ b/ui/qt/byte_view_tab.h @@ -51,6 +51,8 @@ public slots: void selectedFrameChanged(int); /* Selects or marks a field */ void selectedFieldChanged(FieldInformation *); + /* Highlights field */ + void highlightedFieldChanged(FieldInformation *); signals: void fieldSelected(FieldInformation *); @@ -59,12 +61,8 @@ signals: private: capture_file *cap_file_; - FieldInformation * curSelected; - void setTabsVisible(); - ByteViewText * findByteViewTextForTvb(tvbuff_t * search, int * idx = 0); - void addTab(const char *name = "", tvbuff_t *tvb = NULL); protected: diff --git a/ui/qt/widgets/byte_view_text.cpp b/ui/qt/widgets/byte_view_text.cpp index d38dd62bc8..04ac6ec7f9 100644 --- a/ui/qt/widgets/byte_view_text.cpp +++ b/ui/qt/widgets/byte_view_text.cpp @@ -143,11 +143,13 @@ void ByteViewText::markProtocol(int start, int length) viewport()->update(); } -void ByteViewText::markField(int start, int length) +void ByteViewText::markField(int start, int length, bool scroll_to) { field_start_ = start; field_len_ = length; - scrollToByte(start); + if (scroll_to) { + scrollToByte(start); + } viewport()->update(); } @@ -179,7 +181,7 @@ void ByteViewText::paintEvent(QPaintEvent *) { QPainter painter(viewport()); painter.translate(-horizontalScrollBar()->value() * font_width_, 0); - painter.setFont(font()); + painter.setFont(mono_font_); // Pixel offset of this row int row_y = 0; @@ -214,6 +216,31 @@ void ByteViewText::paintEvent(QPaintEvent *) painter.restore(); + // We can't do this in drawLine since the next line might draw over our rect. + if (!hover_outlines_.isEmpty()) { + qreal pen_width = 1.0; + #if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) + pen_width = 1.0 / devicePixelRatio(); + #endif + QPen ho_pen; + QColor ho_color = palette().text().color(); + ho_color.setAlphaF(0.5); + ho_pen.setColor(ho_color); + ho_pen.setWidthF(pen_width); + + painter.save(); + painter.setPen(ho_pen); + painter.setBrush(Qt::NoBrush); + foreach (QRect ho_rect, hover_outlines_) { + // These look good on retina and non-retina displays on macOS. + // We might want to use fontMetrics numbers instead. + ho_rect.adjust(-1, 0, -1, -1); + painter.drawRect(ho_rect); + } + painter.restore(); + } + hover_outlines_.clear(); + QStyleOptionFocusRect option; option.initFrom(this); style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, &painter, this); @@ -237,6 +264,7 @@ void ByteViewText::mousePressEvent (QMouseEvent *event) { mouseMoveEvent(event); } emit byteSelected(marked_byte_offset_); + viewport()->update(); } void ByteViewText::mouseMoveEvent(QMouseEvent *event) @@ -247,13 +275,11 @@ void ByteViewText::mouseMoveEvent(QMouseEvent *event) hovered_byte_offset_ = byteOffsetAtPixel(event->pos()); emit byteHovered(hovered_byte_offset_); - viewport()->update(); } void ByteViewText::leaveEvent(QEvent *event) { - QString empty; emit byteHovered(-1); viewport()->update(); @@ -331,6 +357,13 @@ void ByteViewText::drawLine(QPainter *painter, const int offset, const int row_y if (build_x_pos) { x_pos_to_column_ += QVector<int>().fill(tvb_pos - offset, fontMetrics().width(line) - x_pos_to_column_.size() + slop); } + if (tvb_pos == hovered_byte_offset_) { + int ho_len = recent.gui_bytes_view == BYTES_HEX ? 2 : 8; + QRect ho_rect = painter->boundingRect(QRect(), Qt::AlignHCenter|Qt::AlignVCenter, line.right(ho_len)); + ho_rect.moveRight(fontMetrics().width(line)); + ho_rect.moveTop(row_y); + hover_outlines_.append(ho_rect); + } } line += QString(ascii_start - line.length(), ' '); if (build_x_pos) { @@ -345,9 +378,6 @@ void ByteViewText::drawLine(QPainter *painter, const int offset, const int row_y if (marked_byte_offset_ >= offset && marked_byte_offset_ <= max_tvb_pos) { addHexFormatRange(fmt_list, marked_byte_offset_, 1, offset, max_tvb_pos, ModeMarked); } - if (hovered_byte_offset_ >= offset && hovered_byte_offset_ <= max_tvb_pos) { - addHexFormatRange(fmt_list, hovered_byte_offset_, 1, offset, max_tvb_pos, ModeHover); - } } // ASCII @@ -391,6 +421,12 @@ void ByteViewText::drawLine(QPainter *painter, const int offset, const int row_y if (build_x_pos) { x_pos_to_column_ += QVector<int>().fill(tvb_pos - offset, fontMetrics().width(line) - x_pos_to_column_.size()); } + if (tvb_pos == hovered_byte_offset_) { + QRect ho_rect = painter->boundingRect(QRect(), 0, line.right(1)); + ho_rect.moveRight(fontMetrics().width(line)); + ho_rect.moveTop(row_y); + hover_outlines_.append(ho_rect); + } } if (in_non_printable) { addAsciiFormatRange(fmt_list, np_start, np_len, offset, max_tvb_pos, ModeNonPrintable); @@ -403,9 +439,6 @@ void ByteViewText::drawLine(QPainter *painter, const int offset, const int row_y if (marked_byte_offset_ >= offset && marked_byte_offset_ <= max_tvb_pos) { addAsciiFormatRange(fmt_list, marked_byte_offset_, 1, offset, max_tvb_pos, ModeMarked); } - if (hovered_byte_offset_ >= offset && hovered_byte_offset_ <= max_tvb_pos) { - addAsciiFormatRange(fmt_list, hovered_byte_offset_, 1, offset, max_tvb_pos, ModeHover); - } } // XXX Fields won't be highlighted if neither hex nor ascii are enabled. @@ -447,12 +480,6 @@ bool ByteViewText::addFormatRange(QList<QTextLayout::FormatRange> &fmt_list, int case ModeOffsetField: format_range.format.setForeground(offset_field_fg_); break; - case ModeHover: - // QTextCharFormat doesn't appear to let us draw a complete border. - // This is the next best thing. - format_range.format.setFontUnderline(true); - format_range.format.setFontOverline(true); - break; case ModeMarked: // XXX Should we get rid of byteViewMarkColor and just draw an // overline + underline instead? diff --git a/ui/qt/widgets/byte_view_text.h b/ui/qt/widgets/byte_view_text.h index 46eee40fe9..1096b166f0 100644 --- a/ui/qt/widgets/byte_view_text.h +++ b/ui/qt/widgets/byte_view_text.h @@ -50,7 +50,7 @@ public slots: void setMonospaceFont(const QFont &mono_font); void markProtocol(int start, int length); - void markField(int start, int length); + void markField(int start, int length, bool scroll_to = true); void markAppendix(int start, int length); protected: @@ -69,7 +69,6 @@ private: ModeProtocol, ModeOffsetNormal, ModeOffsetField, - ModeHover, ModeMarked, ModeNonPrintable } HighlightMode; @@ -121,6 +120,7 @@ private: int row_width_; // Number of bytes per line qreal font_width_; // Single character width and text margin. NOTE: Use fontMetrics::width for multiple characters. int line_height_; // Font line spacing + QList<QRect> hover_outlines_; // Hovered byte outlines. // Data selection QVector<int> x_pos_to_column_; |