aboutsummaryrefslogtreecommitdiff
path: root/src/fs
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-02-03 21:07:23 +0000
committerChristian Grothoff <christian@grothoff.org>2014-02-03 21:07:23 +0000
commitea0fc197ef33dba100cdc427f7f8da63567635e0 (patch)
treee3e49b9f2923f911cb1a71eb147a85f81eb37692 /src/fs
parentd70a8769386c0876cddada550c309bb02ceb7c9d (diff)
downloadgnunet-gtk-ea0fc197ef33dba100cdc427f7f8da63567635e0.tar.gz
gnunet-gtk-ea0fc197ef33dba100cdc427f7f8da63567635e0.zip
implementing #2522
Diffstat (limited to 'src/fs')
-rw-r--r--src/fs/gnunet-fs-gtk.c7
-rw-r--r--src/fs/gnunet-fs-gtk_download-save-as.c16
-rw-r--r--src/fs/gnunet-fs-gtk_event-handler.c628
-rw-r--r--src/fs/gnunet-fs-gtk_event-handler.h12
4 files changed, 350 insertions, 313 deletions
diff --git a/src/fs/gnunet-fs-gtk.c b/src/fs/gnunet-fs-gtk.c
index d5974479..ec397b7c 100644
--- a/src/fs/gnunet-fs-gtk.c
+++ b/src/fs/gnunet-fs-gtk.c
@@ -47,6 +47,12 @@
47#define SERVICE_LIST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) 47#define SERVICE_LIST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
48 48
49/** 49/**
50 * The GNUNET_GTK_file_sharing_downloads_tree_store with the
51 * information about active (or completed) downloads.
52 */
53GtkTreeStore *downloads_treestore;
54
55/**
50 * Should gnunet-fs-gtk start in tray mode? 56 * Should gnunet-fs-gtk start in tray mode?
51 */ 57 */
52static int tray_only; 58static int tray_only;
@@ -700,6 +706,7 @@ run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
700 706
701 main_context.search_entry = GTK_ENTRY (GNUNET_FS_GTK_get_main_window_object ("main_window_search_entry")); 707 main_context.search_entry = GTK_ENTRY (GNUNET_FS_GTK_get_main_window_object ("main_window_search_entry"));
702 708
709 downloads_treestore = GTK_TREE_STORE (GNUNET_FS_GTK_get_main_window_object ("GNUNET_GTK_file_sharing_downloads_tree_store"));
703 main_context.anonymity_combo = GTK_COMBO_BOX (GNUNET_FS_GTK_get_main_window_object ("main_window_search_anonymity_combobox")); 710 main_context.anonymity_combo = GTK_COMBO_BOX (GNUNET_FS_GTK_get_main_window_object ("main_window_search_anonymity_combobox"));
704 main_context.anonymity_level_liststore = GTK_LIST_STORE (GNUNET_FS_GTK_get_main_window_object ("anonymity_level_liststore")); 711 main_context.anonymity_level_liststore = GTK_LIST_STORE (GNUNET_FS_GTK_get_main_window_object ("anonymity_level_liststore"));
705 712
diff --git a/src/fs/gnunet-fs-gtk_download-save-as.c b/src/fs/gnunet-fs-gtk_download-save-as.c
index aa0d3604..aeb932a5 100644
--- a/src/fs/gnunet-fs-gtk_download-save-as.c
+++ b/src/fs/gnunet-fs-gtk_download-save-as.c
@@ -94,6 +94,9 @@ clean_up_download_as_context (struct DownloadAsDialogContext *dlc)
94void 94void
95GNUNET_FS_GTK_free_download_entry (struct DownloadEntry *de) 95GNUNET_FS_GTK_free_download_entry (struct DownloadEntry *de)
96{ 96{
97 GtkTreePath *path;
98 GtkTreeIter iter;
99
97 GNUNET_assert (NULL == de->dc); 100 GNUNET_assert (NULL == de->dc);
98 if (NULL != de->sr) 101 if (NULL != de->sr)
99 { 102 {
@@ -103,6 +106,17 @@ GNUNET_FS_GTK_free_download_entry (struct DownloadEntry *de)
103 } 106 }
104 GNUNET_free_non_null (de->filename); 107 GNUNET_free_non_null (de->filename);
105 GNUNET_FS_uri_destroy (de->uri); 108 GNUNET_FS_uri_destroy (de->uri);
109 if (NULL != de->rr)
110 {
111 path = gtk_tree_row_reference_get_path (de->rr);
112 GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (downloads_treestore),
113 &iter, path));
114 gtk_tree_path_free (path);
115 gtk_tree_row_reference_free (de->rr);
116 de->rr = NULL;
117 gtk_tree_store_remove (downloads_treestore,
118 &iter);
119 }
106 GNUNET_free (de); 120 GNUNET_free (de);
107} 121}
108 122
@@ -253,7 +267,7 @@ open_saveas_dialog (struct DownloadEntry *de, int download_directly)
253 } 267 }
254 else 268 else
255 { 269 {
256 dlc->dirname = dirname; 270 dlc->dirname = dirname;
257 } 271 }
258 } 272 }
259 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dlc->dialog), dirname); 273 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dlc->dialog), dirname);
diff --git a/src/fs/gnunet-fs-gtk_event-handler.c b/src/fs/gnunet-fs-gtk_event-handler.c
index ec1f60ad..50694879 100644
--- a/src/fs/gnunet-fs-gtk_event-handler.c
+++ b/src/fs/gnunet-fs-gtk_event-handler.c
@@ -266,8 +266,8 @@ static struct SearchTab *search_tab_head;
266static struct SearchTab *search_tab_tail; 266static struct SearchTab *search_tab_tail;
267 267
268/** 268/**
269 * Special tab we use to for downloads-by-URIs and downloads 269 * Special tab we use to for downloads-by-URIs and
270 * where the search tab has been closed ("parent lost"). 270 * opened directory files.
271 */ 271 */
272static struct SearchTab *uri_tab; 272static struct SearchTab *uri_tab;
273 273
@@ -284,7 +284,7 @@ static struct SearchTab *current_search_tab = NULL;
284/** 284/**
285 * Currently selected row in a search tab. 285 * Currently selected row in a search tab.
286 */ 286 */
287static GtkTreePath *current_selected_search_result = NULL; 287static GtkTreePath *current_selected_search_result;
288 288
289/** 289/**
290 * Animation to display while publishing. 290 * Animation to display while publishing.
@@ -655,7 +655,8 @@ get_suggested_filename_anonymity2 (GtkTreeModel *tm,
655struct SearchListPopupContext 655struct SearchListPopupContext
656{ 656{
657 /** 657 /**
658 * Tab where the search list popup was created. 658 * Tab where the search list popup was created, NULL for
659 * the downloads list.
659 */ 660 */
660 struct SearchTab *tab; 661 struct SearchTab *tab;
661 662
@@ -703,6 +704,74 @@ GNUNET_FS_GTK_search_treeview_cursor_changed (GtkTreeView *tv,
703 704
704 705
705/** 706/**
707 * Setup an entry for the download in the download list.
708 * Initializes the 'rr' field of @a de.
709 *
710 * @param de the download entry to initialize
711 * @param pde download entry of the parent, or NULL for top-level
712 * @param sr associated search result to add to the model
713 */
714static void
715setup_download_list_entry (struct DownloadEntry *de,
716 struct DownloadEntry *pde,
717 struct SearchResult *sr)
718{
719 GtkTreeIter download_iter;
720 GtkTreeIter download_piter;
721 GtkTreePath *path;
722
723 /* created row in download list */
724 if (NULL == pde)
725 {
726 /* top level */
727 gtk_tree_store_insert (downloads_treestore,
728 &download_iter,
729 NULL,
730 G_MAXINT);
731 }
732 else
733 {
734 /* below parent */
735 path = gtk_tree_row_reference_get_path (pde->rr);
736 GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (downloads_treestore),
737 &download_piter, path));
738 gtk_tree_path_free (path);
739 gtk_tree_store_insert (downloads_treestore,
740 &download_iter,
741 &download_piter,
742 G_MAXINT);
743 }
744 gtk_tree_store_set (downloads_treestore, &download_iter,
745 SEARCH_TAB_MC_SEARCH_RESULT, sr,
746 -1);
747 path = gtk_tree_model_get_path (GTK_TREE_MODEL (downloads_treestore),
748 &download_iter);
749 de->rr = gtk_tree_row_reference_new (GTK_TREE_MODEL (downloads_treestore),
750 path);
751 gtk_tree_path_free (path);
752}
753
754
755/**
756 * Obtain the iterator for the respective download entry.
757 *
758 * @param de the download entry
759 * @param[OUT] iter set to the respective position in the #downloads_treestore
760 */
761static void
762get_download_list_entry (struct DownloadEntry *de,
763 GtkTreeIter *iter)
764{
765 GtkTreePath *path;
766
767 path = gtk_tree_row_reference_get_path (de->rr);
768 GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (downloads_treestore),
769 iter, path));
770 gtk_tree_path_free (path);
771}
772
773
774/**
706 * 775 *
707 * @param save_as #GNUNET_YES to open SaveAs dialog, #GNUNET_NO to start downloading. 776 * @param save_as #GNUNET_YES to open SaveAs dialog, #GNUNET_NO to start downloading.
708 * @param download_directly #GNUNET_YES to make SaveAs dialog initiate the download, 777 * @param download_directly #GNUNET_YES to make SaveAs dialog initiate the download,
@@ -774,9 +843,14 @@ start_download2 (int save_as, int download_directly)
774 de->pde = psr->download; 843 de->pde = psr->download;
775 } 844 }
776 /* else pde remains zero */ 845 /* else pde remains zero */
846 setup_download_list_entry (de, de->pde, sr);
777 847
778 de->uri = GNUNET_FS_uri_dup (uri); 848 de->uri = GNUNET_FS_uri_dup (uri);
779 GNUNET_asprintf (&de->filename, "%s%s%s", downloaddir, DIR_SEPARATOR_STR, filename); 849 GNUNET_asprintf (&de->filename,
850 "%s%s%s",
851 downloaddir,
852 DIR_SEPARATOR_STR,
853 filename);
780 de->sr = sr; 854 de->sr = sr;
781 sr->download = de; 855 sr->download = de;
782 if (GNUNET_GTK_get_selected_anonymity_combo_level (mctx->download_anonymity_combo, &anonymity)) 856 if (GNUNET_GTK_get_selected_anonymity_combo_level (mctx->download_anonymity_combo, &anonymity))
@@ -798,7 +872,9 @@ start_download2 (int save_as, int download_directly)
798 872
799 if (!save_as) 873 if (!save_as)
800 { 874 {
801 if (GNUNET_GTK_tree_model_get_next_flat_iter (model, &iter, !recursive, &next_item)) 875 if (GNUNET_GTK_tree_model_get_next_flat_iter (model, &iter,
876 ! recursive,
877 &next_item))
802 gtk_tree_selection_select_iter (sel, &next_item); 878 gtk_tree_selection_select_iter (sel, &next_item);
803 GNUNET_FS_GTK_search_treeview_cursor_changed (tv, st); 879 GNUNET_FS_GTK_search_treeview_cursor_changed (tv, st);
804 } 880 }
@@ -942,6 +1018,21 @@ download_as_ctx_menu (GtkMenuItem *item, gpointer user_data)
942 1018
943 1019
944/** 1020/**
1021 * Selected row has changed in downloads tree view, update preview
1022 * and metadata areas.
1023 *
1024 * @param tv the tree view in a search tab where the selection changed
1025 * @param user_data unused
1026 */
1027void
1028GNUNET_FS_GTK_download_frame_treeview_cursor_changed_cb (GtkTreeView *tv,
1029 gpointer user_data)
1030{
1031 GNUNET_FS_GTK_search_treeview_cursor_changed (tv, NULL);
1032}
1033
1034
1035/**
945 * Download "abort" was selected in the current search context menu. 1036 * Download "abort" was selected in the current search context menu.
946 * 1037 *
947 * @param item the 'abort' menu item 1038 * @param item the 'abort' menu item
@@ -954,10 +1045,18 @@ abort_download_ctx_menu (GtkMenuItem *item, gpointer user_data)
954 struct DownloadEntry *de = spc->sr->download; 1045 struct DownloadEntry *de = spc->sr->download;
955 GtkTreeView *tv; 1046 GtkTreeView *tv;
956 1047
957 GNUNET_assert (de->dc != NULL); 1048 GNUNET_assert (NULL != de->dc);
958 GNUNET_FS_download_stop (de->dc, GNUNET_YES); 1049 GNUNET_FS_download_stop (de->dc, GNUNET_YES);
959 tv = GTK_TREE_VIEW (gtk_builder_get_object (spc->tab->builder, "_search_result_frame")); 1050 if (NULL != spc->tab)
960 GNUNET_FS_GTK_search_treeview_cursor_changed (tv, spc->tab); 1051 {
1052 tv = GTK_TREE_VIEW (gtk_builder_get_object (spc->tab->builder, "_search_result_frame"));
1053 GNUNET_FS_GTK_search_treeview_cursor_changed (tv, spc->tab);
1054 }
1055 else
1056 {
1057 tv = GTK_TREE_VIEW (GNUNET_FS_GTK_get_main_window_object ("GNUNET_GTK_download_frame"));
1058 GNUNET_FS_GTK_download_frame_treeview_cursor_changed_cb (tv, NULL);
1059 }
961} 1060}
962 1061
963 1062
@@ -980,9 +1079,12 @@ copy_search_uri_to_clipboard_ctx_menu (GtkMenuItem *item, gpointer user_data)
980 GtkClipboard *cb; 1079 GtkClipboard *cb;
981 1080
982 path = gtk_tree_row_reference_get_path (spc->rr); 1081 path = gtk_tree_row_reference_get_path (spc->rr);
983 tv = GTK_TREE_VIEW (gtk_builder_get_object 1082 if (NULL != spc->tab)
984 (spc->tab->builder, 1083 tv = GTK_TREE_VIEW (gtk_builder_get_object
985 "_search_result_frame")); 1084 (spc->tab->builder,
1085 "_search_result_frame"));
1086 else
1087 tv = GTK_TREE_VIEW (GNUNET_FS_GTK_get_main_window_object ("GNUNET_GTK_download_frame"));
986 tm = gtk_tree_view_get_model (tv); 1088 tm = gtk_tree_view_get_model (tv);
987 if (! gtk_tree_model_get_iter (tm, &iter, path)) 1089 if (! gtk_tree_model_get_iter (tm, &iter, path))
988 { 1090 {
@@ -1179,7 +1281,7 @@ populate_popup_with_uri_items (void *cls,
1179 * an appropriate menu. 1281 * an appropriate menu.
1180 * 1282 *
1181 * @param tm tree model underlying the tree view where the event happened 1283 * @param tm tree model underlying the tree view where the event happened
1182 * @param tab tab where the event happened 1284 * @param tab tab where the event happened, NULL for download tab
1183 * @param init_button which button triggered the popup, or 0 for none 1285 * @param init_button which button triggered the popup, or 0 for none
1184 * @param event_time at what time was the popup triggered 1286 * @param event_time at what time was the popup triggered
1185 * @param iter location in the tree model selected at the time 1287 * @param iter location in the tree model selected at the time
@@ -1369,6 +1471,46 @@ GNUNET_FS_GTK_search_treeview_button_press_event (GtkWidget * widget,
1369 1471
1370 1472
1371/** 1473/**
1474 * We got a right-click on the downloads list. Display the context
1475 * menu.
1476 *
1477 * @param widget the GtkTreeView with the search result list
1478 * @param event the event, we only care about button events
1479 * @param user_data UNUSED
1480 * @return FALSE to propagate the event further,
1481 * TRUE to stop the propagation
1482 */
1483gboolean
1484GNUNET_GTK_download_frame_button_press_event_cb (GtkWidget * widget,
1485 GdkEvent * event,
1486 gpointer user_data)
1487{
1488 GtkTreeView *tv = GTK_TREE_VIEW (widget);
1489 GdkEventButton *event_button = (GdkEventButton *) event;
1490 GtkTreeModel *tm;
1491 GtkTreePath *path;
1492 GtkTreeIter iter;
1493
1494 if ( (GDK_BUTTON_PRESS != event->type) ||
1495 (3 != event_button->button) )
1496 return FALSE; /* not a right-click */
1497 if (! gtk_tree_view_get_path_at_pos (tv,
1498 event_button->x, event_button->y,
1499 &path, NULL, NULL, NULL))
1500 return FALSE; /* click outside of area with values, ignore */
1501 tm = gtk_tree_view_get_model (tv);
1502 if (! gtk_tree_model_get_iter (tm, &iter, path))
1503 return FALSE; /* not sure how we got a path but no iter... */
1504 gtk_tree_path_free (path);
1505 search_list_popup (tm, NULL,
1506 event_button->button,
1507 event_button->time,
1508 &iter);
1509 return FALSE;
1510}
1511
1512
1513/**
1372 * Recalculate and update the label for a search, as we have 1514 * Recalculate and update the label for a search, as we have
1373 * received additional search results. 1515 * received additional search results.
1374 * 1516 *
@@ -1464,223 +1606,21 @@ GNUNET_FS_GTK_close_uri_tab_ ()
1464 1606
1465 1607
1466/** 1608/**
1467 * Copy all of the children of @a src_iter from the @a src_model to
1468 * become children of @a dst_iter in the @a dst_model. The models are
1469 * both 'GNUNET_GTK_file_sharing_result_tree_store' models.
1470 *
1471 * Note that we also need to update the `struct SearchResult`
1472 * and (if it exists) the respective `struct DownloadEntry`
1473 * to refer to the new model.
1474 *
1475 * @param src_model source model
1476 * @param src_iter parent of the nodes to move
1477 * @param dst_tab destination tab
1478 * @param dst_iter new parent of the entries we are moving
1479 */
1480static void
1481copy_children (GtkTreeModel * src_model, GtkTreeIter * src_iter,
1482 struct SearchTab *dst_tab,
1483 GtkTreeIter * dst_iter)
1484{
1485 GtkTreeIter src_child;
1486 GtkTreeIter dst_child;
1487 GtkTreePath *path;
1488 struct GNUNET_CONTAINER_MetaData *meta;
1489 struct GNUNET_FS_Uri *uri;
1490 guint64 filesize, completed;
1491 GdkPixbuf *preview;
1492 guint percent_progress;
1493 guint percent_availability;
1494 gint unknown_availability;
1495 gchar *filename;
1496 gchar *uri_as_string;
1497 gchar *status_colour;
1498 struct SearchResult *search_result_old;
1499 struct SearchResult *search_result_new;
1500 gchar *mimetype;
1501 guint applicability_rank;
1502 guint availability_certainty;
1503 gint availability_rank;
1504 gchar *downloaded_filename;
1505 gint downloaded_anonymity;
1506 gboolean show_ns_association;
1507
1508 if (! gtk_tree_model_iter_children (src_model, &src_child, src_iter))
1509 return;
1510 do
1511 {
1512 gtk_tree_model_get (src_model, &src_child,
1513 SEARCH_TAB_MC_METADATA, &meta,
1514 SEARCH_TAB_MC_URI, &uri,
1515 SEARCH_TAB_MC_FILESIZE, &filesize,
1516 SEARCH_TAB_MC_PREVIEW, &preview,
1517 SEARCH_TAB_MC_PERCENT_PROGRESS, &percent_progress,
1518 SEARCH_TAB_MC_PERCENT_AVAILABILITY, &percent_availability,
1519 SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, &unknown_availability,
1520 SEARCH_TAB_MC_FILENAME, &filename,
1521 SEARCH_TAB_MC_URI_AS_STRING, &uri_as_string,
1522 SEARCH_TAB_MC_STATUS_COLOUR, &status_colour,
1523 SEARCH_TAB_MC_SEARCH_RESULT, &search_result_old,
1524 SEARCH_TAB_MC_MIMETYPE, &mimetype,
1525 SEARCH_TAB_MC_APPLICABILITY_RANK, &applicability_rank,
1526 SEARCH_TAB_MC_AVAILABILITY_CERTAINTY, &availability_certainty,
1527 SEARCH_TAB_MC_AVAILABILITY_RANK, &availability_rank,
1528 SEARCH_TAB_MC_COMPLETED, &completed,
1529 SEARCH_TAB_MC_DOWNLOADED_FILENAME, &downloaded_filename,
1530 SEARCH_TAB_MC_DOWNLOADED_ANONYMITY, &downloaded_anonymity,
1531 SEARCH_TAB_MC_SHOW_NS_ASSOCIATION, &show_ns_association,
1532 -1);
1533 search_result_new = GNUNET_new (struct SearchResult);
1534 search_result_new->tab = dst_tab;
1535 search_result_new->probe = search_result_old->probe;
1536 search_result_old->probe = NULL;
1537 search_result_new->download = search_result_old->download;
1538 if (NULL != search_result_old->download)
1539 {
1540 search_result_old->download = NULL;
1541 search_result_new->download->sr = search_result_new;
1542 }
1543 gtk_tree_store_insert_with_values (dst_tab->ts, &dst_child,
1544 dst_iter, G_MAXINT,
1545 SEARCH_TAB_MC_METADATA, GNUNET_CONTAINER_meta_data_duplicate (meta),
1546 SEARCH_TAB_MC_URI, GNUNET_FS_uri_dup (uri),
1547 SEARCH_TAB_MC_FILESIZE, filesize,
1548 SEARCH_TAB_MC_PREVIEW, preview,
1549 SEARCH_TAB_MC_PERCENT_PROGRESS, percent_progress,
1550 SEARCH_TAB_MC_PERCENT_AVAILABILITY, percent_availability,
1551 SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, unknown_availability,
1552 SEARCH_TAB_MC_FILENAME, filename,
1553 SEARCH_TAB_MC_URI_AS_STRING, uri_as_string,
1554 SEARCH_TAB_MC_STATUS_COLOUR, status_colour,
1555 SEARCH_TAB_MC_SEARCH_RESULT, search_result_new,
1556 SEARCH_TAB_MC_MIMETYPE, mimetype,
1557 SEARCH_TAB_MC_APPLICABILITY_RANK, applicability_rank,
1558 SEARCH_TAB_MC_AVAILABILITY_CERTAINTY, availability_certainty,
1559 SEARCH_TAB_MC_AVAILABILITY_RANK, availability_rank,
1560 SEARCH_TAB_MC_COMPLETED, completed,
1561 SEARCH_TAB_MC_DOWNLOADED_FILENAME, downloaded_filename,
1562 SEARCH_TAB_MC_DOWNLOADED_ANONYMITY, downloaded_anonymity,
1563 SEARCH_TAB_MC_SHOW_NS_ASSOCIATION, show_ns_association,
1564 -1);
1565 g_free (filename);
1566 g_free (downloaded_filename);
1567 g_free (uri_as_string);
1568 g_free (status_colour);
1569 g_free (mimetype);
1570 if (preview != NULL)
1571 g_object_unref (preview);
1572
1573 path = gtk_tree_model_get_path (GTK_TREE_MODEL (dst_tab->ts), &dst_child);
1574 search_result_new->rr = gtk_tree_row_reference_new (GTK_TREE_MODEL (dst_tab->ts), path);
1575 gtk_tree_path_free (path);
1576
1577 copy_children (src_model, &src_child, dst_tab, &dst_child);
1578 }
1579 while (gtk_tree_model_iter_next (src_model, &src_child));
1580}
1581
1582
1583/**
1584 * Handle the case where an active download lost its 1609 * Handle the case where an active download lost its
1585 * search parent by moving it to the URI tab. 1610 * search parent; need to remember that the respective
1611 * tab and row reference no longer exist.
1586 * 1612 *
1587 * @param de download where the parent (i.e. search) was lost 1613 * @param de download where the parent (i.e. search) was lost
1588 */ 1614 */
1589static void 1615static void
1590download_lost_parent (struct DownloadEntry *de) 1616download_lost_parent (struct DownloadEntry *de)
1591{ 1617{
1592 GtkTreeIter iter; 1618 de->sr->tab = NULL;
1593 GtkTreePath *path; 1619 if (NULL != de->sr->rr)
1594 GtkTreeModel *tm_old;
1595 GtkTreeIter iter_old;
1596 GtkTreeModel *model;
1597 struct GNUNET_CONTAINER_MetaData *meta;
1598 struct GNUNET_FS_Uri *uri;
1599 guint64 completed;
1600 guint percent_progress;
1601 guint percent_availability;
1602 gint unknown_availability;
1603 gchar *filename;
1604 gchar *status_colour;
1605 guint applicability_rank;
1606 guint availability_certainty;
1607 gint availability_rank;
1608 gchar *downloaded_filename;
1609 gint downloaded_anonymity;
1610 GdkPixbuf *status_animation;
1611 gboolean show_ns_association;
1612
1613 /* find the 'old' root */
1614 tm_old = GTK_TREE_MODEL (de->sr->tab->ts);
1615 path = gtk_tree_row_reference_get_path (de->sr->rr);
1616 if (! gtk_tree_model_get_iter (tm_old, &iter_old, path))
1617 { 1620 {
1618 GNUNET_break (0); 1621 gtk_tree_row_reference_free (de->sr->rr);
1619 gtk_tree_path_free (path); 1622 de->sr->rr = NULL;
1620 return;
1621 } 1623 }
1622 gtk_tree_path_free (path);
1623 gtk_tree_model_get (tm_old, &iter_old,
1624 SEARCH_TAB_MC_METADATA, &meta,
1625 SEARCH_TAB_MC_URI, &uri,
1626 SEARCH_TAB_MC_PERCENT_PROGRESS, &percent_progress,
1627 SEARCH_TAB_MC_PERCENT_AVAILABILITY, &percent_availability,
1628 SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, &unknown_availability,
1629 SEARCH_TAB_MC_FILENAME, &filename,
1630 SEARCH_TAB_MC_STATUS_COLOUR, &status_colour,
1631 SEARCH_TAB_MC_APPLICABILITY_RANK, &applicability_rank,
1632 SEARCH_TAB_MC_AVAILABILITY_CERTAINTY, &availability_certainty,
1633 SEARCH_TAB_MC_AVAILABILITY_RANK, &availability_rank,
1634 SEARCH_TAB_MC_COMPLETED, &completed,
1635 SEARCH_TAB_MC_DOWNLOADED_FILENAME, &downloaded_filename,
1636 SEARCH_TAB_MC_DOWNLOADED_ANONYMITY, &downloaded_anonymity,
1637 SEARCH_TAB_MC_STATUS_ICON, &status_animation,
1638 SEARCH_TAB_MC_SHOW_NS_ASSOCIATION, &show_ns_association,
1639 -1);
1640 GNUNET_assert (GNUNET_YES == GNUNET_FS_uri_test_equal (uri, de->uri));
1641 GNUNET_assert (de->sr->download == de);
1642 de->sr->download = NULL;
1643
1644 /* create the target root */
1645 de->sr = GNUNET_GTK_add_to_uri_tab (downloaded_anonymity,
1646 meta, uri);
1647 de->sr->download = de;
1648
1649 /* get positions of the 'new' root */
1650 model = GTK_TREE_MODEL (de->sr->tab->ts);
1651 path = gtk_tree_row_reference_get_path (de->sr->rr);
1652 if (! gtk_tree_model_get_iter (model, &iter, path))
1653 {
1654 GNUNET_break (0);
1655 gtk_tree_path_free (path);
1656 g_free (filename);
1657 g_free (downloaded_filename);
1658 g_free (status_colour);
1659 return;
1660 }
1661 gtk_tree_path_free (path);
1662
1663 gtk_tree_store_set (de->sr->tab->ts, &iter,
1664 SEARCH_TAB_MC_PERCENT_PROGRESS, percent_progress,
1665 SEARCH_TAB_MC_PERCENT_AVAILABILITY, percent_availability,
1666 SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, unknown_availability,
1667 SEARCH_TAB_MC_FILENAME, filename,
1668 SEARCH_TAB_MC_STATUS_COLOUR, status_colour,
1669 SEARCH_TAB_MC_APPLICABILITY_RANK, applicability_rank,
1670 SEARCH_TAB_MC_AVAILABILITY_CERTAINTY, availability_certainty,
1671 SEARCH_TAB_MC_AVAILABILITY_RANK, availability_rank,
1672 SEARCH_TAB_MC_COMPLETED, completed,
1673 SEARCH_TAB_MC_DOWNLOADED_FILENAME, downloaded_filename,
1674 SEARCH_TAB_MC_DOWNLOADED_ANONYMITY, downloaded_anonymity,
1675 SEARCH_TAB_MC_STATUS_ICON, status_animation,
1676 SEARCH_TAB_MC_SHOW_NS_ASSOCIATION, show_ns_association,
1677 -1);
1678 g_free (filename);
1679 g_free (downloaded_filename);
1680 g_free (status_colour);
1681
1682 /* finally, move all children over as well */
1683 copy_children (tm_old, &iter_old, de->sr->tab, &iter);
1684} 1624}
1685 1625
1686 1626
@@ -1707,25 +1647,16 @@ move_downloads_in_subtree (GtkTreeModel *tm,
1707 { 1647 {
1708 do 1648 do
1709 { 1649 {
1650 if (NULL != sr->download)
1651 {
1652 download_lost_parent (sr->download);
1653 continue;
1654 }
1710 gtk_tree_model_get (tm, &child, 1655 gtk_tree_model_get (tm, &child,
1711 SEARCH_TAB_MC_METADATA, &meta, 1656 SEARCH_TAB_MC_METADATA, &meta,
1712 SEARCH_TAB_MC_URI, &uri, 1657 SEARCH_TAB_MC_URI, &uri,
1713 SEARCH_TAB_MC_SEARCH_RESULT, &sr, 1658 SEARCH_TAB_MC_SEARCH_RESULT, &sr,
1714 -1); 1659 -1);
1715 if (NULL != sr->download)
1716 {
1717 if (sr->download->is_done == GNUNET_YES)
1718 {
1719 /* got a finished download, stop it */
1720 GNUNET_FS_download_stop (sr->download->dc, GNUNET_YES);
1721 }
1722 else
1723 {
1724 /* got an active download, move to URI tab! */
1725 download_lost_parent (sr->download);
1726 }
1727 }
1728 GNUNET_assert (NULL == sr->download);
1729 move_downloads_in_subtree (tm, &child); 1660 move_downloads_in_subtree (tm, &child);
1730 GNUNET_FS_uri_destroy (uri); 1661 GNUNET_FS_uri_destroy (uri);
1731 if (NULL != meta) 1662 if (NULL != meta)
@@ -1747,7 +1678,7 @@ move_downloads_in_subtree (GtkTreeModel *tm,
1747 SEARCH_TAB_MC_SEARCH_RESULT, NULL, 1678 SEARCH_TAB_MC_SEARCH_RESULT, NULL,
1748 -1); 1679 -1);
1749 } 1680 }
1750 while (TRUE == gtk_tree_model_iter_next (tm, &child)); 1681 while (gtk_tree_model_iter_next (tm, &child));
1751 } 1682 }
1752} 1683}
1753 1684
@@ -1791,11 +1722,15 @@ free_search_result (struct SearchResult *sr)
1791 SEARCH_TAB_MC_METADATA, &meta, 1722 SEARCH_TAB_MC_METADATA, &meta,
1792 SEARCH_TAB_MC_URI, &uri, 1723 SEARCH_TAB_MC_URI, &uri,
1793 -1); 1724 -1);
1794 if (uri != NULL) 1725 if (NULL != uri)
1795 GNUNET_FS_uri_destroy (uri); 1726 GNUNET_FS_uri_destroy (uri);
1796 if (meta != NULL) 1727 if (NULL != meta)
1797 GNUNET_CONTAINER_meta_data_destroy (meta); 1728 GNUNET_CONTAINER_meta_data_destroy (meta);
1798 gtk_tree_row_reference_free (sr->rr); 1729 if (NULL != sr->rr)
1730 {
1731 gtk_tree_row_reference_free (sr->rr);
1732 sr->rr = NULL;
1733 }
1799 if (NULL != sr->probe) 1734 if (NULL != sr->probe)
1800 { 1735 {
1801 GNUNET_FS_probe_stop (sr->probe); 1736 GNUNET_FS_probe_stop (sr->probe);
@@ -1815,13 +1750,12 @@ free_search_result (struct SearchResult *sr)
1815 * and metadata areas. 1750 * and metadata areas.
1816 * 1751 *
1817 * @param tv the tree view in a search tab where the selection changed 1752 * @param tv the tree view in a search tab where the selection changed
1818 * @param user_data the 'struct SearchTab' that contains the tree view 1753 * @param user_data unused
1819 */ 1754 */
1820void 1755void
1821GNUNET_FS_GTK_search_treeview_cursor_changed (GtkTreeView *tv, 1756GNUNET_FS_GTK_search_treeview_cursor_changed (GtkTreeView *tv,
1822 gpointer user_data) 1757 gpointer user_data)
1823{ 1758{
1824 struct SearchTab *tab = user_data;
1825 GtkTreeSelection *sel; 1759 GtkTreeSelection *sel;
1826 GtkTreeModel *model; 1760 GtkTreeModel *model;
1827 GtkTreeIter iter; 1761 GtkTreeIter iter;
@@ -1832,7 +1766,6 @@ GNUNET_FS_GTK_search_treeview_cursor_changed (GtkTreeView *tv,
1832 struct GNUNET_FS_Uri *uri; 1766 struct GNUNET_FS_Uri *uri;
1833 struct GNUNET_GTK_MainWindowContext *mctx = GNUNET_FS_GTK_get_main_context (); 1767 struct GNUNET_GTK_MainWindowContext *mctx = GNUNET_FS_GTK_get_main_context ();
1834 1768
1835 GNUNET_assert (tab->query_txt != NULL);
1836 gtk_list_store_clear (mctx->md_liststore); 1769 gtk_list_store_clear (mctx->md_liststore);
1837 sel = gtk_tree_view_get_selection (tv); 1770 sel = gtk_tree_view_get_selection (tv);
1838 if (! gtk_tree_selection_get_selected (sel, &model, &iter)) 1771 if (! gtk_tree_selection_get_selected (sel, &model, &iter))
@@ -1948,7 +1881,7 @@ GNUNET_GTK_main_window_notebook_switch_page_cb (GtkWidget * dummy,
1948 clear meta data and preview widgets */ 1881 clear meta data and preview widgets */
1949 gtk_image_clear (mctx->preview_image); 1882 gtk_image_clear (mctx->preview_image);
1950 gtk_list_store_clear (mctx->md_liststore); 1883 gtk_list_store_clear (mctx->md_liststore);
1951 if (current_selected_search_result != NULL) 1884 if (NULL != current_selected_search_result)
1952 gtk_tree_path_free (current_selected_search_result); 1885 gtk_tree_path_free (current_selected_search_result);
1953 current_selected_search_result = NULL; 1886 current_selected_search_result = NULL;
1954} 1887}
@@ -2047,7 +1980,7 @@ stop_downloads_in_subtree (GtkTreeModel *tm,
2047 SEARCH_TAB_MC_SEARCH_RESULT, &sr, 1980 SEARCH_TAB_MC_SEARCH_RESULT, &sr,
2048 -1); 1981 -1);
2049 if ( (NULL != sr->download) && 1982 if ( (NULL != sr->download) &&
2050 (sr->download->is_done == GNUNET_YES) ) 1983 (GNUNET_YES == sr->download->is_done) )
2051 { 1984 {
2052 /* got a finished download, stop it */ 1985 /* got a finished download, stop it */
2053 GNUNET_FS_download_stop (sr->download->dc, GNUNET_YES); 1986 GNUNET_FS_download_stop (sr->download->dc, GNUNET_YES);
@@ -2058,32 +1991,30 @@ stop_downloads_in_subtree (GtkTreeModel *tm,
2058 if (GNUNET_YES != stop_downloads_in_subtree (tm, &child)) 1991 if (GNUNET_YES != stop_downloads_in_subtree (tm, &child))
2059 ret = GNUNET_NO; 1992 ret = GNUNET_NO;
2060 } 1993 }
2061 while (TRUE == gtk_tree_model_iter_next (tm, &child)); 1994 while (gtk_tree_model_iter_next (tm, &child));
2062 } 1995 }
2063 return ret; 1996 return ret;
2064} 1997}
2065 1998
2066 1999
2067/** 2000/**
2068 * User clicked on the 'clean' button of a search tab. 2001 * User clicked on the 'clean' button of the downloads tab.
2069 * Stop completed downloads (or those that failed). Should 2002 * Stop completed downloads (or those that failed). Should
2070 * iterate over the underlying tree store and stop all 2003 * iterate over the underlying tree store and stop all
2071 * completed entries. Furthermore, if the resulting tree 2004 * completed entries.
2072 * store is empty and has no search associated with it,
2073 * the tab should be closed.
2074 * 2005 *
2075 * @param button the button pressed by the user 2006 * @param button the button pressed by the user
2076 * @param user_data the `struct SearchTab` of the respective tab to clean up 2007 * @param user_data
2077 */ 2008 */
2078void 2009void
2079GNUNET_FS_GTK_search_result_clear_button_clicked (GtkButton * button, gpointer user_data) 2010GNUNET_FS_GTK_downloads_clear_button_clicked (GtkButton * button,
2011 gpointer user_data)
2080{ 2012{
2081 struct SearchTab *tab = user_data;
2082 struct SearchResult *sr; 2013 struct SearchResult *sr;
2083 GtkTreeModel *tm; 2014 GtkTreeModel *tm;
2084 GtkTreeIter iter; 2015 GtkTreeIter iter;
2085 2016
2086 tm = GTK_TREE_MODEL (tab->ts); 2017 tm = GTK_TREE_MODEL (downloads_treestore);
2087 if (! gtk_tree_model_get_iter_first (tm, &iter)) 2018 if (! gtk_tree_model_get_iter_first (tm, &iter))
2088 return; 2019 return;
2089 do 2020 do
@@ -2091,11 +2022,13 @@ GNUNET_FS_GTK_search_result_clear_button_clicked (GtkButton * button, gpointer u
2091 gtk_tree_model_get (tm, &iter, 2022 gtk_tree_model_get (tm, &iter,
2092 SEARCH_TAB_MC_SEARCH_RESULT, &sr, 2023 SEARCH_TAB_MC_SEARCH_RESULT, &sr,
2093 -1); 2024 -1);
2094 if ( (sr->download != NULL) && 2025 if ( (NULL != sr->download) &&
2095 (sr->download->is_done == GNUNET_YES) ) 2026 (GNUNET_YES == sr->download->is_done) )
2096 { 2027 {
2097 /* got a finished download, stop it */ 2028 /* got a finished download, stop it */
2098 GNUNET_FS_download_stop (sr->download->dc, GNUNET_YES); 2029 GNUNET_FS_download_stop (sr->download->dc, GNUNET_YES);
2030 if (! gtk_tree_model_get_iter_first (tm, &iter))
2031 return;
2099 } 2032 }
2100 if ( (NULL == sr->download) && 2033 if ( (NULL == sr->download) &&
2101 (NULL == sr->result) && 2034 (NULL == sr->result) &&
@@ -2216,7 +2149,23 @@ update_search_result (struct SearchResult *sr,
2216 SEARCH_TAB_MC_AVAILABILITY_CERTAINTY, (guint) availability_certainty, 2149 SEARCH_TAB_MC_AVAILABILITY_CERTAINTY, (guint) availability_certainty,
2217 SEARCH_TAB_MC_AVAILABILITY_RANK, (gint) availability_rank, 2150 SEARCH_TAB_MC_AVAILABILITY_RANK, (gint) availability_rank,
2218 -1); 2151 -1);
2219 if (pixbuf != NULL) 2152 if (NULL != sr->download)
2153 {
2154 get_download_list_entry (sr->download, &iter);
2155 gtk_tree_store_set (downloads_treestore, &iter,
2156 SEARCH_TAB_MC_METADATA, GNUNET_CONTAINER_meta_data_duplicate (meta),
2157 SEARCH_TAB_MC_PREVIEW, pixbuf,
2158 SEARCH_TAB_MC_PERCENT_AVAILABILITY, (guint) percent_avail,
2159 SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, (0 == availability_certainty) ? (gint) (probe_time.rel_value_us / GNUNET_FS_PROBE_UPDATE_FREQUENCY.rel_value_us) : -1,
2160 SEARCH_TAB_MC_FILENAME, desc,
2161 SEARCH_TAB_MC_MIMETYPE, mime,
2162 SEARCH_TAB_MC_APPLICABILITY_RANK, (guint) applicability_rank,
2163 SEARCH_TAB_MC_AVAILABILITY_CERTAINTY, (guint) availability_certainty,
2164 SEARCH_TAB_MC_AVAILABILITY_RANK, (gint) availability_rank,
2165 -1);
2166 }
2167
2168 if (NULL != pixbuf)
2220 g_object_unref (pixbuf); 2169 g_object_unref (pixbuf);
2221 GNUNET_free (desc); 2170 GNUNET_free (desc);
2222 GNUNET_free_non_null (mime); 2171 GNUNET_free_non_null (mime);
@@ -2264,7 +2213,7 @@ see_if_there_are_any_uris (void *cls,
2264 * not only for 'normal' search results but also for directories that 2213 * not only for 'normal' search results but also for directories that
2265 * are being opened and if the user manually enters a URI. 2214 * are being opened and if the user manually enters a URI.
2266 * 2215 *
2267 * @param tab search tab to extend, never NULL 2216 * @param tab search tab to extend, NULL if we are only in the download tab
2268 * @param anonymity anonymity level to use for probes for this result 2217 * @param anonymity anonymity level to use for probes for this result
2269 * @param parent_rr reference to parent entry in search tab, NULL for normal 2218 * @param parent_rr reference to parent entry in search tab, NULL for normal
2270 * search results, 2219 * search results,
@@ -2375,7 +2324,10 @@ GNUNET_GTK_add_search_result (struct SearchTab *tab,
2375 { 2324 {
2376 /* top-level result */ 2325 /* top-level result */
2377 pitr = NULL; 2326 pitr = NULL;
2378 ts = tab->ts; 2327 if (NULL != tab)
2328 ts = tab->ts;
2329 else
2330 ts = downloads_treestore;
2379 } 2331 }
2380 gtk_tree_store_insert_with_values (ts, &iter, pitr, G_MAXINT, 2332 gtk_tree_store_insert_with_values (ts, &iter, pitr, G_MAXINT,
2381 SEARCH_TAB_MC_METADATA, GNUNET_CONTAINER_meta_data_duplicate (meta), 2333 SEARCH_TAB_MC_METADATA, GNUNET_CONTAINER_meta_data_duplicate (meta),
@@ -2411,10 +2363,12 @@ GNUNET_GTK_add_search_result (struct SearchTab *tab,
2411 2363
2412 /* move up to the outermost tab, in case this is an 'inner' 2364 /* move up to the outermost tab, in case this is an 'inner'
2413 search (namespace update case) */ 2365 search (namespace update case) */
2414 while (NULL != tab->parent) 2366 if (NULL != tab)
2415 tab = tab->parent->tab; 2367 {
2416 tab->num_results++; 2368 while (NULL != tab->parent)
2417 2369 tab = tab->parent->tab;
2370 tab->num_results++;
2371 }
2418 return sr; 2372 return sr;
2419} 2373}
2420 2374
@@ -2736,17 +2690,22 @@ change_download_color (struct DownloadEntry *de,
2736 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2690 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2737 "Changing download DE=%p color to %s\n", 2691 "Changing download DE=%p color to %s\n",
2738 de, color); 2692 de, color);
2739 path = gtk_tree_row_reference_get_path (de->sr->rr); 2693 if (NULL != de->sr->tab)
2740 if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, path))
2741 { 2694 {
2742 GNUNET_break (0); 2695 path = gtk_tree_row_reference_get_path (de->sr->rr);
2696 GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts),
2697 &iter, path));
2743 gtk_tree_path_free (path); 2698 gtk_tree_path_free (path);
2744 return; 2699 gtk_tree_store_set (de->sr->tab->ts, &iter,
2700 SEARCH_TAB_MC_STATUS_COLOUR, color,
2701 -1);
2745 } 2702 }
2746 gtk_tree_path_free (path); 2703 /* do the same update to the downloads tree store */
2747 gtk_tree_store_set (de->sr->tab->ts, &iter, 2704 get_download_list_entry (de, &iter);
2705 gtk_tree_store_set (downloads_treestore, &iter,
2748 SEARCH_TAB_MC_STATUS_COLOUR, color, 2706 SEARCH_TAB_MC_STATUS_COLOUR, color,
2749 -1); 2707 -1);
2708
2750} 2709}
2751 2710
2752 2711
@@ -2763,15 +2722,18 @@ change_download_status_icon (struct DownloadEntry *de,
2763 GtkTreeIter iter; 2722 GtkTreeIter iter;
2764 GtkTreePath *path; 2723 GtkTreePath *path;
2765 2724
2766 path = gtk_tree_row_reference_get_path (de->sr->rr); 2725 if (NULL != de->sr->tab)
2767 if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, path))
2768 { 2726 {
2769 GNUNET_break (0); 2727 path = gtk_tree_row_reference_get_path (de->sr->rr);
2728 GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, path));
2770 gtk_tree_path_free (path); 2729 gtk_tree_path_free (path);
2771 return; 2730 gtk_tree_store_set (de->sr->tab->ts, &iter,
2731 SEARCH_TAB_MC_STATUS_ICON, icon,
2732 -1);
2772 } 2733 }
2773 gtk_tree_path_free (path); 2734 /* do the same update to the downloads tree store */
2774 gtk_tree_store_set (de->sr->tab->ts, &iter, 2735 get_download_list_entry (de, &iter);
2736 gtk_tree_store_set (downloads_treestore, &iter,
2775 SEARCH_TAB_MC_STATUS_ICON, icon, 2737 SEARCH_TAB_MC_STATUS_ICON, icon,
2776 -1); 2738 -1);
2777} 2739}
@@ -2927,25 +2889,30 @@ mark_download_progress (struct DownloadEntry *de,
2927 unsigned int depth) 2889 unsigned int depth)
2928{ 2890{
2929 GtkTreeIter iter; 2891 GtkTreeIter iter;
2892 GtkTreeIter diter;
2930 GtkTreePath *path; 2893 GtkTreePath *path;
2931 2894
2932 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2895 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2933 "Marking download progress for DE=%p, %llu/%llu, %llu@%llu depth=%u\n", 2896 "Marking download progress for DE=%p, %llu/%llu, %llu@%llu depth=%u\n",
2934 de, completed, size, block_size, offset, depth); 2897 de, completed, size, block_size, offset, depth);
2935 2898
2936 path = gtk_tree_row_reference_get_path (de->sr->rr); 2899 if (NULL != de->sr->tab)
2937 if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, path))
2938 { 2900 {
2939 GNUNET_break (0); 2901 path = gtk_tree_row_reference_get_path (de->sr->rr);
2902 GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts),
2903 &iter, path));
2940 gtk_tree_path_free (path); 2904 gtk_tree_path_free (path);
2941 return; 2905 /* FIXME-DESIGN: should we replace the 'availability' with
2906 'progress' once the download has started and re-use the
2907 space in the display? Probably yes, at least once we have
2908 a custom CellRenderer... */
2909 gtk_tree_store_set (de->sr->tab->ts, &iter,
2910 SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) ((size > 0) ? (100 * completed / size) : 100),
2911 SEARCH_TAB_MC_COMPLETED, completed,
2912 -1);
2942 } 2913 }
2943 gtk_tree_path_free (path); 2914 get_download_list_entry (de, &diter);
2944 /* FIXME-DESIGN: should we replace the 'availability' with 2915 gtk_tree_store_set (downloads_treestore, &diter,
2945 'progress' once the download has started and re-use the
2946 space in the display? Probably yes, at least once we have
2947 a custom CellRenderer... */
2948 gtk_tree_store_set (de->sr->tab->ts, &iter,
2949 SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) ((size > 0) ? (100 * completed / size) : 100), 2916 SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) ((size > 0) ? (100 * completed / size) : 100),
2950 SEARCH_TAB_MC_COMPLETED, completed, 2917 SEARCH_TAB_MC_COMPLETED, completed,
2951 -1); 2918 -1);
@@ -2969,7 +2936,11 @@ mark_download_progress (struct DownloadEntry *de,
2969 { 2936 {
2970 /* Mime type was wrong, this is not a directory, update model! */ 2937 /* Mime type was wrong, this is not a directory, update model! */
2971 de->is_directory = GNUNET_SYSERR; 2938 de->is_directory = GNUNET_SYSERR;
2972 gtk_tree_store_set (de->sr->tab->ts, &iter, 2939 if (NULL != de->sr->tab)
2940 gtk_tree_store_set (de->sr->tab->ts, &iter,
2941 SEARCH_TAB_MC_MIMETYPE, "",
2942 -1);
2943 gtk_tree_store_set (downloads_treestore, &diter,
2973 SEARCH_TAB_MC_MIMETYPE, "", 2944 SEARCH_TAB_MC_MIMETYPE, "",
2974 -1); 2945 -1);
2975 } 2946 }
@@ -3012,20 +2983,24 @@ mark_download_error (struct DownloadEntry *de,
3012 2983
3013 change_download_color (de, "red"); 2984 change_download_color (de, "red");
3014 de->is_done = GNUNET_YES; 2985 de->is_done = GNUNET_YES;
3015 path = gtk_tree_row_reference_get_path (de->sr->rr); 2986 if (NULL == animation_error)
3016 if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, path)) 2987 animation_error = load_animation ("error");
2988 if (NULL != de->sr->tab)
3017 { 2989 {
3018 GNUNET_break (0); 2990 path = gtk_tree_row_reference_get_path (de->sr->rr);
2991 GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, path));
3019 gtk_tree_path_free (path); 2992 gtk_tree_path_free (path);
3020 return; 2993 gtk_tree_store_set (de->sr->tab->ts, &iter,
2994 SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) 0,
2995 SEARCH_TAB_MC_URI_AS_STRING, emsg,
2996 SEARCH_TAB_MC_STATUS_ICON, GNUNET_GTK_animation_context_get_pixbuf (animation_error),
2997 -1);
3021 } 2998 }
3022 gtk_tree_path_free (path); 2999 get_download_list_entry (de, &iter);
3023 if (NULL == animation_error) 3000 gtk_tree_store_set (downloads_treestore, &iter,
3024 animation_error = load_animation ("error");
3025 gtk_tree_store_set (de->sr->tab->ts, &iter,
3026 SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) 0, 3001 SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) 0,
3027 SEARCH_TAB_MC_URI_AS_STRING, emsg, 3002 SEARCH_TAB_MC_URI_AS_STRING, emsg,
3028 SEARCH_TAB_MC_STATUS_ICON, GNUNET_GTK_animation_context_get_pixbuf (animation_error), 3003 SEARCH_TAB_MC_STATUS_ICON, GNUNET_GTK_animation_context_get_pixbuf (animation_error),
3029 -1); 3004 -1);
3030} 3005}
3031 3006
@@ -3045,15 +3020,21 @@ mark_download_completed (struct DownloadEntry *de, uint64_t size)
3045 3020
3046 de->is_done = GNUNET_YES; 3021 de->is_done = GNUNET_YES;
3047 change_download_color (de, "green"); 3022 change_download_color (de, "green");
3048 path = gtk_tree_row_reference_get_path (de->sr->rr); 3023 if (NULL != de->sr->tab)
3049 if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, path))
3050 { 3024 {
3051 GNUNET_break (0); 3025 path = gtk_tree_row_reference_get_path (de->sr->rr);
3026 GNUNET_assert (gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts),
3027 &iter, path));
3052 gtk_tree_path_free (path); 3028 gtk_tree_path_free (path);
3053 return; 3029 gtk_tree_store_set (de->sr->tab->ts, &iter,
3030 SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) 100,
3031 SEARCH_TAB_MC_PERCENT_AVAILABILITY, (guint) 100,
3032 SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, -1,
3033 SEARCH_TAB_MC_STATUS_ICON, GNUNET_GTK_animation_context_get_pixbuf (animation_downloaded),
3034 -1);
3054 } 3035 }
3055 gtk_tree_path_free (path); 3036 get_download_list_entry (de, &iter);
3056 gtk_tree_store_set (de->sr->tab->ts, &iter, 3037 gtk_tree_store_set (downloads_treestore, &iter,
3057 SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) 100, 3038 SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) 100,
3058 SEARCH_TAB_MC_PERCENT_AVAILABILITY, (guint) 100, 3039 SEARCH_TAB_MC_PERCENT_AVAILABILITY, (guint) 100,
3059 SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, -1, 3040 SEARCH_TAB_MC_UNKNOWN_AVAILABILITY, -1,
@@ -3075,10 +3056,11 @@ mark_download_completed (struct DownloadEntry *de, uint64_t size)
3075 * @param meta metadata 3056 * @param meta metadata
3076 * @param size total size 3057 * @param size total size
3077 * @param completed current progress 3058 * @param completed current progress
3078 * @return download entry struct for the download (equal to 'de' if 'de' was not NULL) 3059 * @return download entry struct for the download (equal to @a de if @a de was not NULL)
3079 */ 3060 */
3080static struct DownloadEntry * 3061static struct DownloadEntry *
3081setup_download (struct DownloadEntry *de, struct DownloadEntry *pde, 3062setup_download (struct DownloadEntry *de,
3063 struct DownloadEntry *pde,
3082 struct SearchResult *sr, 3064 struct SearchResult *sr,
3083 uint32_t anonymity, 3065 uint32_t anonymity,
3084 struct GNUNET_FS_DownloadContext *dc, 3066 struct GNUNET_FS_DownloadContext *dc,
@@ -3088,6 +3070,7 @@ setup_download (struct DownloadEntry *de, struct DownloadEntry *pde,
3088{ 3070{
3089 GtkTreeIter iter; 3071 GtkTreeIter iter;
3090 GtkTreePath *path; 3072 GtkTreePath *path;
3073 GtkTreeModel *tm;
3091 3074
3092 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3075 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3093 "Setting up download, initially DE=%p, PDE=%p for %p & %p into %llu/%llu `%s'\n", 3076 "Setting up download, initially DE=%p, PDE=%p for %p & %p into %llu/%llu `%s'\n",
@@ -3120,7 +3103,8 @@ setup_download (struct DownloadEntry *de, struct DownloadEntry *pde,
3120 } 3103 }
3121 } 3104 }
3122 if ( (NULL == de->sr) && 3105 if ( (NULL == de->sr) &&
3123 (NULL != pde) ) 3106 (NULL != pde) &&
3107 (NULL != pde->sr->tab) )
3124 { 3108 {
3125 /* child download, find appropriate search result from parent! */ 3109 /* child download, find appropriate search result from parent! */
3126 GtkTreePath *path; 3110 GtkTreePath *path;
@@ -3166,9 +3150,13 @@ setup_download (struct DownloadEntry *de, struct DownloadEntry *pde,
3166 { 3150 {
3167 /* Stand-alone download with no 'row'/search result affiliated 3151 /* Stand-alone download with no 'row'/search result affiliated
3168 with the download so far; create a fresh entry for this 3152 with the download so far; create a fresh entry for this
3169 download in the URI tab */ 3153 download */
3170 de->sr = GNUNET_GTK_add_to_uri_tab (anonymity, 3154 de->sr = GNUNET_GTK_add_search_result (NULL,
3171 meta, uri); 3155 anonymity,
3156 NULL,
3157 uri,
3158 meta,
3159 NULL, 0);
3172 GNUNET_FS_probe_stop (de->sr->probe); 3160 GNUNET_FS_probe_stop (de->sr->probe);
3173 de->sr->probe = NULL; 3161 de->sr->probe = NULL;
3174 GNUNET_CONTAINER_DLL_remove (pl_head, 3162 GNUNET_CONTAINER_DLL_remove (pl_head,
@@ -3176,7 +3164,9 @@ setup_download (struct DownloadEntry *de, struct DownloadEntry *pde,
3176 de->sr); 3164 de->sr);
3177 de->sr->download = de; 3165 de->sr->download = de;
3178 path = gtk_tree_row_reference_get_path (de->sr->rr); 3166 path = gtk_tree_row_reference_get_path (de->sr->rr);
3179 if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, path)) 3167 tm = gtk_tree_row_reference_get_model (de->sr->rr);
3168 if (! gtk_tree_model_get_iter (tm,
3169 &iter, path))
3180 { 3170 {
3181 GNUNET_break (0); 3171 GNUNET_break (0);
3182 gtk_tree_path_free (path); 3172 gtk_tree_path_free (path);
@@ -3189,19 +3179,34 @@ setup_download (struct DownloadEntry *de, struct DownloadEntry *pde,
3189 3179
3190 /* get metadata from existing tab, might have a mime type */ 3180 /* get metadata from existing tab, might have a mime type */
3191 path = gtk_tree_row_reference_get_path (de->sr->rr); 3181 path = gtk_tree_row_reference_get_path (de->sr->rr);
3192 if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (de->sr->tab->ts), &iter, path)) 3182 tm = gtk_tree_row_reference_get_model (de->sr->rr);
3183 if (! gtk_tree_model_get_iter (tm, &iter, path))
3193 { 3184 {
3194 GNUNET_break (0); 3185 GNUNET_break (0);
3195 gtk_tree_path_free (path); 3186 gtk_tree_path_free (path);
3196 return de; 3187 return de;
3197 } 3188 }
3198 gtk_tree_model_get (GTK_TREE_MODEL (de->sr->tab->ts), &iter, 3189 gtk_tree_model_get (tm, &iter,
3199 SEARCH_TAB_MC_METADATA, &meta, 3190 SEARCH_TAB_MC_METADATA, &meta,
3200 -1); 3191 -1);
3201 de->is_directory = GNUNET_FS_meta_data_test_for_directory (meta); 3192 de->is_directory = GNUNET_FS_meta_data_test_for_directory (meta);
3202 } 3193 }
3194 if (NULL == de->rr)
3195 setup_download_list_entry (de, pde, de->sr);
3203 gtk_tree_path_free (path); 3196 gtk_tree_path_free (path);
3204 gtk_tree_store_set (de->sr->tab->ts, &iter, 3197 gtk_tree_store_set (GTK_TREE_STORE (tm), &iter,
3198 SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) ((size > 0) ? (100 * completed / size) : 100),
3199 SEARCH_TAB_MC_FILENAME, filename,
3200 SEARCH_TAB_MC_STATUS_COLOUR, "blue",
3201 SEARCH_TAB_MC_SEARCH_RESULT, de->sr,
3202 SEARCH_TAB_MC_COMPLETED, (guint64) completed,
3203 SEARCH_TAB_MC_DOWNLOADED_FILENAME, de->filename,
3204 SEARCH_TAB_MC_DOWNLOADED_ANONYMITY, de->anonymity,
3205 SEARCH_TAB_MC_STATUS_ICON, GNUNET_GTK_animation_context_get_pixbuf (animation_download_stalled),
3206 -1);
3207 /* also update downloads tab */
3208 get_download_list_entry (de, &iter);
3209 gtk_tree_store_set (downloads_treestore, &iter,
3205 SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) ((size > 0) ? (100 * completed / size) : 100), 3210 SEARCH_TAB_MC_PERCENT_PROGRESS, (guint) ((size > 0) ? (100 * completed / size) : 100),
3206 SEARCH_TAB_MC_FILENAME, filename, 3211 SEARCH_TAB_MC_FILENAME, filename,
3207 SEARCH_TAB_MC_STATUS_COLOUR, "blue", 3212 SEARCH_TAB_MC_STATUS_COLOUR, "blue",
@@ -3404,7 +3409,7 @@ handle_publish_stop (struct PublishEntry *pe)
3404 (void) gtk_tree_store_remove (pe->tab->ts, &iter); 3409 (void) gtk_tree_store_remove (pe->tab->ts, &iter);
3405 gtk_tree_path_free (path); 3410 gtk_tree_path_free (path);
3406 gtk_tree_row_reference_free (pe->rr); 3411 gtk_tree_row_reference_free (pe->rr);
3407 if (pe->uri != NULL) 3412 if (NULL != pe->uri)
3408 { 3413 {
3409 GNUNET_FS_uri_destroy (pe->uri); 3414 GNUNET_FS_uri_destroy (pe->uri);
3410 pe->uri = NULL; 3415 pe->uri = NULL;
@@ -3572,7 +3577,6 @@ struct PublishListPopupContext
3572 */ 3577 */
3573 GtkTreeRowReference *rr; 3578 GtkTreeRowReference *rr;
3574 3579
3575
3576 /** 3580 /**
3577 * Publishing entry at the respective row. 3581 * Publishing entry at the respective row.
3578 */ 3582 */
diff --git a/src/fs/gnunet-fs-gtk_event-handler.h b/src/fs/gnunet-fs-gtk_event-handler.h
index 03a313e3..2d120477 100644
--- a/src/fs/gnunet-fs-gtk_event-handler.h
+++ b/src/fs/gnunet-fs-gtk_event-handler.h
@@ -141,6 +141,12 @@ struct DownloadEntry
141 struct SearchResult *sr; 141 struct SearchResult *sr;
142 142
143 /** 143 /**
144 * Where in the download tab is this result? References the
145 * #downloads_treestore.
146 */
147 GtkTreeRowReference *rr;
148
149 /**
144 * FS handle to control the download, NULL if the download 150 * FS handle to control the download, NULL if the download
145 * has not yet started. 151 * has not yet started.
146 */ 152 */
@@ -240,6 +246,12 @@ extern struct SearchResult *pl_head;
240 */ 246 */
241extern struct SearchResult *pl_tail; 247extern struct SearchResult *pl_tail;
242 248
249/**
250 * The "GNUNET_GTK_file_sharing_downloads_tree_store" with the
251 * information about active (or completed) downloads.
252 */
253extern GtkTreeStore *downloads_treestore;
254
243 255
244 256
245/** 257/**