Add the ability to collapse subtrees with Shift+Left + additional menu items. Bug 9008 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9008).

Currently this is only for GTK, but allows users to test it to see if its worth adding to Qt (my personal opinion is yes).

From Jiří Engelthaler

svn path=/trunk/; revision=52790
This commit is contained in:
Michael Mann 2013-10-23 14:24:17 +00:00
parent f4306bb0cd
commit bb25fad9de
8 changed files with 114 additions and 10 deletions

View File

@ -1113,9 +1113,9 @@ Reset the zoom factor of zoom in / zoom out back to normal font size.
Resize all columns to best fit the current packet display.
=item View:Expand Subtrees
=item View:Expand / Collapse Subtrees
Expands the currently selected item and it's subtrees in the packet details.
Expands / Collapses the currently selected item and it's subtrees in the packet details.
=item View:Expand All

View File

@ -1148,6 +1148,14 @@
</para></entry>
</row>
<row>
<entry><command>Collapse Subtrees</command></entry>
<entry>Shift+Left</entry>
<entry><para>
This menu item collapses the currently selected subtree in the
packet details tree.
</para></entry>
</row>
<row>
<entry><command>Expand All</command></entry>
<entry>Ctrl+Right</entry>
<entry><para>

View File

@ -504,6 +504,15 @@
<para>
Expand the currently selected subtree.
</para>
</entry>
</row>
<row>
<entry><command>Collapse Subtrees</command></entry>
<entry>View</entry>
<entry>
<para>
Collapse the currently selected subtree.
</para>
</entry>
</row>
<row>

View File

@ -1135,6 +1135,47 @@ set_window_title(GtkWidget *win,
g_free(title);
}
/*
* Collapse row and his children
*/
static void
tree_collapse_row_with_children(GtkTreeView *tree_view, GtkTreeModel *model, GtkTreePath *path,
GtkTreeIter *iter)
{
GtkTreeIter child;
if (gtk_tree_view_row_expanded(tree_view, path)) {
if (gtk_tree_model_iter_children(model, &child, iter)) {
gtk_tree_path_down(path);
do {
if (gtk_tree_view_row_expanded(tree_view, path)) {
tree_collapse_row_with_children(tree_view, model, path, &child);
}
gtk_tree_path_next(path);
} while (gtk_tree_model_iter_next(model, &child));
gtk_tree_path_up(path);
gtk_tree_view_collapse_row(tree_view, path);
}
}
}
void
tree_collapse_path_all(GtkTreeView *tree_view, GtkTreePath *path)
{
GtkTreeIter iter;
GtkTreeModel *model;
model = gtk_tree_view_get_model(tree_view);
gtk_tree_model_get_iter(model, &iter, path);
tree_collapse_row_with_children(tree_view, model, path, &iter);
}
/*
* This callback is invoked when keyboard focus is within either
* the packetlist view or the detail view. The keystrokes processed
@ -1165,11 +1206,11 @@ tree_view_key_pressed_cb(GtkWidget *tree,
GdkEventKey *event,
gpointer user_data _U_)
{
GtkTreeSelection* selection;
GtkTreeSelection *selection;
GtkTreeIter iter;
GtkTreeIter parent;
GtkTreeModel* model;
GtkTreePath* path;
GtkTreeModel *model;
GtkTreePath *path;
gboolean expanded, expandable;
int rc = FALSE;
@ -1195,7 +1236,12 @@ tree_view_key_pressed_cb(GtkWidget *tree,
case GDK_Left:
if(expanded) {
/* Subtree is expanded. Collapse it. */
gtk_tree_view_collapse_row(GTK_TREE_VIEW(tree), path);
if (event->state & GDK_SHIFT_MASK)
{
tree_collapse_row_with_children(GTK_TREE_VIEW(tree), model, path, &iter);
}
else
gtk_tree_view_collapse_row(GTK_TREE_VIEW(tree), path);
rc = TRUE;
break;
}

View File

