From fab274034be61b23004791888bc7a7f622df90d7 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 1 Feb 2012 16:00:39 +0000 Subject: -more download handling cleanup --- src/fs/gnunet-fs-gtk-event_handler.c | 236 +++++++++++++++++------------------ 1 file changed, 113 insertions(+), 123 deletions(-) diff --git a/src/fs/gnunet-fs-gtk-event_handler.c b/src/fs/gnunet-fs-gtk-event_handler.c index 52f89dd8..23681bdd 100644 --- a/src/fs/gnunet-fs-gtk-event_handler.c +++ b/src/fs/gnunet-fs-gtk-event_handler.c @@ -1848,47 +1848,57 @@ mark_download_error (struct DownloadEntry *de, } -static struct DownloadEntry * +/** + * FS-API notified us that we're done with a download. Update the + * view accordingly. If the download is a directory, try to display + * the contents. + * + * @param de download that has finished + * @param size overall size of the file + * @param filename name of the downloaded file on disk (possibly a temporary file) + */ +static void mark_download_completed (struct DownloadEntry *de, uint64_t size, const char *filename) { struct AddDirectoryEntryContext ade; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Marking download completed for DE=%p, %llu-byte `%s'\n", - de, size, filename); + "Marking download completed for DE=%p, %llu-byte `%s'\n", + de, size, filename); de->is_done = GNUNET_YES; mark_download_progress (de, size, size, NULL, 0, 0, 0); - if ((GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (de->meta)) && - (filename != NULL)) + if ( (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (de->meta)) && + (filename != NULL) ) { + /* download was for a directory (and we have a temp file for scanning); + add contents of the directory to the view */ ade.tab = de->tab; ade.prr = de->rr; ade.check_duplicates = GNUNET_YES; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "It is a directory, scan its contents\n"); GNUNET_FS_GTK_mmap_and_scan (filename, &add_directory_entry, &ade); } change_download_color (de, "green"); - return de; } - - - /** - * Move (aka copy) all of the children of 'src_iter' from the 'src_model' - * to become children of 'dst_iter' in the 'dst_model'. - * - * The models are both 'GNUNET_GTK_file_sharing_result_tree_store' models. + * Copy all of the children of 'src_iter' from the 'src_model' to + * become children of 'dst_iter' in the 'dst_model'. The models are + * both 'GNUNET_GTK_file_sharing_result_tree_store' models. * * Note that we also need to update the 'struct SearchResult' * and (if it exists) the respective 'struct DownloadEntry' * to refer to the new model. + * + * @param src_model source model + * @param src_iter parent of the nodes to move + * @param dst_model destination model + * @param dst_iter new parent of the entries we are moving */ static void -move_children (GtkTreeModel * src_model, GtkTreeIter * src_iter, +copy_children (GtkTreeModel * src_model, GtkTreeIter * src_iter, GtkTreeModel * dst_model, GtkTreeIter * dst_iter) { GtkTreeIter src_child; @@ -1911,60 +1921,62 @@ move_children (GtkTreeModel * src_model, GtkTreeIter * src_iter, gchar *downloaded_filename; gint downloaded_anonymity; - if (TRUE == gtk_tree_model_iter_children (src_model, &src_child, src_iter)) + if (! gtk_tree_model_iter_children (src_model, &src_child, src_iter)) + return; + do { - do + gtk_tree_model_get (src_model, &src_child, 0, &meta, 1, &uri, 2, + &filesize, 3, &preview, 4, &percent_progress, 5, + &percent_availability, 6, &filename, 7, + &uri_as_string, 8, &status_colour, 9, &search_result, + 10, &mimetype, 11, &applicability_rank, 12, + &availability_certainty, 13, &availability_rank, 14, + &completed, 15, &downloaded_filename, 16, + &downloaded_anonymity, -1); + gtk_tree_store_insert_with_values (GTK_TREE_STORE (dst_model), &dst_child, + dst_iter, G_MAXINT, 0, meta, 1, uri, 2, + filesize, 3, preview, 4, + percent_progress, 5, + percent_availability, 6, filename, 7, + uri_as_string, 8, status_colour, 9, + search_result, 10, mimetype, 11, + applicability_rank, 12, + availability_certainty, 13, + availability_rank, 14, completed, 15, + downloaded_filename, 16, + downloaded_anonymity, -1); + g_free (filename); + g_free (downloaded_filename); + g_free (uri_as_string); + g_free (status_colour); + g_free (mimetype); + if (preview != NULL) + g_object_unref (preview); + gtk_tree_row_reference_free (search_result->rr); + path = gtk_tree_model_get_path (dst_model, &dst_child); + search_result->rr = gtk_tree_row_reference_new (dst_model, path); + search_result->result = NULL; + gtk_tree_path_free (path); + if (search_result->download != NULL) { - gtk_tree_model_get (src_model, &src_child, 0, &meta, 1, &uri, 2, - &filesize, 3, &preview, 4, &percent_progress, 5, - &percent_availability, 6, &filename, 7, - &uri_as_string, 8, &status_colour, 9, &search_result, - 10, &mimetype, 11, &applicability_rank, 12, - &availability_certainty, 13, &availability_rank, 14, - &completed, 15, &downloaded_filename, 16, - &downloaded_anonymity, -1); - gtk_tree_store_insert_with_values (GTK_TREE_STORE (dst_model), &dst_child, - dst_iter, G_MAXINT, 0, meta, 1, uri, 2, - filesize, 3, preview, 4, - percent_progress, 5, - percent_availability, 6, filename, 7, - uri_as_string, 8, status_colour, 9, - search_result, 10, mimetype, 11, - applicability_rank, 12, - availability_certainty, 13, - availability_rank, 14, completed, 15, - downloaded_filename, 16, - downloaded_anonymity, -1); - g_free (filename); - g_free (downloaded_filename); - g_free (uri_as_string); - g_free (status_colour); - g_free (mimetype); - if (preview != NULL) - g_object_unref (preview); - gtk_tree_row_reference_free (search_result->rr); - path = gtk_tree_model_get_path (dst_model, &dst_child); - search_result->rr = gtk_tree_row_reference_new (dst_model, path); - search_result->result = NULL; - gtk_tree_path_free (path); - if (search_result->download != NULL) - { - search_result->download->ts = GTK_TREE_STORE (dst_model); - gtk_tree_row_reference_free (search_result->download->rr); - search_result->download->rr = - gtk_tree_row_reference_copy (search_result->rr); - } - move_children (src_model, &src_child, dst_model, &dst_child); + search_result->download->ts = GTK_TREE_STORE (dst_model); + gtk_tree_row_reference_free (search_result->download->rr); + search_result->download->rr = + gtk_tree_row_reference_copy (search_result->rr); } - while (TRUE == gtk_tree_model_iter_next (src_model, &src_child)); + copy_children (src_model, &src_child, dst_model, &dst_child); } + while (TRUE == gtk_tree_model_iter_next (src_model, &src_child)); } /** - * Delete the entire given subtree from the model. - * Does not free anything inside of the respective - * model's fields (since they have been moved). + * Delete the entire given subtree from the model. Does not free + * anything inside of the respective model's fields (since they have + * been moved). + * + * @param model model that contains the subtree to remove + * @param iter root of the subtree to remove */ static void delete_stale_subtree (GtkTreeModel * model, GtkTreeIter * iter) @@ -1980,10 +1992,11 @@ delete_stale_subtree (GtkTreeModel * model, GtkTreeIter * iter) /** * Handle the case where an active download lost its * search parent by moving it to the URI tab. + * + * @param de download where the parent (i.e. search) was lost */ -static struct DownloadEntry * -download_lost_parent (struct DownloadEntry *de, uint64_t size, - uint64_t completed, int is_active) +static void +download_lost_parent (struct DownloadEntry *de) { GtkTreeIter iter; GtkTreePath *path; @@ -1994,6 +2007,7 @@ download_lost_parent (struct DownloadEntry *de, uint64_t size, GtkTreeIter child; GtkTreeModel *model; + /* first, move the root of the respective 'de'-tree */ rr_old = de->rr; tab = GNUNET_GTK_add_to_uri_tab (&iter, &de->sr, de->meta, de->uri); de->sr->download = de; @@ -2002,46 +2016,37 @@ download_lost_parent (struct DownloadEntry *de, uint64_t size, path = gtk_tree_model_get_path (model, &iter); de->rr = gtk_tree_row_reference_new (model, path); gtk_tree_path_free (path); - mark_download_progress (de, size, completed, NULL, 0, 0, 0); tm_old = gtk_tree_row_reference_get_model (rr_old); path = gtk_tree_row_reference_get_path (rr_old); gtk_tree_row_reference_free (rr_old); - if (TRUE != gtk_tree_model_get_iter (tm_old, &iter_old, path)) + if (! gtk_tree_model_get_iter (tm_old, &iter_old, path)) { GNUNET_break (0); gtk_tree_path_free (path); - return NULL; + return; } gtk_tree_path_free (path); - move_children (tm_old, &iter_old, model, &iter); - while (TRUE == gtk_tree_model_iter_children (model, &child, &iter)) + + /* finally, move all children over as well */ + copy_children (tm_old, &iter_old, model, &iter); + while (gtk_tree_model_iter_children (model, &child, &iter)) delete_stale_subtree (model, &child); - if (size > completed) - { - if (is_active) - change_download_color (de, "yellow"); - else - change_download_color (de, "blue"); - } - else - { - change_download_color (de, "green"); - } - return de; } /** * Setup a new download entry. * - * @param de existing download entry for the download, or NULL + * @param de existing download entry for the download, or NULL (in which case we create a fresh one) * @param pde parent download entry, or NULL * @param sr search result, or NULL * @param dc download context (for stopping) - * @param uri the URI + * @param uri the URI, must not be NULL + * @param filename filename on disk * @param meta metadata * @param size total size * @param completed current progress + * @return download entry struct for the download (equal to 'de' if 'de' was not NULL) */ static struct DownloadEntry * setup_download (struct DownloadEntry *de, struct DownloadEntry *pde, @@ -2055,55 +2060,49 @@ setup_download (struct DownloadEntry *de, struct DownloadEntry *pde, struct SearchResult *srp; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Setting up download, initially DE=%p, PDE=%p for %p & %p into %llu/%llu `%s'\n", - de, pde, sr, dc, completed, size, filename); + "Setting up download, initially DE=%p, PDE=%p for %p & %p into %llu/%llu `%s'\n", + de, pde, sr, dc, completed, size, filename); GNUNET_assert (NULL != uri); srp = NULL; - if (de == NULL) + if (NULL == de) { + /* no existing download entry to build on, create a fresh one */ de = GNUNET_malloc (sizeof (struct DownloadEntry)); de->uri = GNUNET_FS_uri_dup (uri); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Allocated DE=%p\n", de); + } + else + { + GNUNET_assert (GNUNET_YES == GNUNET_FS_uri_test_equal (de->uri, uri)); } de->dc = dc; de->sr = sr; + de->pde = pde; + if ( (meta != NULL) && (de->meta == NULL) ) + de->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); if (NULL != sr) { + /* got a search result; display the download in the same location as the search result */ GNUNET_assert (sr->download == NULL); sr->download = de; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SR=%p now refers to DE=%p\n", sr, de); - } - de->pde = pde; - if ((meta != NULL) && (de->meta == NULL)) - de->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); - if (sr != NULL) - { de->rr = gtk_tree_row_reference_copy (sr->rr); de->ts = sr->tab->ts; de->tab = sr->tab; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "It's started from a search result, store a copy of a reference to rr=%p (%p), ts=%p and tab=%p\n", - sr->rr, de->rr, de->ts, de->tab); + srp = sr; } - else if (de->rr == NULL) + if (NULL == de->rr) { + /* Stand-alone download with no 'row'/search result affiliated + with the download so far; create a fresh entry for this + download in the URI tab */ de->tab = GNUNET_GTK_add_to_uri_tab (&iter, &srp, meta, uri); de->ts = de->tab->ts; path = gtk_tree_model_get_path (GTK_TREE_MODEL (de->ts), &iter); de->rr = gtk_tree_row_reference_new (GTK_TREE_MODEL (de->ts), path); gtk_tree_path_free (path); srp->download = de; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "It's a standalone download, added it to uri tab=%p, ts=%p and rr=%p\n", - de->tab, de->ts, de->rr); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "It's a child download, leaving its rr, ts and tab unset\n"); } path = gtk_tree_row_reference_get_path (de->rr); - if (TRUE != gtk_tree_model_get_iter (GTK_TREE_MODEL (de->ts), &iter, path)) + if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->ts), &iter, path)) { GNUNET_break (0); gtk_tree_path_free (path); @@ -2116,25 +2115,18 @@ setup_download (struct DownloadEntry *de, struct DownloadEntry *pde, size) : 100) /* progress */ , 6, filename /* filename/description */ , 8, "blue" /* status colour: pending */ , + 9, srp, 14, completed, -1); - if (NULL != srp) - gtk_tree_store_set (de->ts, &iter, - 9, srp, - -1); return de; } - - - /* ***************** Publish event handling ****************** */ - /** * Change the (background) color of the given publish entry. * @@ -2160,7 +2152,6 @@ change_publish_color (struct PublishEntry *pe, } gtk_tree_path_free (path); gtk_tree_store_set (pe->tab->ts, &iter, 2, color, -1); - return; } @@ -2518,9 +2509,10 @@ GNUNET_GTK_fs_event_handler (void *cls, info->value.download.specifics.error.message); return info->value.download.cctx; case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: - return mark_download_completed (info->value.download.cctx, - info->value.download.size, - info->value.download.filename); + mark_download_completed (info->value.download.cctx, + info->value.download.size, + info->value.download.filename); + return info->value.download.cctx; case GNUNET_FS_STATUS_DOWNLOAD_STOPPED: stop_download (info->value.download.cctx); return NULL; @@ -2531,10 +2523,8 @@ GNUNET_GTK_fs_event_handler (void *cls, change_download_color (info->value.download.cctx, "blue"); return info->value.download.cctx; case GNUNET_FS_STATUS_DOWNLOAD_LOST_PARENT: - return download_lost_parent (info->value.download.cctx, - info->value.download.size, - info->value.download.completed, - info->value.download.is_active); + download_lost_parent (info->value.download.cctx); + return info->value.download.cctx; case GNUNET_FS_STATUS_SEARCH_START: if (info->value.search.pctx != NULL) return setup_inner_search (info->value.search.sc, -- cgit v1.2.3