summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Soriano <csoriano@gnome.org>2017-03-10 14:10:45 +0100
committerCarlos Soriano <csoriano@gnome.org>2017-03-10 15:26:15 +0100
commit1a1e367fd0a098e97f542b63e7361ba68a9166da (patch)
treeafef01fedd5f71dc41f5e856a0ecc4d81161abba
parent8eaea9080fdd6adc1597d54d65c0ddb1e01973ed (diff)
downloadnautilus-1a1e367fd0a098e97f542b63e7361ba68a9166da.tar.gz
nautilus-view-icon: Rework selection and loading
Better performance, code design and fixes some issues.
-rw-r--r--src/nautilus-view-icon-controller.c64
-rw-r--r--src/nautilus-view-icon-ui.c61
-rw-r--r--src/nautilus-view-icon-ui.h4
-rw-r--r--src/nautilus-view-item-model.c42
-rw-r--r--src/nautilus-view-item-model.h5
-rw-r--r--src/nautilus-view-model.c76
-rw-r--r--src/nautilus-view-model.h8
7 files changed, 114 insertions, 146 deletions
diff --git a/src/nautilus-view-icon-controller.c b/src/nautilus-view-icon-controller.c
index 507eb9464..9c32a1893 100644
--- a/src/nautilus-view-icon-controller.c
+++ b/src/nautilus-view-icon-controller.c
@@ -250,7 +250,7 @@ real_clear (NautilusFilesView *files_view)
{
NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- g_list_store_remove_all (nautilus_view_model_get_g_model (self->model));
+ nautilus_view_model_remove_all_items (self->model);
}
@@ -279,13 +279,17 @@ real_get_selection (NautilusFilesView *files_view)
NautilusViewIconController *self;
GList *selected_files = NULL;
GList *l;
- g_autoptr (GQueue) selected_items = NULL;
+ g_autoptr (GList) selected_items = NULL;
self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
- selected_items = nautilus_view_model_get_selected (self->model);
- for (l = g_queue_peek_head_link (selected_items); l != NULL; l = l->next)
+ selected_items = gtk_flow_box_get_selected_children (GTK_FLOW_BOX (self->view_ui));
+ for (l = selected_items; l != NULL; l = l->next)
{
- selected_files = g_list_prepend (selected_files, l->data);
+ NautilusViewItemModel *item_model;
+
+ item_model = nautilus_view_icon_item_ui_get_model (NAUTILUS_VIEW_ICON_ITEM_UI (l->data));
+ selected_files = g_list_prepend (selected_files,
+ g_object_ref (nautilus_view_item_model_get_file (item_model)));
}
return selected_files;
@@ -378,7 +382,7 @@ real_set_selection (NautilusFilesView *files_view,
selection_files = convert_glist_to_queue (selection);
selection_item_models = nautilus_view_model_get_items_from_files (self->model, selection_files);
- nautilus_view_model_set_selected (self->model, selection_item_models);
+ nautilus_view_icon_ui_set_selection (self->view_ui, selection_item_models);
nautilus_files_view_notify_selection_changed (files_view);
}
@@ -603,27 +607,53 @@ on_button_press_event (GtkWidget *widget,
gpointer user_data)
{
NautilusViewIconController *self;
- GList *selection;
+ g_autoptr (GList) selection = NULL;
GtkWidget *child_at_pos;
- NautilusViewItemModel *item_model;
GdkEventButton *event_button;
self = NAUTILUS_VIEW_ICON_CONTROLLER (user_data);
event_button = (GdkEventButton *) event;
- if ((event_button->button == GDK_BUTTON_SECONDARY))
+ /* Need to update the selection so the popup has the right actions enabled */
+ selection = nautilus_view_get_selection (NAUTILUS_VIEW (self));
+ child_at_pos = GTK_WIDGET (gtk_flow_box_get_child_at_pos (GTK_FLOW_BOX (self->view_ui),
+ event_button->x, event_button->y));
+ if (child_at_pos != NULL)
{
- /* Need to update the selection so the popup has the right actions enabled */
- selection = nautilus_view_get_selection (NAUTILUS_VIEW (self));
- child_at_pos = GTK_WIDGET (gtk_flow_box_get_child_at_pos (GTK_FLOW_BOX (self->view_ui),
- event_button->x, event_button->y));
+ NautilusFile *selected_file;
+ NautilusViewItemModel *item_model;
+
item_model = nautilus_view_icon_item_ui_get_model (NAUTILUS_VIEW_ICON_ITEM_UI (child_at_pos));
- selection = g_list_prepend (selection, nautilus_view_item_model_get_file (item_model));
+ selected_file = nautilus_view_item_model_get_file (item_model);
+ if (g_list_find (selection, selected_file) == NULL)
+ {
+ g_list_foreach (selection, (GFunc) g_object_unref, NULL);
+ selection = g_list_append (NULL, selected_file);
+ }
+ else
+ {
+ selection = g_list_prepend (selection, g_object_ref (selected_file));
+ }
+
nautilus_view_set_selection (NAUTILUS_VIEW (self), selection);
- nautilus_files_view_pop_up_selection_context_menu (NAUTILUS_FILES_VIEW (self),
- event_button);
+ if (event_button->button == GDK_BUTTON_SECONDARY)
+ {
+ nautilus_files_view_pop_up_selection_context_menu (NAUTILUS_FILES_VIEW (self),
+ event_button);
+ }
}
+ else
+ {
+ nautilus_view_set_selection (NAUTILUS_VIEW (self), NULL);
+ if (event_button->button == GDK_BUTTON_SECONDARY)
+ {
+ nautilus_files_view_pop_up_background_context_menu (NAUTILUS_FILES_VIEW (self),
+ event_button);
+ }
+ }
+
+ g_list_foreach (selection, (GFunc) g_object_unref, NULL);
return GDK_EVENT_STOP;
}
@@ -727,7 +757,7 @@ real_add_files (NautilusFilesView *files_view,
files_queue = convert_glist_to_queue (files);
item_models = convert_files_to_item_models (self, files_queue);
- nautilus_view_model_set_items (self->model, item_models);
+ nautilus_view_model_add_items (self->model, item_models);
}
diff --git a/src/nautilus-view-icon-ui.c b/src/nautilus-view-icon-ui.c
index 6df82a7ba..1f2639f4a 100644
--- a/src/nautilus-view-icon-ui.c
+++ b/src/nautilus-view-icon-ui.c
@@ -98,25 +98,34 @@ set_property (GObject *object,
}
}
-static void
-on_view_item_model_selected_changed (GObject *object,
- GParamSpec *pspec,
- gpointer user_data)
+void
+nautilus_view_icon_ui_set_selection (NautilusViewIconUi *self,
+ GQueue *selection)
{
- NautilusViewIconUi *self;
NautilusViewItemModel *item_model;
- GtkFlowBoxChild *item_ui;
+ NautilusViewModel *model;
+ GListStore *gmodel;
+ gint i = 0;
- self = NAUTILUS_VIEW_ICON_UI (user_data);
- item_model = NAUTILUS_VIEW_ITEM_MODEL (object);
- item_ui = GTK_FLOW_BOX_CHILD (nautilus_view_item_model_get_item_ui (item_model));
- if (nautilus_view_item_model_get_is_selected (item_model) && !gtk_flow_box_child_is_selected (item_ui))
- {
- gtk_flow_box_select_child (GTK_FLOW_BOX (self), item_ui);
- }
- else if (!nautilus_view_item_model_get_is_selected (item_model) && gtk_flow_box_child_is_selected (item_ui))
+ model = nautilus_view_icon_controller_get_model (self->controller);
+ gmodel = nautilus_view_model_get_g_model (model);
+ while ((item_model = NAUTILUS_VIEW_ITEM_MODEL (g_list_model_get_item (G_LIST_MODEL (gmodel), i))))
{
- gtk_flow_box_unselect_child (GTK_FLOW_BOX (self), item_ui);
+ GtkWidget *item_ui;
+
+ item_ui = nautilus_view_item_model_get_item_ui (item_model);
+ if (g_queue_find (selection, item_model) != NULL)
+ {
+ gtk_flow_box_select_child (GTK_FLOW_BOX (self),
+ GTK_FLOW_BOX_CHILD (item_ui));
+ }
+ else
+ {
+ gtk_flow_box_unselect_child (GTK_FLOW_BOX (self),
+ GTK_FLOW_BOX_CHILD (item_ui));
+ }
+
+ i++;
}
}
@@ -125,7 +134,6 @@ static GtkWidget *
create_widget_func (gpointer item,
gpointer user_data)
{
- NautilusViewIconUi *self = NAUTILUS_VIEW_ICON_UI (user_data);
NautilusViewItemModel *item_model = NAUTILUS_VIEW_ITEM_MODEL (item);
NautilusViewIconItemUi *child;
@@ -133,9 +141,6 @@ create_widget_func (gpointer item,
nautilus_view_item_model_set_item_ui (item_model, GTK_WIDGET (child));
gtk_widget_show (GTK_WIDGET (child));
- g_signal_connect (item_model, "notify::selected",
- (GCallback) on_view_item_model_selected_changed, self);
-
return GTK_WIDGET (child);
}
@@ -161,25 +166,9 @@ on_ui_selected_children_changed (GtkFlowBox *box,
gpointer user_data)
{
NautilusViewIconUi *self;
- GList *selected_children_ui;
- GList *l;
- GList *files_selection;
self = NAUTILUS_VIEW_ICON_UI (user_data);
- files_selection = NULL;
-
- selected_children_ui = gtk_flow_box_get_selected_children (GTK_FLOW_BOX (self));
- for (l = selected_children_ui; l != NULL; l = l->next)
- {
- NautilusViewItemModel *item_model;
- NautilusFile *file;
-
- item_model = nautilus_view_icon_item_ui_get_model (NAUTILUS_VIEW_ICON_ITEM_UI (l->data));
- file = nautilus_view_item_model_get_file (item_model);
- files_selection = g_list_prepend (files_selection, file);
- }
-
- nautilus_view_set_selection (NAUTILUS_VIEW (self->controller), files_selection);
+ nautilus_files_view_notify_selection_changed (NAUTILUS_FILES_VIEW (self->controller));
}
static void
diff --git a/src/nautilus-view-icon-ui.h b/src/nautilus-view-icon-ui.h
index 5361acc17..e8832759a 100644
--- a/src/nautilus-view-icon-ui.h
+++ b/src/nautilus-view-icon-ui.h
@@ -30,6 +30,10 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (NautilusViewIconUi, nautilus_view_icon_ui, NAUTILUS, VIEW_ICON_UI, GtkFlowBox)
NautilusViewIconUi * nautilus_view_icon_ui_new (NautilusViewIconController *controller);
+/* TODO: this should become the "nautilus_view_set_selection" once we have a proper
+ * MVC also in the nautilus-view level. */
+void nautilus_view_icon_ui_set_selection (NautilusViewIconUi *self,
+ GQueue *selection);
G_END_DECLS
diff --git a/src/nautilus-view-item-model.c b/src/nautilus-view-item-model.c
index 970fb284a..e50f2d800 100644
--- a/src/nautilus-view-item-model.c
+++ b/src/nautilus-view-item-model.c
@@ -7,7 +7,6 @@ struct _NautilusViewItemModel
guint icon_size;
NautilusFile *file;
GtkLabel *label;
- gboolean selected;
GtkWidget *item_ui;
};
@@ -18,7 +17,6 @@ enum
PROP_0,
PROP_FILE,
PROP_ICON_SIZE,
- PROP_SELECTED,
PROP_ITEM_UI,
N_PROPS
};
@@ -51,12 +49,6 @@ nautilus_view_item_model_get_property (GObject *object,
}
break;
- case PROP_SELECTED:
- {
- g_value_set_boolean (value, self->selected);
- }
- break;
-
case PROP_ITEM_UI:
{
g_value_set_object (value, self->item_ui);
@@ -92,12 +84,6 @@ nautilus_view_item_model_set_property (GObject *object,
}
break;
- case PROP_SELECTED:
- {
- nautilus_view_item_model_set_selected (self, g_value_get_boolean (value));
- }
- break;
-
case PROP_ITEM_UI:
{
nautilus_view_item_model_set_item_ui (self, g_value_get_object (value));
@@ -141,13 +127,6 @@ nautilus_view_item_model_class_init (NautilusViewItemModelClass *klass)
"The file the icon item represents",
NAUTILUS_TYPE_FILE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
- g_object_class_install_property (object_class,
- PROP_SELECTED,
- g_param_spec_boolean ("selected",
- "Selected",
- "Sets the item as selected",
- FALSE,
- G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_ITEM_UI,
@@ -207,27 +186,6 @@ nautilus_view_item_model_set_file (NautilusViewItemModel *self,
g_object_notify (G_OBJECT (self), "file");
}
-gboolean
-nautilus_view_item_model_get_is_selected (NautilusViewItemModel *self)
-{
- g_return_val_if_fail (NAUTILUS_IS_VIEW_ITEM_MODEL (self), FALSE);
-
- return self->selected;
-}
-
-void
-nautilus_view_item_model_set_selected (NautilusViewItemModel *self,
- gboolean selected)
-{
- g_return_if_fail (NAUTILUS_IS_VIEW_ITEM_MODEL (self));
-
- if (self->selected != !!selected)
- {
- self->selected = !!selected;
- g_object_notify (G_OBJECT (self), "selected");
- }
-}
-
GtkWidget *
nautilus_view_item_model_get_item_ui (NautilusViewItemModel *self)
{
diff --git a/src/nautilus-view-item-model.h b/src/nautilus-view-item-model.h
index 39a8bc0dd..16870de7a 100644
--- a/src/nautilus-view-item-model.h
+++ b/src/nautilus-view-item-model.h
@@ -25,11 +25,6 @@ void nautilus_view_item_model_set_file (NautilusViewItemModel *self,
NautilusFile * nautilus_view_item_model_get_file (NautilusViewItemModel *self);
-void nautilus_view_item_model_set_selected (NautilusViewItemModel *self,
- gboolean selected);
-
-gboolean nautilus_view_item_model_get_is_selected (NautilusViewItemModel *self);
-
void nautilus_view_item_model_set_item_ui (NautilusViewItemModel *self,
GtkWidget *item_ui);
diff --git a/src/nautilus-view-model.c b/src/nautilus-view-model.c
index 2f054e5e2..f45ecef96 100644
--- a/src/nautilus-view-model.c
+++ b/src/nautilus-view-model.c
@@ -233,67 +233,57 @@ nautilus_view_model_remove_item (NautilusViewModel *self,
if (item_model != NULL)
{
+ NautilusFile *file;
+
+ file = nautilus_view_item_model_get_file (item_model);
g_list_store_remove (self->internal_model, i);
+ g_hash_table_remove (self->map_files_to_model, file);
}
}
void
+nautilus_view_model_remove_all_items (NautilusViewModel *self)
+{
+ g_list_store_remove_all (self->internal_model);
+ g_hash_table_remove_all (self->map_files_to_model);
+}
+
+void
nautilus_view_model_add_item (NautilusViewModel *self,
NautilusViewItemModel *item)
{
+ g_hash_table_insert (self->map_files_to_model,
+ nautilus_view_item_model_get_file (item),
+ item);
g_list_store_insert_sorted (self->internal_model, item, compare_data_func, self);
}
void
-nautilus_view_model_set_selected (NautilusViewModel *self,
- GQueue *item_models)
+nautilus_view_model_add_items (NautilusViewModel *self,
+ GQueue *items)
{
+ g_autofree gpointer *array = NULL;
GList *l;
- NautilusViewItemModel *item_model;
-
- gint i = 0;
- while ((item_model = g_list_model_get_item (G_LIST_MODEL (self->internal_model), i)))
- {
- gboolean selected;
-
- selected = FALSE;
- for (l = g_queue_peek_head_link (item_models); l != NULL; l = l->next)
- {
- NautilusViewItemModel *selected_item_model;
-
- selected_item_model = NAUTILUS_VIEW_ITEM_MODEL (l->data);
- if (item_model == selected_item_model)
- {
- selected = TRUE;
- break;
- }
- }
- i++;
-
- nautilus_view_item_model_set_selected (item_model, selected);
- }
-}
+ int i = 0;
-GQueue *
-nautilus_view_model_get_selected (NautilusViewModel *self)
-{
- NautilusViewItemModel *item_model;
- GQueue *selected_items;
- gint i;
+ array = g_malloc_n (g_queue_get_length (items),
+ sizeof (NautilusViewItemModel *));
- i = 0;
- selected_items = g_queue_new ();
- while ((item_model = g_list_model_get_item (G_LIST_MODEL (self->internal_model), i)))
+ g_hash_table_remove_all (self->map_files_to_model);
+ for (l = g_queue_peek_head_link (items); l != NULL; l = l->next)
{
- if (nautilus_view_item_model_get_is_selected (item_model))
- {
- g_queue_push_tail (selected_items,
- g_object_ref (nautilus_view_item_model_get_file (item_model)));
- }
+ array[i] = l->data;
+ g_hash_table_insert (self->map_files_to_model,
+ nautilus_view_item_model_get_file (l->data),
+ l->data);
i++;
}
- return selected_items;
+ g_list_store_splice (self->internal_model,
+ g_list_model_get_n_items (G_LIST_MODEL (self->internal_model)),
+ 0, array, g_queue_get_length (items));
+
+ g_list_store_sort (self->internal_model, compare_data_func, self);
}
void
@@ -318,8 +308,8 @@ nautilus_view_model_set_items (NautilusViewModel *self,
}
g_list_store_splice (self->internal_model,
- g_list_model_get_n_items (G_LIST_MODEL (self->internal_model)),
- 0, array, g_queue_get_length (items));
+ 0, g_list_model_get_n_items (G_LIST_MODEL (self->internal_model)),
+ array, g_queue_get_length (items));
g_list_store_sort (self->internal_model, compare_data_func, self);
}
diff --git a/src/nautilus-view-model.h b/src/nautilus-view-model.h
index 9734032ed..5e64d842e 100644
--- a/src/nautilus-view-model.h
+++ b/src/nautilus-view-model.h
@@ -28,13 +28,15 @@ NautilusViewItemModel * nautilus_view_model_get_item_from_file (NautilusViewMode
NautilusFile *file);
GQueue * nautilus_view_model_get_items_from_files (NautilusViewModel *self,
GQueue *files);
+/* Don't use inside a loop, use nautilus_view_model_remove_all_items instead. */
void nautilus_view_model_remove_item (NautilusViewModel *self,
NautilusViewItemModel *item);
+void nautilus_view_model_remove_all_items (NautilusViewModel *self);
+/* Don't use inside a loop, use nautilus_view_model_add_items instead. */
void nautilus_view_model_add_item (NautilusViewModel *self,
NautilusViewItemModel *item);
-void nautilus_view_model_set_selected (NautilusViewModel *self,
- GQueue *item_models);
-GQueue * nautilus_view_model_get_selected (NautilusViewModel *self);
+void nautilus_view_model_add_items (NautilusViewModel *self,
+ GQueue *items);
void nautilus_view_model_set_items (NautilusViewModel *self,
GQueue *items);
G_END_DECLS