diff options
author | Peter Wu <peter@lekensteyn.nl> | 2016-03-30 00:47:12 +0200 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2016-04-02 21:17:35 +0000 |
commit | fd4808fbec986bcc24247b9acfba83db95dba2c6 (patch) | |
tree | cb094be3d0cd5fa7ededd1d13059f4f7d36c2305 | |
parent | 959fe0e18b1679672a47e7568e76780863fd0eac (diff) |
Qt: Remember selected item in packet tree
Previously, changing a packet in the packet list would lose the
currently selected field item in the packet tree. After this patch, this
issue no longer occurs because the selected field is focussed again.
The approach is to remember the header field ID on the path from a field
to its root. Limitations of the current simple approach is that multiple
fields/trees under a tree might result in the wrong selection. This is
better than nothing though.
This patch greatly helps analyzing a capture file which has the same
format, except that I need to check a data source for decrypted data.
Previously I would have to scroll down and select the field to see the
data source which also made it impossible to quickly switch between
packets and compare them.
Change-Id: Ic113ca9245fd9faa10f91182794c50cfde8d10f4
Reviewed-on: https://code.wireshark.org/review/14697
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
-rw-r--r-- | ui/qt/packet_list.cpp | 2 | ||||
-rw-r--r-- | ui/qt/proto_tree.cpp | 40 | ||||
-rw-r--r-- | ui/qt/proto_tree.h | 3 |
3 files changed, 45 insertions, 0 deletions
diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp index 80331d7c06..8007cecda0 100644 --- a/ui/qt/packet_list.cpp +++ b/ui/qt/packet_list.cpp @@ -503,6 +503,8 @@ void PacketList::selectionChanged (const QItemSelection & selected, const QItemS if (fi && proto_tree_) { proto_tree_->selectField(fi); } + } else if (!cap_file_->search_in_progress) { + proto_tree_->restoreSelectedField(); } } diff --git a/ui/qt/proto_tree.cpp b/ui/qt/proto_tree.cpp index 3d8d671a6e..f2bca27db0 100644 --- a/ui/qt/proto_tree.cpp +++ b/ui/qt/proto_tree.cpp @@ -433,6 +433,8 @@ void ProtoTree::updateSelectionStatus(QTreeWidgetItem* item) item_info.append(QString(tr(", %1 bytes")).arg(finfo_length)); } + saveSelectedField(item); + emit protoItemSelected(""); emit protoItemSelected(NULL); emit protoItemSelected(item_info); @@ -602,6 +604,44 @@ void ProtoTree::selectField(field_info *fi) } } +// Remember the currently focussed field based on: +// - current hf_id (obviously) +// - parent items (to avoid selecting a text item in a different tree) +// - position within a tree if there are multiple items (wishlist) +static QList<int> serializeAsPath(QTreeWidgetItem *item) +{ + QList<int> path; + do { + field_info *fi = item->data(0, Qt::UserRole).value<field_info *>(); + path.prepend(fi->hfinfo->id); + } while ((item = item->parent())); + return path; +} +void ProtoTree::saveSelectedField(QTreeWidgetItem *item) +{ + selected_field_path_ = serializeAsPath(item); +} + +// Try to focus a tree item which was previously also visible +void ProtoTree::restoreSelectedField() +{ + if (selected_field_path_.isEmpty()) { + return; + } + int last_hf_id = selected_field_path_.last(); + QTreeWidgetItemIterator iter(this); + while (*iter) { + field_info *fi = (*iter)->data(0, Qt::UserRole).value<field_info *>(); + if (last_hf_id == fi->hfinfo->id && + serializeAsPath(*iter) == selected_field_path_) { + setCurrentItem(*iter); + scrollToItem(*iter); + break; + } + iter++; + } +} + /* * Editor modelines * diff --git a/ui/qt/proto_tree.h b/ui/qt/proto_tree.h index 56815cc85d..ff2992ea8b 100644 --- a/ui/qt/proto_tree.h +++ b/ui/qt/proto_tree.h @@ -45,6 +45,8 @@ public: void selectField(field_info *fi); void closeContextMenu(); void clear(); + void saveSelectedField(QTreeWidgetItem *); + void restoreSelectedField(); protected: virtual void contextMenuEvent(QContextMenuEvent *event); @@ -60,6 +62,7 @@ private: QList<QAction *> copy_actions_; QFont mono_font_; int column_resize_timer_; + QList<int> selected_field_path_; signals: void protoItemSelected(const QString &); |