aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ui/qt/CMakeLists.txt2
-rw-r--r--ui/qt/Makefile.common3
-rw-r--r--ui/qt/Wireshark.pro2
-rw-r--r--ui/qt/color_utils.cpp2
-rw-r--r--ui/qt/color_utils.h2
-rw-r--r--ui/qt/overlay_scroll_bar.cpp158
-rw-r--r--ui/qt/overlay_scroll_bar.h62
-rw-r--r--ui/qt/packet_list.cpp232
-rw-r--r--ui/qt/packet_list.h15
-rw-r--r--ui/qt/packet_list_model.cpp18
-rw-r--r--ui/qt/packet_list_model.h1
-rw-r--r--ui/qt/packet_list_record.h1
12 files changed, 483 insertions, 15 deletions
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index 35b2d2e2f4..43bfd7bbd8 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -81,6 +81,7 @@ set(WIRESHARK_QT_HEADERS
main_window_preferences_frame.h
manage_interfaces_dialog.h
module_preferences_scroll_area.h
+ overlay_scroll_bar.h
packet_comment_dialog.h
packet_dialog.h
packet_format_group_box.h
@@ -206,6 +207,7 @@ set(WIRESHARK_QT_SRC
main_window_slots.cpp
manage_interfaces_dialog.cpp
module_preferences_scroll_area.cpp
+ overlay_scroll_bar.cpp
packet_comment_dialog.cpp
packet_dialog.cpp
packet_format_group_box.cpp
diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common
index c1a7479e54..5264100aec 100644
--- a/ui/qt/Makefile.common
+++ b/ui/qt/Makefile.common
@@ -65,6 +65,7 @@ NODIST_GENERATED_HEADER_FILES = \
ui_main_window_preferences_frame.h \
ui_manage_interfaces_dialog.h \
ui_module_preferences_scroll_area.h \
+ ui_overlay_scroll_bar.h \
ui_packet_comment_dialog.h \
ui_packet_dialog.h \
ui_packet_format_group_box.h \
@@ -190,6 +191,7 @@ MOC_HDRS = \
main_window_preferences_frame.h \
manage_interfaces_dialog.h \
module_preferences_scroll_area.h \
+ overlay_scroll_bar.h \
packet_comment_dialog.h \
packet_dialog.h \
packet_format_group_box.h \
@@ -421,6 +423,7 @@ WIRESHARK_QT_SRC = \
main_window_slots.cpp \
manage_interfaces_dialog.cpp \
module_preferences_scroll_area.cpp \
+ overlay_scroll_bar.cpp \
packet_comment_dialog.cpp \
packet_dialog.cpp \
packet_format_group_box.cpp \
diff --git a/ui/qt/Wireshark.pro b/ui/qt/Wireshark.pro
index 3aadf34e63..d2fb545d02 100644
--- a/ui/qt/Wireshark.pro
+++ b/ui/qt/Wireshark.pro
@@ -314,6 +314,7 @@ HEADERS += $$HEADERS_WS_C \
main_window_preferences_frame.h \
manage_interfaces_dialog.h \
module_preferences_scroll_area.h \
+ overlay_scroll_bar.h \
packet_comment_dialog.h \
packet_dialog.h \
packet_format_group_box.h \
@@ -692,6 +693,7 @@ SOURCES += \
main_window_slots.cpp \
manage_interfaces_dialog.cpp \
module_preferences_scroll_area.cpp \
+ overlay_scroll_bar.cpp \
packet_comment_dialog.cpp \
packet_dialog.cpp \
packet_format_group_box.cpp \
diff --git a/ui/qt/color_utils.cpp b/ui/qt/color_utils.cpp
index f63b2a0378..dbb93530f5 100644
--- a/ui/qt/color_utils.cpp
+++ b/ui/qt/color_utils.cpp
@@ -76,7 +76,7 @@ ColorUtils::ColorUtils(QObject *parent) :
{
}
-QColor ColorUtils::fromColorT (color_t *color) {
+QColor ColorUtils::fromColorT (const color_t *color) {
if (!color) return QColor();
return QColor(color->red >> 8, color->green >> 8, color->blue >> 8);
}
diff --git a/ui/qt/color_utils.h b/ui/qt/color_utils.h
index a263f76d23..30f8b170fd 100644
--- a/ui/qt/color_utils.h
+++ b/ui/qt/color_utils.h
@@ -38,7 +38,7 @@ class ColorUtils : public QObject
public:
explicit ColorUtils(QObject *parent = 0);
- static QColor fromColorT(color_t *color);
+ static QColor fromColorT(const 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);
diff --git a/ui/qt/overlay_scroll_bar.cpp b/ui/qt/overlay_scroll_bar.cpp
new file mode 100644
index 0000000000..6990bd57cb
--- /dev/null
+++ b/ui/qt/overlay_scroll_bar.cpp
@@ -0,0 +1,158 @@
+/* overlay_scroll_bar.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 "overlay_scroll_bar.h"
+
+#include <QPainter>
+#include <QResizeEvent>
+#include <QStyle>
+#include <QStyleOptionSlider>
+
+// To do:
+// - The slider hole doesn't match up with the slider on OS X + Qt 5.3.2.
+
+OverlayScrollBar::OverlayScrollBar(Qt::Orientation orientation, QWidget *parent) :
+ QScrollBar(orientation, parent = 0),
+ near_overlay_(QImage()),
+ far_overlay_(QImage())
+{}
+
+QSize OverlayScrollBar::sizeHint() const
+{
+ return QSize(QScrollBar::sizeHint().width() + (far_overlay_.width() * 2), QScrollBar::sizeHint().height());
+}
+
+void OverlayScrollBar::setNearOverlayImage(QImage &overlay_image)
+{
+ near_overlay_ = overlay_image;
+ update();
+}
+
+void OverlayScrollBar::setFarOverlayImage(QImage &overlay_image)
+{
+ int old_width = far_overlay_.width();
+ far_overlay_ = overlay_image;
+ if (old_width != far_overlay_.width()) {
+ updateGeometry();
+ }
+ update();
+}
+
+QRect OverlayScrollBar::grooveRect()
+{
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+
+ return style()->subControlRect(QStyle::CC_ScrollBar, &opt, QStyle::SC_ScrollBarGroove, this);
+}
+
+void OverlayScrollBar::paintEvent(QPaintEvent *event)
+{
+ QScrollBar::paintEvent(event);
+ if (!near_overlay_.isNull()) {
+ QRect groove_rect = grooveRect();
+ QSize gr_size = groove_rect.size();
+#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
+ gr_size *= devicePixelRatio();
+#endif
+ QImage groove_overlay(gr_size, QImage::Format_ARGB32_Premultiplied);
+ groove_overlay.fill(Qt::transparent);
+
+ // Draw the image supplied by the packet list and apply a mask.
+ QPainter go_painter(&groove_overlay);
+ go_painter.setPen(Qt::NoPen);
+
+ int fo_width = far_overlay_.width();
+ QRect near_dest(fo_width, 0, gr_size.width() - (fo_width * 2), gr_size.height());
+ go_painter.drawImage(near_dest, near_overlay_.scaled(near_dest.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ if (fo_width > 0) {
+ QRect far_dest(0, 0, fo_width, gr_size.height());
+ go_painter.drawImage(far_dest, far_overlay_);
+ far_dest.moveLeft(gr_size.width() - fo_width);
+ go_painter.drawImage(far_dest, far_overlay_.mirrored(true, false));
+ }
+ QRect near_outline(near_dest);
+ near_outline.adjust(0, 0, -1, -1);
+ go_painter.save();
+ QColor no_fg(palette().text().color());
+ no_fg.setAlphaF(0.25);
+ go_painter.setPen(no_fg);
+ go_painter.drawRect(near_outline);
+ go_painter.restore();
+
+#if 0
+ // Fade in from the left and right.
+ go_painter.save();
+ go_painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ QLinearGradient fade(0, 0, groove_overlay.width(), 0);
+ fade.setColorAt(0, Qt::transparent);
+ fade.setColorAt(0.2, Qt::white);
+ fade.setColorAt(0.8, Qt::white);
+ fade.setColorAt(1, Qt::transparent);
+
+ go_painter.setBrush(fade);
+ go_painter.drawRect(groove_overlay.rect());
+ go_painter.restore();
+#endif
+
+ // Punch a hole for the slider.
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+
+ QRect slider_rect = style()->subControlRect(QStyle::CC_ScrollBar, &opt, QStyle::SC_ScrollBarSlider, this);
+#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
+ slider_rect.setHeight(slider_rect.height() * devicePixelRatio());
+ slider_rect.setWidth(slider_rect.width() * devicePixelRatio());
+ slider_rect.moveTop((slider_rect.top() - groove_rect.top()) * devicePixelRatio());
+#else
+ slider_rect.moveTop(slider_rect.top() - groove_rect.top());
+#endif
+ slider_rect.adjust(fo_width + 1, 1, -1 - fo_width, -1);
+
+ go_painter.save();
+ go_painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ QColor slider_hole(Qt::white);
+ slider_hole.setAlphaF(0.1);
+ go_painter.setBrush(slider_hole);
+ go_painter.drawRect(slider_rect);
+ go_painter.restore();
+
+ // Draw over the groove.
+ QPainter painter(this);
+#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
+ groove_overlay.setDevicePixelRatio(devicePixelRatio());
+#endif
+ painter.drawImage(groove_rect.topLeft(), groove_overlay);
+ }
+}
+
+/*
+ * 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/overlay_scroll_bar.h b/ui/qt/overlay_scroll_bar.h
new file mode 100644
index 0000000000..76e7612292
--- /dev/null
+++ b/ui/qt/overlay_scroll_bar.h
@@ -0,0 +1,62 @@
+/* overlay_scroll_bar.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 __OVERLAY_SCROLL_BAR_H__
+#define __OVERLAY_SCROLL_BAR_H__
+
+#include <QScrollBar>
+
+class OverlayScrollBar : public QScrollBar
+{
+ Q_OBJECT
+
+public:
+ OverlayScrollBar(Qt::Orientation orientation, QWidget * parent = 0);
+
+ virtual QSize sizeHint() const;
+
+ // Images are assumed to be 1 pixel wide and grooveRect.height() high.
+ void setNearOverlayImage(QImage &overlay_image);
+ void setFarOverlayImage(QImage &overlay_image);
+ QRect grooveRect();
+
+protected:
+ virtual void paintEvent(QPaintEvent * event);
+
+private:
+ QImage near_overlay_;
+ QImage far_overlay_;
+};
+
+#endif // __OVERLAY_SCROLL_BAR_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/packet_list.cpp b/ui/qt/packet_list.cpp
index 4f295971d0..8aee922ace 100644
--- a/ui/qt/packet_list.cpp
+++ b/ui/qt/packet_list.cpp
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "packet_list.h"
+
#include "config.h"
#include <glib.h>
@@ -30,16 +32,10 @@
#include <epan/column-info.h>
#include <epan/column.h>
+#include <epan/ipproto.h>
#include <epan/packet.h>
#include <epan/prefs.h>
-#include "packet_list.h"
-#include "proto_tree.h"
-#include "wireshark_application.h"
-#include "epan/ipproto.h"
-
-#include "qt_ui_utils.h"
-
#include "ui/main_statusbar.h"
#include "ui/packet_list_utils.h"
#include "ui/preference_utils.h"
@@ -47,17 +43,30 @@
#include "ui/recent_utils.h"
#include "ui/ui_util.h"
#include "ui/utf8_entities.h"
+#include "ui/util.h"
#include "wsutil/str_util.h"
+#include "color.h"
+#include "color_filters.h"
#include "frame_tvbuff.h"
+#include "color_utils.h"
+#include "overlay_scroll_bar.h"
+#include "proto_tree.h"
+#include "qt_ui_utils.h"
+#include "wireshark_application.h"
+
#include <QAction>
#include <QActionGroup>
#include <QContextMenuEvent>
+#include <QtCore/qmath.h>
+#include <QElapsedTimer>
#include <QFontMetrics>
#include <QHeaderView>
#include <QMessageBox>
+#include <QPainter>
+#include <QScreen>
#include <QScrollBar>
#include <QTabWidget>
#include <QTextEdit>
@@ -74,6 +83,7 @@ static PacketList *gbl_cur_packet_list = NULL;
const int max_comments_to_fetch_ = 20000000; // Arbitrary
const int tail_update_interval_ = 100; // Milliseconds.
+const int overlay_update_interval_ = 100; // 250; // Milliseconds.
guint
packet_list_append(column_info *, frame_data *fdata)
@@ -224,6 +234,8 @@ PacketList::PacketList(QWidget *parent) :
cap_file_(NULL),
decode_as_(NULL),
ctx_column_(-1),
+ create_near_overlay_(true),
+ create_far_overlay_(true),
capture_in_progress_(false),
tail_timer_id_(0),
rows_inserted_(false)
@@ -237,6 +249,10 @@ PacketList::PacketList(QWidget *parent) :
setAccessibleName("Packet list");
setItemDelegateForColumn(0, &related_packet_delegate_);
+ overlay_sb_ = new OverlayScrollBar(Qt::Vertical, this);
+ setVerticalScrollBar(overlay_sb_);
+ overlay_timer_id_ = startTimer(overlay_update_interval_);
+
packet_list_model_ = new PacketListModel(this, cap_file_);
setModel(packet_list_model_);
sortByColumn(-1, Qt::AscendingOrder);
@@ -578,15 +594,27 @@ void PacketList::timerEvent(QTimerEvent *event)
{
QTreeView::timerEvent(event);
- if (rows_inserted_
- && event->timerId() == tail_timer_id_
+ if (event->timerId() == tail_timer_id_
+ && rows_inserted_
&& capture_in_progress_
&& tail_at_end_) {
scrollToBottom();
rows_inserted_ = false;
+ } else if (event->timerId() == overlay_timer_id_ && !capture_in_progress_) {
+ if (create_near_overlay_) drawNearOverlay();
+ if (create_far_overlay_) drawFarOverlay();
}
}
+void PacketList::paintEvent(QPaintEvent *event)
+{
+ // XXX This is overkill, but there are quite a few events that
+ // require a new overlay, e.g. page up/down, scrolling, column
+ // resizing, etc.
+ create_near_overlay_ = true;
+ QTreeView::paintEvent(event);
+}
+
void PacketList::setColumnVisibility()
{
for (int i = 0; i < prefs.num_cols; i++) {
@@ -671,6 +699,7 @@ void PacketList::columnsChanged()
build_column_format_array(&cap_file_->cinfo, prefs.num_cols, FALSE);
packet_list_model_->recreateVisibleRows(); // Calls PacketListRecord::resetColumns
setColumnVisibility();
+ create_far_overlay_ = true;
redrawVisiblePackets();
}
@@ -761,6 +790,12 @@ void PacketList::clear() {
proto_tree_->clear();
byte_view_tab_->clear();
+ QImage overlay;
+ overlay_sb_->setNearOverlayImage(overlay);
+ overlay_sb_->setFarOverlayImage(overlay);
+ create_near_overlay_ = true;
+ create_far_overlay_ = true;
+
/* XXX is this correct in all cases?
* Reset the sort column, use packetlist as model in case the list is frozen.
*/
@@ -859,6 +894,12 @@ QString &PacketList::getFilterFromRowAndColumn()
return filter;
}
+void PacketList::resetColorized()
+{
+ packet_list_model_->resetColorized();
+ update();
+}
+
QString PacketList::packetComment()
{
int row = currentIndex().row();
@@ -936,6 +977,7 @@ void PacketList::setCaptureFile(capture_file *cf)
}
cap_file_ = cf;
packet_list_model_->setCaptureFile(cf);
+ create_near_overlay_ = true;
}
void PacketList::setMonospaceFont(const QFont &mono_font)
@@ -1004,6 +1046,7 @@ void PacketList::markFrame()
if (!cap_file_ || !packet_list_model_) return;
packet_list_model_->toggleFrameMark(currentIndex());
+ create_far_overlay_ = true;
packets_bar_update();
}
@@ -1012,6 +1055,7 @@ void PacketList::markAllDisplayedFrames(bool set)
if (!cap_file_ || !packet_list_model_) return;
packet_list_model_->setDisplayedFrameMark(set);
+ create_far_overlay_ = true;
packets_bar_update();
}
@@ -1020,6 +1064,7 @@ void PacketList::ignoreFrame()
if (!cap_file_ || !packet_list_model_) return;
packet_list_model_->toggleFrameIgnore(currentIndex());
+ create_far_overlay_ = true;
int sb_val = verticalScrollBar()->value(); // Surely there's a better way to keep our position?
setUpdatesEnabled(false);
emit packetDissectionChanged();
@@ -1032,6 +1077,7 @@ void PacketList::ignoreAllDisplayedFrames(bool set)
if (!cap_file_ || !packet_list_model_) return;
packet_list_model_->setDisplayedFrameIgnore(set);
+ create_far_overlay_ = true;
emit packetDissectionChanged();
}
@@ -1039,12 +1085,14 @@ void PacketList::setTimeReference()
{
if (!cap_file_ || !packet_list_model_) return;
packet_list_model_->toggleFrameRefTime(currentIndex());
+ create_far_overlay_ = true;
}
void PacketList::unsetAllTimeReferences()
{
if (!cap_file_ || !packet_list_model_) return;
packet_list_model_->unsetAllFrameRefTime();
+ create_far_overlay_ = true;
}
void PacketList::showHeaderMenu(QPoint pos)
@@ -1223,6 +1271,172 @@ void PacketList::vScrollBarActionTriggered(int)
}
}
+// Goal: Overlay the packet list scroll bar with the colors of all of the
+// packets.
+// Try 1: Average packet colors in each scroll bar raster line. This has
+// two problems: It's easy to wash out colors and we dissect every packet.
+// Try 2: Color across a 5000 or 10000 packet window. We still end up washing
+// out colors.
+// Try 3: One packet per vertical scroll bar pixel. This seems to work best
+// but has the smallest window.
+// Try 4: Use a multiple of the scroll bar heigh and scale the image down
+// using Qt::SmoothTransformation. This gives us more packets per raster
+// line.
+
+// Odd (prime?) numbers resulted in fewer scaling artifacts. A multiplier
+// of 9 washed out colors a little too much.
+const int height_multiplier_ = 7;
+void PacketList::drawNearOverlay()
+{
+ if (!cap_file_ || cap_file_->state != FILE_READ_DONE) return;
+
+ if (create_near_overlay_) {
+ create_near_overlay_ = false;
+ }
+
+ qreal dp_ratio = 1.0;
+#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
+ dp_ratio = overlay_sb_->devicePixelRatio();
+#endif
+ int o_height = overlay_sb_->height() * dp_ratio * height_multiplier_;
+ int o_rows = qMin(packet_list_model_->rowCount(), o_height);
+
+ if (recent.packet_list_colorize && o_rows > 0) {
+ QImage overlay(1, o_height, QImage::Format_ARGB32_Premultiplied);
+
+ QPainter painter(&overlay);
+#if 0
+ QElapsedTimer timer;
+ timer.start();
+#endif
+
+ overlay.fill(Qt::transparent);
+
+ int cur_line = 0;
+ int start = 0;
+
+ if (packet_list_model_->rowCount() > o_height) {
+ start += ((double) overlay_sb_->value() / overlay_sb_->maximum()) * (packet_list_model_->rowCount() - o_rows);
+ }
+ int end = start + o_rows;
+ for (int row = start; row < end; row++) {
+ packet_list_model_->ensureRowColorized(row);
+
+#if 0
+ // Try to remain responsive for large captures.
+ if (timer.elapsed() > update_time_) {
+ wsApp->processEvents();
+ if (!cap_file_ || cap_file_->state != FILE_READ_DONE) {
+ create_overlay_ = true;
+ return;
+ }
+ timer.restart();
+ }
+#endif
+
+ frame_data *fdata = packet_list_model_->getRowFdata(row);
+ const color_t *bgcolor = NULL;
+ if (fdata->color_filter) {
+ const color_filter_t *color_filter = (const color_filter_t *) fdata->color_filter;
+ bgcolor = &color_filter->bg_color;
+ }
+
+ int next_line = (row - start) * o_height / o_rows;
+ if (bgcolor) {
+ QColor color(ColorUtils::fromColorT(bgcolor));
+
+ painter.setPen(color);
+ painter.drawLine(0, cur_line, 0, next_line);
+ }
+ cur_line = next_line;
+ }
+
+ overlay_sb_->setNearOverlayImage(overlay);
+ } else {
+ QImage overlay;
+ overlay_sb_->setNearOverlayImage(overlay);
+ }
+}
+
+void PacketList::drawFarOverlay()
+{
+ if (!cap_file_ || cap_file_->state != FILE_READ_DONE) return;
+
+ if (create_far_overlay_) {
+ create_far_overlay_ = false;
+ }
+
+ qreal dp_ratio = 1.0;
+#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
+ dp_ratio = overlay_sb_->devicePixelRatio();
+#endif
+ int o_width = 2 * dp_ratio;
+ int o_height = overlay_sb_->height() * dp_ratio;
+ int pl_rows = packet_list_model_->rowCount();
+
+ if (recent.packet_list_colorize && pl_rows > 0) {
+ // Create a tall image here. OverlayScrollBar will scale it to fit.
+ QImage overlay(o_width, o_height, QImage::Format_ARGB32_Premultiplied);
+
+ QPainter painter(&overlay);
+ painter.setRenderHint(QPainter::Antialiasing);
+#if 0
+ QElapsedTimer timer;
+ timer.start();
+#endif
+
+ // The default "marked" background is black and the default "ignored"
+ // background is white. Instead of trying to figure out if our
+ // available colors will show up, just use the palette's background
+ // here and foreground below.
+ overlay.fill(palette().base().color());
+ QColor arrow_fg = palette().text().color();
+ arrow_fg.setAlphaF(0.3);
+ painter.setPen(arrow_fg);
+ painter.setBrush(arrow_fg);
+
+ bool have_far = false;
+ for (int row = 0; row < pl_rows; row++) {
+#if 0
+ // Try to remain responsive for large captures.
+ if (timer.elapsed() > update_time_) {
+ wsApp->processEvents();
+ if (!cap_file_ || cap_file_->state != FILE_READ_DONE) {
+ create_overlay_ = true;
+ return;
+ }
+ timer.restart();
+ }
+#endif
+
+ frame_data *fdata = packet_list_model_->getRowFdata(row);
+ bool marked = false;
+ if (fdata->flags.marked || fdata->flags.ref_time || fdata->flags.ignored) {
+ marked = true;
+ }
+
+ if (marked) {
+ int new_line = (row) * o_height / pl_rows;
+
+ QPointF points[3] = {
+ QPointF(o_width, new_line),
+ QPointF(0, new_line - (o_width * 0.7)),
+ QPointF(0, new_line + (o_width * 0.7))
+ };
+ painter.drawPolygon(points, 3);
+ have_far = true;
+ }
+ }
+
+ if (have_far) {
+ overlay_sb_->setFarOverlayImage(overlay);
+ return;
+ }
+ QImage null_overlay;
+ overlay_sb_->setFarOverlayImage(null_overlay);
+ }
+}
+
void PacketList::rowsInserted(const QModelIndex &parent, int start, int end)
{
QTreeView::rowsInserted(parent, start, end);
diff --git a/ui/qt/packet_list.h b/ui/qt/packet_list.h
index d1059aabc1..ae7b751281 100644
--- a/ui/qt/packet_list.h
+++ b/ui/qt/packet_list.h
@@ -33,6 +33,8 @@
#include <QTime>
#include <QTreeView>
+class OverlayScrollBar;
+
class QAction;
class QTimerEvent;
@@ -62,6 +64,7 @@ public:
void writeRecent(FILE *rf);
bool contextMenuActive();
QString &getFilterFromRowAndColumn();
+ void resetColorized();
QString packetComment();
void setPacketComment(QString new_comment);
QString allPacketComments();
@@ -70,10 +73,11 @@ public:
void setCaptureInProgress(bool in_progress = false) { capture_in_progress_ = in_progress; tail_at_end_ = in_progress; }
protected:
- void showEvent (QShowEvent *);
- void selectionChanged (const QItemSelection & selected, const QItemSelection & deselected);
+ void showEvent(QShowEvent *);
+ void selectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
void contextMenuEvent(QContextMenuEvent *event);
void timerEvent(QTimerEvent *event);
+ void paintEvent(QPaintEvent *event);
protected slots:
void rowsInserted(const QModelIndex &parent, int start, int end);
@@ -89,6 +93,11 @@ private:
QAction *decode_as_;
int ctx_column_;
QByteArray column_state_;
+ OverlayScrollBar *overlay_sb_;
+ int overlay_timer_id_;
+ bool create_near_overlay_;
+ bool create_far_overlay_;
+ QVector<QRgb> overlay_colors_;
RelatedPacketDelegate related_packet_delegate_;
QMenu header_ctx_menu_;
@@ -142,6 +151,8 @@ private slots:
void sectionResized(int col, int, int new_width);
void sectionMoved(int, int, int);
void vScrollBarActionTriggered(int);
+ void drawFarOverlay();
+ void drawNearOverlay();
};
#endif // PACKET_LIST_H
diff --git a/ui/qt/packet_list_model.cpp b/ui/qt/packet_list_model.cpp
index 3de636d947..5fb77eecbc 100644
--- a/ui/qt/packet_list_model.cpp
+++ b/ui/qt/packet_list_model.cpp
@@ -34,7 +34,9 @@
#include "color_filters.h"
#include "frame_tvbuff.h"
+#include "color_utils.h"
#include "wireshark_application.h"
+
#include <QColor>
#include <QFontMetrics>
#include <QModelIndex>
@@ -398,7 +400,7 @@ QVariant PacketListModel::data(const QModelIndex &d_index, int role) const
} else {
return QVariant();
}
- return QColor(color->red >> 8, color->green >> 8, color->blue >> 8);
+ return ColorUtils::fromColorT(color);
case Qt::ForegroundRole:
if (fdata->flags.ignored) {
color = &prefs.gui_ignored_fg;
@@ -410,7 +412,7 @@ QVariant PacketListModel::data(const QModelIndex &d_index, int role) const
} else {
return QVariant();
}
- return QColor(color->red >> 8, color->green >> 8, color->blue >> 8);
+ return ColorUtils::fromColorT(color);
case Qt::DisplayRole:
{
int column = d_index.column();
@@ -485,6 +487,18 @@ frame_data *PacketListModel::getRowFdata(int row) {
return record->frameData();
}
+void PacketListModel::ensureRowColorized(int row)
+{
+ if (row < 0 || row >= visible_rows_.count())
+ return;
+ PacketListRecord *record = visible_rows_[row];
+ if (!record)
+ return;
+ if (!record->colorized()) {
+ record->columnString(cap_file_, 1);
+ }
+}
+
int PacketListModel::visibleIndexOf(frame_data *fdata) const
{
int row = 0;
diff --git a/ui/qt/packet_list_model.h b/ui/qt/packet_list_model.h
index 0c7772fef5..20733f2a5c 100644
--- a/ui/qt/packet_list_model.h
+++ b/ui/qt/packet_list_model.h
@@ -59,6 +59,7 @@ public:
gint appendPacket(frame_data *fdata);
frame_data *getRowFdata(int row);
+ void ensureRowColorized(int row);
int visibleIndexOf(frame_data *fdata) const;
void resetColumns();
void resetColorized();
diff --git a/ui/qt/packet_list_record.h b/ui/qt/packet_list_record.h
index 085c96c7d4..17d7c6ae82 100644
--- a/ui/qt/packet_list_record.h
+++ b/ui/qt/packet_list_record.h
@@ -46,6 +46,7 @@ public:
frame_data *frameData() const { return fdata_; }
// packet_list->col_to_text in gtk/packet_list_store.c
static int textColumn(int column) { return cinfo_column_.value(column, -1); }
+ bool colorized() { return colorized_; }
struct conversation *conversation() { return conv_; }
int columnTextSize(const char *str);