forked from osmocom/wireshark
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>
This commit is contained in:
parent
34381ed20c
commit
d1254247b7
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curSelected = selected;
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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_;
|
||||
|
|
Loading…
Reference in New Issue