aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-fs-gtk-event_handler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-fs-gtk-event_handler.c')
-rw-r--r--src/fs/gnunet-fs-gtk-event_handler.c233
1 files changed, 176 insertions, 57 deletions
diff --git a/src/fs/gnunet-fs-gtk-event_handler.c b/src/fs/gnunet-fs-gtk-event_handler.c
index f5eef201..c0c9fbbc 100644
--- a/src/fs/gnunet-fs-gtk-event_handler.c
+++ b/src/fs/gnunet-fs-gtk-event_handler.c
@@ -105,9 +105,35 @@ struct SearchResult
105}; 105};
106 106
107 107
108struct StartDownloadContext
109{
110 struct SearchTab *tab;
111 gboolean recursive;
112};
108 113
109static struct PublishTab *publish_tab; 114static struct PublishTab *publish_tab;
110 115
116struct UpdateSearchItem
117{
118 struct UpdateSearchItem *prev;
119 struct UpdateSearchItem *next;
120 struct DownloadEntry *de;
121 uint64_t size;
122 uint64_t completed;
123 void *block_data;
124 uint64_t offset;
125 uint64_t block_size;
126 unsigned int depth;
127};
128
129GNUNET_SCHEDULER_TaskIdentifier update_progress_task = GNUNET_SCHEDULER_NO_TASK;
130
131
132static void
133closure_notify_free (gpointer data, GClosure *closure)
134{
135 GNUNET_free (data);
136}
111 137
112static struct DownloadEntry * 138static struct DownloadEntry *
113change_download_colour (struct DownloadEntry *de, const char *colour) 139change_download_colour (struct DownloadEntry *de, const char *colour)
@@ -167,23 +193,26 @@ stop_download (struct DownloadEntry *de, int is_suspend)
167 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping download DE=%p, %s\n", de, is_suspend ? "temporarily" : "permanently"); 193 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping download DE=%p, %s\n", de, is_suspend ? "temporarily" : "permanently");
168 path = gtk_tree_row_reference_get_path (de->rr); 194 path = gtk_tree_row_reference_get_path (de->rr);
169 tm = gtk_tree_row_reference_get_model (de->rr); 195 tm = gtk_tree_row_reference_get_model (de->rr);
170 if (TRUE != gtk_tree_model_get_iter (tm, &iter, path)) 196 if (path != NULL)
171 GNUNET_break (0);
172 else
173 { 197 {
174 gtk_tree_model_get (tm, &iter, 9, &search_result, -1); 198 if (TRUE != gtk_tree_model_get_iter (tm, &iter, path))
175 /*Always fails on downloads started by Download URI */ 199 GNUNET_break (0);
176 /*GNUNET_assert (search_result->download == de); */ 200 else
177 search_result->download = NULL;
178 if (NULL == search_result->result)
179 { 201 {
180 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing it from the tree\n"); 202 gtk_tree_model_get (tm, &iter, 9, &search_result, -1);
181 (void) gtk_tree_store_remove (GTK_TREE_STORE (tm), &iter); 203 /*Always fails on downloads started by Download URI */
204 /*GNUNET_assert (search_result->download == de); */
205 search_result->download = NULL;
206 if (NULL == search_result->result)
207 {
208 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing it from the tree\n");
209 (void) gtk_tree_store_remove (GTK_TREE_STORE (tm), &iter);
210 }
211 else
212 change_download_colour (de, "white");
182 } 213 }
183 else 214 gtk_tree_path_free (path);
184 change_download_colour (de, "white");
185 } 215 }
186 gtk_tree_path_free (path);
187 gtk_tree_row_reference_free (de->rr); 216 gtk_tree_row_reference_free (de->rr);
188 GNUNET_FS_uri_destroy (de->uri); 217 GNUNET_FS_uri_destroy (de->uri);
189 GNUNET_CONTAINER_meta_data_destroy (de->meta); 218 GNUNET_CONTAINER_meta_data_destroy (de->meta);
@@ -282,48 +311,120 @@ add_directory_entry (void *cls, const char *filename,
282} 311}
283 312
284 313
314static void
315mark_download_progress_delayed (struct DownloadEntry *de, uint64_t size,
316 uint64_t completed, const void *block_data,
317 uint64_t offset, uint64_t block_size, unsigned int depth)
318{
319 GtkTreeIter iter;
320 GtkTreePath *path;
321
322 do
323 {
324 path = gtk_tree_row_reference_get_path (de->rr);
325 if (TRUE != gtk_tree_model_get_iter (GTK_TREE_MODEL (de->ts), &iter, path))
326 {
327 GNUNET_break (0);
328 gtk_tree_path_free (path);
329 break;
330 }
331 gtk_tree_path_free (path);
332 gtk_tree_store_set (de->ts, &iter, 4,
333 (guint) ((size >
334 0) ? (100 * completed /
335 size) : 100) /* progress */ ,
336 14, completed, -1);
337 if ((depth == 0) && (block_size > 0) &&
338 (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (de->meta)))
339 {
340 struct AddDirectoryEntryContext ade;
341 ade.de = de;
342 ade.prr = de->rr;
343 ade.check_duplicates = GNUNET_NO;
344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "It is a directory, list its contents\n");
345 if (GNUNET_SYSERR ==
346 GNUNET_FS_directory_list_contents ((size_t) block_size, block_data,
347 offset, &add_directory_entry, &ade))
348 {
349 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
350 _
351 ("Metadata wrongly claims that this is a GNUnet directory!\n"));
352 }
353 }
354 } while (0);
355}
356
357
358void
359GNUNET_FS_GTK_update_download_progress (void *cls,
360 const struct GNUNET_SCHEDULER_TaskContext *tc)
361{
362 struct SearchTab *st;
363 GtkTreeStore *ts;
364 struct UpdateSearchItem *usi_head;
365 struct UpdateSearchItem *usi_tail;
366 struct UpdateSearchItem *usi;
367 struct UpdateSearchItem *next;
368
369 update_progress_task = GNUNET_SCHEDULER_NO_TASK;
370 for (st = search_tab_head; st; st = st->next)
371 {
372 ts = st->ts;
373 usi_head = g_object_get_data (G_OBJECT (ts), "usi_head");
374 usi_tail = g_object_get_data (G_OBJECT (ts), "usi_tail");
375 for (usi = usi_head; NULL != usi; usi = next)
376 {
377 next = usi->next;
378 mark_download_progress_delayed (usi->de, usi->size,
379 usi->completed, usi->block_data, usi->offset, usi->block_size,
380 usi->depth);
381 GNUNET_CONTAINER_DLL_remove (usi_head, usi_tail, usi);
382 GNUNET_free_non_null (usi->block_data);
383 GNUNET_free (usi);
384 }
385 g_object_set_data (G_OBJECT (ts), "usi_head", usi_head);
386 g_object_set_data (G_OBJECT (ts), "usi_tail", usi_tail);
387 }
388 if (!(tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
389 update_progress_task = GNUNET_SCHEDULER_add_delayed (
390 GNUNET_TIME_UNIT_SECONDS,
391 GNUNET_FS_GTK_update_download_progress, NULL);
392}
393
394
285static struct DownloadEntry * 395static struct DownloadEntry *
286mark_download_progress (struct DownloadEntry *de, uint64_t size, 396mark_download_progress (struct DownloadEntry *de, uint64_t size,
287 uint64_t completed, const void *block_data, 397 uint64_t completed, const void *block_data,
288 uint64_t offset, uint64_t block_size, 398 uint64_t offset, uint64_t block_size,
289 unsigned int depth) 399 unsigned int depth)
290{ 400{
291 struct AddDirectoryEntryContext ade; 401 struct UpdateSearchItem *usi_head;
292 GtkTreeIter iter; 402 struct UpdateSearchItem *usi_tail;
293 GtkTreePath *path; 403 struct UpdateSearchItem *usi_new;
294 404
295 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 405 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
296 "Marking download progress for DE=%p, %llu/%llu, %llu@%llu depth=%u\n", 406 "Marking download progress for DE=%p, %llu/%llu, %llu@%llu depth=%u\n",
297 de, completed, size, block_size, offset, depth); 407 de, completed, size, block_size, offset, depth);
298 path = gtk_tree_row_reference_get_path (de->rr); 408
299 if (TRUE != gtk_tree_model_get_iter (GTK_TREE_MODEL (de->ts), &iter, path)) 409 usi_head = g_object_get_data (G_OBJECT (de->ts), "usi_head");
300 { 410 usi_tail = g_object_get_data (G_OBJECT (de->ts), "usi_tail");
301 GNUNET_break (0); 411 usi_new = GNUNET_malloc (sizeof (struct UpdateSearchItem));
302 gtk_tree_path_free (path); 412 usi_new->de = de;
303 return de; 413 usi_new->size = size;
304 } 414 usi_new->completed = completed;
305 gtk_tree_path_free (path); 415 usi_new->block_data = GNUNET_malloc (block_size);
306 gtk_tree_store_set (de->ts, &iter, 4, 416 memcpy (usi_new->block_data, block_data, block_size);
307 (guint) ((size > 417 usi_new->offset = offset;
308 0) ? (100 * completed / 418 usi_new->block_size = block_size;
309 size) : 100) /* progress */ , 419 usi_new->depth = depth;
310 -1); 420 GNUNET_CONTAINER_DLL_insert_tail (usi_head, usi_tail, usi_new);
311 if ((depth == 0) && (block_size > 0) && 421 g_object_set_data (G_OBJECT (de->ts), "usi_head", usi_head);
312 (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (de->meta))) 422 g_object_set_data (G_OBJECT (de->ts), "usi_tail", usi_tail);
313 { 423
314 ade.de = de; 424 if (update_progress_task == GNUNET_SCHEDULER_NO_TASK)
315 ade.prr = de->rr; 425 update_progress_task = GNUNET_SCHEDULER_add_delayed (
316 ade.check_duplicates = GNUNET_NO; 426 GNUNET_TIME_UNIT_SECONDS,
317 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "It is a directory, list its contents\n"); 427 GNUNET_FS_GTK_update_download_progress, NULL);
318 if (GNUNET_SYSERR ==
319 GNUNET_FS_directory_list_contents ((size_t) block_size, block_data,
320 offset, &add_directory_entry, &ade))
321 {
322 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
323 _
324 ("Metadata wrongly claims that this is a GNUnet directory!\n"));
325 }
326 }
327 return de; 428 return de;
328} 429}
329 430
@@ -425,7 +526,7 @@ move_children (GtkTreeModel * src_model, GtkTreeIter * src_iter,
425 GtkTreePath *path; 526 GtkTreePath *path;
426 struct GNUNET_CONTAINER_MetaData *meta; 527 struct GNUNET_CONTAINER_MetaData *meta;
427 struct GNUNET_FS_Uri *uri; 528 struct GNUNET_FS_Uri *uri;
428 guint64 filesize; 529 guint64 filesize, completed;
429 GdkPixbuf *preview; 530 GdkPixbuf *preview;
430 guint percent_progress; 531 guint percent_progress;
431 guint percent_availability; 532 guint percent_availability;
@@ -447,7 +548,8 @@ move_children (GtkTreeModel * src_model, GtkTreeIter * src_iter,
447 &percent_availability, 6, &filename, 7, 548 &percent_availability, 6, &filename, 7,
448 &uri_as_string, 8, &status_colour, 9, &search_result, 549 &uri_as_string, 8, &status_colour, 9, &search_result,
449 10, &mimetype, 11, &applicability_rank, 12, 550 10, &mimetype, 11, &applicability_rank, 12,
450 &availability_certainty, 13, &availability_rank, -1); 551 &availability_certainty, 13, &availability_rank, 14,
552 &completed, -1);
451 gtk_tree_store_insert_with_values (GTK_TREE_STORE (dst_model), &dst_child, 553 gtk_tree_store_insert_with_values (GTK_TREE_STORE (dst_model), &dst_child,
452 dst_iter, G_MAXINT, 0, meta, 1, uri, 2, 554 dst_iter, G_MAXINT, 0, meta, 1, uri, 2,
453 filesize, 3, preview, 4, 555 filesize, 3, preview, 4,
@@ -457,7 +559,7 @@ move_children (GtkTreeModel * src_model, GtkTreeIter * src_iter,
457 search_result, 10, mimetype, 11, 559 search_result, 10, mimetype, 11,
458 applicability_rank, 12, 560 applicability_rank, 12,
459 availability_certainty, 13, 561 availability_certainty, 13,
460 availability_rank, -1); 562 availability_rank, 14, completed, -1);
461 g_free (filename); 563 g_free (filename);
462 g_free (uri_as_string); 564 g_free (uri_as_string);
463 g_free (status_colour); 565 g_free (status_colour);
@@ -644,6 +746,7 @@ setup_download (struct DownloadEntry *de, struct DownloadEntry *pde,
644 6, filename /* filename/description */ , 746 6, filename /* filename/description */ ,
645 8, "blue" /* status colour: pending */ , 747 8, "blue" /* status colour: pending */ ,
646 -1); 748 -1);
749 gtk_tree_store_set (de->ts, &iter, 14, completed, -1);
647 return de; 750 return de;
648} 751}
649 752
@@ -654,9 +757,10 @@ setup_download (struct DownloadEntry *de, struct DownloadEntry *pde,
654 */ 757 */
655static void 758static void
656start_download (GtkTreeView * tree_view, GtkTreePath * path, 759start_download (GtkTreeView * tree_view, GtkTreePath * path,
657 GtkTreeViewColumn * column, gboolean recursive, gpointer user_data) 760 GtkTreeViewColumn * column, gpointer user_data)
658{ 761{
659 struct SearchTab *tab = user_data; 762 struct StartDownloadContext *sdc = user_data;
763 struct SearchTab *tab = sdc->tab;
660 GtkTreeModel *tm; 764 GtkTreeModel *tm;
661 GtkTreeIter iter; 765 GtkTreeIter iter;
662 struct GNUNET_FS_Uri *uri; 766 struct GNUNET_FS_Uri *uri;
@@ -671,13 +775,14 @@ start_download (GtkTreeView * tree_view, GtkTreePath * path,
671 char *filename; 775 char *filename;
672 776
673 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 777 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
674 "Starting a %sdownload\n", recursive ? "recursive " : ""); 778 "Starting a %sdownload\n", sdc->recursive ? "recursive " : "");
675 779
676 GNUNET_assert (tab != NULL); 780 GNUNET_assert (tab != NULL);
677 tm = gtk_tree_view_get_model (tree_view); 781 tm = gtk_tree_view_get_model (tree_view);
678 if (TRUE != gtk_tree_model_get_iter (tm, &iter, path)) 782 if (TRUE != gtk_tree_model_get_iter (tm, &iter, path))
679 { 783 {
680 GNUNET_break (0); 784 GNUNET_break (0);
785 GNUNET_free (sdc);
681 return; 786 return;
682 } 787 }
683 gtk_tree_model_get (tm, &iter, 0, &meta, 1, &uri, 9, &sr, 10, &mime, -1); 788 gtk_tree_model_get (tm, &iter, 0, &meta, 1, &uri, 9, &sr, 10, &mime, -1);
@@ -685,6 +790,7 @@ start_download (GtkTreeView * tree_view, GtkTreePath * path,
685 { 790 {
686 /* can only download chk/loc URIs, ignore */ 791 /* can only download chk/loc URIs, ignore */
687 g_free (mime); 792 g_free (mime);
793 GNUNET_free (sdc);
688 return; 794 return;
689 } 795 }
690 796
@@ -737,7 +843,8 @@ start_download (GtkTreeView * tree_view, GtkTreePath * path,
737 dlc->rr = gtk_tree_row_reference_new (tm, path); 843 dlc->rr = gtk_tree_row_reference_new (tm, path);
738 dlc->sr = sr->result; 844 dlc->sr = sr->result;
739 dlc->anonymity = -1; 845 dlc->anonymity = -1;
740 dlc->is_recursive = recursive; 846 dlc->is_recursive = sdc->recursive;
847 dlc->tab = tab;
741 GNUNET_FS_GTK_open_download_as_dialog (dlc); 848 GNUNET_FS_GTK_open_download_as_dialog (dlc);
742 g_free (mime); 849 g_free (mime);
743} 850}
@@ -762,6 +869,7 @@ start_download_ctx_menu (GtkMenuItem *item, gpointer user_data)
762{ 869{
763 GtkTreePath *path; 870 GtkTreePath *path;
764 GtkTreeView *tv; 871 GtkTreeView *tv;
872 struct StartDownloadContext sdc;
765 873
766 if (current_context_row_reference == NULL) 874 if (current_context_row_reference == NULL)
767 { 875 {
@@ -774,7 +882,9 @@ start_download_ctx_menu (GtkMenuItem *item, gpointer user_data)
774 tv = GTK_TREE_VIEW (gtk_builder_get_object 882 tv = GTK_TREE_VIEW (gtk_builder_get_object
775 (current_context_search_tab->builder, 883 (current_context_search_tab->builder,
776 "_search_result_frame")); 884 "_search_result_frame"));
777 start_download (tv, path, NULL, FALSE, current_context_search_tab); 885 sdc.tab = current_context_search_tab;
886 sdc.recursive = FALSE;
887 start_download (tv, path, NULL, &sdc);
778 gtk_tree_path_free (path); 888 gtk_tree_path_free (path);
779 current_context_search_tab = NULL; 889 current_context_search_tab = NULL;
780} 890}
@@ -787,6 +897,7 @@ start_download_recursively_ctx_menu (GtkMenuItem *item, gpointer user_data)
787{ 897{
788 GtkTreePath *path; 898 GtkTreePath *path;
789 GtkTreeView *tv; 899 GtkTreeView *tv;
900 struct StartDownloadContext sdc;
790 901
791 if (current_context_row_reference == NULL) 902 if (current_context_row_reference == NULL)
792 { 903 {
@@ -799,7 +910,9 @@ start_download_recursively_ctx_menu (GtkMenuItem *item, gpointer user_data)
799 tv = GTK_TREE_VIEW (gtk_builder_get_object 910 tv = GTK_TREE_VIEW (gtk_builder_get_object
800 (current_context_search_tab->builder, 911 (current_context_search_tab->builder,
801 "_search_result_frame")); 912 "_search_result_frame"));
802 start_download (tv, path, NULL, TRUE, current_context_search_tab); 913 sdc.tab = current_context_search_tab;
914 sdc.recursive = TRUE;
915 start_download (tv, path, NULL, &sdc);
803 gtk_tree_path_free (path); 916 gtk_tree_path_free (path);
804 current_context_search_tab = NULL; 917 current_context_search_tab = NULL;
805} 918}
@@ -1240,6 +1353,7 @@ setup_search (struct GNUNET_FS_SearchContext *sc,
1240 GtkNotebook *notebook; 1353 GtkNotebook *notebook;
1241 GtkWindow *sf; 1354 GtkWindow *sf;
1242 gint pages; 1355 gint pages;
1356 struct StartDownloadContext *sdc;
1243 1357
1244 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1245 "Setting up a search for %p\n", sc); 1359 "Setting up a search for %p\n", sc);
@@ -1314,8 +1428,12 @@ setup_search (struct GNUNET_FS_SearchContext *sc,
1314 /* add signal handlers */ 1428 /* add signal handlers */
1315 tv = GTK_TREE_VIEW (gtk_builder_get_object 1429 tv = GTK_TREE_VIEW (gtk_builder_get_object
1316 (tab->builder, "_search_result_frame")); 1430 (tab->builder, "_search_result_frame"));
1317 g_signal_connect (G_OBJECT (tv), "row-activated", G_CALLBACK (start_download), 1431 sdc = GNUNET_malloc (sizeof (struct StartDownloadContext));
1318 tab); 1432 sdc->tab = tab;
1433 sdc->recursive = FALSE;
1434 g_signal_connect_data (G_OBJECT (tv), "row-activated",
1435 G_CALLBACK (start_download), sdc,
1436 &closure_notify_free, 0);
1319 g_signal_connect (G_OBJECT (tv), "cursor-changed", 1437 g_signal_connect (G_OBJECT (tv), "cursor-changed",
1320 G_CALLBACK (update_meta_data_views), tab); 1438 G_CALLBACK (update_meta_data_views), tab);
1321 g_signal_connect (G_OBJECT (tv), "button_press_event", 1439 g_signal_connect (G_OBJECT (tv), "button_press_event",
@@ -1499,7 +1617,8 @@ GNUNET_GTK_add_search_result (struct SearchTab *tab, GtkTreeIter * iter,
1499 7, uris, 8, status_colour, 9, sr, 10, mime, 1617 7, uris, 8, status_colour, 9, sr, 10, mime,
1500 11, applicability_rank, 12, 1618 11, applicability_rank, 12,
1501 0 /* avail-cert */ , 1619 0 /* avail-cert */ ,
1502 13, 0 /* avail-rank */ , 1620 13, 0, /* avail-rank */
1621 14, (guint64) 0, /* completed */
1503 -1); 1622 -1);
1504 if (tab != NULL) 1623 if (tab != NULL)
1505 { 1624 {