[maemo-commits] [maemo-commits] r13008 - projects/haf/trunk/hildon-fm/hildon-fm
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Thu Aug 2 20:11:54 EEST 2007
- Previous message: [maemo-commits] r13007 - projects/haf/trunk/hildon-fm/hildon-fm
- Next message: [maemo-commits] r13009 - in projects/haf/trunk/hildon-fm: . debian hildon-fm
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: marivoll
Date: 2007-08-02 20:11:49 +0300 (Thu, 02 Aug 2007)
New Revision: 13008
Modified:
projects/haf/trunk/hildon-fm/hildon-fm/hildon-file-system-model.c
Log:
* hildon-fm/hildon-file-system-model.c: Removed machinery for
delaying node adding and reloads. The GtkFilesystem API is now
sufficiently asynchronous to make our own trick unnecessary.
(hildon_file_system_model_load_uri): Wait for scan of root folder
to be complete (N62546).
(hildon_file_system_model_load_path): Wait for the parent to be
fully loaded and then expect to find the path instead of just
adding a 'ghost' node.
Modified: projects/haf/trunk/hildon-fm/hildon-fm/hildon-file-system-model.c
===================================================================
--- projects/haf/trunk/hildon-fm/hildon-fm/hildon-file-system-model.c 2007-08-02 17:02:08 UTC (rev 13007)
+++ projects/haf/trunk/hildon-fm/hildon-fm/hildon-file-system-model.c 2007-08-02 17:11:49 UTC (rev 13008)
@@ -49,7 +49,10 @@
#include "hildon-file-common-private.h"
#include "hildon-file-system-special-location.h"
+#include "hildon-file-system-root.h"
+/*#define DEBUG*/
+
/* Reload contents of removable devices after this amount of seconds */
#define RELOAD_THRESHOLD 30
#define THUMBNAIL_WIDTH 80 /* For images inside thumbnail folder */
@@ -106,9 +109,7 @@
GtkWidget *ref_widget; /* Any widget on the same screen, needed
to return correct icons */
GQueue *cache_queue;
- GQueue *delayed_lists;
- GQueue *reload_list; /* Queueing all loads started implicitly by GtkTreeModel interface
- instead of just errors is much more handy... */
+
/* We have to keep references to emblems ourselves. They are used only
while composed image is made, so our new cache approach would free
them immediately after composed image is ready */
@@ -121,6 +122,11 @@
gboolean multiroot;
gulong volumes_changed_handler;
+
+ /* This is set to true when all GnomeVFS devices have been
+ enumerated at least once.
+ */
+ gboolean first_root_scan_completed;
};
typedef struct {
@@ -138,6 +144,12 @@
PROP_MULTI_ROOT
};
+#ifdef DEBUG
+#define DBG(args...) fprintf (stderr, ## args)
+#else
+#define DBG(...) do { } while (0)
+#endif
+
static void hildon_file_system_model_iface_init(GtkTreeModelIface * iface);
static void
hildon_file_system_model_drag_source_iface_init(GtkTreeDragSourceIface *iface);
@@ -151,6 +163,11 @@
GObjectConstructParam *
construct_properties);
+static void
+hildon_file_system_model_add_nodes (GtkTreeModel * model,
+ GNode * parent_node,
+ GtkFileFolder * parent_folder,
+ GSList *children);
static GNode *
hildon_file_system_model_add_node(GtkTreeModel * model,
GNode * parent_node,
@@ -170,9 +187,6 @@
hildon_file_system_model_kick_node(GNode *node, gpointer data);
static void
clear_model_node_caches(HildonFileSystemModelNode *model_node);
-static void
-hildon_file_system_model_delayed_add_children(HildonFileSystemModel *
- model, GNode * node, gboolean force);
static void unlink_file_folder(GNode *node);
static gboolean
link_file_folder(GNode *node, const GtkFilePath *path);
@@ -189,9 +203,12 @@
location_rescan (HildonFileSystemSpecialLocation *location, GNode *node);
static void setup_node_for_location(GNode *node);
static void
-hildon_file_system_model_queue_node_reload (HildonFileSystemModel *model,
+hildon_file_system_model_reload_node (HildonFileSystemModel *model,
GNode *node,
gboolean force);
+static void
+_hildon_file_system_model_load_children(HildonFileSystemModel *model,
+ GtkTreeIter *parent_iter);
static GtkTreePath *hildon_file_system_model_get_path(GtkTreeModel * model,
GtkTreeIter * iter);
@@ -209,42 +226,34 @@
G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_DRAG_SOURCE,
hildon_file_system_model_drag_source_iface_init))
-static void handle_possibly_finished_node(GNode *node)
+static void
+handle_finished_node (GNode *node)
{
GtkTreeIter iter;
HildonFileSystemModel *model = MODEL_FROM_NODE(node);
+ GNode *child_node;
- if (is_node_loaded(model->priv, node))
+ child_node = g_node_first_child(node);
+ while (child_node)
{
- GNode *child_node = g_node_first_child(node);
+ HildonFileSystemModelNode *model_node = child_node->data;
- while (child_node)
- {
- HildonFileSystemModelNode *model_node = child_node->data;
+ /* We do not want to ever kick off devices by accident */
- /* We do not want to ever kick off devices by accident */
+ if (model_node->present_flag
+ || (model_node->location
+ && (!hildon_file_system_special_location_failed_access
+ (model_node->location))))
+ child_node = g_node_next_sibling(child_node);
+ else
+ child_node = hildon_file_system_model_kick_node(child_node, model);
+ }
- if (model_node->present_flag
- || (model_node->location
- && (!hildon_file_system_special_location_failed_access
- (model_node->location))))
- child_node = g_node_next_sibling(child_node);
- else
- child_node = hildon_file_system_model_kick_node(child_node, model);
- }
+ emit_node_changed (node);
- iter.stamp = model->priv->stamp;
- iter.user_data = node;
- g_signal_emit(model, signal_finished_loading, 0, &iter);
-
- {
- GtkTreePath *path =
- hildon_file_system_model_get_path (GTK_TREE_MODEL (model), &iter);
- if (gtk_tree_path_get_depth (path) > 0)
- gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
- gtk_tree_path_free (path);
- }
- }
+ iter.stamp = model->priv->stamp;
+ iter.user_data = node;
+ g_signal_emit (model, signal_finished_loading, 0, &iter);
}
/* This default handler is activated when device tree (mmc/gateway)
@@ -350,7 +359,7 @@
be removed are kicked on when their parent is refreshed. */
if (model_node->location)
{
- g_clear_error(&model_node->error);
+ // g_clear_error(&model_node->error);
send_device_disconnected(node);
emit_node_changed(node);
}
@@ -362,125 +371,8 @@
emit_node_changed(node);
}
-static void delayed_list_free(delayed_list_type *list)
-{
- gtk_file_paths_free(list->children);
- g_free(list);
-}
static gboolean
-hildon_file_system_model_delayed_add_node_list_timeout(gpointer data)
-{
- HildonFileSystemModel *model;
- HildonFileSystemModelPrivate *priv;
- delayed_list_type *current_list;
- GNode *node;
-
- GDK_THREADS_ENTER();
-
- model = HILDON_FILE_SYSTEM_MODEL(data);
- priv = model->priv;
-
- /* Handle pending reloads one at a time. We can now handle errors
- inside delayed_add_children, since we are called from idle and
- we can do modifications to model.
- */
- if ( (node = g_queue_pop_head(priv->reload_list)) != NULL)
- {
- hildon_file_system_model_delayed_add_children(model, node, TRUE);
- GDK_THREADS_LEAVE();
- return TRUE;
- }
-
- current_list = g_queue_peek_head(priv->delayed_lists);
- if (!current_list) { /* No items to insert => remove idle handler */
- priv->timeout_id = 0;
- GDK_THREADS_LEAVE();
- return FALSE;
- }
-
- /* Back to one addition per idle, old approach caused too
- long delays... */
-
- /* Ok, lets add one item from the list and return to main loop. This
- idle handler is then called again. */
- hildon_file_system_model_add_node(GTK_TREE_MODEL(data),
- current_list->parent_node,
- current_list->folder,
- current_list->iter->data);
-
- current_list->iter = g_slist_next(current_list->iter);
-
- if (current_list->iter)
- {
- GDK_THREADS_LEAVE();
- return TRUE; /* Ok, there is items left. Continue with this
- idle handler */
- }
-
- /* Current list ends here. We now have to check
- if loading of some folder is really finished. If this is a
- case we then have to check if there are unflagged
- paths in that folder (paths to be removed) */
-
- node = current_list->parent_node;
- delayed_list_free(current_list);
- g_queue_pop_head(priv->delayed_lists);
- handle_possibly_finished_node(node);
-
- GDK_THREADS_LEAVE();
-
- return TRUE;
-}
-
-/* This is used as a callback */
-static void
-clear_present_flag(GNode *node)
-{
- HildonFileSystemModelNode *model_node;
-
- g_assert(node != NULL && node->data != NULL);
-
- model_node = node->data;
- model_node->present_flag = FALSE;
-}
-
-static void
-hildon_file_system_model_ensure_idle(HildonFileSystemModel *self)
-{
- if (self->priv->timeout_id == 0)
- {
- self->priv->timeout_id =
- g_idle_add_full (G_PRIORITY_DEFAULT_IDLE + 20,
- hildon_file_system_model_delayed_add_node_list_timeout,
- self, NULL);
- }
-}
-
-/* Adds the given list of children to be added to the model. The list must
- be a copy (this class takes ownership) */
-static void
-hildon_file_system_model_delayed_add_node_list(HildonFileSystemModel *
- model, GNode * parent,
- GtkFileFolder * folder,
- GSList * children)
-{
- if (children) {
- delayed_list_type *new_list;
-
- new_list = g_new(delayed_list_type, 1);
- new_list->parent_node = parent;
- new_list->folder = folder;
- new_list->children = children;
- new_list->iter = children;
-
- hildon_file_system_model_ensure_idle(model);
-
- g_queue_push_tail(model->priv->delayed_lists, new_list);
- }
-}
-
-static gboolean
node_needs_reload (HildonFileSystemModel *model, GNode *node,
gboolean force)
{
@@ -500,18 +392,21 @@
if (model_node->location
&& !model_node->accessed
&& (hildon_file_system_special_location_requires_access
- (model_node->location)))
+ (model_node->location))
+ && model_node->error == NULL)
{
/* Accessing this node is expensive and the user has not tried
to do it explicitly yet. We don't reload it even if forced.
*/
+ DBG ("TOO EXPENSIVE\n");
return FALSE;
}
- if (!is_node_loaded (model->priv, node))
+ if (model_node->get_folder_handle != NULL
+ || (model_node->folder
+ && gtk_file_folder_is_finished_loading (model_node->folder)))
{
- /* This node is already queued for a reload, don't queue it
- again.
+ /* This node is being loaded right now, just let it finish.
*/
return FALSE;
}
@@ -524,22 +419,6 @@
return TRUE;
}
- if (model_node->folder == NULL)
- {
- /* This node is not being watched and we ignore it if not
- forced. This case happens when a device is diconnected, for
- example, and its nodes are kicked from the model. The
- selection then moves to the device node and we would try to
- reload it (since it has been accessed already).
-
- We don't reset the 'accessed' property of disconnected
- devices since that would prevent a reload to try again.
-
- XXX - This logic could be improved.
- */
- return FALSE;
- }
-
/* If none of the rules above apply, we reload a node if it hasn't
been loaded yet, or if it is a node that we don't receive change
notifications for and it has been loaded too long ago.
@@ -557,91 +436,7 @@
&& (removable || model_node->error)));
}
-/* We are not any more called directly by GtkTreeModel interface methods, so we can modify
- model and send notifications */
-static void
-hildon_file_system_model_delayed_add_children(HildonFileSystemModel *
- model, GNode * node, gboolean force)
-{
- HildonFileSystemModelNode *model_node;
- gboolean result;
- model_node = node->data;
- g_assert(model_node != NULL);
-
- if (!node_needs_reload (model, node, force))
- {
- handle_possibly_finished_node (node);
- return;
- }
-
- /* Unix backend can fail to set children to NULL if it encounters error */
- {
- GSList *children = NULL;
- time_t current_time = time(NULL);
-
- g_clear_error(&model_node->error);
-
- /* List children do not work reliably with bluetooth connections. It can
- still succeed, even though the connection has died already. This
- if statement can be removed when the backend works better... */
-
- if (!gtk_file_system_path_is_local (model->priv->filesystem,
- model_node->path))
- {
- unlink_file_folder(node);
- if (!link_file_folder(node, model_node->path))
- return;
- }
-
- /* We have to set load time every time. Otherwise we have a deadlock:
- load_children => error => notify => load_children => error */
- model_node->load_time = current_time;
-
- /* We clear present flags for existing children, so we are able to
- use this to detect if children are actually removed */
- g_node_children_foreach(node, G_TRAVERSE_ALL,
- (GNodeForeachFunc) clear_present_flag, NULL);
-
- ULOG_INFO("Delayed add for path %s", (char *) model_node->path);
-
- if (model_node->folder)
- {
- /* Unix backend sends finished loading even before returning
- children. This causes our internal bookkeeping fail. */
- g_signal_handlers_block_by_func
- (model_node->folder,
- hildon_file_system_model_folder_finished_loading, model);
-
- result = gtk_file_folder_list_children
- (model_node->folder, &children, &(model_node->error));
-
- g_signal_handlers_unblock_by_func
- (model_node->folder,
- hildon_file_system_model_folder_finished_loading, model);
- }
- else
- {
- result = TRUE;
- children = NULL;
- model_node->error = NULL;
- }
-
- /* Patched GnomeVFS now also reports errors. */
- if (result)
- {
- hildon_file_system_model_delayed_add_node_list(model, node,
- model_node->folder, children);
- }
- else
- {
- g_assert(children == NULL);
- ULOG_INFO("ERROR: %s", model_node->error->message);
- handle_load_error(node);
- }
- }
-}
-
static GNode *get_node(HildonFileSystemModelPrivate * priv,
GtkTreeIter * iter)
{
@@ -821,30 +616,22 @@
return result;
}
-/* This function searches the insert queue and checks if it contains
- something for the given node */
-static gint queue_finder(gconstpointer a, gconstpointer b)
+static gboolean
+is_node_loaded (HildonFileSystemModelPrivate *priv,
+ GNode * node)
{
- const delayed_list_type *list = a;
- const GNode *search_node = b;
-
- if (list->parent_node == search_node)
- return 0;
-
- return -1;
-}
-
-static gboolean is_node_loaded(HildonFileSystemModelPrivate *priv,
- GNode * node)
-{
HildonFileSystemModelNode *model_node = node->data;
- if (!model_node->folder) /* If there is no folder then think this as loaded */
+ /* Only folders need to be loaded.
+ */
+ if (model_node->location == NULL
+ && (model_node->info == NULL
+ || !gtk_file_info_get_is_folder (model_node->info)))
return TRUE;
- return g_queue_find(priv->reload_list, node) == NULL &&
- gtk_file_folder_is_finished_loading(model_node->folder) &&
- g_queue_find_custom(priv->delayed_lists, node, queue_finder) == NULL;
+ return (model_node->error
+ || (model_node->folder
+ && gtk_file_folder_is_finished_loading (model_node->folder)));
}
static void emit_node_changed(GNode *node)
@@ -861,7 +648,8 @@
iter.stamp = CAST_GET_PRIVATE(model)->stamp;
iter.user_data = node;
path = hildon_file_system_model_get_path(model, &iter);
- gtk_tree_model_row_changed(model, path, &iter);
+ if (gtk_tree_path_get_depth (path) > 0)
+ gtk_tree_model_row_changed(model, path, &iter);
gtk_tree_path_free(path);
}
@@ -999,21 +787,30 @@
break;
case HILDON_FILE_SYSTEM_MODEL_COLUMN_DISPLAY_NAME:
if (!model_node->title_cache)
- model_node->title_cache = _hildon_file_system_create_display_name(fs,
- path, model_node->location, info);
+ {
+ model_node->title_cache =
+ _hildon_file_system_create_display_name (fs,
+ path,
+ model_node->location,
+ info);
+
+ /* We load this node if this is the first time someone
+ asks for its display name and if it is a folder and it
+ has not been loaded yet.
+ */
+
+ if (model_node->load_time == 0
+ && model_node->error == NULL
+ && (model_node->location ||
+ (info && gtk_file_info_get_is_folder (info))))
+ {
+ unlink_file_folder (node);
+ link_file_folder (node, model_node->path);
+ }
+ }
+
g_value_set_string(value, model_node->title_cache);
- /* We try to reload children, if we are actually showing something */
- /* This action should be performed for initial access only. Otherwise
- we always end up loading all the children of a node after long
- time of inactivity. This is not good in case of gateway, since the
- old BT connection is already timed out. UI asks for reloads if
- user actually does something, so we just make sure that children
- initially appear where they should. */
- if (model_node->folder &&
- model_node->load_time == 0)
- _hildon_file_system_model_queue_reload(
- HILDON_FILE_SYSTEM_MODEL(model), iter, FALSE);
break;
case HILDON_FILE_SYSTEM_MODEL_COLUMN_SORT_KEY:
/* We cannot just use display_key from GtkFileInfo, because it is
@@ -1184,7 +981,7 @@
&& (!hildon_file_system_special_location_requires_access
(model_node->location)))
{
- fprintf (stderr, "SCANNING FOR VISIBILITY\n");
+ DBG ("SCANNING FOR VISIBILITY: %s\n", (char*) model_node->path);
_hildon_file_system_model_queue_reload
(HILDON_FILE_SYSTEM_MODEL(model), iter, FALSE);
}
@@ -1359,14 +1156,21 @@
if (paths != NULL)
{
GNode *node;
+ HildonFileSystemModelNode *model_node;
ULOG_INFO("Adding files (monitor = %p)", (void *) monitor);
node = hildon_file_system_model_search_folder(monitor);
if (node != NULL)
- hildon_file_system_model_delayed_add_node_list(data, node, monitor,
- gtk_file_paths_copy
- (paths));
+ {
+ model_node = node->data;
+ model_node->load_time = time(NULL);
+ hildon_file_system_model_add_nodes (GTK_TREE_MODEL (model_node->model),
+ node,
+ monitor,
+ paths);
+ emit_node_changed (node);
+ }
else
ULOG_ERR_F("Data destination not found!");
}
@@ -1422,7 +1226,7 @@
GNode *node = hildon_file_system_model_search_folder(monitor);
g_assert(node != NULL);
ULOG_INFO("Finished loading (monitor = %p)", (void *) monitor);
- handle_possibly_finished_node(node);
+ handle_finished_node (node);
}
static GNode *
@@ -1498,12 +1302,6 @@
gtk_tree_path_free(tree_path);
}
-static gint search_folder_helper(gconstpointer a, gconstpointer b)
-{
- const delayed_list_type *list = a;
- return list->folder != b; /* We have to return 0 if found */
-}
-
static void
unlink_file_folder(GNode *node)
{
@@ -1530,46 +1328,34 @@
}
if (model_node->folder)
- {
- GQueue *queue;
- GList *link;
-
- g_object_set_qdata(G_OBJECT(model_node->folder),
- hildon_file_system_model_quark, NULL);
-
- g_signal_handlers_disconnect_by_func
+ {
+ g_object_set_qdata(G_OBJECT(model_node->folder),
+ hildon_file_system_model_quark, NULL);
+
+ g_signal_handlers_disconnect_by_func
(model_node->folder,
(gpointer) hildon_file_system_model_dir_removed,
model_node->model);
- g_signal_handlers_disconnect_by_func
+ g_signal_handlers_disconnect_by_func
(model_node->folder,
(gpointer) hildon_file_system_model_files_added,
model_node->model);
- g_signal_handlers_disconnect_by_func
+ g_signal_handlers_disconnect_by_func
(model_node->folder,
(gpointer) hildon_file_system_model_files_removed,
model_node->model);
- g_signal_handlers_disconnect_by_func
+ g_signal_handlers_disconnect_by_func
(model_node->folder,
(gpointer) hildon_file_system_model_files_changed,
model_node->model);
- g_signal_handlers_disconnect_by_func
+ g_signal_handlers_disconnect_by_func
(model_node->folder,
(gpointer) hildon_file_system_model_folder_finished_loading,
model_node->model);
- /* Remove possibly pending nodes from queue */
- queue = model_node->model->priv->delayed_lists;
- while ((link = g_queue_find_custom(queue,
- model_node->folder, search_folder_helper)) != NULL)
- {
- delayed_list_free(link->data);
- g_queue_delete_link(queue, link);
+ g_object_unref(model_node->folder);
+ model_node->folder = NULL;
}
-
- g_object_unref(model_node->folder);
- model_node->folder = NULL;
- }
}
static void
@@ -1593,10 +1379,12 @@
g_object_unref (handle);
- /* When the operation has been cancelled, handle_data->node is no longer valid.
+ /* When the operation has been cancelled, handle_data->node is no
+ longer valid.
*/
if (cancelled)
{
+ DBG ("LINK CANCELLED\n");
free_handle_data (handle_data);
return;
}
@@ -1613,6 +1401,18 @@
{
ULOG_ERR_F("Failed to create monitor for path %s",
gtk_file_path_get_string (model_node->path));
+ if (model_node->error == NULL)
+ model_node->error = g_error_new (G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ "failure");
+ }
+
+ DBG ("LINK DONE %s %s %p\n",
+ (char *)model_node->path, error? error->message : "(success)",
+ folder);
+
+ if (model_node->error)
+ {
+ handle_load_error (node);
return;
}
@@ -1624,25 +1424,6 @@
g_object_set_qdata (G_OBJECT(model_node->folder),
hildon_file_system_model_quark, node);
- if (gtk_file_folder_is_finished_loading (model_node->folder))
- {
- GSList *children = NULL;
- gboolean result;
-
- result = gtk_file_folder_list_children
- (model_node->folder, &children, &(model_node->error));
- if (result)
- {
- hildon_file_system_model_files_added (model_node->folder,
- children,
- model);
- hildon_file_system_model_folder_finished_loading
- (model_node->folder, model);
- gtk_file_paths_free (children);
- }
-
- }
-
g_signal_connect_object
(model_node->folder, "files-added",
G_CALLBACK(hildon_file_system_model_files_added),
@@ -1660,10 +1441,38 @@
G_CALLBACK (hildon_file_system_model_folder_finished_loading), model,
0);
- if (error)
- handle_load_error (node);
-
free_handle_data (handle_data);
+
+ /* The following has to be done last since it might do anything to
+ model_node, including loading it again.
+ */
+
+ if (gtk_file_folder_is_finished_loading (folder))
+ {
+ GSList *children = NULL;
+ gboolean result;
+
+ DBG ("LINK FINISHED %s\n", (char *)model_node->path);
+
+ result = gtk_file_folder_list_children
+ (folder, &children, &(model_node->error));
+ if (result)
+ {
+ hildon_file_system_model_files_added (model_node->folder,
+ children,
+ model);
+
+ if (model_node->location &&
+ HILDON_IS_FILE_SYSTEM_ROOT (model_node->location))
+ model->priv->first_root_scan_completed = TRUE;
+
+ hildon_file_system_model_folder_finished_loading
+ (model_node->folder, model);
+ gtk_file_paths_free (children);
+ }
+ else
+ handle_load_error (node);
+ }
}
static gboolean
@@ -1683,6 +1492,8 @@
if (model_node->folder || model_node->get_folder_handle)
return TRUE;
+ DBG ("LINK %s\n", (char *)model_node->path);
+
model = model_node->model;
g_assert(HILDON_IS_FILE_SYSTEM_MODEL(model));
@@ -1721,11 +1532,15 @@
if (model_node->get_folder_handle == NULL)
{
ULOG_ERR_F ("Failed to create monitor for path %s", (char *) path);
+ DBG ("Failed to create monitor for path %s", (char *) path);
free_handle_data (handle_data);
return FALSE;
}
else
- return TRUE;
+ {
+ g_clear_error (&(model_node->error));
+ return TRUE;
+ }
}
static gboolean hildon_file_system_model_destroy_model_node(GNode * node,
@@ -1734,7 +1549,6 @@
HildonFileSystemModelNode *model_node = node->data;
g_assert(HILDON_IS_FILE_SYSTEM_MODEL(data));
- g_queue_remove_all(HILDON_FILE_SYSTEM_MODEL(data)->priv->reload_list, node);
g_queue_remove_all(HILDON_FILE_SYSTEM_MODEL(data)->priv->cache_queue, node);
if (model_node)
@@ -1832,6 +1646,21 @@
}
+static void
+hildon_file_system_model_add_nodes (GtkTreeModel * model,
+ GNode * parent_node,
+ GtkFileFolder * parent_folder,
+ GSList *children)
+{
+ while (children)
+ {
+ hildon_file_system_model_add_node (model,
+ parent_node, parent_folder,
+ (GtkFilePath *) children->data);
+ children = children->next;
+ }
+}
+
static GNode *
hildon_file_system_model_add_node(GtkTreeModel * model,
GNode * parent_node,
@@ -1875,6 +1704,7 @@
* with this name no longer exists. */
if (error)
{
+ DBG ("ADD ERR %s\n", error->message);
ULOG_ERR(error->message);
g_error_free(error);
return NULL;
@@ -1896,7 +1726,7 @@
if (model_node->info)
gtk_file_info_free (model_node->info);
model_node->info = file_info;
- return NULL;
+ return node;
}
}
@@ -2080,7 +1910,9 @@
{
HildonFileSystemModelNode *model_node = node->data;
- if (model_node->folder) /* Sanity check: node has to be a folder */
+ if (model_node->folder
+ || model_node->get_folder_handle) /* Sanity check: node has to
+ be a folder */
{
ULOG_INFO("Waiting folder [%s] to load", (char *) model_node->path);
while (!is_node_loaded(priv, node))
@@ -2159,9 +1991,8 @@
G_TYPE_BOOLEAN;
priv->stamp = g_random_int();
- priv->delayed_lists = g_queue_new();
- priv->reload_list = g_queue_new();
priv->cache_queue = g_queue_new();
+ priv->first_root_scan_completed = FALSE;
}
static void hildon_file_system_model_dispose(GObject *self)
@@ -2198,9 +2029,6 @@
g_free(priv->backend_name); /* No need to check NULL */
g_free(priv->alternative_root_dir);
- g_queue_foreach(priv->delayed_lists, (GFunc) delayed_list_free, NULL);
- g_queue_free(priv->delayed_lists);
- g_queue_free(priv->reload_list);
g_queue_free(priv->cache_queue);
/* Contents of this queue are gone already */
@@ -2493,11 +2321,8 @@
}
else
{
- if (!link_file_folder(node, model_node->path))
- return;
-
- hildon_file_system_model_queue_node_reload
- (HILDON_FILE_SYSTEM_MODEL(model), node, TRUE);
+ hildon_file_system_model_reload_node
+ (HILDON_FILE_SYSTEM_MODEL(model), node, TRUE);
}
}
@@ -2563,8 +2388,6 @@
g_signal_connect(location, "rescan",
G_CALLBACK(location_rescan), node);
}
- else
- link_file_folder (node, model_node->path);
}
}
/* Similar to g_node_copy_deep, but will also allow nodes to be skipped,
@@ -2651,11 +2474,7 @@
model_node->model = HILDON_FILE_SYSTEM_MODEL(obj);
if (link_file_folder (priv->roots, file_path))
- {
- hildon_file_system_model_delayed_add_children
- (HILDON_FILE_SYSTEM_MODEL(obj), priv->roots, TRUE);
- wait_node_load(priv, priv->roots);
- }
+ wait_node_load(priv, priv->roots);
}
else
{
@@ -2839,6 +2658,17 @@
gtk_main_iteration();
}
+ /* Block until the first scanning of the root folder is complete
+ so that we know about all memory cards, usb mass storage
+ devices, etc.
+ */
+ while (!priv->first_root_scan_completed)
+ {
+ DBG ("+");
+ gtk_main_iteration();
+ }
+ DBG ("DONE\n");
+
result = hildon_file_system_model_load_path(model, filepath, iter);
gtk_file_path_free(filepath);
@@ -2870,6 +2700,8 @@
g_return_val_if_fail(path != NULL, FALSE);
g_return_val_if_fail(iter != NULL, FALSE);
+ DBG ("LOAD %s\n", (char *)path);
+
/* XXX - if we are trying to load "upnpav:///", we change it to
"upnpav://", since upnpav:/// will not be found. Urks.
*/
@@ -2884,6 +2716,7 @@
{
/* In case of gateway, we may need this to allow accessing contents */
_hildon_file_system_model_mount_device_iter(model, iter);
+ DBG ("FOUND %s\n", (char *)path);
return TRUE;
}
@@ -2912,58 +2745,64 @@
parent_path = gtk_file_path_new_steal(g_strndup(s, i + 1));
else {
ULOG_ERR_F("Attempt to select folder that is not in user visible area");
+ DBG ("ERR %s\n", (char *)path);
return FALSE; /* Very BAD. We reached the real root. Given
folder was probably not under any of our roots */
}
}
if (hildon_file_system_model_load_path(model, parent_path, &parent_iter))
- {
- GNode *parent_node;
- GtkFileFolder *parent_folder;
- HildonFileSystemModelNode *parent_model_node;
+ {
+ gtk_file_path_free(parent_path);
- parent_node = parent_iter.user_data;
- g_assert(parent_node != NULL);
- parent_model_node = parent_node->data;
- g_assert(parent_model_node != NULL);
+ DBG ("ADD %s\n", (char *)path);
- gtk_file_path_free(parent_path);
- parent_folder = parent_model_node->folder;
+ /* XXX - We trigger the parent to load its children and then
+ * wait for it to finish. This is suboptimal of course
+ * since it might take a long time. Instead, we should
+ * tolerate nodes without a GtkFileInfo and only acquire
+ * the file info when needed.
+ */
+ _hildon_file_system_model_load_children (model, &parent_iter);
+
+ /* Since we waited for the parent to load its children, we
+ can now expect it to be there.
+ */
- /* Ok, if we reached this point we had located "parent_folder". We
- have to add our path to this folder. This is a blocking function,
- but MUCH FASTER than the previous approach that loaded whole levels
- for each folder. */
- iter->user_data = hildon_file_system_model_add_node(GTK_TREE_MODEL(model),
- parent_node, parent_folder,
- real_path);
- iter->stamp = model->priv->stamp;
+ if (hildon_file_system_model_search_path (model, real_path, iter,
+ NULL, TRUE))
+ {
+ DBG ("FOUND %s\n", (char *)path);
+ return TRUE;
+ }
+ else
+ {
+ DBG ("NOT FOUND %s\n", (char *)path);
+ return FALSE;
+ }
+ }
- return iter->user_data != NULL;
- }
-
*iter = parent_iter; /* Return parent iterator if we cannot
found asked path */
gtk_file_path_free(parent_path);
+ DBG ("NO PARENT %s\n", (char *)path);
return FALSE;
}
static void
-hildon_file_system_model_queue_node_reload (HildonFileSystemModel *model,
- GNode *node,
- gboolean force)
+hildon_file_system_model_reload_node (HildonFileSystemModel *model,
+ GNode *node,
+ gboolean force)
{
+ HildonFileSystemModelNode *model_node = node->data;
+
g_return_if_fail(HILDON_IS_FILE_SYSTEM_MODEL(model));
if (!node_needs_reload (model, node, force))
return;
- if (g_queue_find(model->priv->reload_list, node) == NULL)
- {
- hildon_file_system_model_ensure_idle(model);
- g_queue_push_tail(model->priv->reload_list, node);
- }
+ unlink_file_folder (node);
+ link_file_folder (node, model_node->path);
}
void _hildon_file_system_model_queue_reload(HildonFileSystemModel *model,
@@ -2977,20 +2816,38 @@
node = parent_iter->user_data;
- hildon_file_system_model_queue_node_reload (model, node, force);
+ hildon_file_system_model_reload_node (model, node, force);
}
static void
_hildon_file_system_model_load_children(HildonFileSystemModel *model,
GtkTreeIter *parent_iter)
{
+ GNode *parent_node;
+ HildonFileSystemModelNode *parent_model_node;
+
g_return_if_fail(HILDON_IS_FILE_SYSTEM_MODEL(model));
g_return_if_fail(parent_iter != NULL);
g_return_if_fail(parent_iter->stamp == model->priv->stamp);
- hildon_file_system_model_delayed_add_children(model,
- parent_iter->user_data, FALSE);
- wait_node_load(model->priv, parent_iter->user_data);
+ parent_node = parent_iter->user_data;
+ parent_model_node = parent_node->data;
+
+ if (!is_node_loaded (model->priv, parent_node))
+ {
+ if (parent_model_node->get_folder_handle == NULL)
+ link_file_folder (parent_node, parent_model_node->path);
+ else
+ DBG ("NOT LINKING %s\n", (char *)parent_model_node->path);
+ while (!is_node_loaded (model->priv, parent_node))
+ {
+ DBG ("-");
+ gtk_main_iteration ();
+ }
+ DBG ("FINISHED %s\n", (char *)parent_model_node->path);
+ }
+ else
+ DBG ("WAS LOADED %s\n", (char *)parent_model_node->path);
}
GtkFileSystem
@@ -3185,7 +3042,6 @@
if (!success)
return FALSE;
- hildon_file_system_model_delayed_add_children(model, node, TRUE);
return TRUE;
}
}
@@ -3210,7 +3066,9 @@
{
g_return_val_if_fail(HILDON_IS_FILE_SYSTEM_MODEL(model), FALSE);
- return g_queue_is_empty(model->priv->delayed_lists);
+ /* Cough...
+ */
+ return TRUE;
}
#endif
/**
@@ -3382,19 +3240,6 @@
_hildon_file_system_model_prioritize_folder(HildonFileSystemModel *model,
GtkTreeIter *folder_iter)
{
- GNode *folder_node = get_node(model->priv, folder_iter);
- guint n, len;
-
- /* search delayed_lists for the folder and move it to head */
- for (n = 0, len = g_queue_get_length(model->priv->delayed_lists);
- n < len;
- n++) {
- delayed_list_type *list = g_queue_peek_nth(model->priv->delayed_lists, n);
-
- if (list->parent_node == folder_node) {
- g_queue_push_head(model->priv->delayed_lists,
- g_queue_pop_nth(model->priv->delayed_lists, n));
- return;
- }
- }
+ /* We don't have any influence any more over what is loaded first.
+ */
}
- Previous message: [maemo-commits] r13007 - projects/haf/trunk/hildon-fm/hildon-fm
- Next message: [maemo-commits] r13009 - in projects/haf/trunk/hildon-fm: . debian hildon-fm
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
