From a05ed46bc230735bd22b337eb1db6cd6d34f3431 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Thu, 10 May 2007 13:52:01 +0100 Subject: Use GtkTreeModelSort to sort the search hits Like for OPERATION_MODE_RECENT, use a tree model sort to allow sorting the file list view in search mode. Signed-off-by: Emmanuele Bassi --- gtk/gtkfilechooserdefault.c | 104 +++++++++++++++++++++++++++++------------- gtk/gtkfilechooserprivate.h | 1 + 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c index 68455ce..0ad4b6c 100644 --- a/gtk/gtkfilechooserdefault.c +++ b/gtk/gtkfilechooserdefault.c @@ -481,6 +481,9 @@ static void search_switch_to_browse_mode (GtkFileChooserDefault *impl); static GSList *search_get_selected_paths (GtkFileChooserDefault *impl); static void search_entry_activate_cb (GtkEntry *entry, gpointer data); +static void search_get_valid_child_iter (GtkFileChooserDefault *impl, + GtkTreeIter *child_iter, + GtkTreeIter *iter); static void recent_manager_update (GtkFileChooserDefault *impl); static void recent_stop_loading (GtkFileChooserDefault *impl); @@ -2649,8 +2652,7 @@ add_bookmark_foreach_cb (GtkTreeModel *model, break; case OPERATION_MODE_SEARCH: - gtk_tree_model_filter_convert_iter_to_child_iter (impl->search_model_filter, - &child_iter, iter); + search_get_valid_child_iter (impl, &child_iter, iter); gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter, SEARCH_MODEL_COL_PATH, &file_path, -1); @@ -2784,7 +2786,7 @@ selection_check_foreach_cb (GtkTreeModel *model, break; case OPERATION_MODE_SEARCH: - gtk_tree_model_filter_convert_iter_to_child_iter (closure->impl->search_model_filter, &child_iter, iter); + search_get_valid_child_iter (closure->impl, &child_iter, iter); gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->search_model), &child_iter, SEARCH_MODEL_COL_IS_FOLDER, &is_folder, -1); @@ -2858,7 +2860,7 @@ get_selected_path_foreach_cb (GtkTreeModel *model, break; case OPERATION_MODE_SEARCH: - gtk_tree_model_filter_convert_iter_to_child_iter (closure->impl->search_model_filter, &child_iter, iter); + search_get_valid_child_iter (closure->impl, &child_iter, iter); gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->search_model), &child_iter, SEARCH_MODEL_COL_PATH, &closure->path, -1); @@ -2921,7 +2923,7 @@ update_tooltip (GtkTreeModel *model, break; case OPERATION_MODE_SEARCH: - gtk_tree_model_filter_convert_iter_to_child_iter (udata->impl->search_model_filter, &child_iter, iter); + search_get_valid_child_iter (udata->impl, &child_iter, iter); gtk_tree_model_get (GTK_TREE_MODEL (udata->impl->search_model), &child_iter, SEARCH_MODEL_COL_DISPLAY_NAME, &display_name, -1); @@ -6685,9 +6687,7 @@ update_chooser_entry (GtkFileChooserDefault *impl) } else if (impl->operation_mode == OPERATION_MODE_SEARCH) { - gtk_tree_model_filter_convert_iter_to_child_iter (impl->search_model_filter, - &child_iter, - &closure.first_selected_iter); + search_get_valid_child_iter (impl, &child_iter, &closure.first_selected_iter); gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter, SEARCH_MODEL_COL_DISPLAY_NAME, &file_part, -1); @@ -8830,6 +8830,9 @@ search_clear_model (GtkFileChooserDefault *impl, g_object_unref (impl->search_model_filter); impl->search_model_filter = NULL; + + g_object_unref (impl->search_model_sort); + impl->search_model_sort = NULL; if (remove_from_treeview) gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL); @@ -8902,6 +8905,12 @@ search_column_path_sort_func (GtkTreeModel *model, SEARCH_MODEL_COL_COLLATION_KEY, &collation_key_b, -1); + if (!collation_key_a) + return 1; + + if (!collation_key_b) + return -1; + /* always show folders first */ if (is_folder_a != is_folder_b) return is_folder_a ? 1 : -1; @@ -8933,6 +8942,12 @@ search_column_mtime_sort_func (GtkTreeModel *model, SEARCH_MODEL_COL_IS_FOLDER, &is_folder_b, SEARCH_MODEL_COL_STAT, &statbuf_b, -1); + + if (!statbuf_a) + return 1; + + if (!statbuf_b) + return -1; if (is_folder_a != is_folder_b) return is_folder_a ? 1 : -1; @@ -9029,6 +9044,7 @@ search_setup_model (GtkFileChooserDefault *impl) { g_assert (impl->search_model == NULL); g_assert (impl->search_model_filter == NULL); + g_assert (impl->search_model_sort == NULL); /* We store these columns in the search model: * @@ -9056,33 +9072,57 @@ search_setup_model (GtkFileChooserDefault *impl) GDK_TYPE_PIXBUF, G_TYPE_POINTER, G_TYPE_BOOLEAN); - gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->search_model), + + impl->search_model_filter = + GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->search_model), NULL)); + gtk_tree_model_filter_set_visible_func (impl->search_model_filter, + search_model_visible_func, + impl, NULL); + + impl->search_model_sort = + GTK_TREE_MODEL_SORT (gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (impl->search_model_filter))); + gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->search_model_sort), SEARCH_MODEL_COL_PATH, search_column_path_sort_func, impl, NULL); - gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->search_model), + gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->search_model_sort), SEARCH_MODEL_COL_STAT, search_column_mtime_sort_func, impl, NULL); - - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->search_model), + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->search_model_sort), SEARCH_MODEL_COL_STAT, GTK_SORT_DESCENDING); - - impl->search_model_filter = - GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->search_model), NULL)); - gtk_tree_model_filter_set_visible_func (impl->search_model_filter, - search_model_visible_func, - impl, NULL); /* EB: setting the model here will make the hits list update feel * more "alive" than setting the model at the end of the search * run */ gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), - GTK_TREE_MODEL (impl->search_model_filter)); + GTK_TREE_MODEL (impl->search_model_sort)); +} + +static void +search_get_valid_child_iter (GtkFileChooserDefault *impl, + GtkTreeIter *child_iter, + GtkTreeIter *iter) +{ + GtkTreeIter middle; + + if (!impl->search_model) + return; + + if (!impl->search_model_filter || !impl->search_model_sort) + return; + + /* pass 1: get the iterator in the filter model */ + gtk_tree_model_sort_convert_iter_to_child_iter (impl->search_model_sort, + &middle, iter); + + /* pass 2: get the iterator in the real model */ + gtk_tree_model_filter_convert_iter_to_child_iter (impl->search_model_filter, + child_iter, &middle); } /* Creates a new query with the specified text and launches it */ @@ -9947,13 +9987,12 @@ check_preview_change (GtkFileChooserDefault *impl) { GtkTreeIter iter; - gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_filter), + gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, cursor_path); gtk_tree_path_free (cursor_path); - gtk_tree_model_filter_convert_iter_to_child_iter (impl->search_model_filter, - &child_iter, &iter); - gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter, + search_get_valid_child_iter (impl, &child_iter, &iter); + gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter, SEARCH_MODEL_COL_PATH, &new_path, SEARCH_MODEL_COL_DISPLAY_NAME, &new_display_name, -1); @@ -10340,11 +10379,10 @@ list_row_activated (GtkTreeView *tree_view, GtkFilePath *file_path; gboolean is_folder; - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_filter), &iter, path)) + if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, path)) return; - gtk_tree_model_filter_convert_iter_to_child_iter (impl->search_model_filter, - &child_iter, &iter); + search_get_valid_child_iter (impl, &child_iter, &iter); gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter, SEARCH_MODEL_COL_PATH, &file_path, SEARCH_MODEL_COL_IS_FOLDER, &is_folder, @@ -10467,8 +10505,7 @@ list_icon_data_func (GtkTreeViewColumn *tree_column, { GtkTreeIter child_iter; - gtk_tree_model_filter_convert_iter_to_child_iter (impl->search_model_filter, - &child_iter, iter); + search_get_valid_child_iter (impl, &child_iter, iter); gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter, SEARCH_MODEL_COL_PIXBUF, &pixbuf, -1); @@ -10556,7 +10593,7 @@ list_name_data_func (GtkTreeViewColumn *tree_column, gchar *display_name, *tmp; gchar *text; - gtk_tree_model_filter_convert_iter_to_child_iter (impl->search_model_filter, &child_iter, iter); + search_get_valid_child_iter (impl, &child_iter, iter); gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter, SEARCH_MODEL_COL_PATH, &file_path, SEARCH_MODEL_COL_DISPLAY_NAME, &display_name, @@ -10703,11 +10740,14 @@ list_mtime_data_func (GtkTreeViewColumn *tree_column, GtkTreeIter child_iter; struct stat *statbuf; - gtk_tree_model_filter_convert_iter_to_child_iter (impl->search_model_filter, &child_iter, iter); + search_get_valid_child_iter (impl, &child_iter, iter); gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter, - SEARCH_MODEL_COL_STAT, &statbuf, + SEARCH_MODEL_COL_STAT, &statbuf, -1); - time_mtime = statbuf->st_mtime; + if (statbuf) + time_mtime = statbuf->st_mtime; + else + time_mtime = 0; } else if (impl->operation_mode == OPERATION_MODE_RECENT) { diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h index 16abb5c..32d1536 100644 --- a/gtk/gtkfilechooserprivate.h +++ b/gtk/gtkfilechooserprivate.h @@ -197,6 +197,7 @@ struct _GtkFileChooserDefault GtkQuery *search_query; GtkListStore *search_model; GtkTreeModelFilter *search_model_filter; + GtkTreeModelSort *search_model_sort; /* OPERATION_MODE_RECENT */ GtkRecentManager *recent_manager; -- 1.4.4.2