summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2016-03-30 00:47:12 +0200
committerPeter Wu <peter@lekensteyn.nl>2016-04-02 21:17:35 +0000
commitfd4808fbec986bcc24247b9acfba83db95dba2c6 (patch)
treecb094be3d0cd5fa7ededd1d13059f4f7d36c2305
parent959fe0e18b1679672a47e7568e76780863fd0eac (diff)
downloadwireshark-fd4808fbec986bcc24247b9acfba83db95dba2c6.tar.gz
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.cpp2
-rw-r--r--ui/qt/proto_tree.cpp40
-rw-r--r--ui/qt/proto_tree.h3
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 &);