[nautilus/wip/antoniof/new-list-view-without-expanders: 11/20] view-icon-controller: Abstract sharable code
- From: António Fernandes <antoniof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus/wip/antoniof/new-list-view-without-expanders: 11/20] view-icon-controller: Abstract sharable code
- Date: Sat, 4 Jun 2022 00:10:23 +0000 (UTC)
commit 32f5572c140027b6f55ed82bdd6e68d286b63ac1
Author: António Fernandes <antoniof gnome org>
Date: Fri Apr 8 23:27:43 2022 +0100
view-icon-controller: Abstract sharable code
The new list view is going to be GtkColumnView-based, so it's going to
share some code with the GtkGridView-based view.
src/meson.build | 2 +
src/nautilus-files-model-view.c | 1002 +++++++++++++++++++++++++++++++++
src/nautilus-files-model-view.h | 41 ++
src/nautilus-view-icon-controller.c | 1053 +++--------------------------------
src/nautilus-view-icon-controller.h | 5 +-
src/nautilus-view-model.c | 8 +-
src/nautilus-view-model.h | 1 +
7 files changed, 1142 insertions(+), 970 deletions(-)
---
diff --git a/src/meson.build b/src/meson.build
index 35a0dce98..141a20ba4 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -75,6 +75,8 @@ libnautilus_sources = [
'nautilus-error-reporting.h',
'nautilus-preferences-window.c',
'nautilus-preferences-window.h',
+ 'nautilus-files-model-view.c',
+ 'nautilus-files-model-view.h',
'nautilus-files-view.c',
'nautilus-files-view.h',
'nautilus-files-view-dnd.c',
diff --git a/src/nautilus-files-model-view.c b/src/nautilus-files-model-view.c
new file mode 100644
index 000000000..9fe6c332f
--- /dev/null
+++ b/src/nautilus-files-model-view.c
@@ -0,0 +1,1002 @@
+#include "nautilus-clipboard.h"
+#include "nautilus-files-model-view.h"
+#include "nautilus-view-item-model.h"
+#include "nautilus-view-model.h"
+#include "nautilus-files-view.h"
+#include "nautilus-file.h"
+#include "nautilus-metadata.h"
+#include "nautilus-global-preferences.h"
+#include "nautilus-thumbnails.h"
+
+typedef struct _NautilusFilesModelViewPrivate NautilusFilesModelViewPrivate;
+struct _NautilusFilesModelViewPrivate
+{
+ NautilusViewModel *model;
+
+ GList *cut_files;
+
+ guint scroll_to_file_handle_id;
+ guint prioritize_thumbnailing_handle_id;
+ GtkAdjustment *vadjustment;
+};
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (NautilusFilesModelView, nautilus_files_model_view,
NAUTILUS_TYPE_FILES_VIEW)
+
+typedef struct
+{
+ const NautilusFileSortType sort_type;
+ const gchar *metadata_name;
+} SortConstants;
+
+static const SortConstants sorts_constants[] =
+{
+ {
+ NAUTILUS_FILE_SORT_BY_DISPLAY_NAME,
+ "name",
+ },
+ {
+ NAUTILUS_FILE_SORT_BY_SIZE,
+ "size",
+ },
+ {
+ NAUTILUS_FILE_SORT_BY_TYPE,
+ "type",
+ },
+ {
+ NAUTILUS_FILE_SORT_BY_MTIME,
+ "modification date",
+ },
+ {
+ NAUTILUS_FILE_SORT_BY_ATIME,
+ "access date",
+ },
+ {
+ NAUTILUS_FILE_SORT_BY_BTIME,
+ "creation date",
+ },
+ {
+ NAUTILUS_FILE_SORT_BY_TRASHED_TIME,
+ "trashed",
+ },
+ {
+ NAUTILUS_FILE_SORT_BY_SEARCH_RELEVANCE,
+ "search_relevance",
+ },
+ {
+ NAUTILUS_FILE_SORT_BY_RECENCY,
+ "recency",
+ },
+};
+
+static inline NautilusViewItemModel *
+get_view_item (GListModel *model,
+ guint position)
+{
+ return NAUTILUS_VIEW_ITEM_MODEL (g_list_model_get_item (model, position));
+}
+
+static const SortConstants *
+get_sorts_constants_from_sort_type (NautilusFileSortType sort_type)
+{
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (sorts_constants); i++)
+ {
+ if (sort_type == sorts_constants[i].sort_type)
+ {
+ return &sorts_constants[i];
+ }
+ }
+
+ return &sorts_constants[0];
+}
+
+static const SortConstants *
+get_sorts_constants_from_metadata_text (const char *metadata_name)
+{
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (sorts_constants); i++)
+ {
+ if (g_strcmp0 (sorts_constants[i].metadata_name, metadata_name) == 0)
+ {
+ return &sorts_constants[i];
+ }
+ }
+
+ return &sorts_constants[0];
+}
+
+const NautilusFileSortType
+get_sorts_type_from_metadata_text (const char *metadata_name)
+{
+ return get_sorts_constants_from_metadata_text (metadata_name)->sort_type;
+}
+
+static const SortConstants *
+get_default_sort_order (NautilusFile *file,
+ gboolean *reversed)
+{
+ NautilusFileSortType sort_type;
+
+ sort_type = nautilus_file_get_default_sort_type (file, reversed);
+
+ return get_sorts_constants_from_sort_type (sort_type);
+}
+
+static const SortConstants *
+get_directory_sort_by (NautilusFile *file,
+ gboolean *reversed)
+{
+ const SortConstants *default_sort;
+ g_autofree char *sort_by = NULL;
+
+ default_sort = get_default_sort_order (file, reversed);
+ g_return_val_if_fail (default_sort != NULL, NULL);
+
+ sort_by = nautilus_file_get_metadata (file,
+ NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_BY,
+ default_sort->metadata_name);
+
+ *reversed = nautilus_file_get_boolean_metadata (file,
+ NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_REVERSED,
+ *reversed);
+
+ return get_sorts_constants_from_metadata_text (sort_by);
+}
+
+void
+set_directory_sort_metadata (NautilusFile *file,
+ const gchar *metadata_name,
+ gboolean reversed)
+{
+ const SortConstants *default_sort;
+ gboolean default_reversed;
+
+ default_sort = get_default_sort_order (file, &default_reversed);
+
+ nautilus_file_set_metadata (file,
+ NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_BY,
+ default_sort->metadata_name,
+ metadata_name);
+ nautilus_file_set_boolean_metadata (file,
+ NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_REVERSED,
+ default_reversed,
+ reversed);
+}
+
+static void
+update_sort_order_from_metadata_and_preferences (NautilusFilesModelView *self)
+{
+ const SortConstants *default_directory_sort;
+ GActionGroup *view_action_group;
+ gboolean reversed;
+
+ default_directory_sort = get_directory_sort_by (nautilus_files_view_get_directory_as_file
(NAUTILUS_FILES_VIEW (self)),
+ &reversed);
+ view_action_group = nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (self));
+ g_action_group_change_action_state (view_action_group,
+ "sort",
+ g_variant_new ("(sb)",
+ default_directory_sort->metadata_name,
+ reversed));
+}
+
+void
+nautilus_files_model_view_set_icon_size (NautilusFilesModelView *self,
+ gint icon_size)
+{
+ GListModel *model;
+ guint n_items;
+
+ model = G_LIST_MODEL (nautilus_files_model_view_get_model (NAUTILUS_FILES_MODEL_VIEW (self)));
+
+ n_items = g_list_model_get_n_items (model);
+ for (guint i = 0; i < n_items; i++)
+ {
+ g_autoptr (NautilusViewItemModel) current_item_model = NULL;
+
+ current_item_model = get_view_item (model, i);
+ nautilus_view_item_model_set_icon_size (current_item_model, icon_size);
+ }
+}
+
+static void
+nautilus_files_model_view_scroll_to_item (NautilusFilesModelView *self,
+ guint position)
+{
+ NAUTILUS_FILES_MODEL_VIEW_CLASS (G_OBJECT_GET_CLASS (self))->scroll_to_item (self, position);
+}
+
+static guint
+nautilus_files_model_view_get_icon_size (NautilusFilesModelView *self)
+{
+ return NAUTILUS_FILES_MODEL_VIEW_CLASS (G_OBJECT_GET_CLASS (self))->get_icon_size (self);
+}
+
+static GtkWidget *
+nautilus_files_model_view_get_view_ui (NautilusFilesModelView *self)
+{
+ return NAUTILUS_FILES_MODEL_VIEW_CLASS (G_OBJECT_GET_CLASS (self))->get_view_ui (self);
+}
+
+typedef struct
+{
+ NautilusFilesModelView *self;
+ GQuark attribute_q;
+} NautilusFilesModelViewSortData;
+
+static void
+real_begin_loading (NautilusFilesView *files_view)
+{
+ /*TODO move this to the files view class begin_loading and hook up? */
+
+
+ /* TODO: This calls sort once, and update_context_menus calls update_actions
+ * which calls the action again
+ */
+ update_sort_order_from_metadata_and_preferences (NAUTILUS_FILES_MODEL_VIEW (files_view));
+
+ /* We could have changed to the trash directory or to searching, and then
+ * we need to update the menus */
+ nautilus_files_view_update_context_menus (files_view);
+ nautilus_files_view_update_toolbar_menus (files_view);
+}
+
+static void
+real_clear (NautilusFilesView *files_view)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+
+ nautilus_view_model_remove_all_items (priv->model);
+}
+
+static void
+real_file_changed (NautilusFilesView *files_view,
+ NautilusFile *file,
+ NautilusDirectory *directory)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ NautilusViewItemModel *item_model;
+
+ item_model = nautilus_view_model_get_item_from_file (priv->model, file);
+ nautilus_view_item_model_file_changed (item_model);
+}
+
+static GList *
+real_get_selection (NautilusFilesView *files_view)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ g_autoptr (GtkSelectionFilterModel) selection = NULL;
+ guint n_selected;
+ GList *selected_files = NULL;
+
+ selection = gtk_selection_filter_model_new (GTK_SELECTION_MODEL (priv->model));
+ n_selected = g_list_model_get_n_items (G_LIST_MODEL (selection));
+ for (guint i = 0; i < n_selected; i++)
+ {
+ g_autoptr (NautilusViewItemModel) item_model = NULL;
+
+ item_model = get_view_item (G_LIST_MODEL (selection), i);
+ selected_files = g_list_prepend (selected_files,
+ g_object_ref (nautilus_view_item_model_get_file (item_model)));
+ }
+
+ return selected_files;
+}
+
+static gboolean
+real_is_empty (NautilusFilesView *files_view)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+
+ return g_list_model_get_n_items (G_LIST_MODEL (priv->model)) == 0;
+}
+
+static void
+real_end_file_changes (NautilusFilesView *files_view)
+{
+}
+
+static void
+real_remove_file (NautilusFilesView *files_view,
+ NautilusFile *file,
+ NautilusDirectory *directory)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ NautilusViewItemModel *item_model;
+
+ item_model = nautilus_view_model_get_item_from_file (priv->model, file);
+ if (item_model != NULL)
+ {
+ nautilus_view_model_remove_item (priv->model, item_model);
+ }
+}
+
+static GQueue *
+convert_glist_to_queue (GList *list)
+{
+ GList *l;
+ GQueue *queue;
+
+ queue = g_queue_new ();
+ for (l = list; l != NULL; l = l->next)
+ {
+ g_queue_push_tail (queue, l->data);
+ }
+
+ return queue;
+}
+
+static GQueue *
+convert_files_to_item_models (NautilusFilesModelView *self,
+ GQueue *files)
+{
+ GList *l;
+ GQueue *models;
+
+ models = g_queue_new ();
+ for (l = g_queue_peek_head_link (files); l != NULL; l = l->next)
+ {
+ NautilusViewItemModel *item_model;
+
+ item_model = nautilus_view_item_model_new (NAUTILUS_FILE (l->data),
+ nautilus_files_model_view_get_icon_size (self));
+ g_queue_push_tail (models, item_model);
+ }
+
+ return models;
+}
+
+static void
+real_set_selection (NautilusFilesView *files_view,
+ GList *selection)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ g_autoptr (GQueue) selection_files = NULL;
+ g_autoptr (GQueue) selection_item_models = NULL;
+ g_autoptr (GtkBitset) update_set = NULL;
+ g_autoptr (GtkBitset) selection_set = NULL;
+
+ update_set = gtk_selection_model_get_selection (GTK_SELECTION_MODEL (priv->model));
+ selection_set = gtk_bitset_new_empty ();
+
+ /* Convert file list into set of model indices */
+ selection_files = convert_glist_to_queue (selection);
+ selection_item_models = nautilus_view_model_get_items_from_files (priv->model, selection_files);
+ for (GList *l = g_queue_peek_head_link (selection_item_models); l != NULL; l = l->next)
+ {
+ gtk_bitset_add (selection_set,
+ nautilus_view_model_get_index (priv->model, l->data));
+ }
+
+ gtk_bitset_union (update_set, selection_set);
+ gtk_selection_model_set_selection (GTK_SELECTION_MODEL (priv->model),
+ selection_set,
+ update_set);
+}
+
+static void
+real_select_all (NautilusFilesView *files_view)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+
+ gtk_selection_model_select_all (GTK_SELECTION_MODEL (priv->model));
+}
+
+static void
+real_invert_selection (NautilusFilesView *files_view)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ GtkSelectionModel *selection_model = GTK_SELECTION_MODEL (priv->model);
+ g_autoptr (GtkBitset) selected = NULL;
+ g_autoptr (GtkBitset) all = NULL;
+ g_autoptr (GtkBitset) new_selected = NULL;
+
+ selected = gtk_selection_model_get_selection (selection_model);
+
+ /* We are going to flip the selection state of every item in the model. */
+ all = gtk_bitset_new_range (0, g_list_model_get_n_items (G_LIST_MODEL (priv->model)));
+
+ /* The new selection is all items minus the ones currently selected. */
+ new_selected = gtk_bitset_copy (all);
+ gtk_bitset_subtract (new_selected, selected);
+
+ gtk_selection_model_set_selection (selection_model, new_selected, all);
+}
+
+static guint
+get_first_selected_item (NautilusFilesModelView *self)
+{
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ g_autolist (NautilusFile) selection = NULL;
+ NautilusFile *file;
+ NautilusViewItemModel *item_model;
+
+ selection = nautilus_view_get_selection (NAUTILUS_VIEW (self));
+ if (selection == NULL)
+ {
+ return G_MAXUINT;
+ }
+
+ file = NAUTILUS_FILE (selection->data);
+ item_model = nautilus_view_model_get_item_from_file (priv->model, file);
+
+ return nautilus_view_model_get_index (priv->model, item_model);
+}
+
+static void
+real_reveal_selection (NautilusFilesView *files_view)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+
+ nautilus_files_model_view_scroll_to_item (self, get_first_selected_item (self));
+}
+
+static gboolean
+showing_recent_directory (NautilusFilesView *view)
+{
+ NautilusFile *file;
+
+ file = nautilus_files_view_get_directory_as_file (view);
+ if (file != NULL)
+ {
+ return nautilus_file_is_in_recent (file);
+ }
+ return FALSE;
+}
+
+static gboolean
+showing_search_directory (NautilusFilesView *view)
+{
+ NautilusFile *file;
+
+ file = nautilus_files_view_get_directory_as_file (view);
+ if (file != NULL)
+ {
+ return nautilus_file_is_in_search (file);
+ }
+ return FALSE;
+}
+
+static void
+real_update_actions_state (NautilusFilesView *files_view)
+{
+ GAction *action;
+ GActionGroup *view_action_group;
+
+ NAUTILUS_FILES_VIEW_CLASS (nautilus_files_model_view_parent_class)->update_actions_state (files_view);
+
+ view_action_group = nautilus_files_view_get_action_group (files_view);
+ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "sort");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+ !showing_recent_directory (files_view) &&
+ !showing_search_directory (files_view));
+}
+
+
+static int
+real_compare_files (NautilusFilesView *files_view,
+ NautilusFile *file1,
+ NautilusFile *file2)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ GtkSorter *sorter;
+ g_autoptr (NautilusViewItemModel) item1 = NULL;
+ g_autoptr (NautilusViewItemModel) item2 = NULL;
+
+ sorter = nautilus_view_model_get_sorter (priv->model);
+ if (sorter == NULL)
+ {
+ return 0;
+ }
+
+ /* Generate fake model items for sorter use only. */
+ item1 = nautilus_view_item_model_new (file1, NAUTILUS_LIST_ICON_SIZE_SMALL);
+ item2 = nautilus_view_item_model_new (file2, NAUTILUS_LIST_ICON_SIZE_SMALL);
+
+ return gtk_sorter_compare (sorter, item1, item2);
+}
+
+static void
+on_clipboard_contents_received (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ NautilusFilesView *files_view = NAUTILUS_FILES_VIEW (source_object);
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ NautilusClipboard *clip;
+ NautilusViewItemModel *item;
+
+ for (GList *l = priv->cut_files; l != NULL; l = l->next)
+ {
+ item = nautilus_view_model_get_item_from_file (priv->model, l->data);
+ if (item != NULL)
+ {
+ nautilus_view_item_model_set_cut (item, FALSE);
+ }
+ }
+ g_clear_list (&priv->cut_files, g_object_unref);
+
+ clip = nautilus_files_view_get_clipboard_finish (files_view, res, NULL);
+ if (clip != NULL && nautilus_clipboard_is_cut (clip))
+ {
+ priv->cut_files = g_list_copy_deep (nautilus_clipboard_peek_files (clip),
+ (GCopyFunc) g_object_ref,
+ NULL);
+ }
+
+ for (GList *l = priv->cut_files; l != NULL; l = l->next)
+ {
+ item = nautilus_view_model_get_item_from_file (priv->model, l->data);
+ if (item != NULL)
+ {
+ nautilus_view_item_model_set_cut (item, TRUE);
+ }
+ }
+}
+
+static void
+update_clipboard_status (NautilusFilesView *view)
+{
+ nautilus_files_view_get_clipboard_async (view,
+ on_clipboard_contents_received,
+ NULL);
+}
+
+static void
+on_clipboard_owner_changed (GdkClipboard *clipboard,
+ gpointer user_data)
+{
+ update_clipboard_status (NAUTILUS_FILES_VIEW (user_data));
+}
+
+static void
+real_end_loading (NautilusFilesView *files_view,
+ gboolean all_files_seen)
+{
+ update_clipboard_status (files_view);
+}
+
+static guint
+get_first_visible_item (NautilusFilesModelView *self)
+{
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ guint n_items;
+ gdouble scrolled_y;
+ GtkWidget *view_ui;
+
+ n_items = g_list_model_get_n_items (G_LIST_MODEL (priv->model));
+ scrolled_y = gtk_adjustment_get_value (priv->vadjustment);
+ view_ui = nautilus_files_model_view_get_view_ui (self);
+ for (guint i = 0; i < n_items; i++)
+ {
+ g_autoptr (NautilusViewItemModel) item = NULL;
+ GtkWidget *item_ui;
+
+ item = get_view_item (G_LIST_MODEL (priv->model), i);
+ item_ui = nautilus_view_item_model_get_item_ui (item);
+ if (item_ui != NULL)
+ {
+ gdouble y;
+
+ gtk_widget_translate_coordinates (item_ui, view_ui,
+ 0, 0, NULL, &y);
+ if (gtk_widget_is_visible (item_ui) && y >= scrolled_y)
+ {
+ return i;
+ }
+ }
+ }
+
+ return G_MAXUINT;
+}
+
+static char *
+real_get_first_visible_file (NautilusFilesView *files_view)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ guint i;
+ g_autoptr (NautilusViewItemModel) item = NULL;
+ gchar *uri = NULL;
+
+ i = get_first_visible_item (self);
+ if (i < G_MAXUINT)
+ {
+ item = get_view_item (G_LIST_MODEL (priv->model), i);
+ uri = nautilus_file_get_uri (nautilus_view_item_model_get_file (item));
+ }
+ return uri;
+}
+
+typedef struct
+{
+ NautilusFilesModelView *view;
+ char *uri;
+} ScrollToFileData;
+
+static void
+scroll_to_file_data_free (ScrollToFileData *data)
+{
+ g_free (data->uri);
+ g_free (data);
+}
+
+static gboolean
+scroll_to_file_on_idle (ScrollToFileData *data)
+{
+ NautilusFilesModelView *self = data->view;
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ g_autoptr (NautilusFile) file = NULL;
+ NautilusViewItemModel *item;
+ guint i;
+
+ file = nautilus_file_get_existing_by_uri (data->uri);
+ item = nautilus_view_model_get_item_from_file (priv->model, file);
+ i = nautilus_view_model_get_index (priv->model, item);
+
+ nautilus_files_model_view_scroll_to_item (self, i);
+
+ priv->scroll_to_file_handle_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+static void
+real_scroll_to_file (NautilusFilesView *files_view,
+ const char *uri)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ ScrollToFileData *data;
+ guint handle_id;
+
+ data = g_new (ScrollToFileData, 1);
+ data->view = self;
+ data->uri = g_strdup (uri);
+ handle_id = g_idle_add_full (G_PRIORITY_LOW,
+ (GSourceFunc) scroll_to_file_on_idle,
+ data,
+ (GDestroyNotify) scroll_to_file_data_free);
+ priv->scroll_to_file_handle_id = handle_id;
+}
+
+static void
+real_add_files (NautilusFilesView *files_view,
+ GList *files)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ g_autoptr (GQueue) files_queue = NULL;
+ g_autoptr (GQueue) item_models = NULL;
+ gdouble adjustment_value;
+
+ files_queue = convert_glist_to_queue (files);
+ item_models = convert_files_to_item_models (self, files_queue);
+ nautilus_view_model_add_items (priv->model, item_models);
+
+ /* GtkListBase anchoring doesn't cope well with our lazy loading.
+ * Assuming that GtkListBase|list.scroll-to-item resets the anchor to 0, use
+ * that as a workaround to prevent scrolling while we are at the top. */
+ adjustment_value = gtk_adjustment_get_value (priv->vadjustment);
+ if (G_APPROX_VALUE (adjustment_value, 0.0, DBL_EPSILON))
+ {
+ nautilus_files_model_view_scroll_to_item (self, 0);
+ }
+}
+
+static void
+real_select_first (NautilusFilesView *files_view)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ g_autoptr (NautilusViewItemModel) item = NULL;
+ NautilusFile *file;
+ g_autoptr (GList) selection = NULL;
+
+ item = get_view_item (G_LIST_MODEL (priv->model), 0);
+ if (item == NULL)
+ {
+ return;
+ }
+ file = nautilus_view_item_model_get_file (item);
+ selection = g_list_prepend (selection, file);
+ nautilus_view_set_selection (NAUTILUS_VIEW (files_view), selection);
+}
+
+static GdkRectangle *
+get_rectangle_for_item_ui (NautilusFilesModelView *self,
+ GtkWidget *item_ui)
+{
+ GdkRectangle *rectangle;
+ GtkWidget *content_widget;
+ gdouble view_x;
+ gdouble view_y;
+
+ rectangle = g_new0 (GdkRectangle, 1);
+ gtk_widget_get_allocation (item_ui, rectangle);
+
+ content_widget = nautilus_files_view_get_content_widget (NAUTILUS_FILES_VIEW (self));
+ gtk_widget_translate_coordinates (item_ui, content_widget,
+ rectangle->x, rectangle->y,
+ &view_x, &view_y);
+ rectangle->x = view_x;
+ rectangle->y = view_y;
+
+ return rectangle;
+}
+
+static GdkRectangle *
+real_compute_rename_popover_pointing_to (NautilusFilesView *files_view)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ g_autoptr (NautilusViewItemModel) item = NULL;
+ GtkWidget *item_ui;
+
+ /* We only allow one item to be renamed with a popover */
+ item = get_view_item (G_LIST_MODEL (priv->model), get_first_selected_item (self));
+ item_ui = nautilus_view_item_model_get_item_ui (item);
+ g_return_val_if_fail (item_ui != NULL, NULL);
+
+ return get_rectangle_for_item_ui (self, item_ui);
+}
+
+static GdkRectangle *
+real_reveal_for_selection_context_menu (NautilusFilesView *files_view)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ g_autoptr (GtkSelectionFilterModel) selection = NULL;
+ guint n_selected;
+ GtkWidget *focus_child;
+ guint i;
+ GtkWidget *item_ui;
+
+ selection = gtk_selection_filter_model_new (GTK_SELECTION_MODEL (priv->model));
+ n_selected = g_list_model_get_n_items (G_LIST_MODEL (selection));
+ g_return_val_if_fail (n_selected > 0, NULL);
+
+ /* Get the focused item_ui, if selected.
+ * Otherwise, get the selected item_ui which is sorted the lowest.*/
+ focus_child = gtk_widget_get_focus_child (nautilus_files_model_view_get_view_ui (self));
+ for (i = 0; i < n_selected; i++)
+ {
+ g_autoptr (NautilusViewItemModel) item = NULL;
+
+ item = get_view_item (G_LIST_MODEL (selection), i);
+ item_ui = nautilus_view_item_model_get_item_ui (item);
+ if (item_ui != NULL && gtk_widget_get_parent (item_ui) == focus_child)
+ {
+ break;
+ }
+ }
+ nautilus_files_model_view_scroll_to_item (self, i);
+
+ return get_rectangle_for_item_ui (self, item_ui);
+}
+
+static void
+real_preview_selection_event (NautilusFilesView *files_view,
+ GtkDirectionType direction)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (files_view);
+ GtkMovementStep step;
+ gint count;
+ gboolean handled;
+
+ step = (direction == GTK_DIR_UP || direction == GTK_DIR_DOWN) ?
+ GTK_MOVEMENT_DISPLAY_LINES : GTK_MOVEMENT_VISUAL_POSITIONS;
+ count = (direction == GTK_DIR_RIGHT || direction == GTK_DIR_DOWN) ?
+ 1 : -1;
+
+ g_signal_emit_by_name (nautilus_files_model_view_get_view_ui (self),
+ "move-cursor", step, count, &handled);
+}
+
+static void
+default_sort_order_changed_callback (NautilusFilesModelView *self)
+{
+ update_sort_order_from_metadata_and_preferences (self);
+}
+
+static void
+nautilus_files_model_view_dispose (GObject *object)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (object);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+
+ g_clear_handle_id (&priv->scroll_to_file_handle_id, g_source_remove);
+ g_clear_handle_id (&priv->prioritize_thumbnailing_handle_id, g_source_remove);
+
+ G_OBJECT_CLASS (nautilus_files_model_view_parent_class)->dispose (object);
+}
+
+static void
+nautilus_files_model_view_finalize (GObject *object)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (object);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+
+ g_clear_list (&priv->cut_files, g_object_unref);
+
+ G_OBJECT_CLASS (nautilus_files_model_view_parent_class)->finalize (object);
+}
+
+static gboolean
+prioritize_thumbnailing_on_idle (NautilusFilesModelView *self)
+{
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ gdouble page_size;
+ GtkWidget *first_visible_child;
+ GtkWidget *next_child;
+ guint first_index;
+ guint next_index;
+ gdouble y;
+ guint last_index;
+ g_autoptr (NautilusViewItemModel) first_item = NULL;
+ NautilusFile *file;
+
+ priv->prioritize_thumbnailing_handle_id = 0;
+
+ page_size = gtk_adjustment_get_page_size (priv->vadjustment);
+ first_index = get_first_visible_item (self);
+ if (first_index == G_MAXUINT)
+ {
+ return G_SOURCE_REMOVE;
+ }
+
+ first_item = get_view_item (G_LIST_MODEL (priv->model), first_index);
+
+ first_visible_child = nautilus_view_item_model_get_item_ui (first_item);
+
+ for (next_index = first_index + 1; next_index < g_list_model_get_n_items (G_LIST_MODEL (priv->model));
next_index++)
+ {
+ g_autoptr (NautilusViewItemModel) next_item = NULL;
+
+ next_item = get_view_item (G_LIST_MODEL (priv->model), next_index);
+ next_child = nautilus_view_item_model_get_item_ui (next_item);
+ if (next_child == NULL)
+ {
+ break;
+ }
+ if (gtk_widget_translate_coordinates (next_child, first_visible_child,
+ 0, 0, NULL, &y))
+ {
+ if (y > page_size)
+ {
+ break;
+ }
+ }
+ }
+ last_index = next_index - 1;
+
+ /* Do the iteration in reverse to give higher priority to the top */
+ for (gint i = 0; i <= last_index - first_index; i++)
+ {
+ g_autoptr (NautilusViewItemModel) item = NULL;
+
+ item = get_view_item (G_LIST_MODEL (priv->model), last_index - i);
+ g_return_val_if_fail (item != NULL, G_SOURCE_REMOVE);
+
+ file = nautilus_view_item_model_get_file (NAUTILUS_VIEW_ITEM_MODEL (item));
+ if (file != NULL && nautilus_file_is_thumbnailing (file))
+ {
+ g_autofree gchar *uri = nautilus_file_get_uri (file);
+ nautilus_thumbnail_prioritize (uri);
+ }
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+on_vadjustment_changed (GtkAdjustment *adjustment,
+ gpointer user_data)
+{
+ NautilusFilesModelView *self = NAUTILUS_FILES_MODEL_VIEW (user_data);
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ guint handle_id;
+
+ /* Schedule on idle to rate limit and to avoid delaying scrolling. */
+ if (priv->prioritize_thumbnailing_handle_id == 0)
+ {
+ handle_id = g_idle_add ((GSourceFunc) prioritize_thumbnailing_on_idle, self);
+ priv->prioritize_thumbnailing_handle_id = handle_id;
+ }
+}
+
+static void
+nautilus_files_model_view_class_init (NautilusFilesModelViewClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NautilusFilesViewClass *files_view_class = NAUTILUS_FILES_VIEW_CLASS (klass);
+
+ object_class->dispose = nautilus_files_model_view_dispose;
+ object_class->finalize = nautilus_files_model_view_finalize;
+
+ files_view_class->add_files = real_add_files;
+ files_view_class->begin_loading = real_begin_loading;
+ files_view_class->clear = real_clear;
+ files_view_class->file_changed = real_file_changed;
+ files_view_class->get_selection = real_get_selection;
+ /* TODO: remove this get_selection_for_file_transfer, this doesn't even
+ * take into account we could us the view for recursive search :/
+ * CanvasView has the same issue. */
+ files_view_class->get_selection_for_file_transfer = real_get_selection;
+ files_view_class->is_empty = real_is_empty;
+ files_view_class->remove_file = real_remove_file;
+ files_view_class->select_all = real_select_all;
+ files_view_class->set_selection = real_set_selection;
+ files_view_class->invert_selection = real_invert_selection;
+ files_view_class->compare_files = real_compare_files;
+ files_view_class->end_file_changes = real_end_file_changes;
+ files_view_class->end_loading = real_end_loading;
+ files_view_class->get_first_visible_file = real_get_first_visible_file;
+ files_view_class->reveal_selection = real_reveal_selection;
+ files_view_class->update_actions_state = real_update_actions_state;
+ files_view_class->scroll_to_file = real_scroll_to_file;
+ files_view_class->select_first = real_select_first;
+ files_view_class->compute_rename_popover_pointing_to = real_compute_rename_popover_pointing_to;
+ files_view_class->reveal_for_selection_context_menu = real_reveal_for_selection_context_menu;
+ files_view_class->preview_selection_event = real_preview_selection_event;
+}
+
+static void
+nautilus_files_model_view_init (NautilusFilesModelView *self)
+{
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+ GtkWidget *content_widget;
+ GtkAdjustment *vadjustment;
+
+ gtk_widget_add_css_class (GTK_WIDGET (self), "view");
+
+ g_signal_connect_object (nautilus_preferences,
+ "changed::" NAUTILUS_PREFERENCES_DEFAULT_SORT_ORDER,
+ G_CALLBACK (default_sort_order_changed_callback),
+ self,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (nautilus_preferences,
+ "changed::" NAUTILUS_PREFERENCES_DEFAULT_SORT_IN_REVERSE_ORDER,
+ G_CALLBACK (default_sort_order_changed_callback),
+ self,
+ G_CONNECT_SWAPPED);
+
+ /* React to clipboard changes */
+ g_signal_connect_object (gdk_display_get_clipboard (gdk_display_get_default ()),
+ "changed",
+ G_CALLBACK (on_clipboard_owner_changed), self, 0);
+
+ content_widget = nautilus_files_view_get_content_widget (NAUTILUS_FILES_VIEW (self));
+ vadjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (content_widget));
+
+ priv->vadjustment = vadjustment;
+ g_signal_connect (vadjustment, "changed", (GCallback) on_vadjustment_changed, self);
+ g_signal_connect (vadjustment, "value-changed", (GCallback) on_vadjustment_changed, self);
+
+ priv->model = nautilus_view_model_new ();
+
+ g_signal_connect_object (GTK_SELECTION_MODEL (priv->model),
+ "selection-changed",
+ G_CALLBACK (nautilus_files_view_notify_selection_changed),
+ NAUTILUS_FILES_VIEW (self),
+ G_CONNECT_SWAPPED);
+}
+
+NautilusViewModel *
+nautilus_files_model_view_get_model (NautilusFilesModelView *self)
+{
+ NautilusFilesModelViewPrivate *priv = nautilus_files_model_view_get_instance_private (self);
+
+ return priv->model;
+}
diff --git a/src/nautilus-files-model-view.h b/src/nautilus-files-model-view.h
new file mode 100644
index 000000000..b7e50c962
--- /dev/null
+++ b/src/nautilus-files-model-view.h
@@ -0,0 +1,41 @@
+/* nautilus-files-model-view.h
+ *
+ * Header of abstract type, to be considered private to its subclasses.
+ * */
+
+#pragma once
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "nautilus-files-view.h"
+#include "nautilus-view-model.h"
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_FILES_MODEL_VIEW (nautilus_files_model_view_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (NautilusFilesModelView, nautilus_files_model_view, NAUTILUS, FILES_MODEL_VIEW,
NautilusFilesView)
+
+struct _NautilusFilesModelViewClass
+{
+ NautilusFilesViewClass parent_class;
+
+ guint (*get_icon_size) (NautilusFilesModelView *self);
+ GtkWidget *(*get_view_ui) (NautilusFilesModelView *self);
+ void (*scroll_to_item) (NautilusFilesModelView *self,
+ guint position);
+};
+
+/* Methods */
+NautilusViewModel *nautilus_files_model_view_get_model (NautilusFilesModelView *self);
+void nautilus_files_model_view_set_icon_size (NautilusFilesModelView *self,
+ gint icon_size);
+
+/* Shareable helpers */
+void set_directory_sort_metadata (NautilusFile *file,
+ const gchar *metadata_name,
+ gboolean reversed);
+const NautilusFileSortType get_sorts_type_from_metadata_text (const char *metadata_name);
+
+G_END_DECLS
diff --git a/src/nautilus-view-icon-controller.c b/src/nautilus-view-icon-controller.c
index a186a7c53..d9b35b1a4 100644
--- a/src/nautilus-view-icon-controller.c
+++ b/src/nautilus-view-icon-controller.c
@@ -1,193 +1,34 @@
#include "nautilus-view-icon-controller.h"
#include "nautilus-view-item-model.h"
#include "nautilus-view-icon-item-ui.h"
-#include "nautilus-view-model.h"
-#include "nautilus-files-view.h"
#include "nautilus-file.h"
-#include "nautilus-metadata.h"
-#include "nautilus-window-slot.h"
-#include "nautilus-directory.h"
-#include "nautilus-clipboard.h"
#include "nautilus-global-preferences.h"
-#include "nautilus-thumbnails.h"
struct _NautilusViewIconController
{
- NautilusFilesView parent_instance;
+ NautilusFilesModelView parent_instance;
GtkGridView *view_ui;
- NautilusViewModel *model;
-
- GList *cut_files;
GActionGroup *action_group;
gint zoom_level;
- GQuark caption_attributes[NAUTILUS_VIEW_ICON_N_CAPTIONS];
+ gboolean directories_first;
gboolean single_click_mode;
+
gboolean activate_on_release;
gboolean deny_background_click;
- guint scroll_to_file_handle_id;
- guint prioritize_thumbnailing_handle_id;
- GtkAdjustment *vadjustment;
+ GQuark caption_attributes[NAUTILUS_VIEW_ICON_N_CAPTIONS];
NautilusFileSortType sort_type;
- gboolean directories_first;
gboolean reversed;
};
-G_DEFINE_TYPE (NautilusViewIconController, nautilus_view_icon_controller, NAUTILUS_TYPE_FILES_VIEW)
-
-typedef struct
-{
- const NautilusFileSortType sort_type;
- const gchar *metadata_name;
-} SortConstants;
-
-static const SortConstants sorts_constants[] =
-{
- {
- NAUTILUS_FILE_SORT_BY_DISPLAY_NAME,
- "name",
- },
- {
- NAUTILUS_FILE_SORT_BY_SIZE,
- "size",
- },
- {
- NAUTILUS_FILE_SORT_BY_TYPE,
- "type",
- },
- {
- NAUTILUS_FILE_SORT_BY_MTIME,
- "modification date",
- },
- {
- NAUTILUS_FILE_SORT_BY_ATIME,
- "access date",
- },
- {
- NAUTILUS_FILE_SORT_BY_BTIME,
- "creation date",
- },
- {
- NAUTILUS_FILE_SORT_BY_TRASHED_TIME,
- "trashed",
- },
- {
- NAUTILUS_FILE_SORT_BY_SEARCH_RELEVANCE,
- "search_relevance",
- },
- {
- NAUTILUS_FILE_SORT_BY_RECENCY,
- "recency",
- },
-};
+G_DEFINE_TYPE (NautilusViewIconController, nautilus_view_icon_controller, NAUTILUS_TYPE_FILES_MODEL_VIEW)
static guint get_icon_size_for_zoom_level (NautilusGridZoomLevel zoom_level);
-static const SortConstants *
-get_sorts_constants_from_sort_type (NautilusFileSortType sort_type)
-{
- guint i;
-
- for (i = 0; i < G_N_ELEMENTS (sorts_constants); i++)
- {
- if (sort_type == sorts_constants[i].sort_type)
- {
- return &sorts_constants[i];
- }
- }
-
- return &sorts_constants[0];
-}
-
-static const SortConstants *
-get_sorts_constants_from_metadata_text (const char *metadata_name)
-{
- guint i;
-
- for (i = 0; i < G_N_ELEMENTS (sorts_constants); i++)
- {
- if (g_strcmp0 (sorts_constants[i].metadata_name, metadata_name) == 0)
- {
- return &sorts_constants[i];
- }
- }
-
- return &sorts_constants[0];
-}
-
-static const SortConstants *
-get_default_sort_order (NautilusFile *file,
- gboolean *reversed)
-{
- NautilusFileSortType sort_type;
-
- sort_type = nautilus_file_get_default_sort_type (file, reversed);
-
- return get_sorts_constants_from_sort_type (sort_type);
-}
-
-static const SortConstants *
-get_directory_sort_by (NautilusFile *file,
- gboolean *reversed)
-{
- const SortConstants *default_sort;
- g_autofree char *sort_by = NULL;
-
- default_sort = get_default_sort_order (file, reversed);
- g_return_val_if_fail (default_sort != NULL, NULL);
-
- sort_by = nautilus_file_get_metadata (file,
- NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_BY,
- default_sort->metadata_name);
-
- *reversed = nautilus_file_get_boolean_metadata (file,
- NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_REVERSED,
- *reversed);
-
- return get_sorts_constants_from_metadata_text (sort_by);
-}
-
-static void
-set_directory_sort_metadata (NautilusFile *file,
- const SortConstants *sort,
- gboolean reversed)
-{
- const SortConstants *default_sort;
- gboolean default_reversed;
-
- default_sort = get_default_sort_order (file, &default_reversed);
-
- nautilus_file_set_metadata (file,
- NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_BY,
- default_sort->metadata_name,
- sort->metadata_name);
- nautilus_file_set_boolean_metadata (file,
- NAUTILUS_METADATA_KEY_ICON_VIEW_SORT_REVERSED,
- default_reversed,
- reversed);
-}
-
-static void
-update_sort_order_from_metadata_and_preferences (NautilusViewIconController *self)
-{
- const SortConstants *default_directory_sort;
- GActionGroup *view_action_group;
- gboolean reversed;
-
- default_directory_sort = get_directory_sort_by (nautilus_files_view_get_directory_as_file
(NAUTILUS_FILES_VIEW (self)),
- &reversed);
- view_action_group = nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (self));
- g_action_group_change_action_state (view_action_group,
- "sort",
- g_variant_new ("(sb)",
- default_directory_sort->metadata_name,
- reversed));
-}
-
static gint
nautilus_view_icon_controller_sort (gconstpointer a,
gconstpointer b,
@@ -206,258 +47,6 @@ nautilus_view_icon_controller_sort (gconstpointer a,
self->reversed);
}
-static void
-real_begin_loading (NautilusFilesView *files_view)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
-
- /* TODO: This calls sort once, and update_context_menus calls update_actions which calls
- * the action again
- */
- update_sort_order_from_metadata_and_preferences (self);
-
- /*TODO move this to the files view class begin_loading and hook up? */
-
- /* We could have changed to the trash directory or to searching, and then
- * we need to update the menus */
- nautilus_files_view_update_context_menus (files_view);
- nautilus_files_view_update_toolbar_menus (files_view);
-}
-
-static void
-real_clear (NautilusFilesView *files_view)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
-
- nautilus_view_model_remove_all_items (self->model);
-}
-
-static void
-real_file_changed (NautilusFilesView *files_view,
- NautilusFile *file,
- NautilusDirectory *directory)
-{
- NautilusViewIconController *self;
- NautilusViewItemModel *item_model;
-
- self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- item_model = nautilus_view_model_get_item_from_file (self->model, file);
- nautilus_view_item_model_file_changed (item_model);
-}
-
-static GList *
-real_get_selection (NautilusFilesView *files_view)
-{
- NautilusViewIconController *self;
- g_autoptr (GtkSelectionFilterModel) selection = NULL;
- guint n_selected;
- GList *selected_files = NULL;
-
- self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- selection = gtk_selection_filter_model_new (GTK_SELECTION_MODEL (self->model));
- n_selected = g_list_model_get_n_items (G_LIST_MODEL (selection));
- for (guint i = 0; i < n_selected; i++)
- {
- g_autoptr (NautilusViewItemModel) item_model = NULL;
-
- item_model = g_list_model_get_item (G_LIST_MODEL (selection), i);
- selected_files = g_list_prepend (selected_files,
- g_object_ref (nautilus_view_item_model_get_file (item_model)));
- }
-
- return selected_files;
-}
-
-static gboolean
-real_is_empty (NautilusFilesView *files_view)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
-
- return g_list_model_get_n_items (G_LIST_MODEL (self->model)) == 0;
-}
-
-static void
-real_end_file_changes (NautilusFilesView *files_view)
-{
-}
-
-static void
-real_remove_file (NautilusFilesView *files_view,
- NautilusFile *file,
- NautilusDirectory *directory)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- NautilusViewItemModel *item_model;
-
- item_model = nautilus_view_model_get_item_from_file (self->model, file);
- if (item_model != NULL)
- {
- nautilus_view_model_remove_item (self->model, item_model);
- }
-}
-
-static GQueue *
-convert_glist_to_queue (GList *list)
-{
- GList *l;
- GQueue *queue;
-
- queue = g_queue_new ();
- for (l = list; l != NULL; l = l->next)
- {
- g_queue_push_tail (queue, l->data);
- }
-
- return queue;
-}
-
-static GQueue *
-convert_files_to_item_models (NautilusViewIconController *self,
- GQueue *files)
-{
- GList *l;
- GQueue *models;
-
- models = g_queue_new ();
- for (l = g_queue_peek_head_link (files); l != NULL; l = l->next)
- {
- NautilusViewItemModel *item_model;
-
- item_model = nautilus_view_item_model_new (NAUTILUS_FILE (l->data),
- get_icon_size_for_zoom_level (self->zoom_level));
- g_queue_push_tail (models, item_model);
- }
-
- return models;
-}
-
-static void
-real_set_selection (NautilusFilesView *files_view,
- GList *selection)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- g_autoptr (GQueue) selection_files = NULL;
- g_autoptr (GQueue) selection_item_models = NULL;
- g_autoptr (GtkBitset) update_set = NULL;
- g_autoptr (GtkBitset) selection_set = NULL;
-
- update_set = gtk_selection_model_get_selection (GTK_SELECTION_MODEL (self->model));
- selection_set = gtk_bitset_new_empty ();
-
- /* Convert file list into set of model indices */
- selection_files = convert_glist_to_queue (selection);
- selection_item_models = nautilus_view_model_get_items_from_files (self->model, selection_files);
- for (GList *l = g_queue_peek_head_link (selection_item_models); l != NULL ; l = l->next)
- {
- gtk_bitset_add (selection_set,
- nautilus_view_model_get_index (self->model, l->data));
- }
-
- gtk_bitset_union (update_set, selection_set);
- gtk_selection_model_set_selection (GTK_SELECTION_MODEL (self->model),
- selection_set,
- update_set);
-}
-
-static void
-real_select_all (NautilusFilesView *files_view)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- gtk_selection_model_select_all (GTK_SELECTION_MODEL (self->model));
-}
-
-static void
-real_invert_selection (NautilusFilesView *files_view)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- GtkSelectionModel *selection_model = GTK_SELECTION_MODEL (self->model);
- g_autoptr (GtkBitset) selected = NULL;
- g_autoptr (GtkBitset) all = NULL;
- g_autoptr (GtkBitset) new_selected = NULL;
-
- selected = gtk_selection_model_get_selection (selection_model);
-
- /* We are going to flip the selection state of every item in the model. */
- all = gtk_bitset_new_range (0, g_list_model_get_n_items (G_LIST_MODEL (self->model)));
-
- /* The new selection is all items minus the ones currently selected. */
- new_selected = gtk_bitset_copy (all);
- gtk_bitset_subtract (new_selected, selected);
-
- gtk_selection_model_set_selection (selection_model, new_selected, all);
-}
-
-static guint
-get_first_selected_item (NautilusViewIconController *self)
-{
- g_autolist (NautilusFile) selection = NULL;
- NautilusFile *file;
- NautilusViewItemModel *item_model;
-
- selection = nautilus_view_get_selection (NAUTILUS_VIEW (self));
- if (selection == NULL)
- {
- return G_MAXUINT;
- }
-
- file = NAUTILUS_FILE (selection->data);
- item_model = nautilus_view_model_get_item_from_file (self->model, file);
-
- return nautilus_view_model_get_index (self->model, item_model);
-}
-
-static void
-real_reveal_selection (NautilusFilesView *files_view)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
-
- gtk_widget_activate_action (GTK_WIDGET (self->view_ui),
- "list.scroll-to-item",
- "u",
- get_first_selected_item (self));
-}
-
-static gboolean
-showing_recent_directory (NautilusFilesView *view)
-{
- NautilusFile *file;
-
- file = nautilus_files_view_get_directory_as_file (view);
- if (file != NULL)
- {
- return nautilus_file_is_in_recent (file);
- }
- return FALSE;
-}
-
-static gboolean
-showing_search_directory (NautilusFilesView *view)
-{
- NautilusFile *file;
-
- file = nautilus_files_view_get_directory_as_file (view);
- if (file != NULL)
- {
- return nautilus_file_is_in_search (file);
- }
- return FALSE;
-}
-
-static void
-real_update_actions_state (NautilusFilesView *files_view)
-{
- GAction *action;
- GActionGroup *view_action_group;
-
- NAUTILUS_FILES_VIEW_CLASS (nautilus_view_icon_controller_parent_class)->update_actions_state
(files_view);
-
- view_action_group = nautilus_files_view_get_action_group (files_view);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "sort");
- g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- !showing_recent_directory (files_view) &&
- !showing_search_directory (files_view));
-}
-
static void
real_bump_zoom_level (NautilusFilesView *files_view,
int zoom_increment)
@@ -514,6 +103,22 @@ get_icon_size_for_zoom_level (NautilusGridZoomLevel zoom_level)
g_return_val_if_reached (NAUTILUS_GRID_ICON_SIZE_STANDARD);
}
+static guint
+real_get_icon_size (NautilusFilesModelView *files_model_view)
+{
+ NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_model_view);
+
+ return get_icon_size_for_zoom_level (self->zoom_level);
+}
+
+static GtkWidget *
+real_get_view_ui (NautilusFilesModelView *files_model_view)
+{
+ NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_model_view);
+
+ return GTK_WIDGET (self->view_ui);
+}
+
static gint
get_default_zoom_level (void)
{
@@ -556,23 +161,6 @@ set_captions_from_preferences (NautilusViewIconController *self)
}
}
-static void
-set_icon_size (NautilusViewIconController *self,
- gint icon_size)
-{
- guint n_items;
-
- n_items = g_list_model_get_n_items (G_LIST_MODEL (self->model));
- for (guint i = 0; i < n_items; i++)
- {
- g_autoptr (NautilusViewItemModel) current_item_model = NULL;
-
- current_item_model = g_list_model_get_item (G_LIST_MODEL (self->model), i);
- nautilus_view_item_model_set_icon_size (current_item_model,
- get_icon_size_for_zoom_level (self->zoom_level));
- }
-}
-
static void
set_zoom_level (NautilusViewIconController *self,
guint new_level)
@@ -584,7 +172,8 @@ set_zoom_level (NautilusViewIconController *self,
* updates captions whenever the icon size is set*/
set_captions_from_preferences (self);
- set_icon_size (self, get_icon_size_for_zoom_level (new_level));
+ nautilus_files_model_view_set_icon_size (NAUTILUS_FILES_MODEL_VIEW (self),
+ get_icon_size_for_zoom_level (new_level));
nautilus_files_view_update_toolbar_menus (NAUTILUS_FILES_VIEW (self));
}
@@ -628,79 +217,16 @@ real_can_zoom_out (NautilusFilesView *files_view)
return self->zoom_level > NAUTILUS_GRID_ZOOM_LEVEL_SMALL;
}
-static GdkRectangle *
-get_rectangle_for_item_ui (NautilusViewIconController *self,
- GtkWidget *item_ui)
-{
- GdkRectangle *rectangle;
- GtkWidget *content_widget;
- gdouble view_x;
- gdouble view_y;
-
- rectangle = g_new0 (GdkRectangle, 1);
- gtk_widget_get_allocation (item_ui, rectangle);
-
- content_widget = nautilus_files_view_get_content_widget (NAUTILUS_FILES_VIEW (self));
- gtk_widget_translate_coordinates (item_ui, content_widget,
- rectangle->x, rectangle->y,
- &view_x, &view_y);
- rectangle->x = view_x;
- rectangle->y = view_y;
-
- return rectangle;
-}
-
-static GdkRectangle *
-real_compute_rename_popover_pointing_to (NautilusFilesView *files_view)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- g_autoptr (NautilusViewItemModel) item = NULL;
- GtkWidget *item_ui;
-
- /* We only allow one item to be renamed with a popover */
- item = g_list_model_get_item (G_LIST_MODEL (self->model),
- get_first_selected_item (self));
- item_ui = nautilus_view_item_model_get_item_ui (item);
- g_return_val_if_fail (item_ui != NULL, NULL);
-
- return get_rectangle_for_item_ui (self, item_ui);
-}
-
-static GdkRectangle *
-real_reveal_for_selection_context_menu (NautilusFilesView *files_view)
+static void
+real_scroll_to_item (NautilusFilesModelView *files_model_view,
+ guint position)
{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- g_autoptr (GtkSelectionFilterModel) selection = NULL;
- guint n_selected;
- GtkWidget *focus_child;
- guint i;
- GtkWidget *item_ui;
-
- selection = gtk_selection_filter_model_new (GTK_SELECTION_MODEL (self->model));
- n_selected = g_list_model_get_n_items (G_LIST_MODEL (selection));
- g_return_val_if_fail (n_selected > 0, NULL);
-
- /* Get the focused item_ui, if selected.
- * Otherwise, get the selected item_ui which is sorted the lowest.*/
- focus_child = gtk_widget_get_focus_child (GTK_WIDGET (self->view_ui));
- for (i = 0; i < n_selected; i++)
- {
- g_autoptr (NautilusViewItemModel) item = NULL;
-
- item = g_list_model_get_item (G_LIST_MODEL (selection), i);
- item_ui = nautilus_view_item_model_get_item_ui (item);
- if (item_ui != NULL && gtk_widget_get_parent (item_ui) == focus_child)
- {
- break;
- }
- }
+ NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_model_view);
gtk_widget_activate_action (GTK_WIDGET (self->view_ui),
"list.scroll-to-item",
"u",
- i);
-
- return get_rectangle_for_item_ui (self, item_ui);
+ position);
}
static void
@@ -729,13 +255,14 @@ static void
select_single_item_if_not_selected (NautilusViewIconController *self,
NautilusViewItemModel *item)
{
- GtkSelectionModel *selection_model = GTK_SELECTION_MODEL (self->model);
+ NautilusViewModel *model;
guint position;
- position = nautilus_view_model_get_index (self->model, item);
- if (!gtk_selection_model_is_selected (selection_model, position))
+ model = nautilus_files_model_view_get_model (NAUTILUS_FILES_MODEL_VIEW (self));
+ position = nautilus_view_model_get_index (model, item);
+ if (!gtk_selection_model_is_selected (GTK_SELECTION_MODEL (model), position))
{
- gtk_selection_model_select_item (selection_model, position, TRUE);
+ gtk_selection_model_select_item (GTK_SELECTION_MODEL (model), position, TRUE);
}
}
@@ -824,16 +351,18 @@ on_item_click_released (GtkGestureClick *gesture,
if (self->activate_on_release)
{
+ NautilusViewModel *model;
GtkWidget *event_widget;
NautilusViewItemModel *item_model;
guint i;
+ model = nautilus_files_model_view_get_model (NAUTILUS_FILES_MODEL_VIEW (self));
event_widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
item_model = nautilus_view_icon_item_ui_get_model (NAUTILUS_VIEW_ICON_ITEM_UI (event_widget));
- i = nautilus_view_model_get_index (self->model, item_model);
+ i = nautilus_view_model_get_index (model, item_model);
/* Antecipate selection, enforcing single selection of target item. */
- gtk_selection_model_select_item (GTK_SELECTION_MODEL (self->model), i, TRUE);
+ gtk_selection_model_select_item (GTK_SELECTION_MODEL (model), i, TRUE);
activate_selection_on_click (self, FALSE);
}
@@ -927,207 +456,19 @@ on_longpress_gesture_pressed_callback (GtkGestureLongPress *gesture,
}
}
-static int
-real_compare_files (NautilusFilesView *files_view,
- NautilusFile *file1,
- NautilusFile *file2)
-{
- GActionGroup *view_action_group;
- GAction *action;
- const gchar *target_name;
- gboolean reversed;
- const SortConstants *sort_constants;
- gboolean directories_first;
-
- view_action_group = nautilus_files_view_get_action_group (files_view);
- action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), "sort");
- g_variant_get (g_action_get_state (action), "(&sb)", &target_name, &reversed);
- sort_constants = get_sorts_constants_from_metadata_text (target_name);
- directories_first = nautilus_files_view_should_sort_directories_first (files_view);
-
- return nautilus_file_compare_for_sort (file1, file2,
- sort_constants->sort_type,
- directories_first,
- reversed);
-}
-
-static void
-on_clipboard_contents_received (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- NautilusFilesView *files_view = NAUTILUS_FILES_VIEW (source_object);
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- NautilusClipboard *clip;
- NautilusViewItemModel *item;
-
- for (GList *l = self->cut_files; l != NULL; l = l->next)
- {
- item = nautilus_view_model_get_item_from_file (self->model, l->data);
- if (item != NULL)
- {
- nautilus_view_item_model_set_cut (item, FALSE);
- }
- }
- g_clear_list (&self->cut_files, g_object_unref);
-
- clip = nautilus_files_view_get_clipboard_finish (files_view, res, NULL);
- if (clip != NULL && nautilus_clipboard_is_cut (clip))
- {
- self->cut_files = g_list_copy_deep (nautilus_clipboard_peek_files (clip),
- (GCopyFunc) g_object_ref,
- NULL);
- }
-
- for (GList *l = self->cut_files; l != NULL; l = l->next)
- {
- item = nautilus_view_model_get_item_from_file (self->model, l->data);
- if (item != NULL)
- {
- nautilus_view_item_model_set_cut (item, TRUE);
- }
- }
-}
-
-static void
-update_clipboard_status (NautilusFilesView *files_view)
-{
- nautilus_files_view_get_clipboard_async (files_view,
- on_clipboard_contents_received,
- NULL);
-}
-
-static void
-on_clipboard_owner_changed (GdkClipboard *clipboard,
- gpointer user_data)
-{
- update_clipboard_status (NAUTILUS_FILES_VIEW (user_data));
-}
-
-
-static void
-real_end_loading (NautilusFilesView *files_view,
- gboolean all_files_seen)
-{
- update_clipboard_status (files_view);
-}
-
-static guint
-get_first_visible_item (NautilusViewIconController *self)
-{
- guint n_items;
- gdouble scrolled_y;
-
- n_items = g_list_model_get_n_items (G_LIST_MODEL (self->model));
- scrolled_y = gtk_adjustment_get_value (self->vadjustment);
- for (guint i = 0; i < n_items; i++)
- {
- g_autoptr (NautilusViewItemModel) item = NULL;
- GtkWidget *item_ui;
-
- item = g_list_model_get_item (G_LIST_MODEL (self->model), i);
- item_ui = nautilus_view_item_model_get_item_ui (item);
- if (item_ui != NULL)
- {
- gdouble y;
-
- gtk_widget_translate_coordinates (item_ui, GTK_WIDGET (self->view_ui),
- 0, 0, NULL, &y);
- if (gtk_widget_is_visible (item_ui) && y >= scrolled_y)
- {
- return i;
- }
- }
- }
-
- return G_MAXUINT;
-}
-
-static char *
-real_get_first_visible_file (NautilusFilesView *files_view)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- guint i;
- g_autoptr (NautilusViewItemModel) item = NULL;
- gchar *uri = NULL;
-
- i = get_first_visible_item (self);
- if (i < G_MAXUINT)
- {
- item = g_list_model_get_item (G_LIST_MODEL (self->model), i);
- uri = nautilus_file_get_uri (nautilus_view_item_model_get_file (item));
- }
- return uri;
-}
-
-typedef struct
-{
- NautilusViewIconController *view;
- char *uri;
-} ScrollToFileData;
-
-static void
-scroll_to_file_data_free (ScrollToFileData *data)
-{
- g_free (data->uri);
- g_free (data);
-}
-
-static gboolean
-scroll_to_file_on_idle (ScrollToFileData *data)
-{
- NautilusViewIconController *self = data->view;
- g_autoptr (NautilusFile) file = NULL;
- NautilusViewItemModel *item;
- guint i;
-
- file = nautilus_file_get_existing_by_uri (data->uri);
- item = nautilus_view_model_get_item_from_file (self->model, file);
- i = nautilus_view_model_get_index (self->model, item);
-
- gtk_widget_activate_action (GTK_WIDGET (self->view_ui),
- "list.scroll-to-item",
- "u",
- i);
-
- self->scroll_to_file_handle_id = 0;
- return G_SOURCE_REMOVE;
-}
-
-static void
-real_scroll_to_file (NautilusFilesView *files_view,
- const char *uri)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- ScrollToFileData *data;
- guint handle_id;
-
- /* Not exactly sure why, but the child widgets are not yet realized when
- * this is usually called (which is when view finishes loading. Maybe
- * because GtkFlowBox only generates children at the next GMainContext
- * iteration? Anyway, doing it on idle as low priority works. */
-
- data = g_new (ScrollToFileData, 1);
- data->view = self;
- data->uri = g_strdup (uri);
- handle_id = g_idle_add_full (G_PRIORITY_LOW,
- (GSourceFunc) scroll_to_file_on_idle,
- data,
- (GDestroyNotify) scroll_to_file_data_free);
- self->scroll_to_file_handle_id = handle_id;
-}
-
static void
real_sort_directories_first_changed (NautilusFilesView *files_view)
{
NautilusViewIconController *self;
+ NautilusViewModel *model;
g_autoptr (GtkCustomSorter) sorter = NULL;
self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
self->directories_first = nautilus_files_view_should_sort_directories_first (NAUTILUS_FILES_VIEW (self));
+ model = nautilus_files_model_view_get_model (NAUTILUS_FILES_MODEL_VIEW (self));
sorter = gtk_custom_sorter_new (nautilus_view_icon_controller_sort, self, NULL);
- nautilus_view_model_set_sorter (self->model, GTK_SORTER (sorter));
+ nautilus_view_model_set_sorter (model, GTK_SORTER (sorter));
}
static void
@@ -1136,8 +477,8 @@ action_sort_order_changed (GSimpleAction *action,
gpointer user_data)
{
const gchar *target_name;
- const SortConstants *sort_constants;
- NautilusViewIconController *self;
+ NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (user_data);
+ NautilusViewModel *model;
g_autoptr (GtkCustomSorter) sorter = NULL;
/* Don't resort if the action is in the same state as before */
@@ -1146,86 +487,25 @@ action_sort_order_changed (GSimpleAction *action,
return;
}
- self = NAUTILUS_VIEW_ICON_CONTROLLER (user_data);
g_variant_get (value, "(&sb)", &target_name, &self->reversed);
- sort_constants = get_sorts_constants_from_metadata_text (target_name);
- self->sort_type = sort_constants->sort_type;
- self->directories_first = nautilus_files_view_should_sort_directories_first (NAUTILUS_FILES_VIEW (self));
+ self->sort_type = get_sorts_type_from_metadata_text (target_name);
sorter = gtk_custom_sorter_new (nautilus_view_icon_controller_sort, self, NULL);
- nautilus_view_model_set_sorter (self->model, GTK_SORTER (sorter));
+ model = nautilus_files_model_view_get_model (NAUTILUS_FILES_MODEL_VIEW (self));
+ nautilus_view_model_set_sorter (model, GTK_SORTER (sorter));
set_directory_sort_metadata (nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (self)),
- sort_constants,
+ target_name,
self->reversed);
g_simple_action_set_state (action, value);
}
-static void
-real_add_files (NautilusFilesView *files_view,
- GList *files)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- g_autoptr (GQueue) files_queue = NULL;
- g_autoptr (GQueue) item_models = NULL;
- gdouble adjustment_value;
-
- files_queue = convert_glist_to_queue (files);
- item_models = convert_files_to_item_models (self, files_queue);
- nautilus_view_model_add_items (self->model, item_models);
-
- /* GtkListBase anchoring doesn't cope well with our lazy loading.
- * Assuming that GtkListBase|list.scroll-to-item resets the anchor to 0, use
- * that as a workaround to prevent scrolling while we are at the top. */
- adjustment_value = gtk_adjustment_get_value (self->vadjustment);
- if (G_APPROX_VALUE (adjustment_value, 0.0, DBL_EPSILON))
- {
- gtk_widget_activate_action (GTK_WIDGET (self->view_ui), "list.scroll-to-item", "u", 0);
- }
-}
-
-
static guint
real_get_view_id (NautilusFilesView *files_view)
{
return NAUTILUS_VIEW_GRID_ID;
}
-static void
-real_select_first (NautilusFilesView *files_view)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- g_autoptr (NautilusViewItemModel) item = NULL;
- NautilusFile *file;
- g_autoptr (GList) selection = NULL;
-
- item = NAUTILUS_VIEW_ITEM_MODEL (g_list_model_get_item (G_LIST_MODEL (self->model), 0));
- if (item == NULL)
- {
- return;
- }
- file = nautilus_view_item_model_get_file (item);
- selection = g_list_prepend (selection, file);
- nautilus_view_set_selection (NAUTILUS_VIEW (files_view), selection);
-}
-
-static void
-real_preview_selection_event (NautilusFilesView *files_view,
- GtkDirectionType direction)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- GtkMovementStep step;
- gint count;
- gboolean handled;
-
- step = (direction == GTK_DIR_UP || direction == GTK_DIR_DOWN) ?
- GTK_MOVEMENT_DISPLAY_LINES : GTK_MOVEMENT_VISUAL_POSITIONS;
- count = (direction == GTK_DIR_RIGHT || direction == GTK_DIR_DOWN) ?
- 1 : -1;
-
- g_signal_emit_by_name (self->view_ui, "move-cursor", step, count, &handled);
-}
-
static void
action_zoom_to_level (GSimpleAction *action,
GVariant *state,
@@ -1254,119 +534,22 @@ on_captions_preferences_changed (NautilusViewIconController *self)
/* Hack: this relies on the assumption that NautilusViewIconItemUi updates
* captions whenever the icon size is set (even if it's the same value). */
- set_icon_size (self, get_icon_size_for_zoom_level (self->zoom_level));
-}
-
-static void
-on_default_sort_order_changed (NautilusViewIconController *self)
-{
- update_sort_order_from_metadata_and_preferences (self);
+ nautilus_files_model_view_set_icon_size (NAUTILUS_FILES_MODEL_VIEW (self),
+ get_icon_size_for_zoom_level (self->zoom_level));
}
static void
dispose (GObject *object)
{
- NautilusViewIconController *self;
-
- self = NAUTILUS_VIEW_ICON_CONTROLLER (object);
-
- g_clear_handle_id (&self->scroll_to_file_handle_id, g_source_remove);
- g_clear_handle_id (&self->prioritize_thumbnailing_handle_id, g_source_remove);
-
G_OBJECT_CLASS (nautilus_view_icon_controller_parent_class)->dispose (object);
}
static void
finalize (GObject *object)
{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (object);
-
- g_clear_list (&self->cut_files, g_object_unref);
-
G_OBJECT_CLASS (nautilus_view_icon_controller_parent_class)->finalize (object);
}
-static gboolean
-prioritize_thumbnailing_on_idle (NautilusViewIconController *self)
-{
- gdouble page_size;
- GtkWidget *first_visible_child;
- GtkWidget *next_child;
- guint first_index;
- guint next_index;
- gdouble y;
- guint last_index;
- g_autoptr (NautilusViewItemModel) first_item = NULL;
- NautilusFile *file;
-
- self->prioritize_thumbnailing_handle_id = 0;
-
- page_size = gtk_adjustment_get_page_size (self->vadjustment);
- first_index = get_first_visible_item (self);
- if (first_index == G_MAXUINT)
- {
- return G_SOURCE_REMOVE;
- }
-
- first_item = g_list_model_get_item (G_LIST_MODEL (self->model), first_index);
-
- first_visible_child = nautilus_view_item_model_get_item_ui (first_item);
-
- for (next_index = first_index + 1; next_index < g_list_model_get_n_items (G_LIST_MODEL (self->model));
next_index++)
- {
- g_autoptr (NautilusViewItemModel) next_item = NULL;
-
- next_item = g_list_model_get_item (G_LIST_MODEL (self->model), next_index);
- next_child = nautilus_view_item_model_get_item_ui (next_item);
- if (next_child == NULL)
- {
- break;
- }
- if (gtk_widget_translate_coordinates (next_child, first_visible_child,
- 0, 0, NULL, &y))
- {
- if (y > page_size)
- {
- break;
- }
- }
- }
- last_index = next_index - 1;
-
- /* Do the iteration in reverse to give higher priority to the top */
- for (gint i = 0; i <= last_index - first_index; i++)
- {
- g_autoptr (NautilusViewItemModel) item = NULL;
-
- item = g_list_model_get_item (G_LIST_MODEL (self->model), last_index - i);
- g_return_val_if_fail (item != NULL, G_SOURCE_REMOVE);
-
- file = nautilus_view_item_model_get_file (NAUTILUS_VIEW_ITEM_MODEL (item));
- if (file != NULL && nautilus_file_is_thumbnailing (file))
- {
- g_autofree gchar *uri = nautilus_file_get_uri (file);
- nautilus_thumbnail_prioritize (uri);
- }
- }
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-on_vadjustment_changed (GtkAdjustment *adjustment,
- gpointer user_data)
-{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (user_data);
- guint handle_id;
-
- /* Schedule on idle to rate limit and to avoid delaying scrolling. */
- if (self->prioritize_thumbnailing_handle_id == 0)
- {
- handle_id = g_idle_add ((GSourceFunc) prioritize_thumbnailing_on_idle, self);
- self->prioritize_thumbnailing_handle_id = handle_id;
- }
-}
-
static void
bind_item_ui (GtkSignalListItemFactory *factory,
GtkListItem *listitem,
@@ -1445,15 +628,18 @@ setup_item_ui (GtkSignalListItemFactory *factory,
static GtkGridView *
create_view_ui (NautilusViewIconController *self)
{
+ NautilusViewModel *model;
GtkListItemFactory *factory;
GtkWidget *widget;
+ model = nautilus_files_model_view_get_model (NAUTILUS_FILES_MODEL_VIEW (self));
+
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_item_ui), self);
g_signal_connect (factory, "bind", G_CALLBACK (bind_item_ui), self);
g_signal_connect (factory, "unbind", G_CALLBACK (unbind_item_ui), self);
- widget = gtk_grid_view_new (GTK_SELECTION_MODEL (self->model), factory);
+ widget = gtk_grid_view_new (GTK_SELECTION_MODEL (model), factory);
gtk_widget_set_focusable (widget, TRUE);
gtk_widget_set_valign (widget, GTK_ALIGN_START);
@@ -1477,30 +663,49 @@ const GActionEntry view_icon_actions[] =
};
static void
-constructed (GObject *object)
+nautilus_view_icon_controller_class_init (NautilusViewIconControllerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NautilusFilesViewClass *files_view_class = NAUTILUS_FILES_VIEW_CLASS (klass);
+ NautilusFilesModelViewClass *files_model_view_class = NAUTILUS_FILES_MODEL_VIEW_CLASS (klass);
+
+ object_class->dispose = dispose;
+ object_class->finalize = finalize;
+
+ files_view_class->bump_zoom_level = real_bump_zoom_level;
+ files_view_class->can_zoom_in = real_can_zoom_in;
+ files_view_class->can_zoom_out = real_can_zoom_out;
+ files_view_class->click_policy_changed = real_click_policy_changed;
+ files_view_class->sort_directories_first_changed = real_sort_directories_first_changed;
+ files_view_class->get_view_id = real_get_view_id;
+ files_view_class->restore_standard_zoom_level = real_restore_standard_zoom_level;
+ files_view_class->is_zoom_level_default = real_is_zoom_level_default;
+
+ files_model_view_class->get_icon_size = real_get_icon_size;
+ files_model_view_class->get_view_ui = real_get_view_ui;
+ files_model_view_class->scroll_to_item = real_scroll_to_item;
+}
+
+static void
+nautilus_view_icon_controller_init (NautilusViewIconController *self)
{
- NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (object);
GtkWidget *content_widget;
- GtkAdjustment *vadjustment;
- GActionGroup *view_action_group;
GtkEventController *controller;
- content_widget = nautilus_files_view_get_content_widget (NAUTILUS_FILES_VIEW (self));
- vadjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (content_widget));
+ gtk_widget_add_css_class (GTK_WIDGET (self), "nautilus-grid-view");
+ set_click_mode_from_settings (self);
- self->vadjustment = vadjustment;
- g_signal_connect (vadjustment, "changed", (GCallback) on_vadjustment_changed, self);
- g_signal_connect (vadjustment, "value-changed", (GCallback) on_vadjustment_changed, self);
+ set_captions_from_preferences (self);
+ g_signal_connect_object (nautilus_icon_view_preferences,
+ "changed::" NAUTILUS_PREFERENCES_ICON_VIEW_CAPTIONS,
+ G_CALLBACK (on_captions_preferences_changed),
+ self,
+ G_CONNECT_SWAPPED);
- self->model = nautilus_view_model_new ();
- self->view_ui = create_view_ui (self);
- gtk_widget_show (GTK_WIDGET (self->view_ui));
+ content_widget = nautilus_files_view_get_content_widget (NAUTILUS_FILES_VIEW (self));
- g_signal_connect_swapped (GTK_SELECTION_MODEL (self->model),
- "selection-changed",
- G_CALLBACK (nautilus_files_view_notify_selection_changed),
- NAUTILUS_FILES_VIEW (self));
+ self->view_ui = create_view_ui (self);
controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ());
gtk_widget_add_controller (GTK_WIDGET (content_widget), controller);
@@ -1525,96 +730,12 @@ constructed (GObject *object)
G_N_ELEMENTS (view_icon_actions),
self);
- gtk_widget_show (GTK_WIDGET (self));
-
- view_action_group = nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (self));
- g_action_map_add_action_entries (G_ACTION_MAP (view_action_group),
- view_icon_actions,
- G_N_ELEMENTS (view_icon_actions),
- self);
self->zoom_level = get_default_zoom_level ();
/* Keep the action synced with the actual value, so the toolbar can poll it */
g_action_group_change_action_state (nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (self)),
"zoom-to-level", g_variant_new_int32 (self->zoom_level));
}
-static void
-nautilus_view_icon_controller_class_init (NautilusViewIconControllerClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- NautilusFilesViewClass *files_view_class = NAUTILUS_FILES_VIEW_CLASS (klass);
-
- object_class->dispose = dispose;
- object_class->finalize = finalize;
- object_class->constructed = constructed;
-
- files_view_class->add_files = real_add_files;
- files_view_class->begin_loading = real_begin_loading;
- files_view_class->bump_zoom_level = real_bump_zoom_level;
- files_view_class->can_zoom_in = real_can_zoom_in;
- files_view_class->can_zoom_out = real_can_zoom_out;
- files_view_class->click_policy_changed = real_click_policy_changed;
- files_view_class->clear = real_clear;
- files_view_class->file_changed = real_file_changed;
- files_view_class->get_selection = real_get_selection;
- /* TODO: remove this get_selection_for_file_transfer, this doesn't even
- * take into account we could us the view for recursive search :/
- * CanvasView has the same issue. */
- files_view_class->get_selection_for_file_transfer = real_get_selection;
- files_view_class->is_empty = real_is_empty;
- files_view_class->remove_file = real_remove_file;
- files_view_class->update_actions_state = real_update_actions_state;
- files_view_class->reveal_selection = real_reveal_selection;
- files_view_class->select_all = real_select_all;
- files_view_class->invert_selection = real_invert_selection;
- files_view_class->set_selection = real_set_selection;
- files_view_class->compare_files = real_compare_files;
- files_view_class->sort_directories_first_changed = real_sort_directories_first_changed;
- files_view_class->end_file_changes = real_end_file_changes;
- files_view_class->end_loading = real_end_loading;
- files_view_class->get_view_id = real_get_view_id;
- files_view_class->get_first_visible_file = real_get_first_visible_file;
- files_view_class->scroll_to_file = real_scroll_to_file;
- files_view_class->select_first = real_select_first;
- files_view_class->restore_standard_zoom_level = real_restore_standard_zoom_level;
- files_view_class->is_zoom_level_default = real_is_zoom_level_default;
- files_view_class->compute_rename_popover_pointing_to = real_compute_rename_popover_pointing_to;
- files_view_class->reveal_for_selection_context_menu = real_reveal_for_selection_context_menu;
- files_view_class->preview_selection_event = real_preview_selection_event;
-}
-
-static void
-nautilus_view_icon_controller_init (NautilusViewIconController *self)
-{
- gtk_widget_add_css_class (GTK_WIDGET (self), "view");
- gtk_widget_add_css_class (GTK_WIDGET (self), "nautilus-grid-view");
- set_click_mode_from_settings (self);
-
- g_signal_connect_object (nautilus_preferences,
- "changed::" NAUTILUS_PREFERENCES_DEFAULT_SORT_ORDER,
- G_CALLBACK (on_default_sort_order_changed),
- self,
- G_CONNECT_SWAPPED);
- g_signal_connect_object (nautilus_preferences,
- "changed::" NAUTILUS_PREFERENCES_DEFAULT_SORT_IN_REVERSE_ORDER,
- G_CALLBACK (on_default_sort_order_changed),
- self,
- G_CONNECT_SWAPPED);
-
- set_captions_from_preferences (self);
- g_signal_connect_object (nautilus_icon_view_preferences,
- "changed::" NAUTILUS_PREFERENCES_ICON_VIEW_CAPTIONS,
- G_CALLBACK (on_captions_preferences_changed),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (gdk_display_get_clipboard (gdk_display_get_default ()),
- "changed",
- G_CALLBACK (on_clipboard_owner_changed),
- self,
- 0);
-}
-
NautilusViewIconController *
nautilus_view_icon_controller_new (NautilusWindowSlot *slot)
{
diff --git a/src/nautilus-view-icon-controller.h b/src/nautilus-view-icon-controller.h
index be70c94bd..f0e71da57 100644
--- a/src/nautilus-view-icon-controller.h
+++ b/src/nautilus-view-icon-controller.h
@@ -3,15 +3,14 @@
#include <glib.h>
#include <gtk/gtk.h>
-#include "nautilus-files-view.h"
+#include "nautilus-files-model-view.h"
#include "nautilus-window-slot.h"
-#include "nautilus-view-model.h"
G_BEGIN_DECLS
#define NAUTILUS_TYPE_VIEW_ICON_CONTROLLER (nautilus_view_icon_controller_get_type())
-G_DECLARE_FINAL_TYPE (NautilusViewIconController, nautilus_view_icon_controller, NAUTILUS,
VIEW_ICON_CONTROLLER, NautilusFilesView)
+G_DECLARE_FINAL_TYPE (NautilusViewIconController, nautilus_view_icon_controller, NAUTILUS,
VIEW_ICON_CONTROLLER, NautilusFilesModelView)
NautilusViewIconController *nautilus_view_icon_controller_new (NautilusWindowSlot *slot);
diff --git a/src/nautilus-view-model.c b/src/nautilus-view-model.c
index 2d4deee02..55c6cf8b6 100644
--- a/src/nautilus-view-model.c
+++ b/src/nautilus-view-model.c
@@ -172,7 +172,7 @@ get_property (GObject *object,
{
case PROP_SORTER:
{
- g_value_set_object (value, self->sorter);
+ g_value_set_object (value, nautilus_view_model_get_sorter (self));
}
break;
@@ -275,6 +275,12 @@ nautilus_view_model_new ()
return g_object_new (NAUTILUS_TYPE_VIEW_MODEL, NULL);
}
+GtkSorter *
+nautilus_view_model_get_sorter (NautilusViewModel *self)
+{
+ return self->sorter;
+}
+
void
nautilus_view_model_set_sorter (NautilusViewModel *self,
GtkSorter *sorter)
diff --git a/src/nautilus-view-model.h b/src/nautilus-view-model.h
index 1771cd6e2..d76c3987d 100644
--- a/src/nautilus-view-model.h
+++ b/src/nautilus-view-model.h
@@ -12,6 +12,7 @@ G_DECLARE_FINAL_TYPE (NautilusViewModel, nautilus_view_model, NAUTILUS, VIEW_MOD
NautilusViewModel * nautilus_view_model_new (void);
+GtkSorter *nautilus_view_model_get_sorter (NautilusViewModel *self);
void nautilus_view_model_set_sorter (NautilusViewModel *self,
GtkSorter *sorter);
NautilusViewItemModel * nautilus_view_model_get_item_from_file (NautilusViewModel *self,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]