From 54a2785f0e25f2861d7f2b9720306a8e78733f46 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 9 May 2007 20:31:31 +0100 Subject: Support GtkFileChooser filter in recent files mode Add a GtkTreeModelFilter object and use it to display the filtered recent files list in OPERATION_MODE_RECENT. The filter function is basically a copy of get_is_file_filtered(), oly using GtkRecentInfo to retrieve the MIME type and the display name of the recent file. Signed-off-by: Emmanuele Bassi --- gtk/gtkfilechooserdefault.c | 153 ++++++++++++++++++++++++++++++++++++++----- gtk/gtkfilechooserprivate.h | 5 +- 2 files changed, 138 insertions(+), 20 deletions(-) diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c index 31f7746..f3ab294 100644 --- a/gtk/gtkfilechooserdefault.c +++ b/gtk/gtkfilechooserdefault.c @@ -2651,7 +2651,9 @@ add_bookmark_foreach_cb (GtkTreeModel *model, break; case OPERATION_MODE_RECENT: - gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), iter, + gtk_tree_model_filter_convert_iter_to_child_iter (impl->recent_model_filter, + &child_iter, iter); + gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter, RECENT_MODEL_COL_PATH, &file_path, -1); break; @@ -2783,7 +2785,8 @@ selection_check_foreach_cb (GtkTreeModel *model, break; case OPERATION_MODE_RECENT: - gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->recent_model), iter, + gtk_tree_model_filter_convert_iter_to_child_iter (closure->impl->recent_model_filter, &child_iter, iter); + gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->recent_model), &child_iter, RECENT_MODEL_COL_IS_FOLDER, &is_folder, -1); break; @@ -2855,7 +2858,8 @@ get_selected_path_foreach_cb (GtkTreeModel *model, break; case OPERATION_MODE_RECENT: - gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->recent_model), iter, + gtk_tree_model_filter_convert_iter_to_child_iter (closure->impl->recent_model_filter, &child_iter, iter); + gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->recent_model), &child_iter, RECENT_MODEL_COL_PATH, &closure->path, -1); break; @@ -2916,7 +2920,8 @@ update_tooltip (GtkTreeModel *model, break; case OPERATION_MODE_RECENT: - gtk_tree_model_get (GTK_TREE_MODEL (udata->impl->recent_model), iter, + gtk_tree_model_filter_convert_iter_to_child_iter (udata->impl->recent_model_filter, &child_iter, iter); + gtk_tree_model_get (GTK_TREE_MODEL (udata->impl->recent_model), &child_iter, RECENT_MODEL_COL_DISPLAY_NAME, &display_name, -1); break; @@ -6636,9 +6641,10 @@ update_chooser_entry (GtkFileChooserDefault *impl) } else if (closure.num_selected == 1) { + GtkTreeIter child_iter; + if (impl->operation_mode == OPERATION_MODE_BROWSE) { - GtkTreeIter child_iter; const GtkFileInfo *info; gboolean change_entry; @@ -6678,8 +6684,10 @@ update_chooser_entry (GtkFileChooserDefault *impl) } else if (impl->operation_mode == OPERATION_MODE_RECENT) { - gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), - &closure.first_selected_iter, + gtk_tree_model_filter_convert_iter_to_child_iter (impl->recent_model_filter, + &child_iter, + &closure.first_selected_iter); + gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter, RECENT_MODEL_COL_DISPLAY_NAME, &file_part, -1); } @@ -9173,6 +9181,9 @@ recent_clear_model (GtkFileChooserDefault *impl, g_object_unref (impl->recent_model); impl->recent_model = NULL; + g_object_unref (impl->recent_model_filter); + impl->recent_model_filter = NULL; + if (remove_from_treeview) gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL); } @@ -9227,8 +9238,12 @@ recent_column_mtime_sort_func (GtkTreeModel *model, { GtkRecentInfo *info_a, *info_b; - gtk_tree_model_get (model, a, RECENT_MODEL_COL_INFO, &info_a, -1); - gtk_tree_model_get (model, b, RECENT_MODEL_COL_INFO, &info_b, -1); + gtk_tree_model_get (model, a, + RECENT_MODEL_COL_INFO, &info_a, + -1); + gtk_tree_model_get (model, b, + RECENT_MODEL_COL_INFO, &info_b, + -1); if (gtk_recent_info_get_modified (info_a) < gtk_recent_info_get_modified (info_b)) return -1; @@ -9238,11 +9253,86 @@ recent_column_mtime_sort_func (GtkTreeModel *model, return 0; } +static gboolean +recent_get_is_filtered (GtkFileChooserDefault *impl, + const GtkFilePath *path, + GtkRecentInfo *recent_info) +{ + GtkFileFilterInfo filter_info; + GtkFileFilterFlags needed; + gboolean result; + + if (!impl->current_filter) + return FALSE; + + filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE; + needed = gtk_file_filter_get_needed (impl->current_filter); + + filter_info.display_name = gtk_recent_info_get_display_name (recent_info); + filter_info.mime_type = gtk_recent_info_get_mime_type (recent_info); + + if (needed & GTK_FILE_FILTER_FILENAME) + { + filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path); + if (filter_info.filename) + filter_info.contains |= GTK_FILE_FILTER_FILENAME; + } + else + filter_info.filename = NULL; + + if (needed & GTK_FILE_FILTER_URI) + { + filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path); + if (filter_info.uri) + filter_info.contains |= GTK_FILE_FILTER_URI; + } + else + filter_info.uri = NULL; + + result = gtk_file_filter_filter (impl->current_filter, &filter_info); + + if (filter_info.filename) + g_free ((gchar *) filter_info.filename); + if (filter_info.uri) + g_free ((gchar *) filter_info.uri); + + return !result; +} + +/* Visibility function for the recent filter model */ +static gboolean +recent_model_visible_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer user_data) +{ + GtkFileChooserDefault *impl = user_data; + GtkFilePath *file_path; + GtkRecentInfo *recent_info; + gboolean is_folder; + + if (!impl->current_filter) + return TRUE; + + gtk_tree_model_get (model, iter, + RECENT_MODEL_COL_INFO, &recent_info, + RECENT_MODEL_COL_PATH, &file_path, + RECENT_MODEL_COL_IS_FOLDER, &is_folder, + -1); + + if (!recent_info) + return TRUE; + + if (is_folder) + return TRUE; + + return !recent_get_is_filtered (impl, file_path, recent_info); +} static void recent_setup_model (GtkFileChooserDefault *impl) { g_assert (impl->recent_model == NULL); + g_assert (impl->recent_model_filter == NULL); /* We store these columns in the search model: * @@ -9271,10 +9361,16 @@ recent_setup_model (GtkFileChooserDefault *impl) recent_column_mtime_sort_func, impl, NULL); - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->recent_model), RECENT_MODEL_COL_INFO, GTK_SORT_DESCENDING); + + impl->recent_model_filter = + GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->recent_model), NULL)); + gtk_tree_model_filter_set_visible_func (impl->recent_model_filter, + recent_model_visible_func, + impl, + NULL); } typedef struct @@ -9292,7 +9388,7 @@ recent_idle_cleanup (gpointer data) GtkFileChooserDefault *impl = load_data->impl; gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), - GTK_TREE_MODEL (impl->recent_model)); + GTK_TREE_MODEL (impl->recent_model_filter)); set_busy_cursor (impl, FALSE); @@ -9602,6 +9698,9 @@ set_current_filter (GtkFileChooserDefault *impl, if (impl->browse_files_model) install_list_model_filter (impl); + if (impl->recent_model_filter) + gtk_tree_model_filter_refilter (impl->recent_model_filter); + g_object_notify (G_OBJECT (impl), "filter"); } } @@ -9662,11 +9761,16 @@ check_preview_change (GtkFileChooserDefault *impl) else if (impl->operation_mode == OPERATION_MODE_RECENT) { GtkTreeIter iter; + GtkTreeIter child_iter; - gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model), &iter, cursor_path); + gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model_filter), + &iter, cursor_path); gtk_tree_path_free (cursor_path); - gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &iter, + gtk_tree_model_filter_convert_iter_to_child_iter (impl->recent_model_filter, + &child_iter, &iter); + + gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter, RECENT_MODEL_COL_PATH, &new_path, RECENT_MODEL_COL_DISPLAY_NAME, &new_display_name, -1); @@ -10058,13 +10162,17 @@ list_row_activated (GtkTreeView *tree_view, case OPERATION_MODE_RECENT: { + GtkTreeIter child_iter; GtkFilePath *file_path; gboolean is_folder; - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model), &iter, path)) + if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model_filter), &iter, path)) return; + + gtk_tree_model_filter_convert_iter_to_child_iter (impl->recent_model_filter, + &child_iter, &iter); - gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &iter, + gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter, RECENT_MODEL_COL_PATH, &file_path, RECENT_MODEL_COL_IS_FOLDER, &is_folder, -1); @@ -10168,9 +10276,13 @@ list_icon_data_func (GtkTreeViewColumn *tree_column, case OPERATION_MODE_RECENT: { + GtkTreeIter child_iter; GtkRecentInfo *info; - gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), iter, + gtk_tree_model_filter_convert_iter_to_child_iter (impl->recent_model_filter, + &child_iter, iter); + + gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter, RECENT_MODEL_COL_INFO, &info, -1); @@ -10265,10 +10377,13 @@ list_name_data_func (GtkTreeViewColumn *tree_column, if (impl->operation_mode == OPERATION_MODE_RECENT) { + GtkTreeIter child_iter; GtkRecentInfo *recent_info; char *tmp, *text; - gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), iter, + gtk_tree_model_filter_convert_iter_to_child_iter (impl->recent_model_filter, &child_iter, iter); + + gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter, RECENT_MODEL_COL_INFO, &recent_info, -1); @@ -10393,9 +10508,11 @@ list_mtime_data_func (GtkTreeViewColumn *tree_column, } else if (impl->operation_mode == OPERATION_MODE_RECENT) { + GtkTreeIter child_iter; GtkRecentInfo *info; - gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), iter, + gtk_tree_model_filter_convert_iter_to_child_iter (impl->recent_model_filter, &child_iter, iter); + gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter, RECENT_MODEL_COL_INFO, &info, -1); time_mtime = (GtkFileTime) gtk_recent_info_get_modified (info); diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h index 1750627..f7820aa 100644 --- a/gtk/gtkfilechooserprivate.h +++ b/gtk/gtkfilechooserprivate.h @@ -190,17 +190,18 @@ struct _GtkFileChooserDefault GtkFileSystemModel *browse_files_model; char *browse_files_last_selected_name; - /* Search */ + /* OPERATION_MODE_SEARCH */ GtkWidget *search_hbox; GtkWidget *search_entry; GtkSearchEngine *search_engine; GtkQuery *search_query; GtkListStore *search_model; - /* Recently Used */ + /* OPERATION_MODE_RECENT */ GtkRecentManager *recent_manager; GtkListStore *recent_model; guint load_recent_id; + GtkTreeModelFilter *recent_model_filter; GtkWidget *filter_combo_hbox; GtkWidget *filter_combo; -- 1.4.4.2