@ -311,6 +311,13 @@ extern gchar *create_user_window_title(const gchar *caption);
*/
extern void set_window_title(GtkWidget *win, const gchar *caption);
/** Collapses tree item and his expanded children
*
* @param tree_view A GtkTreeView
* @param path Path to the field
*/
extern void tree_collapse_path_all(GtkTreeView *tree_view, GtkTreePath *path);
/** Renders a float with two decimals precission, called from gtk_tree_view_column_set_cell_data_func().
* the user data must be the column number.
* Present floats with two decimals

View File

@ -878,12 +878,14 @@ tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
proto_help_menu_modify(sel, &cfile);
}
void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_)
{
if (cfile.edt->tree)
collapse_all_tree(cfile.edt->tree, tree_view_gbl);
}
void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_)
{
if (cfile.edt->tree)
expand_all_tree(cfile.edt->tree, tree_view_gbl);
}
@ -902,7 +904,8 @@ void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
}
}
void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
{
GtkTreePath *path;
path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
@ -913,7 +916,21 @@ void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
}
}
void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
void collapse_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
{
GtkTreePath *path;
path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
if(path) {
/* the mouse position is at an entry, expand that one */
tree_collapse_path_all(GTK_TREE_VIEW(tree_view_gbl), path);
gtk_tree_path_free(path);
}
}
void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_)
{
static const e_addr_resolve resolv_flags = {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE};
if (cfile.edt->tree) {

View File

@ -238,6 +238,13 @@ extern void export_carrays_cmd_cb(GtkWidget *widget, gpointer data);
*/
extern void expand_tree_cb(GtkWidget *widget, gpointer data);
/** User requested "Collapse Tree" by menu.
*
* @param widget parent widget (unused)
* @param data unused
*/
extern void collapse_tree_cb(GtkWidget *widget, gpointer data);
/** User requested "Expand All" by menu.
*
* @param widget parent widget (unused)

View File

@ -1085,6 +1085,7 @@ static const char *ui_desc_menubar =
" <menuitem name='DisplayedColumns' action='/View/DisplayedColumns'/>\n"
" <separator/>\n"
" <menuitem name='ExpandSubtrees' action='/View/ExpandSubtrees'/>\n"
" <menuitem name='CollapseSubtrees' action='/View/CollapseSubtrees'/>\n"
" <menuitem name='ExpandAll' action='/View/ExpandAll'/>\n"
" <menuitem name='CollapseAll' action='/View/CollapseAll'/>\n"
" <separator/>\n"
@ -1567,6 +1568,7 @@ static const GtkActionEntry main_menu_bar_entries[] = {
{ "/View/ResizeAllColumns", WIRESHARK_STOCK_RESIZE_COLUMNS, "Resize All Columns", "<shift><control>R", NULL, G_CALLBACK(packet_list_resize_columns_cb) },
{ "/View/DisplayedColumns", NULL, "Displayed Columns", NULL, NULL, NULL },
{ "/View/ExpandSubtrees", NULL, "E_xpand Subtrees", "<shift>Right", NULL, G_CALLBACK(expand_tree_cb) },
{ "/View/CollapseSubtrees", NULL, "Collapse Subtrees", "<shift>Left", NULL, G_CALLBACK(collapse_tree_cb) },
{ "/View/ExpandAll", NULL, "_Expand All", "<control>Right", NULL, G_CALLBACK(expand_all_cb) },
{ "/View/CollapseAll", NULL, "Collapse _All", "<control>Left", NULL, G_CALLBACK(collapse_all_cb) },
{ "/View/ColorizeConversation", NULL, "Colorize Conversation",NULL, NULL, NULL },
@ -2926,6 +2928,7 @@ static const char *ui_desc_tree_view_menu_popup =
"<ui>\n"
" <popup name='TreeViewPopup' action='PopupAction'>\n"
" <menuitem name='ExpandSubtrees' action='/ExpandSubtrees'/>\n"
" <menuitem name='CollapseSubtrees' action='/CollapseSubtrees'/>\n"
" <menuitem name='ExpandAll' action='/ExpandAll'/>\n"
" <menuitem name='CollapseAll' action='/CollapseAll'/>\n"
" <separator/>\n"
@ -2997,6 +3000,7 @@ static const char *ui_desc_tree_view_menu_popup =
static const GtkActionEntry tree_view_menu_popup_action_entries[] = {
{ "/ExpandSubtrees", NULL, "Expand Subtrees", NULL, NULL, G_CALLBACK(expand_tree_cb) },
{ "/CollapseSubtrees", NULL, "Collapse Subtrees", NULL, NULL, G_CALLBACK(collapse_tree_cb) },
{ "/ExpandAll", NULL, "Expand All", NULL, NULL, G_CALLBACK(expand_all_cb) },
{ "/CollapseAll", NULL, "Collapse All", NULL, NULL, G_CALLBACK(collapse_all_cb) },
{ "/Apply as Column", NULL, "Apply as Column", NULL, NULL, G_CALLBACK(apply_as_custom_column_cb) },
@ -5616,6 +5620,8 @@ set_menus_for_selected_tree_row(capture_file *cf)
(id == -1) ? FALSE : proto_can_toggle_protocol(id));
set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/ExpandSubtrees",
cf->finfo_selected->tree_type != -1);
set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/CollapseSubtrees",
cf->finfo_selected->tree_type != -1);
set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/WikiProtocolPage",
(id == -1) ? FALSE : TRUE);
set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/FilterFieldReference",
@ -5640,6 +5646,8 @@ set_menus_for_selected_tree_row(capture_file *cf)
proto_can_match_selected(cf->finfo_selected, cf->edt));
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/ExpandSubtrees",
cf->finfo_selected->tree_type != -1);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/CollapseSubtrees",
cf->finfo_selected->tree_type != -1);
prev_abbrev = (char *)g_object_get_data(G_OBJECT(ui_manager_tree_view_menu), "menu_abbrev");
if (!prev_abbrev || (strcmp (prev_abbrev, abbrev) != 0)) {
/* No previous protocol or protocol changed - update Protocol Preferences menu */
@ -5661,6 +5669,7 @@ set_menus_for_selected_tree_row(capture_file *cf)
FALSE);
set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/DisableProtocol", FALSE);
set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/ExpandSubtrees", FALSE);
set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/CollapseSubtrees", FALSE);
set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/WikiProtocolPage",
FALSE);
set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/FilterFieldReference",
@ -5677,6 +5686,7 @@ set_menus_for_selected_tree_row(capture_file *cf)
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/AnalyzeMenu/ApplyAsFilter", FALSE);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/AnalyzeMenu/PrepareaFilter", FALSE);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/ExpandSubtrees", FALSE);
set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/CollapseSubtrees", FALSE);
}
}