diff --git a/doc/geany.txt b/doc/geany.txt index 4c2b006a7..d10600746 100644 --- a/doc/geany.txt +++ b/doc/geany.txt @@ -264,6 +264,7 @@ described by that plugin documentation): * expand/collapse the tree * control sorting order + * control whether to group symbols by their type * locate the symbol in documents The symbols tab can also be filtered by typing a string into diff --git a/src/document.c b/src/document.c index 4ad10e7f4..8b30ef15d 100644 --- a/src/document.c +++ b/src/document.c @@ -648,6 +648,7 @@ static GeanyDocument *document_create(const gchar *utf8_filename) /* initialize default document settings */ doc->priv = g_new0(GeanyDocumentPrivate, 1); doc->priv->tag_filter = g_strdup(""); + doc->priv->symbols_group_by_type = TRUE; doc->id = ++doc_id_counter; doc->index = new_idx; doc->file_name = g_strdup(utf8_filename); diff --git a/src/documentprivate.h b/src/documentprivate.h index 02a2cd6b6..9dc53b095 100644 --- a/src/documentprivate.h +++ b/src/documentprivate.h @@ -114,6 +114,8 @@ typedef struct GeanyDocumentPrivate GData *data; /* Text used for filtering symbol tree. */ gchar *tag_filter; + /* Group symbols in symbol tree by their type. */ + gboolean symbols_group_by_type; } GeanyDocumentPrivate; diff --git a/src/keyfile.c b/src/keyfile.c index 5607f5261..817bdcd70 100644 --- a/src/keyfile.c +++ b/src/keyfile.c @@ -606,6 +606,7 @@ static void save_ui_prefs(GKeyFile *config) g_key_file_set_boolean(config, PACKAGE, "statusbar_visible", interface_prefs.statusbar_visible); g_key_file_set_boolean(config, PACKAGE, "msgwindow_visible", ui_prefs.msgwindow_visible); g_key_file_set_boolean(config, PACKAGE, "fullscreen", ui_prefs.fullscreen); + g_key_file_set_boolean(config, PACKAGE, "symbols_group_by_type", ui_prefs.symbols_group_by_type); g_key_file_set_string(config, PACKAGE, "color_picker_palette", ui_prefs.color_picker_palette); /* get the text from the scribble textview */ @@ -1032,6 +1033,7 @@ static void load_ui_prefs(GKeyFile *config) ui_prefs.sidebar_visible = utils_get_setting_boolean(config, PACKAGE, "sidebar_visible", TRUE); ui_prefs.msgwindow_visible = utils_get_setting_boolean(config, PACKAGE, "msgwindow_visible", TRUE); ui_prefs.fullscreen = utils_get_setting_boolean(config, PACKAGE, "fullscreen", FALSE); + ui_prefs.symbols_group_by_type = utils_get_setting_boolean(config, PACKAGE, "symbols_group_by_type", TRUE); ui_prefs.custom_date_format = utils_get_setting_string(config, PACKAGE, "custom_date_format", ""); ui_prefs.custom_commands = g_key_file_get_string_list(config, PACKAGE, "custom_commands", NULL, NULL); ui_prefs.custom_commands_labels = g_key_file_get_string_list(config, PACKAGE, "custom_commands_labels", NULL, NULL); diff --git a/src/symbols.c b/src/symbols.c index c70d97604..a55397d36 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -100,6 +100,7 @@ static struct GtkWidget *find_usage; GtkWidget *find_doc_usage; GtkWidget *find_in_files; + GtkWidget *group_by_type; } symbol_menu; @@ -975,16 +976,18 @@ static void update_tree_tags(GeanyDocument *doc, GList **tags) foreach_list (item, *tags) { TMTag *tag = item->data; - GtkTreeIter *parent; + GtkTreeIter *parent, *parent_group; - parent = get_tag_type_iter(tag->lang, tag->type); - if (parent) + parent_group = get_tag_type_iter(tag->lang, tag->type); + /* tv_iters[0] is reserved for the "Symbols" group */ + parent = ui_prefs.symbols_group_by_type ? parent_group : &tv_iters[0]; + if (parent_group) { gboolean expand; const gchar *name; const gchar *parent_name; gchar *tooltip; - GdkPixbuf *icon = get_child_icon(store, parent); + GdkPixbuf *icon = get_child_icon(store, parent_group); parent_name = get_parent_name(tag); if (parent_name) @@ -1137,6 +1140,11 @@ gboolean symbols_recreate_tag_list(GeanyDocument *doc, gint sort_mode) if (tags == NULL) return FALSE; + if (doc->priv->symbols_group_by_type != ui_prefs.symbols_group_by_type) + gtk_tree_store_clear(doc->priv->tag_store); + + doc->priv->symbols_group_by_type = ui_prefs.symbols_group_by_type; + /* FIXME: Not sure why we detached the model here? */ /* disable sorting during update because the code doesn't support correctly @@ -2035,6 +2043,17 @@ static void on_symbol_tree_sort_clicked(GtkMenuItem *menuitem, gpointer user_dat doc->has_tags = symbols_recreate_tag_list(doc, sort_mode); } +static void on_symbol_tree_group_by_type_clicked(GtkMenuItem *menuitem, gpointer user_data) +{ + GeanyDocument *doc = document_get_current(); + + if (ignore_callback) + return; + + ui_prefs.symbols_group_by_type = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)); + if (doc != NULL) + doc->has_tags = symbols_recreate_tag_list(doc, SYMBOLS_SORT_USE_PREVIOUS); +} static void on_symbol_tree_menu_show(GtkWidget *widget, gpointer user_data) @@ -2045,6 +2064,7 @@ static void on_symbol_tree_menu_show(GtkWidget *widget, enable = doc && doc->has_tags; gtk_widget_set_sensitive(symbol_menu.sort_by_name, enable); gtk_widget_set_sensitive(symbol_menu.sort_by_appearance, enable); + gtk_widget_set_sensitive(symbol_menu.group_by_type, enable); gtk_widget_set_sensitive(symbol_menu.expand_all, enable); gtk_widget_set_sensitive(symbol_menu.collapse_all, enable); gtk_widget_set_sensitive(symbol_menu.find_usage, enable); @@ -2060,6 +2080,9 @@ static void on_symbol_tree_menu_show(GtkWidget *widget, else gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(symbol_menu.sort_by_appearance), TRUE); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(symbol_menu.group_by_type), + ui_prefs.symbols_group_by_type); + ignore_callback = FALSE; } @@ -2147,6 +2170,15 @@ static void create_taglist_popup_menu(void) gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); + symbol_menu.group_by_type = item = gtk_check_menu_item_new_with_mnemonic(_("_Group by Type")); + gtk_widget_show(item); + gtk_container_add(GTK_CONTAINER(menu), item); + g_signal_connect(item, "activate", G_CALLBACK(on_symbol_tree_group_by_type_clicked), NULL); + + item = gtk_separator_menu_item_new(); + gtk_widget_show(item); + gtk_container_add(GTK_CONTAINER(menu), item); + symbol_menu.find_usage = item = ui_image_menu_item_new(GTK_STOCK_FIND, _("Find _Usage")); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); diff --git a/src/tagmanager/tm_parser.c b/src/tagmanager/tm_parser.c index a305674e2..a60d39bc1 100644 --- a/src/tagmanager/tm_parser.c +++ b/src/tagmanager/tm_parser.c @@ -1057,7 +1057,7 @@ gint tm_parser_get_sidebar_group(TMParserType lang, TMTagType type) for (i = 0; i < map->group_num; i++) { if (map->groups[i].types & type) - return i; + return i + 1; // "Symbols" group is always first } return -1; } @@ -1065,22 +1065,32 @@ gint tm_parser_get_sidebar_group(TMParserType lang, TMTagType type) const gchar *tm_parser_get_sidebar_info(TMParserType lang, gint group, guint *icon) { + const gchar *name; TMParserMap *map; TMParserMapGroup *grp; if (lang >= TM_PARSER_COUNT) return NULL; - map = &parser_map[lang]; - if (group >= (gint)map->group_num) - return NULL; + if (group == 0) + { + name = _("Symbols"); + *icon = TM_ICON_NAMESPACE; + } + else + { + map = &parser_map[lang]; + if (group > (gint)map->group_num) + return NULL; - grp = &map->groups[group]; - *icon = grp->icon; + grp = &map->groups[group - 1]; + name = grp->name; + *icon = grp->icon; + } #ifdef GETTEXT_PACKAGE - return g_dgettext(GETTEXT_PACKAGE, grp->name); + return g_dgettext(GETTEXT_PACKAGE, name); #else - return grp->name; + return name; #endif } diff --git a/src/ui_utils.h b/src/ui_utils.h index 32ae84e95..08987882a 100644 --- a/src/ui_utils.h +++ b/src/ui_utils.h @@ -167,6 +167,7 @@ typedef struct UIPrefs gboolean allow_always_save; /* if set, files can always be saved, even if unchanged */ gchar *statusbar_template; gboolean new_document_after_close; + gboolean symbols_group_by_type; /* Menu-item related data */ GQueue *recent_queue;