[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 ]