[gtk/gbsneto/filechooser-column-view: 60/82] filechooserwidget: Use GtkSelectionModel for selection
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gbsneto/filechooser-column-view: 60/82] filechooserwidget: Use GtkSelectionModel for selection
- Date: Tue, 11 Oct 2022 22:04:06 +0000 (UTC)
commit 0c20f868afb06ace7b96820df1c79087b1103d9b
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Sat Oct 8 20:12:20 2022 -0300
filechooserwidget: Use GtkSelectionModel for selection
So far, GtkFileChooserWidget has relied on GtkTreeView's selection
management. This commit moves it away from GtkTreeView, and that's
a massive surgery - sorry :(
The most important aspect of this commit is that 'selection_model'
is now the main model we deal with. Changing between directories,
recent files, and search, all sets the selection_model's model.
Selections are entirely handled by GtkSelectionModel now.
gtk/gtkfilechooserwidget.c | 966 +++++++++++++++++------------------------
gtk/ui/gtkfilechooserwidget.ui | 5 -
2 files changed, 399 insertions(+), 572 deletions(-)
---
diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c
index 36cfb0287d..f1e7b0538d 100644
--- a/gtk/gtkfilechooserwidget.c
+++ b/gtk/gtkfilechooserwidget.c
@@ -22,6 +22,7 @@
#include "gtkfilechooserwidget.h"
#include "gtkfilechooserwidgetprivate.h"
+#include "gtkbitset.h"
#include "gtkbookmarksmanagerprivate.h"
#include "gtkbutton.h"
#include "deprecated/gtkcellrendererpixbuf.h"
@@ -188,6 +189,12 @@ struct _GtkFileChooserWidget
GtkWidget *save_widgets;
GtkWidget *save_widgets_table;
+ /* This is the model that the column view always show. Changing
+ * between browsing, search, and recent, sets the model of the
+ * selection model.
+ */
+ GtkSelectionModel *selection_model;
+
/* The file browsing widgets */
GtkWidget *browse_widgets_hpaned;
GtkWidget *browse_header_revealer;
@@ -216,8 +223,6 @@ struct _GtkFileChooserWidget
GtkFileSystemModel *browse_files_model;
char *browse_files_last_selected_name;
- GtkSelectionModel *browse_files_selection_model;
-
GtkWidget *places_sidebar;
GtkWidget *places_view;
StartupMode startup_mode;
@@ -466,15 +471,10 @@ static void set_current_filter (GtkFileChooserWidget *impl,
static void filter_combo_changed (GtkDropDown *dropdown,
GParamSpec *pspec,
GtkFileChooserWidget *impl);
-
-static gboolean list_select_func (GtkTreeSelection *selection,
- GtkTreeModel *model,
- GtkTreePath *path,
- gboolean path_currently_selected,
- gpointer data);
-
-static void list_selection_changed (GtkTreeSelection *tree_selection,
- GtkFileChooserWidget *impl);
+static void list_selection_changed (GtkSelectionModel *selection_model,
+ guint position,
+ guint n_items,
+ GtkFileChooserWidget *impl);
static void path_bar_clicked (GtkPathBar *path_bar,
GFile *file,
GFile *child,
@@ -507,7 +507,6 @@ static gboolean recent_files_setting_is_enabled (GtkFileChooserWidget *impl);
static void recent_start_loading (GtkFileChooserWidget *impl);
static void recent_clear_model (GtkFileChooserWidget *impl,
gboolean remove_from_treeview);
-static gboolean recent_should_respond (GtkFileChooserWidget *impl);
static void set_model_filter (GtkFileChooserWidget *impl,
GtkFileFilter *filter);
static void switch_to_home_dir (GtkFileChooserWidget *impl);
@@ -608,6 +607,33 @@ get_toplevel (GtkWidget *widget)
return NULL;
}
+static GListModel *
+get_current_model (GtkFileChooserWidget *self)
+{
+ g_assert (self->selection_model != NULL);
+ g_assert (GTK_IS_MULTI_SELECTION (self->selection_model) ||
+ GTK_IS_SINGLE_SELECTION (self->selection_model));
+
+ if (GTK_IS_MULTI_SELECTION (self->selection_model))
+ return gtk_multi_selection_get_model (GTK_MULTI_SELECTION (self->selection_model));
+ else
+ return gtk_single_selection_get_model (GTK_SINGLE_SELECTION (self->selection_model));
+}
+
+static void
+set_current_model (GtkFileChooserWidget *self,
+ GListModel *model)
+{
+ g_assert (self->selection_model != NULL);
+ g_assert (GTK_IS_MULTI_SELECTION (self->selection_model) ||
+ GTK_IS_SINGLE_SELECTION (self->selection_model));
+
+ if (GTK_IS_MULTI_SELECTION (self->selection_model))
+ gtk_multi_selection_set_model (GTK_MULTI_SELECTION (self->selection_model), model);
+ else
+ gtk_single_selection_set_model (GTK_SINGLE_SELECTION (self->selection_model), model);
+}
+
/* Extracts the parent folders out of the supplied list of GtkRecentInfo* items, and returns
* a list of GFile* for those unique parents.
*/
@@ -973,71 +999,54 @@ new_folder_create_clicked (GtkButton *button,
error_creating_folder_dialog (impl, file, error);
}
-struct selection_check_closure {
- GtkFileChooserWidget *impl;
- int num_selected;
- gboolean all_files;
- gboolean all_folders;
-};
-
-/* Used from gtk_tree_selection_selected_foreach() */
+/* Checks whether the selected items in the file list are all files or all folders */
static void
-selection_check_foreach_cb (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
+selection_check (GtkFileChooserWidget *impl,
+ int *out_num_selected,
+ gboolean *out_all_files,
+ gboolean *out_all_folders)
{
- struct selection_check_closure *closure;
- gboolean is_folder;
- GFile *file;
-
- gtk_tree_model_get (model, iter,
- MODEL_COL_FILE, &file,
- MODEL_COL_IS_FOLDER, &is_folder,
- -1);
-
- if (file == NULL)
- return;
-
- g_object_unref (file);
+ GtkBitsetIter iter;
+ GtkBitset *bitset;
+ gboolean all_folders;
+ gboolean all_files;
+ guint i;
+ int n_selected;
- closure = data;
- closure->num_selected++;
+ all_folders = TRUE;
+ all_files = TRUE;
+ n_selected = 0;
+ bitset = gtk_selection_model_get_selection (impl->selection_model);
- closure->all_folders = closure->all_folders && is_folder;
- closure->all_files = closure->all_files && !is_folder;
-}
+ for (gtk_bitset_iter_init_first (&iter, bitset, &i);
+ gtk_bitset_iter_is_valid (&iter);
+ gtk_bitset_iter_next (&iter, &i))
+ {
+ GtkFileSystemItem *item;
+ GFileInfo *info;
+ gboolean is_folder;
-/* Checks whether the selected items in the file list are all files or all folders */
-static void
-selection_check (GtkFileChooserWidget *impl,
- int *num_selected,
- gboolean *all_files,
- gboolean *all_folders)
-{
- struct selection_check_closure closure;
- GtkTreeSelection *selection;
+ item = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), i);
+ info = _gtk_file_system_item_get_file_info (item);
+ is_folder = _gtk_file_info_consider_as_directory (info);
- closure.impl = impl;
- closure.num_selected = 0;
- closure.all_files = TRUE;
- closure.all_folders = TRUE;
+ all_folders &= is_folder;
+ all_files &= !is_folder;
+ n_selected++;
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- gtk_tree_selection_selected_foreach (selection,
- selection_check_foreach_cb,
- &closure);
+ g_clear_object (&item);
+ }
- g_assert (closure.num_selected == 0 || !(closure.all_files && closure.all_folders));
+ g_assert (n_selected == 0 || !(all_files && all_folders));
- if (num_selected)
- *num_selected = closure.num_selected;
+ if (out_num_selected)
+ *out_num_selected = n_selected;
- if (all_files)
- *all_files = closure.all_files;
+ if (out_all_files)
+ *out_all_files = all_files;
- if (all_folders)
- *all_folders = closure.all_folders;
+ if (out_all_folders)
+ *out_all_folders = all_folders;
}
static gboolean
@@ -1105,27 +1114,6 @@ trigger_location_entry (GtkWidget *widget,
return TRUE;
}
-/* Callback used from gtk_tree_selection_selected_foreach(); adds a bookmark for
- * each selected item in the file list.
- */
-static void
-add_bookmark_foreach_cb (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- GtkFileChooserWidget *impl = (GtkFileChooserWidget *) data;
- GFile *file;
-
- gtk_tree_model_get (model, iter,
- MODEL_COL_FILE, &file,
- -1);
-
- _gtk_bookmarks_manager_insert_bookmark (impl->bookmarks_manager, file, 0, NULL); /* NULL-GError */
-
- g_object_unref (file);
-}
-
/* Callback used when the "Add to Bookmarks" menu item is activated */
static void
add_to_shortcuts_cb (GSimpleAction *action,
@@ -1133,13 +1121,26 @@ add_to_shortcuts_cb (GSimpleAction *action,
gpointer data)
{
GtkFileChooserWidget *impl = data;
- GtkTreeSelection *selection;
+ GtkBitsetIter iter;
+ GtkBitset *bitset;
+ guint i;
+
+ bitset = gtk_selection_model_get_selection (impl->selection_model);
+
+ for (gtk_bitset_iter_init_first (&iter, bitset, &i);
+ gtk_bitset_iter_is_valid (&iter);
+ gtk_bitset_iter_next (&iter, &i))
+ {
+ GtkFileSystemItem *item;
+ GFile *file;
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
+ item = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), i);
+ file = _gtk_file_system_item_get_file (item);
- gtk_tree_selection_selected_foreach (selection,
- add_bookmark_foreach_cb,
- impl);
+ _gtk_bookmarks_manager_insert_bookmark (impl->bookmarks_manager, file, 0, NULL);
+
+ g_clear_object (&item);
+ }
}
typedef struct {
@@ -1207,50 +1208,35 @@ confirm_delete (GtkFileChooserWidget *impl,
data);
}
-static void
-delete_selected_cb (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- GtkFileChooserWidget *impl = data;
- GFile *file;
- GFileInfo *info;
-
- file = _gtk_file_system_model_get_file (GTK_FILE_SYSTEM_MODEL (model), iter);
- info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (model), iter);
-
- confirm_delete (impl, file, info);
-}
-
static void
delete_file_cb (GSimpleAction *action,
GVariant *parameter,
gpointer data)
{
GtkFileChooserWidget *impl = data;
- GtkTreeSelection *selection;
+ GtkBitsetIter iter;
+ GtkBitset *bitset;
+ guint i;
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- gtk_tree_selection_selected_foreach (selection, delete_selected_cb, impl);
-}
+ bitset = gtk_selection_model_get_selection (impl->selection_model);
-static void
-trash_selected_cb (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- GtkFileChooserWidget *impl = data;
- GFile *file;
- GError *error = NULL;
+ for (gtk_bitset_iter_init_first (&iter, bitset, &i);
+ gtk_bitset_iter_is_valid (&iter);
+ gtk_bitset_iter_next (&iter, &i))
+ {
+ GtkFileSystemItem *item;
+ GFileInfo *info;
+ GFile *file;
- file = _gtk_file_system_model_get_file (GTK_FILE_SYSTEM_MODEL (model), iter);
+ item = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), i);
+ file = _gtk_file_system_item_get_file (item);
+ info = _gtk_file_system_item_get_file_info (item);
- if (!g_file_trash (file, NULL, &error))
- error_trashing_file (impl, file, error);
-}
+ confirm_delete (impl, file, info);
+ g_clear_object (&item);
+ }
+}
static void
trash_file_cb (GSimpleAction *action,
@@ -1258,10 +1244,28 @@ trash_file_cb (GSimpleAction *action,
gpointer data)
{
GtkFileChooserWidget *impl = data;
- GtkTreeSelection *selection;
+ GtkBitsetIter iter;
+ GtkBitset *bitset;
+ guint i;
+
+ bitset = gtk_selection_model_get_selection (impl->selection_model);
+
+ for (gtk_bitset_iter_init_first (&iter, bitset, &i);
+ gtk_bitset_iter_is_valid (&iter);
+ gtk_bitset_iter_next (&iter, &i))
+ {
+ GtkFileSystemItem *item;
+ GError *error = NULL;
+ GFile *file;
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- gtk_tree_selection_selected_foreach (selection, trash_selected_cb, impl);
+ item = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), i);
+ file = _gtk_file_system_item_get_file (item);
+
+ if (!g_file_trash (file, NULL, &error))
+ error_trashing_file (impl, file, error);
+
+ g_clear_object (&item);
+ }
}
static void
@@ -1329,26 +1333,33 @@ rename_file_rename_clicked (GtkButton *button,
}
static void
-rename_selected_cb (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
+rename_file_cb (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
{
GtkFileChooserWidget *impl = data;
+ GtkFileSystemItem *item;
+ GtkBitsetIter iter;
GdkRectangle rect;
- char *filename;
+ GtkBitset *bitset;
+ GFile *file;
double x, y;
+ guint position;
+ char *filename;
- gtk_tree_model_get (model, iter,
- MODEL_COL_FILE, &impl->rename_file_source_file,
- -1);
+ bitset = gtk_selection_model_get_selection (impl->selection_model);
+ if (!gtk_bitset_iter_init_first (&iter, bitset, &position))
+ return;
+ /* insensitive until we change the name */
+ gtk_widget_set_sensitive (impl->rename_file_rename_button, FALSE);
+
+ item = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), position);
+ file = _gtk_file_system_item_get_file (item);
+ impl->rename_file_source_file = g_object_ref (file);
rect = (GdkRectangle) { 0, 0, 1, 1 };
- gtk_tree_view_convert_bin_window_to_widget_coords (GTK_TREE_VIEW (impl->browse_files_tree_view),
- rect.x, rect.y,
- &rect.x, &rect.y);
- gtk_widget_translate_coordinates (impl->browse_files_tree_view,
+ gtk_widget_translate_coordinates (impl->browse_files_column_view,
GTK_WIDGET (impl),
rect.x, rect.y,
&x, &y);
@@ -1364,21 +1375,6 @@ rename_selected_cb (GtkTreeModel *model,
gtk_widget_grab_focus (impl->rename_file_popover);
}
-static void
-rename_file_cb (GSimpleAction *action,
- GVariant *parameter,
- gpointer data)
-{
- GtkFileChooserWidget *impl = data;
- GtkTreeSelection *selection;
-
- /* insensitive until we change the name */
- gtk_widget_set_sensitive (impl->rename_file_rename_button, FALSE);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- gtk_tree_selection_selected_foreach (selection, rename_selected_cb, impl);
-}
-
/* Callback used when the "Copy file’s location" menu item is activated */
static void
copy_file_location_cb (GSimpleAction *action,
@@ -1747,10 +1743,6 @@ file_list_show_popover (GtkFileChooserWidget *impl,
double y)
{
GdkRectangle rect;
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GList *list;
- GtkTreePath *path;
graphene_rect_t bounds;
if (!gtk_widget_compute_bounds (impl->browse_files_tree_view,
@@ -1760,33 +1752,8 @@ file_list_show_popover (GtkFileChooserWidget *impl,
file_list_update_popover (impl);
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- list = gtk_tree_selection_get_selected_rows (selection, &model);
- if (list)
- {
- path = list->data;
- gtk_tree_view_get_cell_area (GTK_TREE_VIEW (impl->browse_files_tree_view), path, NULL, &rect);
- gtk_tree_view_convert_bin_window_to_widget_coords (GTK_TREE_VIEW (impl->browse_files_tree_view),
- rect.x, rect.y,
- &rect.x, &rect.y);
- gtk_widget_translate_coordinates (impl->browse_files_tree_view,
- GTK_WIDGET (impl),
- rect.x, rect.y,
- &x, &y);
-
- rect.x = CLAMP (x - 20, 0, bounds.size.width - 40);
- rect.y = y;
- rect.width = 40;
-
- g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
- }
- else
- {
- rect.x = x;
- rect.y = y;
- rect.width = 1;
- rect.height = 1;
- }
+ /* TODO: figure out popover position */
+ rect = (GdkRectangle) { 0, 0, 0, 0 };
gtk_popover_set_pointing_to (GTK_POPOVER (impl->browse_files_popover), &rect);
gtk_popover_popup (GTK_POPOVER (impl->browse_files_popover));
@@ -2062,7 +2029,6 @@ column_view_get_tooltip_text (GtkListItem *list_item)
if (impl->operation_mode == OPERATION_MODE_BROWSE)
return NULL;
- item = gtk_list_item_get_item (list_item);
file = _gtk_file_system_item_get_file (item);
return g_file_get_path (file);
@@ -2524,19 +2490,30 @@ static void
set_select_multiple (GtkFileChooserWidget *impl,
gboolean select_multiple)
{
+ GListModel *model = NULL;
+
if (select_multiple == impl->select_multiple)
return;
gtk_column_view_set_enable_rubberband (GTK_COLUMN_VIEW (impl->browse_files_column_view),
select_multiple);
- g_clear_object (&impl->browse_files_selection_model);
- impl->browse_files_selection_model = select_multiple
- ? GTK_SELECTION_MODEL (gtk_multi_selection_new (G_LIST_MODEL (impl->browse_files_model)))
- : GTK_SELECTION_MODEL (gtk_single_selection_new (G_LIST_MODEL (impl->browse_files_model)));
+ model = get_current_model (impl);
+
+ g_clear_object (&impl->selection_model);
+
+ if (select_multiple)
+ impl->selection_model = GTK_SELECTION_MODEL (gtk_multi_selection_new (model));
+ else
+ impl->selection_model = GTK_SELECTION_MODEL (gtk_single_selection_new (model));
+
+ g_signal_connect (impl->selection_model,
+ "selection-changed",
+ G_CALLBACK (list_selection_changed),
+ impl);
gtk_column_view_set_model (GTK_COLUMN_VIEW (impl->browse_files_column_view),
- GTK_SELECTION_MODEL (impl->browse_files_selection_model));
+ GTK_SELECTION_MODEL (impl->selection_model));
impl->select_multiple = select_multiple;
g_object_notify (G_OBJECT (impl), "select-multiple");
@@ -2544,15 +2521,19 @@ set_select_multiple (GtkFileChooserWidget *impl,
/* Takes the folder stored in a row in the recent_model, and puts it in the pathbar */
static void
-put_recent_folder_in_pathbar (GtkFileChooserWidget *impl, GtkTreeIter *iter)
+put_recent_folder_in_pathbar (GtkFileChooserWidget *impl,
+ guint position)
{
- GFile *file;
+ GtkFileSystemItem *item;
- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), iter,
- MODEL_COL_FILE, &file,
- -1);
- _gtk_path_bar_set_file (GTK_PATH_BAR (impl->browse_path_bar), file, FALSE);
- g_object_unref (file);
+ item = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), position);
+ g_assert (item != NULL);
+
+ _gtk_path_bar_set_file (GTK_PATH_BAR (impl->browse_path_bar),
+ _gtk_file_system_item_get_file (item),
+ FALSE);
+
+ g_clear_object (&item);
}
/* Sets the location bar in the appropriate mode according to the
@@ -2581,17 +2562,15 @@ location_bar_update (GtkFileChooserWidget *impl)
case OPERATION_MODE_RECENT:
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
{
- GtkTreeSelection *selection;
- gboolean have_selected;
- GtkTreeIter iter;
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
+ GtkBitsetIter iter;
+ GtkBitset *bitset;
+ guint position;
/* Save mode means single-selection mode, so the following is valid */
- have_selected = gtk_tree_selection_get_selected (selection, NULL, &iter);
+ bitset = gtk_selection_model_get_selection (impl->selection_model);
- if (have_selected)
- put_recent_folder_in_pathbar (impl, &iter);
+ if (gtk_bitset_iter_init_first (&iter, bitset, &position))
+ put_recent_folder_in_pathbar (impl, position);
}
visible = FALSE;
break;
@@ -3456,8 +3435,7 @@ load_set_model (GtkFileChooserWidget *impl)
{
g_assert (impl->browse_files_model != NULL);
- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
- GTK_TREE_MODEL (impl->browse_files_model));
+ set_current_model (impl, G_LIST_MODEL (impl->browse_files_model));
update_columns (impl, FALSE, _("Modified"));
g_set_object (&impl->model_for_search, impl->browse_files_model);
@@ -3516,44 +3494,10 @@ load_remove_timer (GtkFileChooserWidget *impl, LoadState new_load_state)
}
/* Selects the first row in the file list */
-static void
-browse_files_select_first_row (GtkFileChooserWidget *impl)
-{
- GtkTreePath *path;
- GtkTreeIter dummy_iter;
- GtkTreeModel *tree_model;
-
- tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (impl->browse_files_tree_view));
-
- if (!tree_model)
- return;
-
- path = gtk_tree_path_new_from_indices (0, -1);
-
- /* If the list is empty, do nothing. */
- if (gtk_tree_model_get_iter (tree_model, &dummy_iter, path))
- {
- /* Although the following call to gtk_tree_view_set_cursor() is intended to
- * only change the focus to the first row (not select it), GtkTreeView *will*
- * select the row anyway due to bug #492206. So, we'll use a flag to
- * keep our own callbacks from changing the location_entry when the selection
- * is changed. This entire function, browse_files_select_first_row(), may
- * go away when that bug is fixed in GtkTreeView.
- */
- impl->auto_selecting_first_row = TRUE;
-
- gtk_tree_view_set_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view), path, NULL, FALSE);
-
- impl->auto_selecting_first_row = FALSE;
- }
- gtk_tree_path_free (path);
-}
-
static gboolean
show_and_select_files (GtkFileChooserWidget *impl,
GSList *files)
{
- GtkTreeSelection *selection;
GtkFileSystemModel *fsmodel;
gboolean enabled_hidden, removed_filters;
gboolean selected_a_file;
@@ -3562,8 +3506,7 @@ show_and_select_files (GtkFileChooserWidget *impl,
g_assert (impl->load_state == LOAD_FINISHED);
g_assert (impl->browse_files_model != NULL);
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- fsmodel = GTK_FILE_SYSTEM_MODEL (gtk_tree_view_get_model (GTK_TREE_VIEW (impl->browse_files_tree_view)));
+ fsmodel = GTK_FILE_SYSTEM_MODEL (get_current_model (impl));
g_assert (fsmodel == impl->browse_files_model);
@@ -3574,18 +3517,18 @@ show_and_select_files (GtkFileChooserWidget *impl,
for (walk = files; walk; walk = walk->next)
{
+ GtkFileSystemItem *item;
GFile *file = walk->data;
- GtkTreeIter iter;
/* Is it a hidden file? */
- if (!_gtk_file_system_model_get_iter_for_file (fsmodel, &iter, file))
+ item = _gtk_file_system_model_get_item_for_file (fsmodel, file);
+ if (!item)
continue;
- if (!_gtk_file_system_model_iter_is_visible (fsmodel, &iter))
+ if (!_gtk_file_system_item_is_visible (item))
{
- GFileInfo *info = _gtk_file_system_model_get_info (fsmodel, &iter);
-
+ GFileInfo *info = _gtk_file_system_item_get_file_info (item);
if (!enabled_hidden &&
(g_file_info_get_is_hidden (info) ||
g_file_info_get_is_backup (info)))
@@ -3597,10 +3540,11 @@ show_and_select_files (GtkFileChooserWidget *impl,
/* Is it a filtered file? */
- if (!_gtk_file_system_model_get_iter_for_file (fsmodel, &iter, file))
+ item = _gtk_file_system_model_get_item_for_file (fsmodel, file);
+ if (!item)
continue; /* re-get the iter as it may change when the model refilters */
- if (!_gtk_file_system_model_iter_is_visible (fsmodel, &iter))
+ if (!_gtk_file_system_item_is_visible (item))
{
/* Maybe we should have a way to ask the fsmodel if it had filtered a file */
if (!removed_filters)
@@ -3611,21 +3555,32 @@ show_and_select_files (GtkFileChooserWidget *impl,
}
/* Okay, can we select the file now? */
- if (!_gtk_file_system_model_get_iter_for_file (fsmodel, &iter, file))
+ item = _gtk_file_system_model_get_item_for_file (fsmodel, file);
+ if (!item)
continue;
- if (_gtk_file_system_model_iter_is_visible (fsmodel, &iter))
+ if (_gtk_file_system_item_is_visible (item))
{
- GtkTreePath *path;
+ guint i;
- gtk_tree_selection_select_iter (selection, &iter);
+ /* TODO: "accidentally" quadratic! */
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (fsmodel), &iter);
- gtk_tree_view_set_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view),
- path, NULL, FALSE);
- gtk_tree_path_free (path);
-
- selected_a_file = TRUE;
+ for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (impl->selection_model)); i++)
+ {
+ GtkFileSystemItem *item2 = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), i);
+
+ if (item2 == item)
+ {
+ gtk_selection_model_select_item (impl->selection_model,
+ i,
+ FALSE);
+ g_clear_object (&item2);
+ selected_a_file = TRUE;
+ break;
+ }
+
+ g_clear_object (&item2);
+ }
}
}
@@ -3655,7 +3610,7 @@ pending_select_files_process (GtkFileChooserWidget *impl)
*/
if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN &&
gtk_widget_get_mapped (GTK_WIDGET (impl)))
- browse_files_select_first_row (impl);
+ gtk_selection_model_select_item (impl->selection_model, 0, TRUE);
}
g_assert (impl->pending_select_files == NULL);
@@ -3758,7 +3713,7 @@ stop_loading_and_clear_list_model (GtkFileChooserWidget *impl,
g_set_object (&impl->browse_files_model, NULL);
if (remove)
- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
+ set_current_model (impl, NULL);
}
/* Replace 'target' with 'replacement' in the input string. */
@@ -4070,22 +4025,11 @@ set_list_model (GtkFileChooserWidget *impl,
_gtk_file_system_model_set_filter (impl->browse_files_model, impl->current_filter);
- g_clear_object (&impl->browse_files_selection_model);
- impl->browse_files_selection_model = impl->select_multiple
- ? GTK_SELECTION_MODEL (gtk_multi_selection_new (G_LIST_MODEL (impl->browse_files_model)))
- : GTK_SELECTION_MODEL (gtk_single_selection_new (G_LIST_MODEL (impl->browse_files_model)));
-
- gtk_column_view_set_model (GTK_COLUMN_VIEW (impl->browse_files_column_view),
- GTK_SELECTION_MODEL (impl->browse_files_selection_model));
+ set_current_model (impl, G_LIST_MODEL (impl->browse_files_model));
return TRUE;
}
-struct update_chooser_entry_selected_foreach_closure {
- int num_selected;
- GtkTreeIter first_selected_iter;
-};
-
static int
compare_utf8_filenames (const char *a,
const char *b)
@@ -4104,26 +4048,13 @@ compare_utf8_filenames (const char *a,
return retval;
}
-static void
-update_chooser_entry_selected_foreach (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- struct update_chooser_entry_selected_foreach_closure *closure;
-
- closure = data;
- closure->num_selected++;
-
- if (closure->num_selected == 1)
- closure->first_selected_iter = *iter;
-}
-
static void
update_chooser_entry (GtkFileChooserWidget *impl)
{
- GtkTreeSelection *selection;
- struct update_chooser_entry_selected_foreach_closure closure;
+ GtkBitsetIter iter;
+ GtkBitset *bitset;
+ guint n_selected;
+ guint first;
/* no need to update the file chooser's entry if there's no entry */
if (impl->operation_mode == OPERATION_MODE_SEARCH ||
@@ -4138,31 +4069,34 @@ update_chooser_entry (GtkFileChooserWidget *impl)
g_assert (impl->location_entry != NULL);
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- closure.num_selected = 0;
- gtk_tree_selection_selected_foreach (selection, update_chooser_entry_selected_foreach, &closure);
+ bitset = gtk_selection_model_get_selection (impl->selection_model);
- if (closure.num_selected == 0)
+ n_selected = 0;
+ if (gtk_bitset_iter_init_first (&iter, bitset, &first))
+ {
+ n_selected++;
+ while (gtk_bitset_iter_next (&iter, NULL))
+ n_selected++;
+ }
+
+ if (n_selected == 0)
{
if (impl->operation_mode == OPERATION_MODE_RECENT)
_gtk_file_chooser_entry_set_base_folder (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), NULL);
else
goto maybe_clear_entry;
}
- else if (closure.num_selected == 1)
+ else if (n_selected == 1)
{
if (impl->operation_mode == OPERATION_MODE_BROWSE)
{
+ GtkFileSystemItem *item;
GFileInfo *info;
gboolean change_entry;
- info = _gtk_file_system_model_get_info (impl->browse_files_model, &closure.first_selected_iter);
-
- /* If the cursor moved to the row of the newly created folder,
- * retrieving info will return NULL.
- */
- if (!info)
- return;
+ item = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), first);
+ info = _gtk_file_system_item_get_file_info (item);
+ g_clear_object (&item);
g_free (impl->browse_files_last_selected_name);
impl->browse_files_last_selected_name =
@@ -4202,15 +4136,16 @@ G_GNUC_END_IGNORE_DEPRECATIONS
else if (impl->operation_mode == OPERATION_MODE_RECENT
&& impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
{
+ GtkFileSystemItem *item;
GFile *folder;
/* Set the base folder on the name entry, so it will do completion relative to the correct
recent-folder */
- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &closure.first_selected_iter,
- MODEL_COL_FILE, &folder,
- -1);
+ item = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), first);
+ folder = _gtk_file_system_item_get_file (item);
+ g_clear_object (&item);
+
_gtk_file_chooser_entry_set_base_folder (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), folder);
- g_object_unref (folder);
return;
}
}
@@ -4575,7 +4510,7 @@ gtk_file_chooser_widget_select_file (GtkFileChooser *chooser,
if (!parent_file)
return gtk_file_chooser_set_current_folder (chooser, file, error);
- fsmodel = GTK_FILE_SYSTEM_MODEL (gtk_tree_view_get_model (GTK_TREE_VIEW (impl->browse_files_tree_view)));
+ fsmodel = GTK_FILE_SYSTEM_MODEL (get_current_model (impl));
if (impl->operation_mode == OPERATION_MODE_SEARCH ||
impl->operation_mode == OPERATION_MODE_RECENT ||
@@ -4627,47 +4562,28 @@ gtk_file_chooser_widget_unselect_file (GtkFileChooser *chooser,
GFile *file)
{
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
- GtkTreeView *tree_view;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- tree_view = GTK_TREE_VIEW (impl->browse_files_tree_view);
- model = gtk_tree_view_get_model (tree_view);
- if (!model)
- return;
-
- if (!_gtk_file_system_model_get_iter_for_file (GTK_FILE_SYSTEM_MODEL (model), &iter, file))
- return;
-
- gtk_tree_selection_unselect_iter (gtk_tree_view_get_selection (tree_view), &iter);
-}
-
-static gboolean
-maybe_select (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (data);
- GtkTreeSelection *selection;
- gboolean is_sensitive;
- gboolean is_folder;
+ GtkBitsetIter iter;
+ GtkBitset *bitset;
+ guint i;
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
+ bitset = gtk_selection_model_get_selection (impl->selection_model);
+ for (gtk_bitset_iter_init_first (&iter, bitset, &i);
+ gtk_bitset_iter_is_valid (&iter);
+ gtk_bitset_iter_next (&iter, &i))
+ {
+ GtkFileSystemItem *item;
+ GFile *f;
- gtk_tree_model_get (model, iter,
- MODEL_COL_IS_FOLDER, &is_folder,
- MODEL_COL_IS_SENSITIVE, &is_sensitive,
- -1);
+ item = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), i);
+ f = _gtk_file_system_item_get_file (item);
+ g_clear_object (&item);
- if (is_sensitive &&
- ((is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ||
- (!is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)))
- gtk_tree_selection_select_iter (selection, iter);
- else
- gtk_tree_selection_unselect_iter (selection, iter);
+ if (g_file_equal (f, file))
+ break;
+ }
- return FALSE;
+ if (gtk_bitset_iter_is_valid (&iter))
+ gtk_selection_model_unselect_item (impl->selection_model, i);
}
static void
@@ -4678,25 +4594,41 @@ gtk_file_chooser_widget_select_all (GtkFileChooser *chooser)
if (impl->operation_mode == OPERATION_MODE_SEARCH ||
impl->operation_mode == OPERATION_MODE_RECENT)
{
- GtkTreeSelection *selection;
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- gtk_tree_selection_select_all (selection);
+ gtk_selection_model_select_all (impl->selection_model);
return;
}
if (impl->select_multiple)
- gtk_tree_model_foreach (GTK_TREE_MODEL (impl->browse_files_model),
- maybe_select, impl);
+ {
+ guint i;
+
+ for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (impl->selection_model)); i++)
+ {
+ GtkFileSystemItem *item;
+ GFileInfo *info;
+ gboolean is_folder;
+
+ item = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), i);
+ info = _gtk_file_system_item_get_file_info (item);
+ g_clear_object (&item);
+
+ is_folder = _gtk_file_info_consider_as_directory (info);
+
+ if ((is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ||
+ (!is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN))
+ gtk_selection_model_select_item (impl->selection_model, i, FALSE);
+ else
+ gtk_selection_model_unselect_item (impl->selection_model, i);
+ }
+ }
}
static void
gtk_file_chooser_widget_unselect_all (GtkFileChooser *chooser)
{
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
- GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- gtk_tree_selection_unselect_all (selection);
+ gtk_selection_model_unselect_all (impl->selection_model);
pending_select_files_free (impl);
}
@@ -4793,28 +4725,6 @@ check_save_entry (GtkFileChooserWidget *impl,
*is_folder = _gtk_file_chooser_entry_get_is_folder (chooser_entry, file);
}
-struct get_files_closure {
- GtkFileChooserWidget *impl;
- GListStore *result;
- GFile *file_from_entry;
-};
-
-static void
-get_files_foreach (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- GtkFileSystemModel *fs_model = GTK_FILE_SYSTEM_MODEL (model);
- struct get_files_closure *info = data;
- GFile *file;
-
- file = _gtk_file_system_model_get_file (fs_model, iter);
-
- if (!info->file_from_entry || !g_file_equal (info->file_from_entry, file))
- g_list_store_append (info->result, file);
-}
-
static GListModel *
get_selected_files_as_model (GtkFileChooserWidget *impl)
{
@@ -4834,17 +4744,17 @@ static GListModel *
gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
{
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
- struct get_files_closure info;
+ GListStore *result;
GtkWindow *toplevel;
GtkWidget *current_focus;
+ GFile *file_from_entry;
gboolean file_list_seen;
if (impl->operation_mode == OPERATION_MODE_SEARCH)
return get_selected_files_as_model (impl);
- info.impl = impl;
- info.result = g_list_store_new (G_TYPE_FILE);
- info.file_from_entry = NULL;
+ result = g_list_store_new (G_TYPE_FILE);
+ file_from_entry = NULL;
if (impl->operation_mode == OPERATION_MODE_RECENT)
{
@@ -4855,7 +4765,7 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
}
else
{
- g_object_unref (info.result);
+ g_object_unref (result);
return get_selected_files_as_model (impl);
}
}
@@ -4869,13 +4779,28 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
file_list_seen = FALSE;
if (current_focus == impl->browse_files_column_view)
{
- GtkTreeSelection *selection;
+ GtkBitsetIter iter;
+ GtkBitset *bitset;
+ guint i;
file_list:
file_list_seen = TRUE;
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- gtk_tree_selection_selected_foreach (selection, get_files_foreach, &info);
+ bitset = gtk_selection_model_get_selection (impl->selection_model);
+ for (gtk_bitset_iter_init_first (&iter, bitset, &i);
+ gtk_bitset_iter_is_valid (&iter);
+ gtk_bitset_iter_next (&iter, &i))
+ {
+ GtkFileSystemItem *item;
+ GFile *file;
+
+ item = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), i);
+ file = _gtk_file_system_item_get_file (item);
+ g_clear_object (&item);
+
+ if (!file_from_entry || !g_file_equal (file_from_entry, file))
+ g_list_store_append (result, file);
+ }
/* If there is no selection in the file list, we probably have this situation:
*
@@ -4885,7 +4810,7 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
* So we want the selection to be "bar/foo.txt". Jump to the case for the
* filename entry to see if that is the case.
*/
- if (g_list_model_get_n_items (G_LIST_MODEL (info.result)) == 0 && impl->location_entry)
+ if (g_list_model_get_n_items (G_LIST_MODEL (result)) == 0 && impl->location_entry)
goto file_entry;
}
else if (impl->location_entry &&
@@ -4897,7 +4822,7 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
file_entry:
- check_save_entry (impl, &info.file_from_entry, &is_well_formed, &is_empty, &is_file_part_empty,
&is_folder);
+ check_save_entry (impl, &file_from_entry, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder);
if (is_empty)
goto out;
@@ -4905,10 +4830,10 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
if (!is_well_formed)
goto empty;
- if (info.file_from_entry)
+ if (file_from_entry)
{
- g_list_store_append (info.result, info.file_from_entry);
- g_object_unref (info.file_from_entry);
+ g_list_store_append (result, file_from_entry);
+ g_object_unref (file_from_entry);
}
else if (!file_list_seen)
goto file_list;
@@ -4934,22 +4859,22 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
* then we fall back to the current directory
*/
if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER &&
- g_list_model_get_n_items (G_LIST_MODEL (info.result)) == 0)
+ g_list_model_get_n_items (G_LIST_MODEL (result)) == 0)
{
GFile *current_folder;
current_folder = gtk_file_chooser_get_current_folder (chooser);
if (current_folder)
- g_list_store_append (info.result, current_folder);
+ g_list_store_append (result, current_folder);
}
- return G_LIST_MODEL (info.result);
+ return G_LIST_MODEL (result);
empty:
- g_list_store_remove_all (info.result);
- return G_LIST_MODEL (info.result);
+ g_list_store_remove_all (result);
+ return G_LIST_MODEL (result);
}
/* Shows or hides the filter widgets */
@@ -5065,74 +4990,21 @@ gtk_file_chooser_widget_get_shortcut_folders (GtkFileChooser *chooser)
return gtk_places_sidebar_get_shortcuts (GTK_PLACES_SIDEBAR (impl->places_sidebar));
}
-struct switch_folder_closure {
- GtkFileChooserWidget *impl;
- GFile *file;
- int num_selected;
-};
-
-/* Used from gtk_tree_selection_selected_foreach() in switch_to_selected_folder() */
-static void
-switch_folder_foreach_cb (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- struct switch_folder_closure *closure;
-
- closure = data;
-
- closure->file = _gtk_file_system_model_get_file (GTK_FILE_SYSTEM_MODEL (model), iter);
- closure->num_selected++;
-}
-
/* Changes to the selected folder in the list view */
static void
switch_to_selected_folder (GtkFileChooserWidget *impl)
{
- GtkTreeSelection *selection;
- struct switch_folder_closure closure;
-
- /* We do this with foreach() rather than get_selected() as we may be in
- * multiple selection mode
- */
-
- closure.impl = impl;
- closure.file = NULL;
- closure.num_selected = 0;
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- gtk_tree_selection_selected_foreach (selection, switch_folder_foreach_cb, &closure);
-
- g_assert (closure.file && closure.num_selected == 1);
-
- change_folder_and_display_error (impl, closure.file, FALSE);
-}
-
-/* Gets the GFileInfo for the selected row in the file list; assumes single
- * selection mode.
- */
-static GFileInfo *
-get_selected_file_info_from_file_list (GtkFileChooserWidget *impl,
- gboolean *had_selection)
-{
- GtkTreeSelection *selection;
- GtkTreeIter iter;
- GFileInfo *info;
- GtkTreeModel *model;
+ GtkFileSystemItem *item;
+ GFile *file;
g_assert (!impl->select_multiple);
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- if (!gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- *had_selection = FALSE;
- return NULL;
- }
+ g_assert (GTK_IS_SINGLE_SELECTION (impl->selection_model));
- *had_selection = TRUE;
+ item = gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (impl->selection_model));
+ g_assert (item != NULL);
- info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (model), &iter);
- return info;
+ file = _gtk_file_system_item_get_file (item);
+ change_folder_and_display_error (impl, file, FALSE);
}
/* Gets the display name of the selected file in the file list; assumes single
@@ -5141,12 +5013,16 @@ get_selected_file_info_from_file_list (GtkFileChooserWidget *impl,
static const char *
get_display_name_from_file_list (GtkFileChooserWidget *impl)
{
+ GtkFileSystemItem *item;
GFileInfo *info;
- gboolean had_selection;
- info = get_selected_file_info_from_file_list (impl, &had_selection);
- g_assert (had_selection);
- g_assert (info != NULL);
+ g_assert (!impl->select_multiple);
+ g_assert (GTK_IS_SINGLE_SELECTION (impl->selection_model));
+
+ item = gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (impl->selection_model));
+ g_assert (item != NULL);
+
+ info = _gtk_file_system_item_get_file_info (item);
return g_file_info_get_display_name (info);
}
@@ -5542,6 +5418,14 @@ location_popup_on_paste_handler (GtkFileChooserWidget *impl)
}
/* Implementation for GtkFileChooserEmbed::should_respond() */
+static gboolean
+recent_should_respond (GtkFileChooserWidget *impl)
+{
+ g_assert (impl->operation_mode == OPERATION_MODE_RECENT);
+
+ return g_list_model_get_n_items (G_LIST_MODEL (impl->selection_model)) > 0;
+}
+
static void
add_selection_to_recent_list (GtkFileChooserWidget *impl)
{
@@ -5848,65 +5732,58 @@ gtk_file_chooser_widget_initial_focus (GtkFileChooserWidget *impl)
gtk_widget_grab_focus (widget);
}
-static void
-selected_foreach_get_file_cb (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- GSList **list;
- GFile *file;
-
- list = data;
-
- gtk_tree_model_get (model, iter, MODEL_COL_FILE, &file, -1);
- /* The file already has a new ref courtesy of gtk_tree_model_get();
- * this will be unreffed by the caller
- */
- *list = g_slist_prepend (*list, file);
-}
-
static GSList *
get_selected_files (GtkFileChooserWidget *impl)
{
- GSList *result;
- GtkTreeSelection *selection;
+ GtkBitsetIter iter;
+ GtkBitset *bitset;
+ GSList *result = NULL;
+ guint i;
- result = NULL;
+ bitset = gtk_selection_model_get_selection (impl->selection_model);
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- gtk_tree_selection_selected_foreach (selection, selected_foreach_get_file_cb, &result);
- result = g_slist_reverse (result);
+ for (gtk_bitset_iter_init_first (&iter, bitset, &i);
+ gtk_bitset_iter_is_valid (&iter);
+ gtk_bitset_iter_next (&iter, &i))
+ {
+ GtkFileSystemItem *item;
+ GFile *file;
- return result;
-}
+ item = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), i);
+ file = _gtk_file_system_item_get_file (item);
-static void
-selected_foreach_get_info_cb (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- GSList **list;
- GFileInfo *info;
+ result = g_slist_prepend (result, g_object_ref (file));
- list = data;
+ g_clear_object (&item);
+ }
- info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (model), iter);
- *list = g_slist_prepend (*list, g_object_ref (info));
+ return result;
}
static GSList *
get_selected_infos (GtkFileChooserWidget *impl)
{
- GSList *result;
- GtkTreeSelection *selection;
+ GtkBitsetIter iter;
+ GtkBitset *bitset;
+ GSList *result = NULL;
+ guint i;
- result = NULL;
+ bitset = gtk_selection_model_get_selection (impl->selection_model);
+
+ for (gtk_bitset_iter_init_first (&iter, bitset, &i);
+ gtk_bitset_iter_is_valid (&iter);
+ gtk_bitset_iter_next (&iter, &i))
+ {
+ GtkFileSystemItem *item;
+ GFileInfo *info;
+
+ item = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), i);
+ info = _gtk_file_system_item_get_file_info (item);
+
+ result = g_slist_prepend (result, g_object_ref (info));
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- gtk_tree_selection_selected_foreach (selection, selected_foreach_get_info_cb, &result);
- result = g_slist_reverse (result);
+ g_clear_object (&item);
+ }
return result;
}
@@ -5991,9 +5868,8 @@ search_clear_model (GtkFileChooserWidget *impl,
if (!impl->search_model)
return;
- if (remove &&
- gtk_tree_view_get_model (GTK_TREE_VIEW (impl->browse_files_tree_view)) == GTK_TREE_MODEL
(impl->search_model))
- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
+ if (remove && get_current_model (impl) == G_LIST_MODEL (impl->search_model))
+ set_current_model (impl, NULL);
g_clear_object (&impl->search_model);
}
@@ -6035,9 +5911,7 @@ search_setup_model (GtkFileChooserWidget *impl)
impl,
MODEL_COLUMN_TYPES);
- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
- GTK_TREE_MODEL (impl->search_model));
-
+ set_current_model (impl, G_LIST_MODEL (impl->search_model));
update_columns (impl, TRUE, _("Modified"));
}
@@ -6184,7 +6058,7 @@ recent_clear_model (GtkFileChooserWidget *impl,
return;
if (remove)
- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
+ set_current_model (impl, NULL);
g_set_object (&impl->recent_model, NULL);
}
@@ -6261,27 +6135,11 @@ recent_start_loading (GtkFileChooserWidget *impl)
g_list_free_full (items, (GDestroyNotify) gtk_recent_info_unref);
- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
- GTK_TREE_MODEL (impl->recent_model));
- gtk_tree_view_set_search_column (GTK_TREE_VIEW (impl->browse_files_tree_view), -1);
+ set_current_model (impl, G_LIST_MODEL (impl->recent_model));
update_columns (impl, TRUE, _("Accessed"));
}
-/* Called from ::should_respond(). We return whether there are selected
- * files in the recent files list.
- */
-static gboolean
-recent_should_respond (GtkFileChooserWidget *impl)
-{
- GtkTreeSelection *selection;
-
- g_assert (impl->operation_mode == OPERATION_MODE_RECENT);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- return (gtk_tree_selection_count_selected_rows (selection) != 0);
-}
-
static void
set_current_filter (GtkFileChooserWidget *impl,
GtkFileFilter *filter)
@@ -6330,39 +6188,13 @@ filter_combo_changed (GtkDropDown *dropdown,
new_filter);
}
-static gboolean
-list_select_func (GtkTreeSelection *selection,
- GtkTreeModel *model,
- GtkTreePath *path,
- gboolean path_currently_selected,
- gpointer data)
-{
- GtkFileChooserWidget *impl = data;
-
- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
- {
- GtkTreeIter iter;
- gboolean is_sensitive;
- gboolean is_folder;
-
- if (!gtk_tree_model_get_iter (model, &iter, path))
- return FALSE;
- gtk_tree_model_get (model, &iter,
- MODEL_COL_IS_SENSITIVE, &is_sensitive,
- MODEL_COL_IS_FOLDER, &is_folder,
- -1);
- if (!is_sensitive || !is_folder)
- return FALSE;
- }
-
- return TRUE;
-}
-
static void
-list_selection_changed (GtkTreeSelection *selection,
+list_selection_changed (GtkSelectionModel *selection_model,
+ guint position,
+ guint n_items,
GtkFileChooserWidget *impl)
{
- if (gtk_tree_view_get_model (GTK_TREE_VIEW (impl->browse_files_tree_view)) == NULL)
+ if (get_current_model (impl) == NULL)
return;
if (impl->location_entry &&
@@ -6397,11 +6229,10 @@ column_view_row_activated_cb (GtkColumnView *column_view,
GtkFileChooserWidget *self)
{
GtkFileSystemItem *item;
- GtkSelectionModel *selection_model;
GFileInfo *info;
- selection_model = gtk_column_view_get_model (column_view);
- item = g_list_model_get_item (G_LIST_MODEL (selection_model), position);
+ item = g_list_model_get_item (G_LIST_MODEL (self->selection_model),
+ position);
info = _gtk_file_system_item_get_file_info (item);
if (_gtk_file_info_consider_as_directory (info))
@@ -7043,7 +6874,6 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
gtk_widget_class_bind_template_child (widget_class, GtkFileChooserWidget, box);
/* And a *lot* of callbacks to bind ... */
- gtk_widget_class_bind_template_callback (widget_class, list_selection_changed);
gtk_widget_class_bind_template_callback (widget_class, browse_files_column_view_keynav_failed_cb);
gtk_widget_class_bind_template_callback (widget_class, filter_combo_changed);
gtk_widget_class_bind_template_callback (widget_class, path_bar_clicked);
@@ -7111,7 +6941,6 @@ captured_key (GtkEventControllerKey *controller,
static void
post_process_ui (GtkFileChooserWidget *impl)
{
- GtkTreeSelection *selection;
GFile *file;
GtkGesture *gesture;
GtkEventController *controller;
@@ -7119,12 +6948,6 @@ post_process_ui (GtkFileChooserWidget *impl)
GtkShortcutAction *action;
GtkShortcut *shortcut;
- /* Setup file list treeview */
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
- gtk_tree_selection_set_select_function (selection,
- list_select_func,
- impl, NULL);
-
file = g_file_new_for_path ("/");
_gtk_path_bar_set_file (GTK_PATH_BAR (impl->browse_path_bar), file, FALSE);
g_object_unref (file);
@@ -7214,6 +7037,7 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
{
GtkExpression *expression;
+ impl->selection_model = GTK_SELECTION_MODEL (gtk_single_selection_new (NULL));
impl->select_multiple = FALSE;
impl->show_hidden = FALSE;
impl->show_size_column = TRUE;
@@ -7229,6 +7053,11 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
impl->auto_selecting_first_row = FALSE;
impl->renamed_file = NULL;
+ g_signal_connect (impl->selection_model,
+ "selection-changed",
+ G_CALLBACK (list_selection_changed),
+ impl);
+
/* Ensure private types used by the template
* definition before calling gtk_widget_init_template()
*/
@@ -7239,6 +7068,9 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
gtk_widget_init_template (GTK_WIDGET (impl));
+ gtk_column_view_set_model (GTK_COLUMN_VIEW (impl->browse_files_column_view),
+ impl->selection_model);
+
g_signal_connect (impl, "notify::display,", G_CALLBACK (display_changed_cb), impl);
check_icon_theme (impl);
diff --git a/gtk/ui/gtkfilechooserwidget.ui b/gtk/ui/gtkfilechooserwidget.ui
index ec742cfde6..b22ad24c81 100644
--- a/gtk/ui/gtkfilechooserwidget.ui
+++ b/gtk/ui/gtkfilechooserwidget.ui
@@ -387,11 +387,6 @@
<signal name="pressed" handler="click_cb" swapped="no"/>
</object>
</child>
- <child internal-child="selection">
- <object class="GtkTreeSelection" id="treeview-selection2">
- <signal name="changed" handler="list_selection_changed"
swapped="no"/>
- </object>
- </child>
</object>
</child>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]