diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index 926658816d8b40891a745940379feea9f55064a8..5057f3b20d2faf3aeaac0a8ee59870feb481d88d 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -212,7 +212,6 @@ typedef struct
* after it finishes loading the directory and its view.
*/
gboolean loading;
- gboolean subdirectory_loading;
gboolean in_destruction;
@@ -224,6 +223,7 @@ typedef struct
gboolean metadata_for_files_in_directory_pending;
GList *subdirectory_list;
+ GList *subdirectories_loading;
GMenu *selection_menu_model;
GMenu *background_menu_model;
@@ -734,23 +734,6 @@ real_end_loading (NautilusFilesView *self,
update_cut_status (self);
}
-static char *
-real_get_backing_uri (NautilusFilesView *view)
-{
- NautilusFilesViewPrivate *priv;
-
- g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
-
- priv = nautilus_files_view_get_instance_private (view);
-
- if (priv->directory == NULL)
- {
- return NULL;
- }
-
- return nautilus_directory_get_uri (priv->directory);
-}
-
/**
*
* nautilus_files_view_get_backing_uri:
@@ -764,7 +747,19 @@ nautilus_files_view_get_backing_uri (NautilusFilesView *view)
{
g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
- return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_backing_uri (view);
+ NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
+ g_autoptr (NautilusViewItem) item = nautilus_list_base_get_backing_item (NAUTILUS_LIST_BASE (view));
+
+ if (item != NULL)
+ {
+ return nautilus_file_get_uri (nautilus_view_item_get_file (item));
+ }
+ else if (priv->directory != NULL)
+ {
+ return nautilus_directory_get_uri (priv->directory);
+ }
+
+ return NULL;
}
/**
@@ -1225,18 +1220,6 @@ nautilus_files_view_get_window (NautilusFilesView *view)
return nautilus_window_slot_get_window (priv->slot);
}
-NautilusWindowSlot *
-nautilus_files_view_get_nautilus_window_slot (NautilusFilesView *view)
-{
- NautilusFilesViewPrivate *priv;
-
- priv = nautilus_files_view_get_instance_private (view);
-
- g_assert (priv->slot != NULL);
-
- return priv->slot;
-}
-
/* Returns the GtkWindow that this directory view occupies, or NULL
* if at the moment this directory view is not in a GtkWindow or the
* GtkWindow cannot be determined. Primarily used for parenting dialogs.
@@ -1446,7 +1429,8 @@ action_open_item_location (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
- NautilusFilesView *view;
+ NautilusFilesView *view = NAUTILUS_FILES_VIEW (user_data);
+ NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
g_autolist (NautilusFile) selection = NULL;
NautilusFile *item;
GFile *activation_location;
@@ -1454,7 +1438,6 @@ action_open_item_location (GSimpleAction *action,
NautilusFile *parent;
g_autoptr (GFile) parent_location = NULL;
- view = NAUTILUS_FILES_VIEW (user_data);
selection = nautilus_view_get_selection (NAUTILUS_VIEW (view));
if (!selection)
@@ -1479,7 +1462,7 @@ action_open_item_location (GSimpleAction *action,
nautilus_application_open_location_full (NAUTILUS_APPLICATION (g_application_get_default ()),
parent_location, 0, selection, NULL,
- nautilus_files_view_get_nautilus_window_slot (view));
+ priv->slot);
nautilus_file_unref (parent);
nautilus_file_unref (activation_file);
@@ -3282,6 +3265,34 @@ on_popup_selection_context_menu (NautilusListBase *list_base,
nautilus_files_view_pop_up_selection_context_menu (self, &view_point);
}
+static void
+on_load_subdirectory (NautilusListBase *list_base,
+ NautilusViewItem *item,
+ gpointer user_data)
+{
+ NautilusFilesView *self = NAUTILUS_FILES_VIEW (user_data);
+ g_autoptr (NautilusDirectory) directory = nautilus_directory_get_for_file (nautilus_view_item_get_file (item));
+
+ if (!nautilus_files_view_has_subdirectory (self, directory))
+ {
+ nautilus_files_view_add_subdirectory (self, directory);
+ }
+}
+
+static void
+on_unload_subdirectory (NautilusListBase *list_base,
+ NautilusViewItem *item,
+ gpointer user_data)
+{
+ NautilusFilesView *self = NAUTILUS_FILES_VIEW (user_data);
+ g_autoptr (NautilusDirectory) directory = nautilus_directory_get_for_file (nautilus_view_item_get_file (item));
+
+ if (nautilus_files_view_has_subdirectory (self, directory))
+ {
+ nautilus_files_view_remove_subdirectory (self, directory);
+ }
+}
+
static void
nautilus_files_view_constructed (GObject *object)
{
@@ -3311,6 +3322,16 @@ nautilus_files_view_constructed (GObject *object)
g_signal_connect_object (NAUTILUS_LIST_BASE (self), "popup-selection-context-menu",
G_CALLBACK (on_popup_selection_context_menu), self,
G_CONNECT_DEFAULT);
+
+ if (NAUTILUS_IS_LIST_VIEW (NAUTILUS_LIST_BASE (self)))
+ {
+ g_signal_connect_object (NAUTILUS_LIST_BASE (self), "load-subdirectory",
+ G_CALLBACK (on_load_subdirectory), self,
+ G_CONNECT_DEFAULT);
+ g_signal_connect_object (NAUTILUS_LIST_BASE (self), "unload-subdirectory",
+ G_CALLBACK (on_unload_subdirectory), self,
+ G_CONNECT_DEFAULT);
+ }
}
static void
@@ -3349,6 +3370,7 @@ nautilus_files_view_dispose (GObject *object)
remove_directory_from_templates_directory_list (view, node->data);
}
+ g_clear_pointer (&priv->subdirectories_loading, g_list_free);
while (priv->subdirectory_list != NULL)
{
nautilus_files_view_remove_subdirectory (view,
@@ -4612,7 +4634,7 @@ queue_pending_files (NautilusFilesView *view,
* search it can be a long wait, and we actually want to show files as
* they are getting found. So for search is fine if not all files are
* seen */
- if ((!priv->loading && !priv->subdirectory_loading) ||
+ if ((!priv->loading && priv->subdirectories_loading == NULL) ||
(nautilus_directory_are_all_files_seen (directory) ||
nautilus_view_is_searching (NAUTILUS_VIEW (view))))
{
@@ -4823,8 +4845,15 @@ subdirectory_done_loading (NautilusDirectory *directory,
{
NautilusFilesView *view = user_data;
NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
+ g_autoptr (NautilusFile) file = nautilus_directory_get_corresponding_file (directory);
+ NautilusViewItem *item = nautilus_view_model_get_item_for_file (priv->model, file);
- priv->subdirectory_loading = FALSE;
+ priv->subdirectories_loading = g_list_remove (priv->subdirectories_loading, directory);
+
+ if (item != NULL)
+ {
+ nautilus_view_item_set_loading (item, FALSE);
+ }
}
void
@@ -4832,11 +4861,9 @@ nautilus_files_view_add_subdirectory (NautilusFilesView *view,
NautilusDirectory *directory)
{
NautilusFileAttributes attributes;
- NautilusFilesViewPrivate *priv;
-
- priv = nautilus_files_view_get_instance_private (view);
-
- priv->subdirectory_loading = TRUE;
+ NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
+ g_autoptr (NautilusFile) file = nautilus_directory_get_corresponding_file (directory);
+ NautilusViewItem *item = nautilus_view_model_get_item_for_file (priv->model, file);
g_return_if_fail (!g_list_find (priv->subdirectory_list, directory));
@@ -4865,23 +4892,36 @@ nautilus_files_view_add_subdirectory (NautilusFilesView *view,
G_CALLBACK (subdirectory_done_loading),
view, 0);
- priv->subdirectory_list = g_list_prepend (
- priv->subdirectory_list, directory);
+ priv->subdirectory_list = g_list_prepend (priv->subdirectory_list, directory);
+ priv->subdirectories_loading = g_list_prepend (priv->subdirectories_loading, directory);
+
+ if (item != NULL &&
+ !nautilus_directory_are_all_files_seen (directory))
+ {
+ nautilus_view_item_set_loading (item, TRUE);
+ }
}
void
nautilus_files_view_remove_subdirectory (NautilusFilesView *view,
NautilusDirectory *directory)
{
- NautilusFilesViewPrivate *priv;
- priv = nautilus_files_view_get_instance_private (view);
-
- priv->subdirectory_loading = FALSE;
+ NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
+ g_autoptr (NautilusFile) file = nautilus_directory_get_corresponding_file (directory);
+ NautilusViewItem *item = nautilus_view_model_get_item_for_file (priv->model, file);
g_return_if_fail (g_list_find (priv->subdirectory_list, directory));
- priv->subdirectory_list = g_list_remove (
- priv->subdirectory_list, directory);
+ priv->subdirectory_list = g_list_remove (priv->subdirectory_list, directory);
+ priv->subdirectories_loading = g_list_remove (priv->subdirectories_loading, directory);
+
+ if (item != NULL)
+ {
+ nautilus_view_item_set_loading (item, FALSE);
+
+ /* The model holds a GListStore for every subdirectory. Empty it. */
+ nautilus_view_model_clear_subdirectory (priv->model, item);
+ }
g_signal_handlers_disconnect_by_func (directory,
G_CALLBACK (files_added_callback),
@@ -8688,6 +8728,7 @@ load_directory (NautilusFilesView *view,
*/
schedule_update_context_menus (view);
+ g_clear_pointer (&priv->subdirectories_loading, g_list_free);
while (priv->subdirectory_list != NULL)
{
nautilus_files_view_remove_subdirectory (view,
@@ -9538,7 +9579,6 @@ nautilus_files_view_class_init (NautilusFilesViewClass *klass)
klass->end_file_changes = real_end_file_changes;
klass->begin_loading = real_begin_loading;
klass->end_loading = real_end_loading;
- klass->get_backing_uri = real_get_backing_uri;
klass->update_context_menus = real_update_context_menus;
klass->update_actions_state = real_update_actions_state;
klass->check_empty_states = real_check_empty_states;
diff --git a/src/nautilus-files-view.h b/src/nautilus-files-view.h
index 3c198d73473bcf6fe013f9a65adbc0731a49a3a4..3f6cdaa36a6081b9acbb457c627b7b42d77191b0 100644
--- a/src/nautilus-files-view.h
+++ b/src/nautilus-files-view.h
@@ -98,14 +98,6 @@ struct _NautilusFilesViewClass {
/* Function pointers that don't have corresponding signals */
- /* get_backing uri is a function pointer for subclasses to
- * override. Subclasses may replace it with a function that
- * returns the URI for the location where to create new folders,
- * files, links and paste the clipboard to.
- */
-
- char * (* get_backing_uri) (NautilusFilesView *view);
-
/* update_menus is a function pointer that subclasses can override to
* update the sensitivity or wording of menu items in the menu bar.
* It is called (at least) whenever the selection changes. If overridden,
@@ -123,9 +115,6 @@ struct _NautilusFilesViewClass {
NautilusFilesView * nautilus_files_view_new (guint id,
NautilusWindowSlot *slot);
-/* Functions callable from the user interface and elsewhere. */
-NautilusWindowSlot *nautilus_files_view_get_nautilus_window_slot (NautilusFilesView *view);
-
/* Wrappers for signal emitters. These are normally called
* only by NautilusFilesView itself. They have corresponding signals
* that observers might want to connect with.
diff --git a/src/nautilus-list-base.c b/src/nautilus-list-base.c
index be2bdbeb5b074946775b6d8517d22922a8b7f8fc..45f49b96f88c50ee56659097453e377353878266 100644
--- a/src/nautilus-list-base.c
+++ b/src/nautilus-list-base.c
@@ -945,6 +945,12 @@ nautilus_list_base_get_selected_item_ui (NautilusListBase *self)
return nautilus_view_item_get_item_ui (item);
}
+static NautilusViewItem *
+default_get_backing_item (NautilusListBase *self)
+{
+ return NULL;
+}
+
static void
default_preview_selection_event (NautilusListBase *self,
GtkDirectionType direction)
@@ -1091,6 +1097,7 @@ nautilus_list_base_class_init (NautilusListBaseClass *klass)
widget_class->focus = nautilus_list_base_focus;
+ klass->get_backing_item = default_get_backing_item;
klass->preview_selection_event = default_preview_selection_event;
klass->setup_directory = base_setup_directory;
@@ -1203,6 +1210,23 @@ nautilus_list_base_setup_gestures (NautilusListBase *self)
priv->view_drop_target = drop_target;
}
+/**
+ * nautilus_list_base_get_backing_item:
+ *
+ * Get a view item representing the subdirectory which, based on user action,
+ * should be used in place the view directory when performing file operations
+ * such as create new folders, paste from the clipboard, etc.
+ *
+ * If the view directory should be used, NULL is returned instead.
+ *
+ * Returns: (transfer full) (nullable): The subdirectory backing file operations.
+ */
+NautilusViewItem *
+nautilus_list_base_get_backing_item (NautilusListBase *self)
+{
+ return NAUTILUS_LIST_BASE_CLASS (G_OBJECT_GET_CLASS (self))->get_backing_item (self);
+}
+
NautilusViewInfo
nautilus_list_base_get_view_info (NautilusListBase *self)
{
diff --git a/src/nautilus-list-base.h b/src/nautilus-list-base.h
index 067b76cd879fdf01f741fb38517107114b4605a1..1e92dd814fd4c2c4d401cd59b01d97bf5befe9f4 100644
--- a/src/nautilus-list-base.h
+++ b/src/nautilus-list-base.h
@@ -27,13 +27,12 @@ struct _NautilusListBaseClass
{
NautilusFilesViewClass parent_class;
+ /* Subclasses must provide implementation. */
NautilusViewInfo (*get_view_info) (NautilusListBase *self);
guint (*get_icon_size) (NautilusListBase *self);
GVariant *(*get_sort_state) (NautilusListBase *self);
GtkWidget *(*get_view_ui) (NautilusListBase *self);
int (*get_zoom_level) (NautilusListBase *self);
- void (*preview_selection_event) (NautilusListBase *self,
- GtkDirectionType direction);
void (*scroll_to) (NautilusListBase *self,
guint position,
GtkListScrollFlags flags,
@@ -43,11 +42,17 @@ struct _NautilusListBaseClass
void (*set_zoom_level) (NautilusListBase *self,
int new_zoom_level);
+ /* Subclasses may override base implementation. */
+ NautilusViewItem *(*get_backing_item) (NautilusListBase *self);
+ void (*preview_selection_event) (NautilusListBase *self,
+ GtkDirectionType direction);
+
/* Subclass override must chain-up to base implementation. */
void (*setup_directory) (NautilusListBase *self,
NautilusDirectory *directory);
};
+NautilusViewItem *nautilus_list_base_get_backing_item (NautilusListBase *self);
GtkWidget *nautilus_list_base_get_selected_item_ui (NautilusListBase *self);
GVariant *nautilus_list_base_get_sort_state (NautilusListBase *self);
NautilusViewInfo nautilus_list_base_get_view_info (NautilusListBase *self) G_GNUC_PURE;
diff --git a/src/nautilus-list-view.c b/src/nautilus-list-view.c
index aac6a185c88f8c9f80a2b7d366d895c941227011..82080240e15a8b8146a37f613f5b8cd0b4b1bb00 100644
--- a/src/nautilus-list-view.c
+++ b/src/nautilus-list-view.c
@@ -54,6 +54,15 @@ struct _NautilusListView
G_DEFINE_TYPE (NautilusListView, nautilus_list_view, NAUTILUS_TYPE_LIST_BASE)
+enum
+{
+ LOAD_SUBDIRECTORY,
+ UNLOAD_SUBDIRECTORY,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
#define get_view_item(cell) \
(NAUTILUS_VIEW_ITEM (gtk_tree_list_row_get_item (GTK_TREE_LIST_ROW (gtk_column_view_cell_get_item (cell)))))
@@ -606,73 +615,69 @@ get_default_zoom_level (void)
list_view_info.zoom_level_max);
}
-static char *
-real_get_backing_uri (NautilusFilesView *view)
+static NautilusViewItem *
+real_get_backing_item (NautilusListBase *list_base)
{
- NautilusListView *self = NAUTILUS_LIST_VIEW (view);
- NautilusViewModel *model = nautilus_list_base_get_model (NAUTILUS_LIST_BASE (self));
- g_autoptr (NautilusFile) common_parent = NULL;
+ NautilusListView *self = NAUTILUS_LIST_VIEW (list_base);
if (!self->expand_as_a_tree)
{
- return NAUTILUS_FILES_VIEW_CLASS (nautilus_list_view_parent_class)->get_backing_uri (view);
+ return NULL;
}
/* If we are using tree expanders use the items parent, unless it
* is an expanded folder, in which case we should use that folder directly.
* When dealing with multiple selections, use the same rules, but only
* if a common parent exists. */
-
- for (guint i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (model)); i++)
+ NautilusViewModel *model = nautilus_list_base_get_model (list_base);
+ g_autoptr (GtkBitset) selection = gtk_selection_model_get_selection (GTK_SELECTION_MODEL (model));
+ g_autoptr (GtkTreeListRow) common_parent = NULL;
+ GtkBitsetIter iter;
+ guint i;
+
+ for (gtk_bitset_iter_init_first (&iter, selection, &i);
+ gtk_bitset_iter_is_valid (&iter);
+ gtk_bitset_iter_next (&iter, &i))
{
g_autoptr (GtkTreeListRow) row = g_list_model_get_item (G_LIST_MODEL (model), i);
- g_autoptr (NautilusViewItem) item = NULL;
- g_autoptr (NautilusFile) parent_file = NULL;
- NautilusFile *file;
- NautilusFile *current_parent;
+ g_autoptr (GtkTreeListRow) parent = gtk_tree_list_row_get_parent (row);
+ GtkTreeListRow *current_parent = gtk_tree_list_row_get_expanded (row) ? row : parent;
- if (!gtk_selection_model_is_selected (GTK_SELECTION_MODEL (model), i))
+ if (current_parent == NULL)
{
- continue;
+ return NULL;
}
- item = gtk_tree_list_row_get_item (row);
- file = nautilus_view_item_get_file (item);
- parent_file = nautilus_file_get_parent (file);
- current_parent = gtk_tree_list_row_get_expanded (row) ? file : parent_file;
-
if (common_parent == NULL)
{
- common_parent = nautilus_file_ref (current_parent);
+ common_parent = g_object_ref (current_parent);
}
else if (current_parent != common_parent)
{
- g_clear_pointer (&common_parent, nautilus_file_unref);
+ g_clear_object (&common_parent);
break;
}
}
if (common_parent != NULL)
{
- return nautilus_file_get_uri (common_parent);
+ return gtk_tree_list_row_get_item (common_parent);
}
- return NAUTILUS_FILES_VIEW_CLASS (nautilus_list_view_parent_class)->get_backing_uri (view);
+ return NULL;
}
typedef struct
{
NautilusListView *self;
- NautilusViewItem *item;
- NautilusDirectory *directory;
+ GtkTreeListRow *row;
} UnloadDelayData;
static void
unload_delay_data_free (UnloadDelayData *unload_data)
{
g_clear_weak_pointer (&unload_data->self);
- g_clear_object (&unload_data->item);
- g_clear_object (&unload_data->directory);
+ g_clear_object (&unload_data->row);
g_free (unload_data);
}
@@ -680,79 +685,44 @@ unload_delay_data_free (UnloadDelayData *unload_data)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (UnloadDelayData, unload_delay_data_free)
static UnloadDelayData *
-unload_delay_data_new (NautilusListView *self,
- NautilusViewItem *item,
- NautilusDirectory *directory)
+unload_delay_data_new (NautilusListView *self,
+ GtkTreeListRow *row)
{
UnloadDelayData *unload_data;
unload_data = g_new0 (UnloadDelayData, 1);
g_set_weak_pointer (&unload_data->self, self);
- g_set_object (&unload_data->item, item);
- g_set_object (&unload_data->directory, directory);
+ g_set_object (&unload_data->row, row);
return unload_data;
}
-static gboolean
+static void
unload_file_timeout (gpointer data)
{
g_autoptr (UnloadDelayData) unload_data = data;
NautilusListView *self = unload_data->self;
- NautilusViewModel *model;
if (unload_data->self == NULL)
{
- return G_SOURCE_REMOVE;
- }
- model = nautilus_list_base_get_model (NAUTILUS_LIST_BASE (self));
-
- for (guint i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (model)); i++)
- {
- g_autoptr (GtkTreeListRow) row = g_list_model_get_item (G_LIST_MODEL (model), i);
- g_autoptr (NautilusViewItem) item = gtk_tree_list_row_get_item (row);
- if (item != NULL && item == unload_data->item)
- {
- if (gtk_tree_list_row_get_expanded (row))
- {
- /* It has been expanded again before the timeout. Do nothing. */
- return G_SOURCE_REMOVE;
- }
- break;
- }
+ return;
}
- if (nautilus_files_view_has_subdirectory (NAUTILUS_FILES_VIEW (self),
- unload_data->directory))
+ if (gtk_tree_list_row_get_expanded (unload_data->row))
{
- nautilus_files_view_remove_subdirectory (NAUTILUS_FILES_VIEW (self),
- unload_data->directory);
+ /* It has been expanded again before the timeout. Do nothing. */
+ return;
}
- /* The model holds a GListStore for every subdirectory. Empty it. */
- nautilus_view_model_clear_subdirectory (model, unload_data->item);
+ g_autoptr (NautilusViewItem) item = gtk_tree_list_row_get_item (unload_data->row);
- return G_SOURCE_REMOVE;
-}
-
-static void
-on_subdirectory_done_loading (NautilusDirectory *directory,
- GtkTreeListRow *row)
-{
- g_autoptr (NautilusViewItem) item = NULL;
-
- g_signal_handlers_disconnect_by_func (directory, on_subdirectory_done_loading, row);
-
- item = NAUTILUS_VIEW_ITEM (gtk_tree_list_row_get_item (row));
- nautilus_view_item_set_loading (item, FALSE);
-
- if (!nautilus_directory_is_not_empty (directory))
+ if (nautilus_file_is_gone (nautilus_view_item_get_file (item)))
{
- GtkWidget *name_cell = nautilus_view_item_get_item_ui (item);
- GtkTreeExpander *expander = nautilus_name_cell_get_expander (NAUTILUS_NAME_CELL (name_cell));
-
- gtk_tree_expander_set_hide_expander (expander, TRUE);
+ /* It's been removed in the meantime. */
+ return;
}
+
+ g_signal_emit (self, signals[UNLOAD_SUBDIRECTORY], 0, item);
}
static void
@@ -762,42 +732,18 @@ on_row_expanded_changed (GObject *gobject,
{
GtkTreeListRow *row = GTK_TREE_LIST_ROW (gobject);
NautilusListView *self = NAUTILUS_LIST_VIEW (user_data);
- g_autoptr (NautilusViewItem) item = NULL;
- g_autoptr (NautilusDirectory) directory = NULL;
- gboolean expanded;
+ g_autoptr (NautilusViewItem) item = NAUTILUS_VIEW_ITEM (gtk_tree_list_row_get_item (row));
- item = NAUTILUS_VIEW_ITEM (gtk_tree_list_row_get_item (row));
- if (item == NULL)
+ if (gtk_tree_list_row_get_expanded (row))
{
- /* Row has been destroyed. */
- return;
- }
-
- directory = nautilus_directory_get_for_file (nautilus_view_item_get_file (item));
- expanded = gtk_tree_list_row_get_expanded (row);
- if (expanded)
- {
- if (!nautilus_files_view_has_subdirectory (NAUTILUS_FILES_VIEW (self), directory))
- {
- nautilus_files_view_add_subdirectory (NAUTILUS_FILES_VIEW (self), directory);
- }
- if (!nautilus_directory_are_all_files_seen (directory))
- {
- nautilus_view_item_set_loading (item, TRUE);
-
- g_signal_connect_object (directory,
- "done-loading",
- G_CALLBACK (on_subdirectory_done_loading),
- row,
- 0);
- }
+ g_signal_emit (self, signals[LOAD_SUBDIRECTORY], 0, item);
}
else
{
nautilus_view_item_set_loading (item, FALSE);
- g_timeout_add_seconds (COLLAPSE_TO_UNLOAD_DELAY,
- unload_file_timeout,
- unload_delay_data_new (self, item, directory));
+ g_timeout_add_seconds_once (COLLAPSE_TO_UNLOAD_DELAY,
+ unload_file_timeout,
+ unload_delay_data_new (self, row));
}
}
@@ -1103,10 +1049,7 @@ setup_view_columns (NautilusListView *self)
static void
nautilus_list_view_reload (NautilusListView *self)
{
- NautilusWindowSlot *slot;
-
- slot = nautilus_files_view_get_nautilus_window_slot (NAUTILUS_FILES_VIEW (self));
- nautilus_window_slot_queue_reload (slot);
+ gtk_widget_activate_action (GTK_WIDGET (self), "win.reload", NULL);
}
static void
@@ -1216,14 +1159,12 @@ static void
nautilus_list_view_class_init (NautilusListViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- NautilusFilesViewClass *files_view_class = NAUTILUS_FILES_VIEW_CLASS (klass);
NautilusListBaseClass *list_base_view_class = NAUTILUS_LIST_BASE_CLASS (klass);
object_class->dispose = nautilus_list_view_dispose;
object_class->finalize = nautilus_list_view_finalize;
- files_view_class->get_backing_uri = real_get_backing_uri;
-
+ list_base_view_class->get_backing_item = real_get_backing_item;
list_base_view_class->get_icon_size = real_get_icon_size;
list_base_view_class->get_sort_state = real_get_sort_state;
list_base_view_class->get_view_info = real_get_view_info;
@@ -1233,6 +1174,21 @@ nautilus_list_view_class_init (NautilusListViewClass *klass)
list_base_view_class->set_sort_state = real_set_sort_state;
list_base_view_class->set_zoom_level = real_set_zoom_level;
list_base_view_class->setup_directory = nautilus_list_view_setup_directory;
+
+ signals[LOAD_SUBDIRECTORY] = g_signal_new ("load-subdirectory",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1, NAUTILUS_TYPE_VIEW_ITEM);
+ signals[UNLOAD_SUBDIRECTORY] = g_signal_new ("unload-subdirectory",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1, NAUTILUS_TYPE_VIEW_ITEM);
}
NautilusListView *
diff --git a/src/nautilus-name-cell.c b/src/nautilus-name-cell.c
index f18a83efbd6dcc1b9049db8b3e055bdbc1e531e0..09667a488ad20151fd149195190145b72fec1a22 100644
--- a/src/nautilus-name-cell.c
+++ b/src/nautilus-name-cell.c
@@ -6,10 +6,11 @@
#include "nautilus-name-cell.h"
+#include "nautilus-directory.h"
#include "nautilus-file-utilities.h"
#include "nautilus-thumbnails.h"
-#define LOADING_TIMEOUT_SECONDS 1
+#define SPINNER_DELAY_MS 200
struct _NautilusNameCell
{
@@ -272,43 +273,43 @@ on_item_is_cut_changed (NautilusNameCell *self)
}
}
-static gboolean
+static void
on_loading_timeout (gpointer user_data)
{
NautilusNameCell *self = NAUTILUS_NAME_CELL (user_data);
g_autoptr (NautilusViewItem) item = nautilus_view_cell_get_item (NAUTILUS_VIEW_CELL (self));
- gboolean is_loading;
+ gboolean is_loading = nautilus_view_item_get_loading (item);
self->loading_timeout_id = 0;
- g_object_get (item,
- "is-loading", &is_loading,
- NULL);
if (is_loading)
{
gtk_widget_set_visible (self->spinner, TRUE);
gtk_spinner_start (GTK_SPINNER (self->spinner));
}
-
- return G_SOURCE_REMOVE;
}
static void
on_item_is_loading_changed (NautilusNameCell *self)
{
- gboolean is_loading;
g_autoptr (NautilusViewItem) item = nautilus_view_cell_get_item (NAUTILUS_VIEW_CELL (self));
+ gboolean is_loading = nautilus_view_item_get_loading (item);
g_clear_handle_id (&self->loading_timeout_id, g_source_remove);
- g_object_get (item, "is-loading", &is_loading, NULL);
+
if (is_loading)
{
- self->loading_timeout_id = g_timeout_add_seconds (LOADING_TIMEOUT_SECONDS,
- G_SOURCE_FUNC (on_loading_timeout),
- self);
+ self->loading_timeout_id = g_timeout_add_once (SPINNER_DELAY_MS,
+ on_loading_timeout,
+ self);
}
else
{
+ g_autoptr (NautilusDirectory) directory = nautilus_directory_get_for_file (nautilus_view_item_get_file (item));
+
+ gtk_tree_expander_set_hide_expander (GTK_TREE_EXPANDER (self->expander),
+ !nautilus_directory_is_not_empty (directory));
+
gtk_widget_set_visible (self->spinner, FALSE);
gtk_spinner_stop (GTK_SPINNER (self->spinner));
}
@@ -356,7 +357,7 @@ nautilus_name_cell_init (NautilusNameCell *self)
(GCallback) on_item_drag_accept_changed, self);
g_signal_group_connect_swapped (self->item_signal_group, "notify::is-cut",
(GCallback) on_item_is_cut_changed, self);
- g_signal_group_connect_swapped (self->item_signal_group, "notify::is-loading",
+ g_signal_group_connect_swapped (self->item_signal_group, "notify::loading",
(GCallback) on_item_is_loading_changed, self);
g_signal_group_connect_swapped (self->item_signal_group, "file-changed",
(GCallback) on_file_changed, self);
diff --git a/src/nautilus-view-item.c b/src/nautilus-view-item.c
index b83862b78f3ba39407201d9a59715ce91ca8ae93..6c2247c1eb82d6408c81b8367cc6dc6c145a763b 100644
--- a/src/nautilus-view-item.c
+++ b/src/nautilus-view-item.c
@@ -11,7 +11,7 @@ struct _NautilusViewItem
GObject parent_instance;
gboolean is_cut;
gboolean drag_accept;
- gboolean is_loading;
+ gboolean loading;
NautilusFile *file;
GtkWidget *item_ui;
};
@@ -24,7 +24,7 @@ enum
PROP_FILE,
PROP_IS_CUT,
PROP_DRAG_ACCEPT,
- PROP_IS_LOADING,
+ PROP_LOADING,
N_PROPS
};
@@ -86,9 +86,9 @@ nautilus_view_item_get_property (GObject *object,
}
break;
- case PROP_IS_LOADING:
+ case PROP_LOADING:
{
- g_value_set_boolean (value, self->is_loading);
+ g_value_set_boolean (value, self->loading);
}
break;
@@ -127,9 +127,9 @@ nautilus_view_item_set_property (GObject *object,
}
break;
- case PROP_IS_LOADING:
+ case PROP_LOADING:
{
- self->is_loading = g_value_get_boolean (value);
+ nautilus_view_item_set_loading (self, g_value_get_boolean (value));
}
break;
@@ -167,10 +167,9 @@ nautilus_view_item_class_init (NautilusViewItemClass *klass)
"", "",
NAUTILUS_TYPE_FILE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
- properties[PROP_IS_LOADING] = g_param_spec_boolean ("is-loading",
- "", "",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ properties[PROP_LOADING] = g_param_spec_boolean ("loading", NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
signals[FILE_CHANGED] = g_signal_new ("file-changed",
@@ -208,13 +207,25 @@ nautilus_view_item_set_drag_accept (NautilusViewItem *self,
g_object_set (self, "drag-accept", drag_accept, NULL);
}
+gboolean
+nautilus_view_item_get_loading (NautilusViewItem *self)
+{
+ g_return_val_if_fail (NAUTILUS_IS_VIEW_ITEM (self), FALSE);
+
+ return self->loading;
+}
+
void
nautilus_view_item_set_loading (NautilusViewItem *self,
gboolean loading)
{
g_return_if_fail (NAUTILUS_IS_VIEW_ITEM (self));
- g_object_set (self, "is-loading", loading, NULL);
+ if (self->loading != loading)
+ {
+ self->loading = loading;
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LOADING]);
+ }
}
NautilusFile *
diff --git a/src/nautilus-view-item.h b/src/nautilus-view-item.h
index 6b21645f595cdf10320535d890e065ff43d05b54..42f74a708c0c8e535c80a861850df12a5a8d7eeb 100644
--- a/src/nautilus-view-item.h
+++ b/src/nautilus-view-item.h
@@ -23,6 +23,7 @@ void nautilus_view_item_set_cut (NautilusViewItem *self,
gboolean is_cut);
void nautilus_view_item_set_drag_accept (NautilusViewItem *self,
gboolean drag_accept);
+gboolean nautilus_view_item_get_loading (NautilusViewItem *self);
void nautilus_view_item_set_loading (NautilusViewItem *self,
gboolean is_loading);
diff --git a/src/resources/ui/nautilus-name-cell.ui b/src/resources/ui/nautilus-name-cell.ui
index 30415032056be6dc00cda9e70aefe2fccc3621c8..ba0ea0cd492f086cf524e992014652338a74eb21 100644
--- a/src/resources/ui/nautilus-name-cell.ui
+++ b/src/resources/ui/nautilus-name-cell.ui
@@ -19,14 +19,6 @@
horizontal
fill
center
-
-
-
+
+
+