From 107a91a8cc283f648552a4924fade2216670fb23 Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Mon, 15 Jan 2018 17:13:45 -0800 Subject: [PATCH] Qt: Fix proto tree links and related frames. Add FieldInformation::isLink and use it to style link items. Add back a related frame information. Get rid of rowsInserted() and just visit each tree node starting from the root. Change-Id: I0e7ef6b2e11d25465705adffbb77d6f6cfb2a435 Reviewed-on: https://code.wireshark.org/review/25342 Petri-Dish: Gerald Combs Tested-by: Petri Dish Buildbot Reviewed-by: Gerald Combs --- ui/qt/models/proto_tree_model.cpp | 15 +++++++ ui/qt/proto_tree.cpp | 68 +++++++++++++++---------------- ui/qt/proto_tree.h | 3 +- ui/qt/utils/field_information.cpp | 13 +++++- ui/qt/utils/field_information.h | 3 +- 5 files changed, 62 insertions(+), 40 deletions(-) diff --git a/ui/qt/models/proto_tree_model.cpp b/ui/qt/models/proto_tree_model.cpp index b67e772ec0..45e1d6b056 100644 --- a/ui/qt/models/proto_tree_model.cpp +++ b/ui/qt/models/proto_tree_model.cpp @@ -67,6 +67,12 @@ int ProtoTreeModel::rowCount(const QModelIndex &parent) const return ProtoNode(root_node_).childrenCount(); } +// The QItemDelegate documentation says +// "When displaying items from a custom model in a standard view, it is +// often sufficient to simply ensure that the model returns appropriate +// data for each of the roles that determine the appearance of items in +// views." +// We might want to move this to a delegate regardless. QVariant ProtoTreeModel::data(const QModelIndex &index, int role) const { ProtoNode index_node = protoNodeFromIndex(index); @@ -106,11 +112,20 @@ QVariant ProtoTreeModel::data(const QModelIndex &index, int role) const if(finfo.flag(PI_SEVERITY_MASK)) { return ColorUtils::expert_color_foreground; } + if (finfo.isLink()) { + return QApplication::palette().link(); + } if(finfo.headerInfo().type == FT_PROTOCOL) { return QApplication::palette().windowText(); } return QApplication::palette().text(); } + case Qt::FontRole: + if (finfo.isLink()) { + QFont font; + font.setUnderline(true); + return font; + } default: break; } diff --git a/ui/qt/proto_tree.cpp b/ui/qt/proto_tree.cpp index ec97df9252..12eb589c8e 100644 --- a/ui/qt/proto_tree.cpp +++ b/ui/qt/proto_tree.cpp @@ -234,10 +234,42 @@ void ProtoTree::setMonospaceFont(const QFont &mono_font) update(); } +void ProtoTree::foreachTreeNode(proto_node *node, gpointer proto_tree_ptr) +{ + ProtoTree *tree_view = static_cast(proto_tree_ptr); + ProtoTreeModel *model = qobject_cast(tree_view->model()); + if (!tree_view || !model) { + return; + } + + // Expanded state + if (tree_expanded(node->finfo->tree_type)) { + ProtoNode expand_node = ProtoNode(node); + tree_view->expand(model->indexFromProtoNode(expand_node)); + } + + // Related frames + if (node->finfo->hfinfo->type == FT_FRAMENUM) { + ft_framenum_type_t framenum_type = (ft_framenum_type_t)GPOINTER_TO_INT(node->finfo->hfinfo->strings); + tree_view->emitRelatedFrame(node->finfo->value.value.uinteger, framenum_type); + } + + proto_tree_children_foreach(node, foreachTreeNode, proto_tree_ptr); +} + +// We track item expansion using proto.c:tree_is_expanded. QTreeView +// tracks it using QTreeViewPrivate::expandedIndexes. When we're handed +// a new tree, clear expandedIndexes and repopulate it by walking the +// tree and calling QTreeView::expand above. void ProtoTree::setRootNode(proto_node *root_node) { setFont(mono_font_); reset(); // clears expandedIndexes. proto_tree_model_->setRootNode(root_node); + + disconnect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(syncExpanded(QModelIndex))); + proto_tree_children_foreach(root_node, foreachTreeNode, this); + connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(syncExpanded(QModelIndex))); + updateContentWidth(); } @@ -567,42 +599,6 @@ bool ProtoTree::eventFilter(QObject * obj, QEvent * event) return QTreeView::eventFilter(obj, event); } -void ProtoTree::foreachSyncExpansion(proto_node *node, gpointer proto_tree_ptr) -{ - if (tree_expanded(node->finfo->tree_type)) { - QTreeView *tree_view = static_cast(proto_tree_ptr); - ProtoTreeModel *model = qobject_cast(tree_view->model()); - if (!tree_view || !model) { - return; - } - - ProtoNode expand_node = ProtoNode(node); - tree_view->expand(model->indexFromProtoNode(expand_node)); - } - - proto_tree_children_foreach(node, foreachSyncExpansion, proto_tree_ptr); -} - -// We track item expansion using proto.c:tree_is_expanded. QTreeView -// tracks it using QTreeViewPrivate::expandedIndexes. When we're handed -// a new tree, clear expandedIndexes (which we do above in setRootNode) -// and repopulate it by walking the tree and calling -// QTreeView::expand. -void ProtoTree::rowsInserted(const QModelIndex &parent, int start, int end) -{ - disconnect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(syncExpanded(QModelIndex))); - for (int row = start; row <= end; row++) { - QModelIndex index = proto_tree_model_->index(row, 0, parent); - ProtoNode row_node = proto_tree_model_->protoNodeFromIndex(index); - if (row_node.isExpanded()) { - expand(index); - } - proto_tree_children_foreach(row_node.protoNode(), foreachSyncExpansion, this); - } - connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(syncExpanded(QModelIndex))); - QTreeView::rowsInserted(parent, start, end); -} - /* * Editor modelines * diff --git a/ui/qt/proto_tree.h b/ui/qt/proto_tree.h index f048a6b843..8c6e891e22 100644 --- a/ui/qt/proto_tree.h +++ b/ui/qt/proto_tree.h @@ -45,7 +45,6 @@ protected: virtual void timerEvent(QTimerEvent *event); virtual void keyReleaseEvent(QKeyEvent *event); virtual bool eventFilter(QObject * obj, QEvent * ev); - virtual void rowsInserted(const QModelIndex & parent, int start, int end); private: ProtoTreeModel *proto_tree_model_; @@ -64,7 +63,7 @@ private: capture_file *cap_file_; void saveSelectedField(QModelIndex &index); - static void foreachSyncExpansion(proto_node *node, gpointer proto_tree_ptr); + static void foreachTreeNode(proto_node *node, gpointer proto_tree_ptr); signals: void fieldSelected(FieldInformation *); diff --git a/ui/qt/utils/field_information.cpp b/ui/qt/utils/field_information.cpp index 797f650347..5a919627b0 100644 --- a/ui/qt/utils/field_information.cpp +++ b/ui/qt/utils/field_information.cpp @@ -28,7 +28,7 @@ FieldInformation::FieldInformation(proto_node *node, QObject * parent) parent_fi_ = NULL; } -bool FieldInformation::isValid() +bool FieldInformation::isValid() const { bool ret = false; @@ -44,6 +44,17 @@ bool FieldInformation::isValid() return ret; } +bool FieldInformation::isLink() const +{ + if (fi_ && fi_->hfinfo) { + if((fi_->hfinfo->type == FT_FRAMENUM) || + (FI_GET_FLAG(fi_, FI_URL) && IS_FT_STRING(fi_->hfinfo->type))) { + return true; + } + } + return false; +} + void FieldInformation::setParentField(field_info * par_fi) { parent_fi_ = par_fi; diff --git a/ui/qt/utils/field_information.h b/ui/qt/utils/field_information.h index 722c30bfaa..a9284966b9 100644 --- a/ui/qt/utils/field_information.h +++ b/ui/qt/utils/field_information.h @@ -45,7 +45,8 @@ public: explicit FieldInformation(field_info * fi, QObject * parent = Q_NULLPTR); explicit FieldInformation(proto_node * node, QObject * parent = Q_NULLPTR); - bool isValid(); + bool isValid() const; + bool isLink() const ; field_info * fieldInfo() const;