Branch: refs/heads/master Author: Jiří Techet techet@gmail.com Committer: Jiří Techet techet@gmail.com Date: Sun, 19 Jan 2025 19:31:07 UTC Commit: b2e70fd16b678f2954e54ed84eef0df1b7c22ad8 https://github.com/geany/geany/commit/b2e70fd16b678f2954e54ed84eef0df1b7c22a...
Log Message: ----------- Set GtkTreeModelFilter as a model for document tree
This commit doesn't perform any filtering yet - it only uses GtkTreeModelFilter and makes sure that existing functionality works as before.
The reason for the additional changes is the fact that some tree operations work on top of GtkTreeIter/GtkTreePath referring the filtered model (typically "visual" things like item selection or expanding/collapsing) while other operations work on top of the original model/store - typically insertions/deletions/modifications of the stored data. When needed, conversions from one type of iterator/path to the other were added.
Modified Paths: -------------- src/document.c src/sidebar.c src/sidebar.h
Modified: src/document.c 14 lines changed, 11 insertions(+), 3 deletions(-) =================================================================== @@ -660,10 +660,18 @@ static GeanyDocument *document_create(const gchar *utf8_filename)
/* select document in sidebar */ { - GtkTreeSelection *sel; + GtkTreeModel *filter_model = gtk_tree_view_get_model(GTK_TREE_VIEW(tv.tree_openfiles)); + GtkTreeIter filter_iter; + gboolean have_filter_iter;
- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles)); - gtk_tree_selection_select_iter(sel, &doc->priv->iter); + have_filter_iter = gtk_tree_model_filter_convert_child_iter_to_iter( + GTK_TREE_MODEL_FILTER(filter_model), &filter_iter, &doc->priv->iter); + + if (have_filter_iter) + { + GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles)); + gtk_tree_selection_select_iter(sel, &filter_iter); + } }
ui_document_buttons_update();
Modified: src/sidebar.c 116 lines changed, 86 insertions(+), 30 deletions(-) =================================================================== @@ -285,8 +285,8 @@ GtkTreeStore *sidebar_create_store_openfiles(void) GtkTreeStore *store; /* store the icon and the short filename to show, and the index as reference, * the colour (black/red/green) and the full name for the tooltip */ - store = gtk_tree_store_new(6, G_TYPE_ICON, G_TYPE_STRING, - G_TYPE_POINTER, GDK_TYPE_COLOR, G_TYPE_STRING, G_TYPE_BOOLEAN); + store = gtk_tree_store_new(DOCUMENTS_COLUMNS_NUM, G_TYPE_ICON, G_TYPE_STRING, + G_TYPE_POINTER, GDK_TYPE_COLOR, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
/* sort opened filenames in the store_openfiles treeview */ sortable = GTK_TREE_SORTABLE(GTK_TREE_MODEL(store)); @@ -332,32 +332,40 @@ static void store_fold_recurse(GtkTreeView *view, }
+/* returns GtkTreeIter and GtkTreePath of GtkTreeModelFilter */ static gboolean on_row_expand(GtkTreeView *view, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { - GtkTreeModel *model; + GtkTreeModel *filter_model = gtk_tree_view_get_model(GTK_TREE_VIEW(tv.tree_openfiles)); + GtkTreeIter store_iter; + + gtk_tree_model_filter_convert_iter_to_child_iter( + GTK_TREE_MODEL_FILTER(filter_model), &store_iter, iter);
- model = gtk_tree_view_get_model(view); - gtk_tree_store_set(GTK_TREE_STORE(model), iter, DOCUMENTS_FOLD, FALSE, -1); + gtk_tree_store_set(store_openfiles, &store_iter, DOCUMENTS_FOLD, FALSE, -1); return FALSE; }
+/* returns GtkTreeIter and GtkTreePath of GtkTreeModelFilter */ static gboolean on_row_collapse(GtkTreeView *view, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { - GtkTreeModel *model; - GtkTreeIter child_iter; + GtkTreeModel *model = GTK_TREE_MODEL(store_openfiles); + GtkTreeModel *filter_model = gtk_tree_view_get_model(GTK_TREE_VIEW(tv.tree_openfiles)); + GtkTreeIter child_iter, store_iter; gboolean valid;
- model = gtk_tree_view_get_model(view); - gtk_tree_store_set(GTK_TREE_STORE(model), iter, DOCUMENTS_FOLD, TRUE, -1); + gtk_tree_model_filter_convert_iter_to_child_iter( + GTK_TREE_MODEL_FILTER(filter_model), &store_iter, iter);
- valid = gtk_tree_model_iter_children(model, &child_iter, iter); + gtk_tree_store_set(store_openfiles, &store_iter, DOCUMENTS_FOLD, TRUE, -1); + + valid = gtk_tree_model_iter_children(model, &child_iter, &store_iter); while (valid) { store_fold_recurse(view, &child_iter, model); @@ -368,20 +376,23 @@ static gboolean on_row_collapse(GtkTreeView *view, }
+/* returns GtkTreeIter and GtkTreePath of GtkTreeModelFilter */ static void on_row_expanded(GtkTreeView *view, GtkTreeIter *iter, GtkTreePath *path_, gpointer user_data) { - GtkTreeIter child_iter; - GtkTreeModel *model; + GtkTreeModel *filter_model = gtk_tree_view_get_model(GTK_TREE_VIEW(tv.tree_openfiles)); + GtkTreeModel *model = GTK_TREE_MODEL(store_openfiles); + GtkTreeIter child_iter, store_iter; GtkTreePath *path; gboolean valid; GeanyDocument *doc;
- model = gtk_tree_view_get_model(view); + gtk_tree_model_filter_convert_iter_to_child_iter( + GTK_TREE_MODEL_FILTER(filter_model), &store_iter, iter);
- valid = gtk_tree_model_iter_children(model, &child_iter, iter); + valid = gtk_tree_model_iter_children(model, &child_iter, &store_iter); while (valid) { gboolean fold; @@ -390,7 +401,15 @@ static void on_row_expanded(GtkTreeView *view, path = gtk_tree_model_get_path(model, &child_iter);
if (!doc && !fold) - gtk_tree_view_expand_row(view, path, FALSE); + { + GtkTreePath *filter_path = gtk_tree_model_filter_convert_child_path_to_path( + GTK_TREE_MODEL_FILTER(filter_model), path); + + if (filter_path) + gtk_tree_view_expand_row(view, filter_path, FALSE); + + gtk_tree_path_free(filter_path); + }
valid = gtk_tree_model_iter_next(model, &child_iter); gtk_tree_path_free(path); @@ -405,12 +424,17 @@ static void prepare_openfiles(void) GtkCellRenderer *text_renderer; GtkTreeViewColumn *column; GtkTreeSelection *selection; + GtkTreeModel *filter_model;
tv.tree_openfiles = ui_lookup_widget(main_widgets.window, "treeview6");
sidebar_create_store_openfiles();
- gtk_tree_view_set_model(GTK_TREE_VIEW(tv.tree_openfiles), GTK_TREE_MODEL(store_openfiles)); + filter_model = gtk_tree_model_filter_new(GTK_TREE_MODEL(store_openfiles), NULL); + gtk_tree_model_filter_set_visible_column(GTK_TREE_MODEL_FILTER(filter_model), + DOCUMENTS_VISIBLE); + gtk_tree_view_set_model(GTK_TREE_VIEW(tv.tree_openfiles), filter_model); + g_object_unref(filter_model);
/* These two implement "remember fold state of rows when their parents are folded". Normally * GTK does not remember the fold state and can only expand all or no children when @@ -876,11 +900,18 @@ static gboolean sidebar_openfiles_add_iter(GtkTreeStore *tree, const gchar *file
static void expand_iter(GtkTreeIter *iter) { - GtkTreePath *path; + GtkTreeModel *filter_model = gtk_tree_view_get_model(GTK_TREE_VIEW(tv.tree_openfiles)); + GtkTreePath *path, *filter_path;
path = gtk_tree_model_get_path(GTK_TREE_MODEL(store_openfiles), iter); - gtk_tree_view_expand_to_path(GTK_TREE_VIEW(tv.tree_openfiles), path); + filter_path = gtk_tree_model_filter_convert_child_path_to_path( + GTK_TREE_MODEL_FILTER(filter_model), path); + + if (filter_path) + gtk_tree_view_expand_to_path(GTK_TREE_VIEW(tv.tree_openfiles), filter_path); + gtk_tree_path_free(path); + gtk_tree_path_free(filter_path); }
@@ -995,16 +1026,26 @@ void sidebar_openfiles_update(GeanyDocument *doc) else { /* path has changed, so remove and re-add */ + GtkTreeModel *filter_model = gtk_tree_view_get_model(GTK_TREE_VIEW(tv.tree_openfiles)); + GtkTreeIter filter_iter; GtkTreeSelection *treesel; - gboolean sel; + gboolean sel = FALSE; + gboolean have_filter_iter;
- treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles)); - sel = gtk_tree_selection_iter_is_selected(treesel, &doc->priv->iter); - openfiles_remove(doc); + have_filter_iter = gtk_tree_model_filter_convert_child_iter_to_iter( + GTK_TREE_MODEL_FILTER(filter_model), &filter_iter, iter);
+ if (have_filter_iter) + { + treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv.tree_openfiles)); + sel = gtk_tree_selection_iter_is_selected(treesel, &filter_iter); + } + + openfiles_remove(doc); sidebar_openfiles_add(doc); + if (sel) - gtk_tree_selection_select_iter(treesel, &doc->priv->iter); + gtk_tree_selection_select_iter(treesel, &filter_iter); } g_free(fname); } @@ -1270,9 +1311,17 @@ static gboolean tree_model_find_node(GtkTreeModel *model, gtk_tree_model_get(model, iter, DOCUMENTS_DOCUMENT, &doc, -1); if (doc == data) { - gtk_tree_view_expand_to_path(GTK_TREE_VIEW(tv.tree_openfiles), path); - gtk_tree_view_set_cursor(GTK_TREE_VIEW(tv.tree_openfiles), path, NULL, FALSE); - return TRUE; + GtkTreeModel *filter_model = gtk_tree_view_get_model(GTK_TREE_VIEW(tv.tree_openfiles)); + GtkTreePath *filter_path = gtk_tree_model_filter_convert_child_path_to_path( + GTK_TREE_MODEL_FILTER(filter_model), path); + + if (filter_path) + { + gtk_tree_view_expand_to_path(GTK_TREE_VIEW(tv.tree_openfiles), filter_path); + gtk_tree_view_set_cursor(GTK_TREE_VIEW(tv.tree_openfiles), filter_path, NULL, FALSE); + gtk_tree_path_free(filter_path); + return TRUE; + } }
return FALSE; @@ -1477,14 +1526,21 @@ static gboolean sidebar_button_press_cb(GtkWidget *widget, GdkEventButton *event { if (gtk_tree_model_iter_has_child(model, &iter)) { + GtkTreeModel *filter_model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); GtkTreePath *path = gtk_tree_model_get_path(model, &iter); + GtkTreePath *filter_path = gtk_tree_model_filter_convert_child_path_to_path( + GTK_TREE_MODEL_FILTER(filter_model), path);
- if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget), path)) - gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget), path); - else - gtk_tree_view_expand_row(GTK_TREE_VIEW(widget), path, FALSE); + if (filter_path) + { + if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget), filter_path)) + gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget), filter_path); + else + gtk_tree_view_expand_row(GTK_TREE_VIEW(widget), filter_path, FALSE); + }
gtk_tree_path_free(path); + gtk_tree_path_free(filter_path); return TRUE; } }
Modified: src/sidebar.h 2 lines changed, 2 insertions(+), 0 deletions(-) =================================================================== @@ -67,6 +67,8 @@ enum DOCUMENTS_COLOR, DOCUMENTS_FILENAME, /* full filename */ DOCUMENTS_FOLD, /* fold state stored when folding parent rows */ + DOCUMENTS_VISIBLE, + DOCUMENTS_COLUMNS_NUM };
void sidebar_init(void);
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).