mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-10-29 03:34:16 +00:00
Slightly slower auto hover expand.
2005-06-16 Alexander Larsson <alexl@redhat.com> * libnautilus-private/nautilus-tree-view-drag-dest.c: Slightly slower auto hover expand. * src/file-manager/fm-directory-view.c: Make add/remove_subdirectory more straightforward. Now remove just removes the NautilusDirectory passed in, and you're not allowed to add multiple times or remove non-added. * src/file-manager/fm-list-model.[ch]: Actually track the NautilusDirectories that are added to the FMDirectoryView so we can easily remove them when the files are removed. This was causing problem before where directories for removed files weren't removed. Emits the subdirectory_unloaded signal when subdirectories go away. Add support for unloading subdirectories. * src/file-manager/fm-list-view.c: Unload subdirectories in timeout on collapse. remove subdirectories when they get unloaded.
This commit is contained in:
parent
ec1cdbcc44
commit
9efbacad75
6 changed files with 321 additions and 123 deletions
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
|||
2005-06-16 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* libnautilus-private/nautilus-tree-view-drag-dest.c:
|
||||
Slightly slower auto hover expand.
|
||||
|
||||
* src/file-manager/fm-directory-view.c:
|
||||
Make add/remove_subdirectory more straightforward.
|
||||
Now remove just removes the NautilusDirectory passed in, and
|
||||
you're not allowed to add multiple times or remove non-added.
|
||||
|
||||
* src/file-manager/fm-list-model.[ch]:
|
||||
Actually track the NautilusDirectories that are added to the
|
||||
FMDirectoryView so we can easily remove them when the files are
|
||||
removed. This was causing problem before where directories for
|
||||
removed files weren't removed.
|
||||
|
||||
Emits the subdirectory_unloaded signal when subdirectories go away.
|
||||
|
||||
Add support for unloading subdirectories.
|
||||
|
||||
* src/file-manager/fm-list-view.c:
|
||||
Unload subdirectories in timeout on collapse.
|
||||
remove subdirectories when they get unloaded.
|
||||
|
||||
2005-06-16 Anders Carlsson <andersca@imendio.com>
|
||||
|
||||
* src/nautilus-navigation-window-menus.c
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
|
||||
#define AUTO_SCROLL_MARGIN 20
|
||||
|
||||
#define HOVER_EXPAND_TIMEOUT 1000
|
||||
|
||||
struct _NautilusTreeViewDragDestDetails {
|
||||
GtkTreeView *tree_view;
|
||||
|
||||
|
@ -429,9 +431,9 @@ drag_motion_callback (GtkWidget *widget,
|
|||
if (dest->details->expand_id == 0 && drop_path != NULL) {
|
||||
gtk_tree_model_get_iter (model, &drop_iter, drop_path);
|
||||
if (gtk_tree_model_iter_has_child (model, &drop_iter)) {
|
||||
dest->details->expand_id = g_timeout_add (500,
|
||||
expand_timeout,
|
||||
dest->details->tree_view);
|
||||
dest->details->expand_id = g_timeout_add (HOVER_EXPAND_TIMEOUT,
|
||||
expand_timeout,
|
||||
dest->details->tree_view);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -2758,43 +2758,45 @@ fm_directory_view_queue_file_change (FMDirectoryView *view, NautilusFile *file)
|
|||
|
||||
void
|
||||
fm_directory_view_add_subdirectory (FMDirectoryView *view,
|
||||
NautilusDirectory*directory)
|
||||
NautilusDirectory*directory)
|
||||
{
|
||||
NautilusFileAttributes attributes;
|
||||
|
||||
if (g_list_find (view->details->subdirectory_list, directory) == NULL) {
|
||||
nautilus_directory_ref (directory);
|
||||
g_assert (!g_list_find (view->details->subdirectory_list, directory));
|
||||
|
||||
nautilus_directory_ref (directory);
|
||||
|
||||
attributes = nautilus_icon_factory_get_required_file_attributes ();
|
||||
attributes |= NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT |
|
||||
NAUTILUS_FILE_ATTRIBUTE_METADATA |
|
||||
NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE |
|
||||
NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME |
|
||||
NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO;
|
||||
|
||||
nautilus_directory_file_monitor_add (directory,
|
||||
&view->details->model,
|
||||
view->details->show_hidden_files,
|
||||
view->details->show_backup_files,
|
||||
attributes,
|
||||
files_added_callback, view);
|
||||
|
||||
g_signal_connect
|
||||
(directory, "files_added",
|
||||
G_CALLBACK (files_added_callback), view);
|
||||
g_signal_connect
|
||||
(directory, "files_changed",
|
||||
G_CALLBACK (files_changed_callback), view);
|
||||
|
||||
view->details->subdirectory_list = g_list_prepend (
|
||||
view->details->subdirectory_list, directory);
|
||||
}
|
||||
attributes = nautilus_icon_factory_get_required_file_attributes ();
|
||||
attributes |= NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT |
|
||||
NAUTILUS_FILE_ATTRIBUTE_METADATA |
|
||||
NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE |
|
||||
NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME |
|
||||
NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO;
|
||||
|
||||
nautilus_directory_file_monitor_add (directory,
|
||||
&view->details->model,
|
||||
view->details->show_hidden_files,
|
||||
view->details->show_backup_files,
|
||||
attributes,
|
||||
files_added_callback, view);
|
||||
|
||||
g_signal_connect
|
||||
(directory, "files_added",
|
||||
G_CALLBACK (files_added_callback), view);
|
||||
g_signal_connect
|
||||
(directory, "files_changed",
|
||||
G_CALLBACK (files_changed_callback), view);
|
||||
|
||||
view->details->subdirectory_list = g_list_prepend (
|
||||
view->details->subdirectory_list, directory);
|
||||
}
|
||||
|
||||
static void
|
||||
real_remove_subdirectory (FMDirectoryView *view,
|
||||
NautilusDirectory*directory)
|
||||
void
|
||||
fm_directory_view_remove_subdirectory (FMDirectoryView *view,
|
||||
NautilusDirectory*directory)
|
||||
{
|
||||
g_assert (g_list_find (view->details->subdirectory_list, directory));
|
||||
|
||||
view->details->subdirectory_list = g_list_remove (
|
||||
view->details->subdirectory_list, directory);
|
||||
|
||||
|
@ -2810,34 +2812,6 @@ real_remove_subdirectory (FMDirectoryView *view,
|
|||
nautilus_directory_unref (directory);
|
||||
}
|
||||
|
||||
void
|
||||
fm_directory_view_remove_subdirectory (FMDirectoryView *view,
|
||||
NautilusDirectory*directory)
|
||||
{
|
||||
GList *node;
|
||||
NautilusFile *parent, *file1, *file2;
|
||||
NautilusDirectory *subdir;
|
||||
|
||||
parent = nautilus_directory_get_corresponding_file (directory);
|
||||
|
||||
for (node = view->details->subdirectory_list; node != NULL;) {
|
||||
file1 = nautilus_directory_get_corresponding_file (node->data);
|
||||
while (file1 != parent && file1 != NULL) {
|
||||
file2 = nautilus_file_get_parent (file1);
|
||||
nautilus_file_unref (file1);
|
||||
file1 = file2;
|
||||
}
|
||||
subdir = NAUTILUS_DIRECTORY (node->data);
|
||||
node = node->next;
|
||||
if (file1 == parent) {
|
||||
real_remove_subdirectory (view, subdir);
|
||||
}
|
||||
if (file1 != NULL) {
|
||||
nautilus_file_unref (file1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fm_directory_view_clear:
|
||||
*
|
||||
|
@ -7494,7 +7468,7 @@ load_directory (FMDirectoryView *view,
|
|||
schedule_update_menus (view);
|
||||
|
||||
while (view->details->subdirectory_list != NULL) {
|
||||
real_remove_subdirectory (view,
|
||||
fm_directory_view_remove_subdirectory (view,
|
||||
view->details->subdirectory_list->data);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,13 @@
|
|||
#include <libnautilus-private/nautilus-dnd.h>
|
||||
#include <gsequence/gsequence.h>
|
||||
|
||||
enum {
|
||||
SUBDIRECTORY_UNLOADED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint list_model_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static int fm_list_model_file_entry_compare_func (gconstpointer a,
|
||||
gconstpointer b,
|
||||
gpointer user_data);
|
||||
|
@ -76,6 +83,7 @@ typedef struct FileEntry FileEntry;
|
|||
|
||||
struct FileEntry {
|
||||
NautilusFile *file;
|
||||
NautilusDirectory *subdirectory;
|
||||
FileEntry *parent;
|
||||
GSequence *files;
|
||||
GSequencePtr ptr;
|
||||
|
@ -95,6 +103,9 @@ static void
|
|||
file_entry_free (FileEntry *file_entry)
|
||||
{
|
||||
nautilus_file_unref (file_entry->file);
|
||||
if (file_entry->subdirectory != NULL) {
|
||||
nautilus_directory_unref (file_entry->subdirectory);
|
||||
}
|
||||
if (file_entry->files != NULL) {
|
||||
g_sequence_free (file_entry->files);
|
||||
}
|
||||
|
@ -119,6 +130,8 @@ fm_list_model_get_column_type (GtkTreeModel *tree_model, int index)
|
|||
switch (index) {
|
||||
case FM_LIST_MODEL_FILE_COLUMN:
|
||||
return NAUTILUS_TYPE_FILE;
|
||||
case FM_LIST_MODEL_SUBDIRECTORY_COLUMN:
|
||||
return NAUTILUS_TYPE_DIRECTORY;
|
||||
case FM_LIST_MODEL_SMALLEST_ICON_COLUMN:
|
||||
case FM_LIST_MODEL_SMALLER_ICON_COLUMN:
|
||||
case FM_LIST_MODEL_SMALL_ICON_COLUMN:
|
||||
|
@ -240,6 +253,11 @@ fm_list_model_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, int column
|
|||
|
||||
g_value_set_object (value, file);
|
||||
break;
|
||||
case FM_LIST_MODEL_SUBDIRECTORY_COLUMN:
|
||||
g_value_init (value, NAUTILUS_TYPE_DIRECTORY);
|
||||
|
||||
g_value_set_object (value, file_entry->subdirectory);
|
||||
break;
|
||||
case FM_LIST_MODEL_SMALLEST_ICON_COLUMN:
|
||||
case FM_LIST_MODEL_SMALLER_ICON_COLUMN:
|
||||
case FM_LIST_MODEL_SMALL_ICON_COLUMN:
|
||||
|
@ -498,8 +516,8 @@ fm_list_model_get_tree_iter_from_file (FMListModel *model, NautilusFile *file, G
|
|||
|
||||
static int
|
||||
fm_list_model_file_entry_compare_func (gconstpointer a,
|
||||
gconstpointer b,
|
||||
gpointer user_data)
|
||||
gconstpointer b,
|
||||
gpointer user_data)
|
||||
{
|
||||
FileEntry *file_entry1;
|
||||
FileEntry *file_entry2;
|
||||
|
@ -770,17 +788,36 @@ fm_list_model_multi_drag_data_delete (EggTreeMultiDragSource *drag_source, GList
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
add_dummy_row (FMListModel *model, FileEntry *parent_entry)
|
||||
{
|
||||
FileEntry *dummy_file_entry;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
|
||||
dummy_file_entry = g_new0 (FileEntry, 1);
|
||||
dummy_file_entry->parent = parent_entry;
|
||||
dummy_file_entry->ptr = g_sequence_insert_sorted (parent_entry->files, dummy_file_entry,
|
||||
fm_list_model_file_entry_compare_func, model);
|
||||
iter.stamp = model->details->stamp;
|
||||
iter.user_data = dummy_file_entry->ptr;
|
||||
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
|
||||
gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fm_list_model_add_file (FMListModel *model, NautilusFile *file)
|
||||
{
|
||||
GtkTreeIter iter, child_iter;
|
||||
GtkTreePath *path, *child_path;
|
||||
FileEntry *file_entry, *child_file_entry;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
FileEntry *file_entry;
|
||||
NautilusFile *parent_file;
|
||||
GSequencePtr parent_ptr;
|
||||
GSequence *files;
|
||||
gboolean replace_dummy;
|
||||
|
||||
|
||||
/* We may only add each file once. */
|
||||
if (fm_list_model_get_tree_iter_from_file (model, file, NULL)) {
|
||||
return FALSE;
|
||||
|
@ -791,7 +828,8 @@ fm_list_model_add_file (FMListModel *model, NautilusFile *file)
|
|||
file_entry = g_new0 (FileEntry, 1);
|
||||
file_entry->file = file;
|
||||
file_entry->parent = NULL;
|
||||
file_entry->files = g_sequence_new ((GDestroyNotify)file_entry_free);
|
||||
file_entry->subdirectory = NULL;
|
||||
file_entry->files = NULL;
|
||||
|
||||
files = model->details->files;
|
||||
|
||||
|
@ -810,6 +848,7 @@ fm_list_model_add_file (FMListModel *model, NautilusFile *file)
|
|||
FileEntry *dummy_entry = g_sequence_ptr_get_data (dummy_ptr);
|
||||
if (dummy_entry->file == NULL) {
|
||||
/* replace the dummy loading entry */
|
||||
model->details->stamp++;
|
||||
g_sequence_remove (dummy_ptr);
|
||||
|
||||
replace_dummy = TRUE;
|
||||
|
@ -832,18 +871,11 @@ fm_list_model_add_file (FMListModel *model, NautilusFile *file)
|
|||
} else {
|
||||
gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter);
|
||||
}
|
||||
if (nautilus_file_is_directory (file)) {
|
||||
|
||||
child_file_entry = g_new0 (FileEntry, 1);
|
||||
child_file_entry->parent = file_entry;
|
||||
child_file_entry->ptr = g_sequence_insert_sorted (file_entry->files, child_file_entry,
|
||||
fm_list_model_file_entry_compare_func, model);
|
||||
child_iter.stamp = model->details->stamp;
|
||||
child_iter.user_data = child_file_entry->ptr;
|
||||
|
||||
child_path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &child_iter);
|
||||
gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), child_path, &child_iter);
|
||||
gtk_tree_path_free (child_path);
|
||||
if (nautilus_file_is_directory (file)) {
|
||||
file_entry->files = g_sequence_new ((GDestroyNotify)file_entry_free);
|
||||
|
||||
add_dummy_row (model, file_entry);
|
||||
|
||||
gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (model),
|
||||
path, &iter);
|
||||
|
@ -888,14 +920,14 @@ fm_list_model_get_length (FMListModel *model)
|
|||
return g_sequence_get_length (model->details->files);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fm_list_model_remove (FMListModel *model, GtkTreeIter *iter)
|
||||
{
|
||||
GSequencePtr ptr, child_ptr;
|
||||
FileEntry *file_entry, *child_file_entry;
|
||||
FileEntry *file_entry, *child_file_entry, *parent_file_entry;
|
||||
GtkTreePath *path;
|
||||
GtkTreeIter dummy_iter;
|
||||
GtkTreeIter parent_iter;
|
||||
gboolean add_dummy;
|
||||
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter);
|
||||
ptr = iter->user_data;
|
||||
|
@ -910,6 +942,7 @@ fm_list_model_remove (FMListModel *model, GtkTreeIter *iter)
|
|||
child_file_entry->file);
|
||||
} else {
|
||||
gtk_tree_path_append_index (path, 0);
|
||||
model->details->stamp++;
|
||||
g_sequence_remove (child_ptr);
|
||||
gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
|
||||
gtk_tree_path_up (path);
|
||||
|
@ -920,27 +953,37 @@ fm_list_model_remove (FMListModel *model, GtkTreeIter *iter)
|
|||
|
||||
g_hash_table_remove (model->details->reverse_map, file_entry->file);
|
||||
|
||||
if (file_entry->parent &&
|
||||
g_sequence_get_length (file_entry->parent->files) == 1 &&
|
||||
add_dummy = FALSE;
|
||||
parent_file_entry = file_entry->parent;
|
||||
if (parent_file_entry && g_sequence_get_length (parent_file_entry->files) == 1 &&
|
||||
file_entry->file != NULL) {
|
||||
/* this is the last non-dummy child, change it to a dummy node */
|
||||
dummy_iter.stamp = model->details->stamp++;
|
||||
dummy_iter.user_data = ptr;
|
||||
|
||||
nautilus_file_unref (file_entry->file);
|
||||
file_entry->file = NULL;
|
||||
file_entry->loaded = TRUE;
|
||||
|
||||
gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path,
|
||||
&dummy_iter);
|
||||
} else {
|
||||
g_sequence_remove (ptr);
|
||||
/* this is the last non-dummy child, add a dummy node */
|
||||
add_dummy = TRUE;
|
||||
}
|
||||
|
||||
model->details->stamp++;
|
||||
gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
|
||||
if (file_entry->subdirectory != NULL) {
|
||||
g_signal_emit (model,
|
||||
list_model_signals[SUBDIRECTORY_UNLOADED], 0,
|
||||
file_entry->subdirectory);
|
||||
}
|
||||
|
||||
g_sequence_remove (ptr);
|
||||
|
||||
model->details->stamp++;
|
||||
gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
if (add_dummy) {
|
||||
add_dummy_row (model, parent_file_entry);
|
||||
} else if (parent_file_entry && g_sequence_get_length (parent_file_entry->files) == 0) {
|
||||
parent_iter.stamp = model->details->stamp;
|
||||
parent_iter.user_data = parent_file_entry->ptr;
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &parent_iter);
|
||||
gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (model),
|
||||
path, &parent_iter);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -958,7 +1001,7 @@ fm_list_model_clear_directory (FMListModel *model, GSequence *files)
|
|||
{
|
||||
GtkTreeIter iter;
|
||||
FileEntry *file_entry;
|
||||
|
||||
|
||||
while (g_sequence_get_length (files) > 0) {
|
||||
iter.user_data = g_sequence_get_begin_ptr (files);
|
||||
|
||||
|
@ -997,6 +1040,67 @@ fm_list_model_file_for_path (FMListModel *model, GtkTreePath *path)
|
|||
return file;
|
||||
}
|
||||
|
||||
gboolean
|
||||
fm_list_model_load_subdirectory (FMListModel *model, GtkTreePath *path, NautilusDirectory **directory)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
FileEntry *file_entry;
|
||||
|
||||
if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
file_entry = g_sequence_ptr_get_data (iter.user_data);
|
||||
if (file_entry->file == NULL ||
|
||||
file_entry->subdirectory != NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
file_entry->subdirectory = nautilus_directory_get_for_file (file_entry->file);
|
||||
nautilus_directory_ref (file_entry->subdirectory);
|
||||
*directory = file_entry->subdirectory;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* removes all children of the subfolder and unloads the subdirectory */
|
||||
void
|
||||
fm_list_model_unload_subdirectory (FMListModel *model, GtkTreeIter *iter)
|
||||
{
|
||||
GSequencePtr child_ptr;
|
||||
FileEntry *file_entry, *child_file_entry;
|
||||
|
||||
file_entry = g_sequence_ptr_get_data (iter->user_data);
|
||||
if (file_entry->file == NULL ||
|
||||
file_entry->subdirectory == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove all children */
|
||||
while (g_sequence_get_length (file_entry->files) > 0) {
|
||||
child_ptr = g_sequence_get_begin_ptr (file_entry->files);
|
||||
child_file_entry = g_sequence_ptr_get_data (child_ptr);
|
||||
if (child_file_entry->file == NULL) {
|
||||
/* Don't delete the dummy node */
|
||||
break;
|
||||
} else {
|
||||
fm_list_model_remove_file (model,
|
||||
child_file_entry->file);
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit unload signal */
|
||||
g_signal_emit (model,
|
||||
list_model_signals[SUBDIRECTORY_UNLOADED], 0,
|
||||
file_entry->subdirectory);
|
||||
|
||||
/* actually unload */
|
||||
nautilus_directory_unref (file_entry->subdirectory);
|
||||
file_entry->subdirectory = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
fm_list_model_set_should_sort_directories_first (FMListModel *model, gboolean sort_directories_first)
|
||||
{
|
||||
|
@ -1277,6 +1381,16 @@ fm_list_model_class_init (FMListModelClass *klass)
|
|||
|
||||
object_class->finalize = fm_list_model_finalize;
|
||||
object_class->dispose = fm_list_model_dispose;
|
||||
|
||||
list_model_signals[SUBDIRECTORY_UNLOADED] =
|
||||
g_signal_new ("subdirectory_unloaded",
|
||||
FM_TYPE_LIST_MODEL,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (FMListModelClass, subdirectory_unloaded),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
NAUTILUS_TYPE_DIRECTORY);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
enum {
|
||||
FM_LIST_MODEL_FILE_COLUMN,
|
||||
FM_LIST_MODEL_SUBDIRECTORY_COLUMN,
|
||||
FM_LIST_MODEL_SMALLEST_ICON_COLUMN,
|
||||
FM_LIST_MODEL_SMALLER_ICON_COLUMN,
|
||||
FM_LIST_MODEL_SMALL_ICON_COLUMN,
|
||||
|
@ -68,6 +69,9 @@ typedef struct FMListModel {
|
|||
|
||||
typedef struct {
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* subdirectory_unloaded)(FMListModel *model,
|
||||
NautilusDirectory *subdirectory);
|
||||
} FMListModelClass;
|
||||
|
||||
GType fm_list_model_get_type (void);
|
||||
|
@ -100,8 +104,8 @@ NautilusZoomLevel fm_list_model_get_zoom_level_from_emblem_column_id (int
|
|||
int fm_list_model_get_emblem_column_id_from_zoom_level (NautilusZoomLevel zoom_level);
|
||||
|
||||
NautilusFile * fm_list_model_file_for_path (FMListModel *model, GtkTreePath *path);
|
||||
|
||||
|
||||
gboolean fm_list_model_load_subdirectory (FMListModel *model, GtkTreePath *path, NautilusDirectory **directory);
|
||||
void fm_list_model_unload_subdirectory (FMListModel *model, GtkTreeIter *iter);
|
||||
|
||||
void fm_list_model_set_drag_view (FMListModel *model,
|
||||
GtkTreeView *view,
|
||||
|
|
|
@ -131,6 +131,9 @@ struct SelectionForeachData {
|
|||
*/
|
||||
#define LIST_VIEW_MINIMUM_ROW_HEIGHT 28
|
||||
|
||||
/* We wait two seconds after row is collapsed to unload the subdirectory */
|
||||
#define COLLAPSE_TO_UNLOAD_DELAY 2000
|
||||
|
||||
static int click_policy_auto_value;
|
||||
static char * default_sort_order_auto_value;
|
||||
static gboolean default_sort_reversed_auto_value;
|
||||
|
@ -782,26 +785,103 @@ static void
|
|||
row_expanded_callback (GtkTreeView *treeview, GtkTreeIter *iter, GtkTreePath *path, gpointer callback_data)
|
||||
{
|
||||
FMListView *view;
|
||||
NautilusFile *file;
|
||||
NautilusDirectory *directory;
|
||||
|
||||
view = FM_LIST_VIEW (callback_data);
|
||||
|
||||
file = fm_list_model_file_for_path (view->details->model, path);
|
||||
directory = nautilus_directory_get_for_file (file);
|
||||
|
||||
fm_directory_view_add_subdirectory (FM_DIRECTORY_VIEW (view), directory);
|
||||
|
||||
if (nautilus_directory_are_all_files_seen (directory)) {
|
||||
fm_list_model_subdirectory_done_loading (view->details->model,
|
||||
directory);
|
||||
} else {
|
||||
g_signal_connect_object (directory, "done_loading",
|
||||
G_CALLBACK (subdirectory_done_loading_callback),
|
||||
view, 0);
|
||||
if (fm_list_model_load_subdirectory (view->details->model, path, &directory)) {
|
||||
fm_directory_view_add_subdirectory (FM_DIRECTORY_VIEW (view), directory);
|
||||
|
||||
if (nautilus_directory_are_all_files_seen (directory)) {
|
||||
fm_list_model_subdirectory_done_loading (view->details->model,
|
||||
directory);
|
||||
} else {
|
||||
g_signal_connect_object (directory, "done_loading",
|
||||
G_CALLBACK (subdirectory_done_loading_callback),
|
||||
view, 0);
|
||||
}
|
||||
|
||||
nautilus_directory_unref (directory);
|
||||
}
|
||||
}
|
||||
|
||||
struct UnloadDelayData {
|
||||
NautilusFile *file;
|
||||
FMListView *view;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
unload_file_timeout (gpointer data)
|
||||
{
|
||||
struct UnloadDelayData *unload_data = data;
|
||||
GtkTreeIter iter;
|
||||
FMListModel *model;
|
||||
GtkTreePath *path;
|
||||
|
||||
if (unload_data->view != NULL) {
|
||||
model = unload_data->view->details->model;
|
||||
if (fm_list_model_get_tree_iter_from_file (model,
|
||||
unload_data->file,
|
||||
&iter)) {
|
||||
path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
|
||||
if (!gtk_tree_view_row_expanded (unload_data->view->details->tree_view,
|
||||
path)) {
|
||||
fm_list_model_unload_subdirectory (model, &iter);
|
||||
}
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
}
|
||||
|
||||
eel_remove_weak_pointer (&unload_data->view);
|
||||
|
||||
nautilus_directory_unref (directory);
|
||||
|
||||
g_object_unref (unload_data->file);
|
||||
g_free (unload_data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
row_collapsed_callback (GtkTreeView *treeview, GtkTreeIter *iter, GtkTreePath *path, gpointer callback_data)
|
||||
{
|
||||
FMListView *view;
|
||||
NautilusFile *file;
|
||||
struct UnloadDelayData *unload_data;
|
||||
|
||||
view = FM_LIST_VIEW (callback_data);
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (view->details->model),
|
||||
iter,
|
||||
FM_LIST_MODEL_FILE_COLUMN, &file,
|
||||
-1);
|
||||
|
||||
unload_data = g_new (struct UnloadDelayData, 1);
|
||||
unload_data->view = view;
|
||||
unload_data->file = file;
|
||||
|
||||
eel_add_weak_pointer (&unload_data->view);
|
||||
|
||||
g_timeout_add (COLLAPSE_TO_UNLOAD_DELAY,
|
||||
unload_file_timeout,
|
||||
unload_data);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
subdirectory_unloaded_callback (FMListModel *model,
|
||||
NautilusDirectory *directory,
|
||||
gpointer callback_data)
|
||||
{
|
||||
FMListView *view;
|
||||
|
||||
g_return_if_fail (FM_IS_LIST_MODEL (model));
|
||||
g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
|
||||
|
||||
view = FM_LIST_VIEW(callback_data);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (directory,
|
||||
G_CALLBACK (subdirectory_done_loading_callback),
|
||||
view);
|
||||
fm_directory_view_remove_subdirectory (FM_DIRECTORY_VIEW (view), directory);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -1136,6 +1216,8 @@ create_and_set_up_tree_view (FMListView *view)
|
|||
G_CALLBACK (popup_menu_callback), view, 0);
|
||||
g_signal_connect_object (view->details->tree_view, "row_expanded",
|
||||
G_CALLBACK (row_expanded_callback), view, 0);
|
||||
g_signal_connect_object (view->details->tree_view, "row_collapsed",
|
||||
G_CALLBACK (row_collapsed_callback), view, 0);
|
||||
|
||||
view->details->model = g_object_new (FM_TYPE_LIST_MODEL, NULL);
|
||||
gtk_tree_view_set_model (view->details->tree_view, GTK_TREE_MODEL (view->details->model));
|
||||
|
@ -1145,6 +1227,9 @@ create_and_set_up_tree_view (FMListView *view)
|
|||
|
||||
g_signal_connect_object (view->details->model, "sort_column_changed",
|
||||
G_CALLBACK (sort_column_changed_callback), view, 0);
|
||||
|
||||
g_signal_connect_object (view->details->model, "subdirectory_unloaded",
|
||||
G_CALLBACK (subdirectory_unloaded_callback), view, 0);
|
||||
|
||||
view->details->source_target_list =
|
||||
gtk_target_list_new (drag_types, num_drag_types);
|
||||
|
@ -1250,12 +1335,7 @@ fm_list_view_add_file (FMDirectoryView *view, NautilusFile *file)
|
|||
FMListModel *model;
|
||||
|
||||
model = FM_LIST_VIEW (view)->details->model;
|
||||
if (!fm_list_model_add_file (model, file)) {
|
||||
fm_directory_view_remove_subdirectory (view,
|
||||
nautilus_directory_get_for_file (file));
|
||||
fm_list_model_remove_file (model, file);
|
||||
fm_list_model_add_file (model, file);
|
||||
}
|
||||
fm_list_model_add_file (model, file);
|
||||
}
|
||||
|
||||
static GList *
|
||||
|
@ -1591,7 +1671,7 @@ fm_list_view_remove_file (FMDirectoryView *view, NautilusFile *file)
|
|||
gtk_tree_path_free (file_path);
|
||||
|
||||
fm_list_model_remove_file (list_view->details->model, file);
|
||||
|
||||
|
||||
if (gtk_tree_row_reference_valid (row_reference)) {
|
||||
if (list_view->details->new_selection_path) {
|
||||
gtk_tree_path_free (list_view->details->new_selection_path);
|
||||
|
|
Loading…
Reference in a new issue