aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ui/qt/proto_tree.cpp48
1 files changed, 45 insertions, 3 deletions
diff --git a/ui/qt/proto_tree.cpp b/ui/qt/proto_tree.cpp
index 32c73e4085..177383d616 100644
--- a/ui/qt/proto_tree.cpp
+++ b/ui/qt/proto_tree.cpp
@@ -603,16 +603,58 @@ void ProtoTree::selectField(field_info *fi)
}
}
+// Finds position item at a level, counting only similar fields.
+static unsigned indexOfField(QTreeWidgetItem *item, header_field_info *hfi)
+{
+ QTreeWidgetItem *parent = item->parent();
+ unsigned pos = 0;
+ if (!parent) {
+ // In case multiple top-level layers are present for the same protocol,
+ // try to find its position (this will likely be the first match, zero).
+ QTreeWidget *tree = item->treeWidget();
+ for (int i = 0; i < tree->topLevelItemCount(); i++) {
+ QTreeWidgetItem *current = tree->topLevelItem(i);
+ if (current == item) {
+ return pos;
+ }
+ if (hfi == VariantPointer<field_info>::asPtr(current->data(0, Qt::UserRole))->hfinfo) {
+ pos++;
+ }
+ }
+ } else {
+ QTreeWidgetItemIterator iter(parent);
+ while (*iter) {
+ QTreeWidgetItem *current = *iter;
+ if (current == item) {
+ return pos;
+ }
+ if (hfi == VariantPointer<field_info>::asPtr(current->data(0, Qt::UserRole))->hfinfo) {
+ pos++;
+ }
+ ++iter;
+ }
+ }
+ // should not happen (child is not found at parent?!)
+ return 0;
+}
+
+// Assume about 2^8 items in tree and 2^24 different registered fields.
+// If there are more of each, then a collision may occur, but since the full
+// path is matched this is unlikely to be a problem.
+#define POS_SHIFT 24
+#define POS_MASK (((unsigned)-1) << POS_SHIFT)
+
// 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)
+// - position within a tree if there are multiple items
static QList<int> serializeAsPath(QTreeWidgetItem *item)
{
QList<int> path;
do {
field_info *fi = VariantPointer<field_info>::asPtr(item->data(0, Qt::UserRole));
- path.prepend(fi->hfinfo->id);
+ unsigned pos = indexOfField(item, fi->hfinfo);
+ path.prepend((pos << POS_SHIFT) | (fi->hfinfo->id & ~POS_MASK));
} while ((item = item->parent()));
return path;
}
@@ -627,7 +669,7 @@ void ProtoTree::restoreSelectedField()
if (selected_field_path_.isEmpty()) {
return;
}
- int last_hf_id = selected_field_path_.last();
+ int last_hf_id = selected_field_path_.last() & ~POS_MASK;
QTreeWidgetItemIterator iter(this);
while (*iter) {
field_info *fi = VariantPointer<field_info>::asPtr((*iter)->data(0, Qt::UserRole));