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 <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Gerald Combs <gerald@wireshark.org>
This commit is contained in:
Gerald Combs 2018-01-15 17:13:45 -08:00
parent 96e865b4b8
commit 107a91a8cc
5 changed files with 62 additions and 40 deletions

View File

@ -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;
}

View File

@ -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<ProtoTree *>(proto_tree_ptr);
ProtoTreeModel *model = qobject_cast<ProtoTreeModel *>(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<QTreeView *>(proto_tree_ptr);
ProtoTreeModel *model = qobject_cast<ProtoTreeModel *>(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
*

View File

@ -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 *);

View File

@ -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;

View File

@ -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;