From 73a98b86fd3f662ba1d56febd36f3c6784f2955e Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Sat, 29 Jun 2013 18:15:48 +0200 Subject: [PATCH] Split tree model creation from preparing the widget (#39). --- src/completion.c | 100 ++++++++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 45 deletions(-) diff --git a/src/completion.c b/src/completion.c index 501a1e3..18cd73f 100644 --- a/src/completion.c +++ b/src/completion.c @@ -39,7 +39,8 @@ static struct { char *text; /* text of the current active tree item */ } comp; -static gboolean init_completion(GList *source); +static GtkTreeModel *get_tree_model(GList *source); +static void init_completion(GtkTreeModel *model); static void show(gboolean back); static void move_cursor(gboolean back); static gboolean tree_selection_func(GtkTreeSelection *selection, @@ -50,7 +51,7 @@ gboolean completion_complete(gboolean back) VbInputType type; const char *input, *prefix, *suffix; GList *source = NULL; - gboolean hasItems = false; + GtkTreeModel *model = NULL; input = GET_TEXT(); type = vb_get_input_parts(input, &prefix, &suffix); @@ -74,17 +75,22 @@ gboolean completion_complete(gboolean back) if (type == VB_INPUT_SET) { source = g_list_sort(setting_get_by_prefix(suffix), (GCompareFunc)g_strcmp0); - hasItems = init_completion(source); + if (!g_list_first(source)) { + return false; + } + model = get_tree_model(source); g_list_free(source); } else if (type == VB_INPUT_OPEN || type == VB_INPUT_TABOPEN) { /* if search string begins with TAG_INDICATOR lookup the bookmarks */ if (suffix && *suffix == TAG_INDICATOR) { source = bookmark_get_by_tags(suffix + 1); - hasItems = init_completion(source); } else { source = history_get_by_tags(HISTORY_URL, suffix); - hasItems = init_completion(source); } + if (!g_list_first(source)) { + return false; + } + model = get_tree_model(source); g_list_free_full(source, (GDestroyNotify)g_free); } else if (type == VB_INPUT_COMMAND) { char *command = NULL; @@ -92,21 +98,24 @@ gboolean completion_complete(gboolean back) comp.count = g_ascii_strtoll(suffix, &command, 10); source = g_list_sort(command_get_by_prefix(command), (GCompareFunc)g_strcmp0); - hasItems = init_completion(source); + if (!g_list_first(source)) { + return false; + } + model = get_tree_model(source); g_list_free(source); } else if (type == VB_INPUT_SEARCH_FORWARD || type == VB_INPUT_SEARCH_BACKWARD) { source = g_list_sort(history_get_by_tags(HISTORY_SEARCH, suffix), (GCompareFunc)g_strcmp0); - hasItems = init_completion(source); + if (!g_list_first(source)) { + return false; + } + model = get_tree_model(source); g_list_free_full(source, (GDestroyNotify)g_free); } - if (!hasItems) { - return false; - } - vb_set_mode(VB_MODE_COMMAND | VB_MODE_COMPLETE, false); OVERWRITE_STRING(comp.prefix, prefix); + init_completion(model); show(back); return true; @@ -126,19 +135,28 @@ void completion_clean(void) vb.state.mode &= ~VB_MODE_COMPLETE; } -static gboolean init_completion(GList *source) +static GtkTreeModel *get_tree_model(GList *source) +{ + GtkTreeIter iter; + GtkListStore *store = gtk_list_store_new(1, G_TYPE_STRING); + + for (GList *l = source; l; l = l->next) { + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, COMP_ITEM, l->data, -1); + } + return GTK_TREE_MODEL(store); +} + +static void init_completion(GtkTreeModel *model) { - GtkListStore *store; GtkCellRenderer *renderer; GtkTreeSelection *selection; - GtkTreeIter iter; GtkRequisition size; - gboolean hasItems = (source != NULL); int height; - /* init the tree view and the list store */ + /* prepare the tree view */ + comp.win = gtk_scrolled_window_new(NULL, NULL); comp.tree = gtk_tree_view_new(); - comp.win = gtk_scrolled_window_new(NULL, NULL); #ifndef HAS_GTK3 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(comp.win), GTK_POLICY_NEVER, GTK_POLICY_NEVER); #endif @@ -146,58 +164,50 @@ static gboolean init_completion(GList *source) gtk_container_add(GTK_CONTAINER(comp.win), comp.tree); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(comp.tree), false); + /* we have only on line per item so we can use the faster fixed heigh mode */ gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(comp.tree), true); + gtk_tree_view_set_model(GTK_TREE_VIEW(comp.tree), model); + g_object_unref(model); + + VB_WIDGET_OVERRIDE_TEXT(comp.tree, VB_GTK_STATE_NORMAL, &vb.style.comp_fg[VB_COMP_NORMAL]); + VB_WIDGET_OVERRIDE_BASE(comp.tree, VB_GTK_STATE_NORMAL, &vb.style.comp_bg[VB_COMP_NORMAL]); + VB_WIDGET_OVERRIDE_TEXT(comp.tree, VB_GTK_STATE_SELECTED, &vb.style.comp_fg[VB_COMP_ACTIVE]); + VB_WIDGET_OVERRIDE_BASE(comp.tree, VB_GTK_STATE_SELECTED, &vb.style.comp_bg[VB_COMP_ACTIVE]); + /* prepare the selection */ + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(comp.tree)); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); + gtk_tree_selection_set_select_function(selection, tree_selection_func, NULL, NULL); + + /* prepare the column renderer */ renderer = gtk_cell_renderer_text_new(); g_object_set(renderer, "font-desc", vb.style.comp_font, "ellipsize", PANGO_ELLIPSIZE_MIDDLE, NULL ); - - selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(comp.tree)); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); - gtk_tree_selection_set_select_function(selection, tree_selection_func, NULL, NULL); - - VB_WIDGET_OVERRIDE_TEXT(comp.tree, VB_GTK_STATE_NORMAL, &vb.style.comp_fg[VB_COMP_NORMAL]); - VB_WIDGET_OVERRIDE_BASE(comp.tree, VB_GTK_STATE_NORMAL, &vb.style.comp_bg[VB_COMP_NORMAL]); - VB_WIDGET_OVERRIDE_TEXT(comp.tree, VB_GTK_STATE_SELECTED, &vb.style.comp_fg[VB_COMP_ACTIVE]); - VB_WIDGET_OVERRIDE_BASE(comp.tree, VB_GTK_STATE_SELECTED, &vb.style.comp_bg[VB_COMP_ACTIVE]); - gtk_tree_view_insert_column_with_attributes( GTK_TREE_VIEW(comp.tree), -1, "", renderer, "text", COMP_ITEM, NULL ); - store = gtk_list_store_new(1, G_TYPE_STRING); - - for (GList *l = source; l; l = l->next) { - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, COMP_ITEM, l->data, -1); - } - - /* add the model after inserting the items - that's faster */ - gtk_tree_view_set_model(GTK_TREE_VIEW(comp.tree), GTK_TREE_MODEL(store)); - g_object_unref(store); - /* use max 1/3 of window height for the completion */ #ifdef HAS_GTK3 gtk_widget_get_preferred_size(comp.tree, NULL, &size); -#else - gtk_widget_size_request(comp.tree, &size); -#endif gtk_window_get_size(GTK_WINDOW(vb.gui.window), NULL, &height); height /= 3; if (size.height > height) { -#ifdef HAS_GTK3 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(comp.win), height); + } #else + gtk_widget_size_request(comp.tree, &size); + gtk_window_get_size(GTK_WINDOW(vb.gui.window), NULL, &height); + height /= 3; + if (size.height > height) { gtk_widget_set_size_request(comp.win, -1, height); -#endif } - - return hasItems; +#endif } static void show(gboolean back) -- 2.20.1