summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Labedzki <michal.labedzki@tieto.com>2015-02-20 15:30:23 +0100
committerGerald Combs <gerald@wireshark.org>2015-02-27 20:27:14 +0000
commit2d4817966ee88d2b163dca46e4df75e8f6262b7a (patch)
treed887a5bcee4b267d55556436f320bb32cd49c738
parent2462c0d35a113043b003a73b8b3fe31a674264bb (diff)
downloadwireshark-2d4817966ee88d2b163dca46e4df75e8f6262b7a.tar.gz
Qt: Automatically scroll the packet list.
Add an "Auto Scroll in Live Capture" action to the Go menu. It's in the View menu in the GTK+ UI but it seems to make more sense as a navigation item. Use a timeout interval for automatic scrolling. I haven't run any tests to see if this makes a difference but it would seem that the less drawing we do during a high speed capture the better, particularly for remote displays. Update the x-stay-last icons. Note that we might want to make prefs.capture_auto_scroll a "recent" setting. Mark auto_scroll_live and packet_list_check_end GTK+ only. Bug: 10601 Co-authored-by: Gerald Combs <gerald@wireshark.org> Change-Id: I645d27c0814f0e4a0d5b01ae68be366847e2522d Reviewed-on: https://code.wireshark.org/review/7292 Reviewed-by: Gerald Combs <gerald@wireshark.org>
-rw-r--r--epan/prefs.c1
-rw-r--r--file.c2
-rw-r--r--image/toolbar/16x16/x-stay-last.pngbin267 -> 303 bytes
-rw-r--r--image/toolbar/16x16/x-stay-last.svg44
-rw-r--r--image/toolbar/16x16/x-stay-last@2x.pngbin425 -> 380 bytes
-rw-r--r--image/toolbar/24x24/x-stay-last.pngbin295 -> 313 bytes
-rw-r--r--image/toolbar/24x24/x-stay-last.svg46
-rw-r--r--image/toolbar/24x24/x-stay-last@2x.pngbin479 -> 408 bytes
-rw-r--r--ui/preference_utils.h2
-rw-r--r--ui/qt/capture_file.cpp1
-rw-r--r--ui/qt/main_window.cpp14
-rw-r--r--ui/qt/main_window.h3
-rw-r--r--ui/qt/main_window.ui14
-rw-r--r--ui/qt/main_window_slots.cpp10
-rw-r--r--ui/qt/packet_list.cpp70
-rw-r--r--ui/qt/packet_list.h16
-rw-r--r--ui/ui_util.h2
17 files changed, 177 insertions, 48 deletions
diff --git a/epan/prefs.c b/epan/prefs.c
index 7c90d8570d..00890d9c66 100644
--- a/epan/prefs.c
+++ b/epan/prefs.c
@@ -2416,6 +2416,7 @@ prefs_register_modules(void)
prefs_register_bool_preference(capture_module, "real_time_update", "Update packet list in real time during capture",
"Update packet list in real time during capture?", &prefs.capture_real_time);
+ /* We might want to make this a "recent" setting. */
prefs_register_bool_preference(capture_module, "auto_scroll", "Scroll packet list during capture",
"Scroll packet list during capture?", &prefs.capture_auto_scroll);
diff --git a/file.c b/file.c
index 01ed0d4fda..8e531d8222 100644
--- a/file.c
+++ b/file.c
@@ -102,7 +102,7 @@
#endif
#ifdef HAVE_LIBPCAP
-gboolean auto_scroll_live;
+gboolean auto_scroll_live; /* GTK+ only? */
#endif
static int read_packet(capture_file *cf, dfilter_t *dfcode, epan_dissect_t *edt,
diff --git a/image/toolbar/16x16/x-stay-last.png b/image/toolbar/16x16/x-stay-last.png
index e5bb6ea5b5..68629cc289 100644
--- a/image/toolbar/16x16/x-stay-last.png
+++ b/image/toolbar/16x16/x-stay-last.png
Binary files differ
diff --git a/image/toolbar/16x16/x-stay-last.svg b/image/toolbar/16x16/x-stay-last.svg
index acec8379f7..2962556869 100644
--- a/image/toolbar/16x16/x-stay-last.svg
+++ b/image/toolbar/16x16/x-stay-last.svg
@@ -14,7 +14,7 @@
id="svg2"
version="1.1"
inkscape:version="0.48.2 r9819"
- sodipodi:docname="x-colorize-packets.svg"
+ sodipodi:docname="x-stay-last.svg"
inkscape:export-filename="x-colorize-packets.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
@@ -27,16 +27,16 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="34.9375"
- inkscape:cx="7.7733362"
+ inkscape:zoom="39.25"
+ inkscape:cx="8"
inkscape:cy="8"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
- inkscape:window-width="1028"
- inkscape:window-height="728"
- inkscape:window-x="283"
- inkscape:window-y="792"
+ inkscape:window-width="1263"
+ inkscape:window-height="799"
+ inkscape:window-x="65"
+ inkscape:window-y="1"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
@@ -54,7 +54,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
+ <dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@@ -95,7 +95,7 @@
id="path4099"
inkscape:connector-curvature="0" />
<path
- style="fill:#204a87;stroke:#ef2929;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ style="fill:#204a87;stroke:#babdb6;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
d="m 1.4821429,1040.8622 c 13.0357141,0 13.0357141,0 13.0357141,0"
id="path4103"
inkscape:connector-curvature="0" />
@@ -103,12 +103,12 @@
inkscape:connector-curvature="0"
id="path4105"
d="m 1.5185185,1043.8622 c 12.9629625,0 12.9629625,0 12.9629625,0"
- style="fill:none;stroke:#3465a4;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
+ style="fill:none;stroke:#babdb6;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path4109"
d="m 1.5185185,1046.8622 c 12.9629625,0 12.9629625,0 12.9629625,0"
- style="fill:none;stroke:#75507b;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
+ style="fill:none;stroke:#babdb6;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;stroke:#2e3436;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
d="m 1.5,1050.8622 c 13,0 13,0 13,0"
@@ -116,7 +116,7 @@
inkscape:connector-curvature="0" />
<path
sodipodi:type="star"
- style="fill:#c4a000;fill-opacity:1;stroke:#725000;stroke-width:3.77809595999999992;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ style="fill:#c4a000;fill-opacity:1;stroke:#725000;stroke-width:3.77809596;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path4205"
sodipodi:sides="3"
sodipodi:cx="28"
@@ -129,7 +129,25 @@
inkscape:rounded="1"
inkscape:randomized="0"
d="M 28,14 C 17.607695,14 17.607695,14 22.803847,5.0000001 28,-4 28,-4 33.196152,4.9999999 38.392305,14 38.392305,14 28,14 z"
- transform="matrix(-0.36780134,0,0,-0.19047619,21.631938,1050.5289)"
+ transform="matrix(-0.36780134,0,0,-0.19047619,33.631938,1050.5289)"
inkscape:transform-center-y="0.35714706" />
+ <path
+ inkscape:transform-center-x="-3.8849402e-05"
+ transform="matrix(-0.40653866,0,0,-0.25396825,22.383082,1050.4178)"
+ d="M 28,14 C 17.607695,14 17.607695,14 22.803847,5.0000001 28,-4 28,-4 33.196152,4.9999999 38.392305,14 38.392305,14 28,14 z"
+ inkscape:randomized="0"
+ inkscape:rounded="1"
+ inkscape:flatsided="true"
+ sodipodi:arg2="2.6179939"
+ sodipodi:arg1="1.5707963"
+ sodipodi:r2="3"
+ sodipodi:r1="6"
+ sodipodi:cy="8"
+ sodipodi:cx="28"
+ sodipodi:sides="3"
+ id="path4590"
+ style="fill:#3465a4;fill-opacity:1;stroke:#3465a4;stroke-width:3.11214161;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="star"
+ inkscape:transform-center-y="0.47633785" />
</g>
</svg>
diff --git a/image/toolbar/16x16/x-stay-last@2x.png b/image/toolbar/16x16/x-stay-last@2x.png
index cb8ee9eb88..23c73aab9a 100644
--- a/image/toolbar/16x16/x-stay-last@2x.png
+++ b/image/toolbar/16x16/x-stay-last@2x.png
Binary files differ
diff --git a/image/toolbar/24x24/x-stay-last.png b/image/toolbar/24x24/x-stay-last.png
index 06b9d30bcd..9c04995d80 100644
--- a/image/toolbar/24x24/x-stay-last.png
+++ b/image/toolbar/24x24/x-stay-last.png
Binary files differ
diff --git a/image/toolbar/24x24/x-stay-last.svg b/image/toolbar/24x24/x-stay-last.svg
index 06ce2fdc8b..2bbd401b6f 100644
--- a/image/toolbar/24x24/x-stay-last.svg
+++ b/image/toolbar/24x24/x-stay-last.svg
@@ -27,16 +27,16 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="23.291667"
- inkscape:cx="10.503891"
+ inkscape:zoom="23.369223"
+ inkscape:cx="15.441568"
inkscape:cy="12"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
- inkscape:window-width="1028"
- inkscape:window-height="728"
- inkscape:window-x="132"
- inkscape:window-y="821"
+ inkscape:window-width="1300"
+ inkscape:window-height="732"
+ inkscape:window-x="70"
+ inkscape:window-y="702"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
@@ -54,7 +54,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
+ <dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@@ -97,9 +97,9 @@
inkscape:connector-curvature="0"
id="path4115"
d="m 1.5,1032.8622 c 21,0 21,0 21,0"
- style="fill:#ef2929;stroke:#ef2929;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
+ style="fill:#babdb6;stroke:#babdb6;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" />
<path
- style="fill:none;stroke:#73d216;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ style="fill:#babdb6;stroke:#babdb6;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
d="m 1.4999999,1038.8622 c 20.9999991,0 20.9999991,0 20.9999991,0"
id="path4117"
inkscape:connector-curvature="0" />
@@ -107,9 +107,9 @@
inkscape:connector-curvature="0"
id="path4119"
d="m 1.4999999,1035.8622 c 20.9999991,0 20.9999991,0 20.9999991,0"
- style="fill:none;stroke:#3465a4;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
+ style="fill:#babdb6;stroke:#babdb6;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" />
<path
- style="fill:none;stroke:#3465a4;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ style="fill:#babdb6;stroke:#babdb6;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
d="m 1.4999999,1041.8622 c 20.9999991,0 20.9999991,0 20.9999991,0"
id="path4121"
inkscape:connector-curvature="0" />
@@ -117,9 +117,9 @@
inkscape:connector-curvature="0"
id="path4123"
d="m 1.5,1047.8622 c 21,0 21,0 21,0"
- style="fill:#f57900;stroke:#f57900;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
+ style="fill:#babdb6;stroke:#babdb6;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" />
<path
- style="fill:none;stroke:#75507b;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ style="fill:#babdb6;stroke:#babdb6;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
d="m 1.4999999,1044.8622 c 20.9999991,0 20.9999991,0 20.9999991,0"
id="path4125"
inkscape:connector-curvature="0" />
@@ -143,7 +143,25 @@
inkscape:rounded="1"
inkscape:randomized="0"
d="M 28,14 C 17.607695,14 17.607695,14 22.803847,5.0000001 28,-4 28,-4 33.196152,4.9999999 38.392305,14 38.392305,14 28,14 z"
- transform="matrix(0.58076952,0,0,-0.31746032,1.2384534,1050.3066)"
+ transform="matrix(0.58076952,0,0,-0.31746032,15.238453,1050.3066)"
inkscape:transform-center-y="0.59532957" />
+ <path
+ inkscape:transform-center-x="-6.9566908e-05"
+ transform="matrix(-0.58076952,0,0,-0.31746032,32.761547,1050.3066)"
+ d="M 28,14 C 17.607695,14 17.607695,14 22.803847,5.0000001 28,-4 28,-4 33.196152,4.9999999 38.392305,14 38.392305,14 28,14 z"
+ inkscape:randomized="0"
+ inkscape:rounded="1"
+ inkscape:flatsided="true"
+ sodipodi:arg2="2.6179939"
+ sodipodi:arg1="1.5707963"
+ sodipodi:r2="3"
+ sodipodi:r1="6"
+ sodipodi:cy="8"
+ sodipodi:cx="28"
+ sodipodi:sides="3"
+ id="path4550"
+ style="fill:#3465a4;fill-opacity:1;stroke:#3465a4;stroke-width:2.32891345;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="star"
+ inkscape:transform-center-y="0.5953435" />
</g>
</svg>
diff --git a/image/toolbar/24x24/x-stay-last@2x.png b/image/toolbar/24x24/x-stay-last@2x.png
index fff5b22a0f..a66c2a8007 100644
--- a/image/toolbar/24x24/x-stay-last@2x.png
+++ b/image/toolbar/24x24/x-stay-last@2x.png
Binary files differ
diff --git a/ui/preference_utils.h b/ui/preference_utils.h
index 074b974844..e4117d682e 100644
--- a/ui/preference_utils.h
+++ b/ui/preference_utils.h
@@ -70,7 +70,7 @@ extern void reset_stashed_pref(pref_t *pref);
/** If autoscroll in live captures is active or not
*/
-extern gboolean auto_scroll_live;
+extern gboolean auto_scroll_live; /* GTK+ only. */
/** Fill in capture options with values from the preferences
*/
diff --git a/ui/qt/capture_file.cpp b/ui/qt/capture_file.cpp
index a32f225f15..a15e8ebdba 100644
--- a/ui/qt/capture_file.cpp
+++ b/ui/qt/capture_file.cpp
@@ -40,6 +40,7 @@ capture_file cfile;
// To do:
// - Add getters and (if needed) setters:
// - Full filename
+// - Capture state (stopped, prepared, running).
QString CaptureFile::no_capture_file_ = QObject::tr("[no capture file]");
diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp
index c69d50a68d..7eb7b702b7 100644
--- a/ui/qt/main_window.cpp
+++ b/ui/qt/main_window.cpp
@@ -187,7 +187,6 @@ MainWindow::MainWindow(QWidget *parent) :
setForCapturedPackets(false);
setMenusForSelectedPacket();
setMenusForSelectedTreeRow();
- setForCaptureInProgress(false);
setMenusForFileSet(false);
interfaceSelectionChanged();
loadWindowGeometry();
@@ -202,7 +201,7 @@ MainWindow::MainWindow(QWidget *parent) :
connect(wsApp, SIGNAL(profileChanging()), this, SLOT(saveWindowGeometry()));
connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(layoutPanes()));
connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(layoutToolbars()));
- connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(updateNameResolutionActions()));
+ connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(updatePreferenceActions()));
connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(zoomText()));
connect(wsApp, SIGNAL(updateRecentItemStatus(const QString &, qint64, bool)), this, SLOT(updateRecentFiles()));
@@ -286,7 +285,8 @@ MainWindow::MainWindow(QWidget *parent) :
initShowHideMainWidgets();
initTimeDisplayFormatMenu();
initTimePrecisionFormatMenu();
- updateNameResolutionActions();
+ updatePreferenceActions();
+ setForCaptureInProgress(false);
connect(&capture_file_, SIGNAL(captureCapturePrepared(capture_session *)),
this, SLOT(captureCapturePrepared(capture_session *)));
@@ -388,6 +388,8 @@ MainWindow::MainWindow(QWidget *parent) :
packet_list_, SLOT(redrawVisiblePackets()));
connect(packet_list_, SIGNAL(doubleClicked(QModelIndex)),
this, SLOT(openPacketDialog()));
+ connect(packet_list_, SIGNAL(packetListScrolled(bool)),
+ main_ui_->actionGoAutoScroll, SLOT(setChecked(bool)));
connect(proto_tree_, SIGNAL(protoItemSelected(QString&)),
main_ui_->statusBar, SLOT(pushFieldStatus(QString&)));
@@ -1420,6 +1422,7 @@ void MainWindow::initMainToolbarIcons()
main_ui_->actionGoGoToPacket->setIcon(StockIcon("go-jump"));
main_ui_->actionGoFirstPacket->setIcon(StockIcon("go-first"));
main_ui_->actionGoLastPacket->setIcon(StockIcon("go-last"));
+ main_ui_->actionGoAutoScroll->setIcon(StockIcon("x-stay-last"));
main_ui_->actionViewColorizePacketList->setIcon(StockIcon("x-colorize-packets"));
main_ui_->actionViewColorizePacketList->setChecked(recent.packet_list_colorize);
@@ -1818,11 +1821,12 @@ void MainWindow::setForCaptureInProgress(gboolean capture_in_progress)
{
setMenusForCaptureInProgress(capture_in_progress);
-//#ifdef HAVE_LIBPCAP
+#ifdef HAVE_LIBPCAP
+ packet_list_->setCaptureInProgress(capture_in_progress);
// set_toolbar_for_capture_in_progress(capture_in_progress);
// set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
-//#endif
+#endif
}
/*
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index 5310c00033..05f73e3f61 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -190,7 +190,7 @@ public slots:
void layoutPanes();
void applyRecentPaneGeometry();
void layoutToolbars();
- void updateNameResolutionActions();
+ void updatePreferenceActions();
void captureCapturePrepared(capture_session *);
void captureCaptureUpdateStarted(capture_session *);
@@ -324,6 +324,7 @@ private slots:
void on_actionViewReload_triggered();
void on_actionGoGoToPacket_triggered();
+ void on_actionGoAutoScroll_toggled(bool checked);
void resetPreviousFocus();
#ifdef HAVE_LIBPCAP
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index 29a9efba84..6a9901a3a4 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -225,6 +225,8 @@
<addaction name="actionGoPreviousPacket"/>
<addaction name="actionGoFirstPacket"/>
<addaction name="actionGoLastPacket"/>
+ <addaction name="separator"/>
+ <addaction name="actionGoAutoScroll"/>
</widget>
<widget class="QMenu" name="menuView">
<property name="title">
@@ -568,6 +570,7 @@
<addaction name="actionGoGoToPacket"/>
<addaction name="actionGoFirstPacket"/>
<addaction name="actionGoLastPacket"/>
+ <addaction name="actionGoAutoScroll"/>
<addaction name="separator"/>
<addaction name="actionViewColorizePacketList"/>
<addaction name="separator"/>
@@ -2293,6 +2296,17 @@
<string>Show the linked packet in a separate window.</string>
</property>
</action>
+ <action name="actionGoAutoScroll">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Auto Scroll in Li&amp;ve Capture</string>
+ </property>
+ <property name="toolTip">
+ <string>Automatically scroll to the last packet during a live capture.</string>
+ </property>
+ </action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 8291e0d3c8..bd366ae0e8 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -415,11 +415,14 @@ void MainWindow::layoutToolbars()
main_ui_->mainToolBar->setToolButtonStyle(tbstyle);
}
-void MainWindow::updateNameResolutionActions()
+void MainWindow::updatePreferenceActions()
{
main_ui_->actionViewNameResolutionPhysical->setChecked(gbl_resolv_flags.mac_name);
main_ui_->actionViewNameResolutionNetwork->setChecked(gbl_resolv_flags.network_name);
main_ui_->actionViewNameResolutionTransport->setChecked(gbl_resolv_flags.transport_name);
+
+ // Should this be a "recent" setting?
+ main_ui_->actionGoAutoScroll->setChecked(prefs.capture_auto_scroll);
}
void MainWindow::filterAction(QString &action_filter, FilterAction::Action action, FilterAction::ActionType type)
@@ -2693,6 +2696,11 @@ void MainWindow::on_actionGoGoToPacket_triggered() {
main_ui_->goToLineEdit->setFocus();
}
+void MainWindow::on_actionGoAutoScroll_toggled(bool checked)
+{
+ packet_list_->setAutoScroll(checked);
+}
+
void MainWindow::resetPreviousFocus() {
previous_focus_ = NULL;
}
diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp
index 428a51f1f7..4d6e3905ac 100644
--- a/ui/qt/packet_list.cpp
+++ b/ui/qt/packet_list.cpp
@@ -60,11 +60,12 @@
#include <QScrollBar>
#include <QTabWidget>
#include <QTextEdit>
+#include <QTimerEvent>
#include <QTreeWidget>
// To do:
-// - Heading context menus
// - Catch column reordering and rebuild the column list accoringly.
+// - Use a timer to trigger automatic scrolling.
// If we ever add the ability to open multiple capture files we might be
// able to use something like QMap<capture_file *, PacketList *> to match
@@ -72,6 +73,7 @@
static PacketList *gbl_cur_packet_list = NULL;
const int max_comments_to_fetch_ = 20000000; // Arbitrary
+const int tail_update_interval_ = 100; // Milliseconds.
guint
packet_list_append(column_info *cinfo, frame_data *fdata)
@@ -135,13 +137,7 @@ packet_list_select_row_from_data(frame_data *fdata_needle)
gboolean
packet_list_check_end(void)
{
- if (gbl_cur_packet_list) {
- QScrollBar *sb = gbl_cur_packet_list->verticalScrollBar();
- if (sb && sb->isVisible() && sb->value() == sb->maximum()) {
- return TRUE;
- }
- }
- return FALSE;
+ return FALSE; // GTK+ only.
}
void
@@ -230,7 +226,9 @@ PacketList::PacketList(QWidget *parent) :
byte_view_tab_(NULL),
cap_file_(NULL),
decode_as_(NULL),
- ctx_column_(-1)
+ ctx_column_(-1),
+ capture_in_progress_(false),
+ tail_timer_id_(0)
{
QMenu *submenu, *subsubmenu;
QAction *action;
@@ -419,6 +417,8 @@ PacketList::PacketList(QWidget *parent) :
connect(header(), SIGNAL(customContextMenuRequested(QPoint)),
SLOT(showHeaderMenu(QPoint)));
connect(header(), SIGNAL(sectionResized(int,int,int)), this, SLOT(sectionResized(int,int,int)));
+
+ connect(verticalScrollBar(), SIGNAL(actionTriggered(int)), this, SLOT(vScrollBarActionTriggered(int)));
}
void PacketList::setProtoTree (ProtoTree *proto_tree) {
@@ -519,6 +519,27 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
decode_as_->setData(QVariant());
}
+// Auto scroll if:
+// - We're not at the end
+// - We are capturing
+// - actionGoAutoScroll in the main UI is checked.
+// - It's been more than tail_update_interval_ ms since we last scrolled
+// - The last user-set vertical scrollbar position was at the end.
+
+// Using a timer assumes that we can save CPU overhead by updating
+// periodically. If that's not the case we can dispense with it and call
+// scrollToBottom() from rowsInserted().
+void PacketList::timerEvent(QTimerEvent *event)
+{
+ if (rows_inserted_
+ && event->timerId() == tail_timer_id_
+ && capture_in_progress_
+ && tail_at_end_) {
+ scrollToBottom();
+ rows_inserted_ = false;
+ }
+}
+
void PacketList::markFramesReady()
{
packets_bar_update();
@@ -661,6 +682,18 @@ void PacketList::recolorPackets()
redrawVisiblePackets();
}
+void PacketList::setAutoScroll(bool enabled)
+{
+ tail_at_end_ = enabled;
+ if (enabled) {
+ scrollToBottom();
+ if (tail_timer_id_ < 1) tail_timer_id_ = startTimer(tail_update_interval_);
+ } else if (tail_timer_id_ > 0) {
+ killTimer(tail_timer_id_);
+ tail_timer_id_ = 0;
+ }
+}
+
void PacketList::freeze()
{
setUpdatesEnabled(false);
@@ -1129,6 +1162,25 @@ void PacketList::sectionResized(int, int, int)
}
}
+// We need to tell when the user has scrolled the packet list, either to
+// the end or anywhere other than the end.
+void PacketList::vScrollBarActionTriggered(int)
+{
+ // If we're scrolling with a mouse wheel or trackpad sliderPosition can end up
+ // past the end.
+ tail_at_end_ = (verticalScrollBar()->sliderPosition() >= verticalScrollBar()->maximum());
+
+ if (capture_in_progress_ && prefs.capture_auto_scroll) {
+ emit packetListScrolled(tail_at_end_);
+ }
+}
+
+void PacketList::rowsInserted(const QModelIndex &parent, int start, int end)
+{
+ QTreeView::rowsInserted(parent, start, end);
+ rows_inserted_ = true;
+}
+
/*
* Editor modelines
*
diff --git a/ui/qt/packet_list.h b/ui/qt/packet_list.h
index 04fcf74e2e..357533c67b 100644
--- a/ui/qt/packet_list.h
+++ b/ui/qt/packet_list.h
@@ -28,10 +28,12 @@
#include "proto_tree.h"
#include "related_packet_delegate.h"
-#include <QTreeView>
#include <QMenu>
+#include <QTime>
+#include <QTreeView>
class QAction;
+class QTimerEvent;
class PacketList : public QTreeView
{
@@ -63,12 +65,17 @@ public:
void setPacketComment(QString new_comment);
QString allPacketComments();
void recolorPackets();
+ void setAutoScroll(bool enabled = true);
+ 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 contextMenuEvent(QContextMenuEvent *event);
+ void timerEvent(QTimerEvent *event);
+protected slots:
+ void rowsInserted(const QModelIndex &parent, int start, int end);
private:
PacketListModel *packet_list_model_;
@@ -87,6 +94,10 @@ private:
int header_ctx_column_;
QAction *show_hide_separator_;
QList<QAction *>show_hide_actions_;
+ bool capture_in_progress_;
+ int tail_timer_id_;
+ bool tail_at_end_;
+ bool rows_inserted_;
void markFramesReady();
void setFrameMark(gboolean set, frame_data *fdata);
@@ -94,12 +105,12 @@ private:
void setFrameReftime(gboolean set, frame_data *fdata);
void setColumnVisibility();
void initHeaderContextMenu();
-
signals:
void packetDissectionChanged();
void packetSelectionChanged();
void showPreferences(PreferencesDialog::PreferencesPane start_pane);
void editColumn(int column);
+ void packetListScrolled(bool at_end);
public slots:
void setCaptureFile(capture_file *cf);
@@ -124,6 +135,7 @@ private slots:
void headerMenuTriggered();
void columnVisibilityTriggered();
void sectionResized(int, int, int);
+ void vScrollBarActionTriggered(int);
};
#endif // PACKET_LIST_H
diff --git a/ui/ui_util.h b/ui/ui_util.h
index 7ebd59bd3d..b76e218951 100644
--- a/ui/ui_util.h
+++ b/ui/ui_util.h
@@ -74,7 +74,7 @@ void packet_list_queue_draw(void);
void packet_list_select_first_row(void);
void packet_list_select_last_row(void);
void packet_list_moveto_end(void);
-gboolean packet_list_check_end(void);
+gboolean packet_list_check_end(void); /* GTK+ only */
gboolean packet_list_select_row_from_data(frame_data *fdata_needle);
void packet_list_resize_column(gint col);