diff options
author | Gerald Combs <gerald@wireshark.org> | 2016-03-10 12:43:59 -0800 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 2016-03-11 20:42:11 +0000 |
commit | 28bfb3210537ce60895e10526f0a3e8cdfbd279d (patch) | |
tree | 44af57314c924e1d9794dc20f2a4bfbb4bb38d8a /ui/qt | |
parent | 6ed543dbe6115170be335b42c6ba01c42568c6e8 (diff) | |
download | wireshark-28bfb3210537ce60895e10526f0a3e8cdfbd279d.tar.gz |
Qt: Defer proto tree column content resizing.
Try to avoid the following call graph:
ProtoTree::expandAll
...
ProtoTree::expand
...
QTreeView::resizeColumnToContents
QTreeView::resizeColumnToContents calls sizeHintForColumn, which
iterates over a number of items (default 1000). Calling it from
ProtoTree::expand can lead to excessive wheel-spinning.
Add a single-shot timer for resizeColumnToContents. This is similar to
what QTreeView does internally when columns are resized.
Bug: 12228
Change-Id: I7b50c1486b3a25817efae58efbb8c9e961dbdab0
Reviewed-on: https://code.wireshark.org/review/14411
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Diffstat (limited to 'ui/qt')
-rw-r--r-- | ui/qt/proto_tree.cpp | 59 | ||||
-rw-r--r-- | ui/qt/proto_tree.h | 8 |
2 files changed, 58 insertions, 9 deletions
diff --git a/ui/qt/proto_tree.cpp b/ui/qt/proto_tree.cpp index 22e411fe88..aaf76392be 100644 --- a/ui/qt/proto_tree.cpp +++ b/ui/qt/proto_tree.cpp @@ -32,6 +32,7 @@ #include <QContextMenuEvent> #include <QDesktopServices> #include <QHeaderView> +#include <QScrollBar> #include <QTreeWidgetItemIterator> #include <QUrl> @@ -151,7 +152,8 @@ proto_tree_draw_node(proto_node *node, gpointer data) ProtoTree::ProtoTree(QWidget *parent) : QTreeWidget(parent), - decode_as_(NULL) + decode_as_(NULL), + column_resize_timer_(0) { setAccessibleName(tr("Packet details")); // Leave the uniformRowHeights property as-is (false) since items might @@ -275,6 +277,11 @@ ProtoTree::ProtoTree(QWidget *parent) : this, SIGNAL(showProtocolPreferences(QString))); connect(&proto_prefs_menu_, SIGNAL(editProtocolPreference(preference*,pref_module*)), this, SIGNAL(editProtocolPreference(preference*,pref_module*))); + + // resizeColumnToContents checks 1000 items by default. The user might + // have scrolled to an area with a different width at this point. + connect(verticalScrollBar(), SIGNAL(sliderReleased()), + this, SLOT(updateContentWidth())); } void ProtoTree::closeContextMenu() @@ -285,7 +292,7 @@ void ProtoTree::closeContextMenu() void ProtoTree::clear() { updateSelectionStatus(NULL); QTreeWidget::clear(); - resizeColumnToContents(0); + updateContentWidth(); } void ProtoTree::contextMenuEvent(QContextMenuEvent *event) @@ -324,6 +331,42 @@ void ProtoTree::contextMenuEvent(QContextMenuEvent *event) decode_as_->setData(QVariant()); } +void ProtoTree::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == column_resize_timer_) { + killTimer(column_resize_timer_); + column_resize_timer_ = 0; + resizeColumnToContents(0); + } +} + +// resizeColumnToContents checks 1000 items by default. The user might +// have scrolled to an area with a different width at this point. +void ProtoTree::keyReleaseEvent(QKeyEvent *event) +{ + if (event->isAutoRepeat()) return; + + switch(event->key()) { + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + case Qt::Key_Home: + case Qt::Key_End: + updateContentWidth(); + break; + default: + break; + } +} + +void ProtoTree::updateContentWidth() +{ + if (column_resize_timer_ == 0) { + column_resize_timer_ = startTimer(0); + } +} + void ProtoTree::setMonospaceFont(const QFont &mono_font) { mono_font_ = mono_font; @@ -336,7 +379,7 @@ void ProtoTree::fillProtocolTree(proto_tree *protocol_tree) { setFont(mono_font_); proto_tree_children_foreach(protocol_tree, proto_tree_draw_node, invisibleRootItem()); - resizeColumnToContents(0); + updateContentWidth(); } void ProtoTree::emitRelatedFrame(int related_frame, ft_framenum_type_t framenum_type) @@ -445,7 +488,7 @@ void ProtoTree::expand(const QModelIndex & index) { tree_expanded_set(fi->tree_type, TRUE); } - resizeColumnToContents(0); + updateContentWidth(); } void ProtoTree::collapse(const QModelIndex & index) { @@ -463,7 +506,7 @@ void ProtoTree::collapse(const QModelIndex & index) { fi->tree_type < num_tree_types); tree_expanded_set(fi->tree_type, FALSE); } - resizeColumnToContents(0); + updateContentWidth(); } void ProtoTree::expandSubtrees() @@ -493,7 +536,7 @@ void ProtoTree::expandSubtrees() (*iter)->setExpanded(true); iter++; } - resizeColumnToContents(0); + updateContentWidth(); } void ProtoTree::expandAll() @@ -503,7 +546,7 @@ void ProtoTree::expandAll() tree_expanded_set(i, TRUE); } QTreeWidget::expandAll(); - resizeColumnToContents(0); + updateContentWidth(); } void ProtoTree::collapseAll() @@ -513,7 +556,7 @@ void ProtoTree::collapseAll() tree_expanded_set(i, FALSE); } QTreeWidget::collapseAll(); - resizeColumnToContents(0); + updateContentWidth(); } void ProtoTree::itemDoubleClick(QTreeWidgetItem *item, int) { diff --git a/ui/qt/proto_tree.h b/ui/qt/proto_tree.h index a97f69c6a5..56815cc85d 100644 --- a/ui/qt/proto_tree.h +++ b/ui/qt/proto_tree.h @@ -47,7 +47,9 @@ public: void clear(); protected: - void contextMenuEvent(QContextMenuEvent *event); + virtual void contextMenuEvent(QContextMenuEvent *event); + virtual void timerEvent(QTimerEvent *event); + virtual void keyReleaseEvent(QKeyEvent *event); private: QMenu ctx_menu_; @@ -57,6 +59,7 @@ private: QAction *decode_as_; QList<QAction *> copy_actions_; QFont mono_font_; + int column_resize_timer_; signals: void protoItemSelected(const QString &); @@ -76,6 +79,9 @@ public slots: void expandAll(); void collapseAll(); void itemDoubleClick(QTreeWidgetItem *item, int column); + +private slots: + void updateContentWidth(); }; #endif // PROTO_TREE_H |