diff options
Diffstat (limited to 'src/fs/gnunet-fs-gtk-event_handler.c')
-rw-r--r-- | src/fs/gnunet-fs-gtk-event_handler.c | 286 |
1 files changed, 159 insertions, 127 deletions
diff --git a/src/fs/gnunet-fs-gtk-event_handler.c b/src/fs/gnunet-fs-gtk-event_handler.c index 81b61725..3b4dc667 100644 --- a/src/fs/gnunet-fs-gtk-event_handler.c +++ b/src/fs/gnunet-fs-gtk-event_handler.c | |||
@@ -163,11 +163,12 @@ static struct SearchTab *current_context_search_tab; | |||
163 | * somewhere else, at least until application restart, or maybe even | 163 | * somewhere else, at least until application restart, or maybe even |
164 | * between application restarts). | 164 | * between application restarts). |
165 | * | 165 | * |
166 | * Fills the @buffer up to @size bytes, returns a pointer to it. | 166 | * Fills the 'buffer' up to 'size' bytes, returns a pointer to it. |
167 | */ | 167 | */ |
168 | static char * | 168 | static char * |
169 | get_default_download_directory (char *buffer, size_t size) | 169 | get_default_download_directory (char *buffer, size_t size) |
170 | { | 170 | { |
171 | /* FIXME: implement... */ | ||
171 | return NULL; | 172 | return NULL; |
172 | } | 173 | } |
173 | 174 | ||
@@ -208,6 +209,8 @@ get_suggested_filename_anonymity (GtkTreeModel *tm, | |||
208 | const char *basename; | 209 | const char *basename; |
209 | char *dot; | 210 | char *dot; |
210 | 211 | ||
212 | /* FIXME: this function is likely responsible for not always | ||
213 | suggesting the best filename... To be investigated some more... */ | ||
211 | gtk_tree_model_get (tm, iter, 0, &meta, | 214 | gtk_tree_model_get (tm, iter, 0, &meta, |
212 | 15, &local_filename, | 215 | 15, &local_filename, |
213 | 16, &downloaded_anonymity, | 216 | 16, &downloaded_anonymity, |
@@ -289,8 +292,8 @@ get_suggested_filename_anonymity (GtkTreeModel *tm, | |||
289 | * @param is_recursive was the request for a recursive download? | 292 | * @param is_recursive was the request for a recursive download? |
290 | */ | 293 | */ |
291 | static void | 294 | static void |
292 | start_download (GtkTreeView * tree_view, | 295 | start_download (GtkTreeView *tree_view, |
293 | GtkTreePath * path, | 296 | GtkTreePath *path, |
294 | struct SearchTab *tab, | 297 | struct SearchTab *tab, |
295 | int is_recursive) | 298 | int is_recursive) |
296 | { | 299 | { |
@@ -346,7 +349,9 @@ start_download (GtkTreeView * tree_view, | |||
346 | local_parents = GNUNET_YES; | 349 | local_parents = GNUNET_YES; |
347 | anonymity = -1; | 350 | anonymity = -1; |
348 | filename_is_absolute = GNUNET_NO; | 351 | filename_is_absolute = GNUNET_NO; |
349 | filename = get_suggested_filename_anonymity (tm, &iter, GNUNET_YES, &local_parents, &anonymity, &filename_is_absolute); | 352 | filename = get_suggested_filename_anonymity (tm, &iter, GNUNET_YES, |
353 | &local_parents, &anonymity, | ||
354 | &filename_is_absolute); | ||
350 | have_a_suggestion = GNUNET_NO; | 355 | have_a_suggestion = GNUNET_NO; |
351 | if (NULL != download_directory) | 356 | if (NULL != download_directory) |
352 | { | 357 | { |
@@ -397,7 +402,8 @@ start_download (GtkTreeView * tree_view, | |||
397 | dc->anonymity = anonymity; | 402 | dc->anonymity = anonymity; |
398 | dc->is_recursive = is_recursive; | 403 | dc->is_recursive = is_recursive; |
399 | dc->tab = tab; | 404 | dc->tab = tab; |
400 | if (local_parents && have_a_suggestion) | 405 | if ( (GNUNET_YES == local_parents) && |
406 | (GNUNET_YES == have_a_suggestion) ) | ||
401 | /* Skip the dialog, call directly */ | 407 | /* Skip the dialog, call directly */ |
402 | GNUNET_FS_GTK_download_context_start_download (dc); | 408 | GNUNET_FS_GTK_download_context_start_download (dc); |
403 | else | 409 | else |
@@ -406,8 +412,7 @@ start_download (GtkTreeView * tree_view, | |||
406 | 412 | ||
407 | 413 | ||
408 | /** | 414 | /** |
409 | * An item was selected from the context menu; destroy | 415 | * An item was selected from the context menu; destroy the menu shell. |
410 | * the menu shell. | ||
411 | * | 416 | * |
412 | * @param menushell menu to destroy | 417 | * @param menushell menu to destroy |
413 | * @parma user_data the 'struct DownloadEntry' for the menu (unused) | 418 | * @parma user_data the 'struct DownloadEntry' for the menu (unused) |
@@ -423,7 +428,6 @@ search_list_popup_selection_done (GtkMenuShell *menushell, | |||
423 | } | 428 | } |
424 | 429 | ||
425 | 430 | ||
426 | |||
427 | /** | 431 | /** |
428 | * This function is called when the user double-clicks on a search | 432 | * This function is called when the user double-clicks on a search |
429 | * result. Begins the download, if necessary by opening the "save as" | 433 | * result. Begins the download, if necessary by opening the "save as" |
@@ -523,10 +527,10 @@ abort_download_ctx_menu (GtkMenuItem *item, gpointer user_data) | |||
523 | 527 | ||
524 | 528 | ||
525 | /** | 529 | /** |
526 | * Copy current URI to clipboard. | 530 | * Copy current URI to clipboard was selected in the current context menu. |
527 | * | 531 | * |
528 | * @param item the 'copy-to-clipboard' menu item | 532 | * @param item the 'copy-to-clipboard' menu item |
529 | * @parma user_data the 'struct DownloadEntry' to copy from | 533 | * @parma user_data NULL |
530 | */ | 534 | */ |
531 | static void | 535 | static void |
532 | copy_uri_to_clipboard_ctx_menu (GtkMenuItem *item, gpointer user_data) | 536 | copy_uri_to_clipboard_ctx_menu (GtkMenuItem *item, gpointer user_data) |
@@ -573,89 +577,73 @@ copy_uri_to_clipboard_ctx_menu (GtkMenuItem *item, gpointer user_data) | |||
573 | } | 577 | } |
574 | 578 | ||
575 | 579 | ||
580 | /** | ||
581 | * Context menu was requested for a search result list. | ||
582 | * Compute which menu items are applicable and display | ||
583 | * an appropriate menu. | ||
584 | * | ||
585 | * @param tm tree model underlying the tree view where the event happened | ||
586 | * @param tab tab where the event happened | ||
587 | * @param event_button the event | ||
588 | * @return FALSE if no menu could be popped up, | ||
589 | * TRUE if there is now a pop-up menu | ||
590 | */ | ||
576 | static gboolean | 591 | static gboolean |
577 | search_list_popup (GtkTreeView *tv, struct SearchTab *tab, GdkEventButton *event_button) | 592 | search_list_popup (GtkTreeModel *tm, |
593 | struct SearchTab *tab, | ||
594 | gint init_button, | ||
595 | guint32 event_time, | ||
596 | GtkTreeIter *iter) | ||
578 | { | 597 | { |
579 | GtkMenu *menu; | 598 | GtkMenu *menu; |
580 | GtkWidget *child; | 599 | GtkWidget *child; |
581 | GtkTreeSelection *sel; | ||
582 | GtkTreePath *path; | 600 | GtkTreePath *path; |
583 | GtkTreeModel *tm; | ||
584 | GtkTreeIter iter; | ||
585 | struct SearchResult *sr; | 601 | struct SearchResult *sr; |
586 | struct GNUNET_FS_Uri *uri; | 602 | struct GNUNET_FS_Uri *uri; |
587 | gboolean got_selection; | ||
588 | gint init_button; | ||
589 | guint32 event_time; | ||
590 | 603 | ||
604 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
605 | "Creating a menu for SR=%p, DE=%p\n", | ||
606 | sr, | ||
607 | sr->download); | ||
608 | |||
609 | /* FIXME: move these to some menu context struct | ||
610 | (de-globalize) */ | ||
591 | current_context_search_tab = tab; | 611 | current_context_search_tab = tab; |
592 | if (current_context_row_reference != NULL) | 612 | if (current_context_row_reference != NULL) |
593 | { | 613 | { |
594 | gtk_tree_row_reference_free (current_context_row_reference); | 614 | gtk_tree_row_reference_free (current_context_row_reference); |
595 | current_context_row_reference = NULL; | 615 | current_context_row_reference = NULL; |
596 | } | 616 | } |
597 | path = NULL; | 617 | path = gtk_tree_model_get_path (tm, iter); |
598 | if (event_button != NULL) | 618 | current_context_row_reference = gtk_tree_row_reference_new (tm, path); |
599 | { | 619 | gtk_tree_path_free (path); |
600 | got_selection = | 620 | |
601 | gtk_tree_view_get_path_at_pos (tv, event_button->x, event_button->y, | 621 | gtk_tree_model_get (tm, iter, 1, &uri, 9, &sr, -1); |
602 | &path, NULL, NULL, NULL); | ||
603 | if (got_selection) | ||
604 | { | ||
605 | tm = gtk_tree_view_get_model (tv); | ||
606 | got_selection = gtk_tree_model_get_iter (tm, &iter, path); | ||
607 | current_context_row_reference = gtk_tree_row_reference_new (tm, path); | ||
608 | gtk_tree_path_free (path); | ||
609 | } | ||
610 | init_button = event_button->button; | ||
611 | event_time = event_button->time; | ||
612 | } | ||
613 | else | ||
614 | { | ||
615 | sel = gtk_tree_view_get_selection (tv); | ||
616 | got_selection = gtk_tree_selection_get_selected (sel, &tm, &iter); | ||
617 | path = gtk_tree_model_get_path (tm, &iter); | ||
618 | current_context_row_reference = gtk_tree_row_reference_new (tm, path); | ||
619 | gtk_tree_path_free (path); | ||
620 | init_button = 0; | ||
621 | event_time = gtk_get_current_event_time (); | ||
622 | } | ||
623 | if (!got_selection) | ||
624 | { | ||
625 | /* nothing selected or model empty? */ | ||
626 | current_context_search_tab = NULL; | ||
627 | return FALSE; | ||
628 | } | ||
629 | gtk_tree_model_get (tm, &iter, 1, &uri, 9, &sr, -1); | ||
630 | 622 | ||
631 | menu = GTK_MENU (gtk_menu_new ()); | 623 | menu = GTK_MENU (gtk_menu_new ()); |
632 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 624 | if ( (NULL == sr->download) && |
633 | "Creating a menu for SR=%p, DE=%p\n", sr, sr->download); | 625 | (NULL != uri) ) |
634 | if (sr->download == NULL) | 626 | { |
635 | { | 627 | /* only display download menus if there is a URI */ |
636 | if (NULL != uri) | 628 | child = gtk_menu_item_new_with_label (_("_Download")); |
637 | { | 629 | g_signal_connect (child, "activate", |
638 | /* only display download menus if there is a URI */ | 630 | G_CALLBACK (start_download_ctx_menu), NULL); |
639 | child = gtk_menu_item_new_with_label (_("_Download")); | 631 | gtk_label_set_use_underline (GTK_LABEL |
640 | g_signal_connect (child, "activate", | 632 | (gtk_bin_get_child (GTK_BIN (child))), |
641 | G_CALLBACK (start_download_ctx_menu), NULL); | 633 | TRUE); |
642 | gtk_label_set_use_underline (GTK_LABEL | 634 | gtk_widget_show (child); |
643 | (gtk_bin_get_child (GTK_BIN (child))), | 635 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); |
644 | TRUE); | 636 | |
645 | gtk_widget_show (child); | 637 | child = gtk_menu_item_new_with_label (_("Download _recursively")); |
646 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); | 638 | g_signal_connect (child, "activate", |
647 | 639 | G_CALLBACK (start_download_recursively_ctx_menu), NULL); | |
648 | child = gtk_menu_item_new_with_label (_("Download _recursively")); | 640 | gtk_label_set_use_underline (GTK_LABEL |
649 | g_signal_connect (child, "activate", | 641 | (gtk_bin_get_child (GTK_BIN (child))), |
650 | G_CALLBACK (start_download_recursively_ctx_menu), NULL); | 642 | TRUE); |
651 | gtk_label_set_use_underline (GTK_LABEL | 643 | gtk_widget_show (child); |
652 | (gtk_bin_get_child (GTK_BIN (child))), | 644 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); |
653 | TRUE); | ||
654 | gtk_widget_show (child); | ||
655 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); | ||
656 | } | ||
657 | } | 645 | } |
658 | else | 646 | if (NULL != sr->download) |
659 | { | 647 | { |
660 | child = gtk_menu_item_new_with_label (_("_Abort download")); | 648 | child = gtk_menu_item_new_with_label (_("_Abort download")); |
661 | g_signal_connect (child, "activate", | 649 | g_signal_connect (child, "activate", |
@@ -666,31 +654,100 @@ search_list_popup (GtkTreeView *tv, struct SearchTab *tab, GdkEventButton *event | |||
666 | gtk_widget_show (child); | 654 | gtk_widget_show (child); |
667 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); | 655 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); |
668 | } | 656 | } |
669 | 657 | if (NULL != uri) | |
670 | child = gtk_menu_item_new_with_label (_("_Copy URI to Clipboard")); | 658 | { |
671 | g_signal_connect (child, "activate", | 659 | child = gtk_menu_item_new_with_label (_("_Copy URI to Clipboard")); |
672 | G_CALLBACK (copy_uri_to_clipboard_ctx_menu), NULL); | 660 | g_signal_connect (child, "activate", |
673 | gtk_label_set_use_underline (GTK_LABEL | 661 | G_CALLBACK (copy_uri_to_clipboard_ctx_menu), NULL); |
674 | (gtk_bin_get_child (GTK_BIN (child))), TRUE); | 662 | gtk_label_set_use_underline (GTK_LABEL |
675 | gtk_widget_show (child); | 663 | (gtk_bin_get_child (GTK_BIN (child))), TRUE); |
676 | 664 | gtk_widget_show (child); | |
665 | } | ||
677 | g_signal_connect (menu, "selection-done", | 666 | g_signal_connect (menu, "selection-done", |
678 | G_CALLBACK (search_list_popup_selection_done), NULL); | 667 | G_CALLBACK (search_list_popup_selection_done), NULL); |
679 | |||
680 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); | 668 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); |
681 | gtk_menu_popup (menu, NULL, NULL, NULL, NULL, init_button, event_time); | 669 | gtk_menu_popup (menu, NULL, NULL, NULL, NULL, init_button, event_time); |
682 | return TRUE; | 670 | return TRUE; |
683 | } | 671 | } |
684 | 672 | ||
685 | 673 | ||
686 | static void | 674 | /** |
687 | closure_notify_free (gpointer data, GClosure *closure) | 675 | * We got a 'popup-menu' event, display the context menu. |
676 | * | ||
677 | * @param widget the tree view where the event happened | ||
678 | * @param user_data the 'struct SearchTab' of the tree view | ||
679 | * @return FALSE if no menu could be popped up, | ||
680 | * TRUE if there is now a pop-up menu | ||
681 | */ | ||
682 | static gboolean | ||
683 | search_list_on_popup (GtkWidget *widget, gpointer user_data) | ||
688 | { | 684 | { |
689 | GNUNET_free (data); | 685 | GtkTreeView *tv = GTK_TREE_VIEW (widget); |
686 | struct SearchTab *tab = user_data; | ||
687 | GtkTreeSelection *sel; | ||
688 | GtkTreeIter iter; | ||
689 | GtkTreeModel *tm; | ||
690 | |||
691 | sel = gtk_tree_view_get_selection (tv); | ||
692 | if (! gtk_tree_selection_get_selected (sel, &tm, &iter)) | ||
693 | return FALSE; /* nothing selected */ | ||
694 | return search_list_popup (tm, tab, 0, gtk_get_current_event_time (), &iter); | ||
690 | } | 695 | } |
691 | 696 | ||
697 | |||
698 | /** | ||
699 | * We got a right-click on the search result list. Display the context | ||
700 | * menu. | ||
701 | * | ||
702 | * @param widget the GtkTreeView with the search result list | ||
703 | * @param event the event, we only care about button events | ||
704 | * @param user_data the 'struct SearchTab' the widget is in | ||
705 | * @return FALSE if no menu could be popped up, | ||
706 | * TRUE if there is now a pop-up menu | ||
707 | */ | ||
708 | static gboolean | ||
709 | search_list_on_menu (GtkWidget * widget, | ||
710 | GdkEvent * event, | ||
711 | gpointer user_data) | ||
712 | { | ||
713 | GtkTreeView *tv = GTK_TREE_VIEW (widget); | ||
714 | GdkEventButton *event_button = (GdkEventButton *) event; | ||
715 | struct SearchTab *tab = user_data; | ||
716 | GtkTreeModel *tm; | ||
717 | GtkTreePath *path; | ||
718 | GtkTreeIter iter; | ||
719 | |||
720 | if ( (event->type != GDK_BUTTON_PRESS) || | ||
721 | (event_button->button != 3) ) | ||
722 | return FALSE; /* not a right-click */ | ||
723 | if (! gtk_tree_view_get_path_at_pos (tv, | ||
724 | event_button->x, event_button->y, | ||
725 | &path, NULL, NULL, NULL)) | ||
726 | return FALSE; /* click outside of area with values, ignore */ | ||
727 | tm = gtk_tree_view_get_model (tv); | ||
728 | if (! gtk_tree_model_get_iter (tm, &iter, path)) | ||
729 | return FALSE; /* not sure how we got a path but no iter... */ | ||
730 | gtk_tree_path_free (path); | ||
731 | return search_list_popup (tm, tab, | ||
732 | event_button->button, | ||
733 | event_button->time, | ||
734 | &iter); | ||
735 | } | ||
736 | |||
737 | |||
738 | |||
739 | |||
740 | |||
741 | /* FIXME: go over code from here on and document & clean up... */ | ||
742 | |||
743 | |||
744 | |||
745 | |||
746 | |||
747 | |||
692 | static struct DownloadEntry * | 748 | static struct DownloadEntry * |
693 | change_download_colour (struct DownloadEntry *de, const char *colour) | 749 | change_download_colour (struct DownloadEntry *de, |
750 | const char *colour) | ||
694 | { | 751 | { |
695 | GtkTreeIter iter; | 752 | GtkTreeIter iter; |
696 | GtkTreePath *path; | 753 | GtkTreePath *path; |
@@ -782,7 +839,7 @@ struct AddDirectoryEntryContext | |||
782 | { | 839 | { |
783 | 840 | ||
784 | /** | 841 | /** |
785 | * | 842 | * FIXME |
786 | */ | 843 | */ |
787 | struct DownloadEntry *de; | 844 | struct DownloadEntry *de; |
788 | 845 | ||
@@ -1243,40 +1300,6 @@ setup_download (struct DownloadEntry *de, struct DownloadEntry *pde, | |||
1243 | 1300 | ||
1244 | 1301 | ||
1245 | 1302 | ||
1246 | static gboolean | ||
1247 | search_list_on_popup (GtkWidget *widget, gpointer user_data) | ||
1248 | { | ||
1249 | GtkTreeView *tv; | ||
1250 | struct SearchTab *tab = user_data; | ||
1251 | |||
1252 | tv = GTK_TREE_VIEW (widget); | ||
1253 | return search_list_popup (tv, tab, NULL); | ||
1254 | } | ||
1255 | |||
1256 | |||
1257 | |||
1258 | /** | ||
1259 | * We got a right-click on the search result list. Display the context | ||
1260 | * menu. | ||
1261 | */ | ||
1262 | static int | ||
1263 | search_list_on_menu (GtkWidget * widget, GdkEvent * event, gpointer user_data) | ||
1264 | { | ||
1265 | GdkEventButton *event_button; | ||
1266 | struct SearchTab *tab = user_data; | ||
1267 | GtkTreeView *tv; | ||
1268 | |||
1269 | tv = GTK_TREE_VIEW (widget); | ||
1270 | if (event->type == GDK_BUTTON_PRESS) | ||
1271 | { | ||
1272 | event_button = (GdkEventButton *) event; | ||
1273 | if (event_button->button == 3) | ||
1274 | { | ||
1275 | return search_list_popup (tv, tab, event_button); | ||
1276 | } | ||
1277 | } | ||
1278 | return FALSE; | ||
1279 | } | ||
1280 | 1303 | ||
1281 | /** | 1304 | /** |
1282 | * Selected row has changed, update preview and metadata | 1305 | * Selected row has changed, update preview and metadata |
@@ -1574,6 +1597,16 @@ continue_search (GtkButton * button, gpointer user_data) | |||
1574 | 1597 | ||
1575 | 1598 | ||
1576 | /** | 1599 | /** |
1600 | * FIXME: what exactly are we freeing here on 'row_activated'? | ||
1601 | */ | ||
1602 | static void | ||
1603 | closure_notify_free (gpointer data, GClosure *closure) | ||
1604 | { | ||
1605 | GNUNET_free (data); | ||
1606 | } | ||
1607 | |||
1608 | |||
1609 | /** | ||
1577 | * Setup a new search tab. | 1610 | * Setup a new search tab. |
1578 | * | 1611 | * |
1579 | * @param sc context with FS for the search | 1612 | * @param sc context with FS for the search |
@@ -1688,7 +1721,7 @@ setup_search (struct GNUNET_FS_SearchContext *sc, | |||
1688 | 1721 | ||
1689 | 1722 | ||
1690 | /** | 1723 | /** |
1691 | * Setup an inner search. | 1724 | * Setup an inner search. FIXME: explain what an 'inner' search is... |
1692 | * | 1725 | * |
1693 | * @param sc context with FS for the search | 1726 | * @param sc context with FS for the search |
1694 | * @param parent parent search tab | 1727 | * @param parent parent search tab |
@@ -1716,7 +1749,6 @@ setup_inner_search (struct GNUNET_FS_SearchContext *sc, | |||
1716 | } | 1749 | } |
1717 | 1750 | ||
1718 | 1751 | ||
1719 | |||
1720 | /** | 1752 | /** |
1721 | * Add a search result to the given search tab. | 1753 | * Add a search result to the given search tab. |
1722 | * | 1754 | * |