diff options
Diffstat (limited to 'src/fs/gnunet-fs-gtk.c')
-rw-r--r-- | src/fs/gnunet-fs-gtk.c | 262 |
1 files changed, 211 insertions, 51 deletions
diff --git a/src/fs/gnunet-fs-gtk.c b/src/fs/gnunet-fs-gtk.c index a1230c03..c0e52797 100644 --- a/src/fs/gnunet-fs-gtk.c +++ b/src/fs/gnunet-fs-gtk.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include "gnunet-fs-gtk_common.h" | 27 | #include "gnunet-fs-gtk_common.h" |
28 | #include "gnunet-fs-gtk_event-handler.h" | 28 | #include "gnunet-fs-gtk_event-handler.h" |
29 | #include "gnunet-fs-gtk_open-uri.h" | 29 | #include "gnunet-fs-gtk_open-uri.h" |
30 | #include "gnunet/gnunet_namestore_service.h" | ||
31 | #include <gmodule.h> | ||
30 | 32 | ||
31 | #if HAVE_LIBUNIQUE | 33 | #if HAVE_LIBUNIQUE |
32 | #include <unique/unique.h> | 34 | #include <unique/unique.h> |
@@ -73,10 +75,58 @@ static struct GNUNET_ARM_MonitorHandle *armon; | |||
73 | static struct GNUNET_ARM_Handle *arm; | 75 | static struct GNUNET_ARM_Handle *arm; |
74 | 76 | ||
75 | /** | 77 | /** |
78 | * Ongoing identity operation. | ||
79 | */ | ||
80 | static struct GNUNET_IDENTITY_Operation *iop; | ||
81 | |||
82 | /** | ||
76 | * Context for main window. | 83 | * Context for main window. |
77 | */ | 84 | */ |
78 | static struct GNUNET_GTK_MainWindowContext main_context; | 85 | static struct GNUNET_GTK_MainWindowContext main_context; |
79 | 86 | ||
87 | /** | ||
88 | * Identity combo box in the main window. | ||
89 | */ | ||
90 | static GtkComboBox *id_combo_box; | ||
91 | |||
92 | /** | ||
93 | * Currently selected entry in #id_liststore. | ||
94 | */ | ||
95 | static GtkTreeIter id_iter; | ||
96 | |||
97 | /** | ||
98 | * List of all known egos. | ||
99 | */ | ||
100 | static GtkListStore *id_liststore; | ||
101 | |||
102 | /** | ||
103 | * Status label in main window. | ||
104 | */ | ||
105 | static GtkLabel *status_label; | ||
106 | |||
107 | /** | ||
108 | * Are we shutting down? | ||
109 | */ | ||
110 | static int in_shutdown = 0; | ||
111 | |||
112 | /** | ||
113 | * Columns in the id list store. | ||
114 | */ | ||
115 | enum ID_COLUMNS | ||
116 | { | ||
117 | |||
118 | /** | ||
119 | * A gchararray | ||
120 | */ | ||
121 | ID_LS_NAME = 0, | ||
122 | |||
123 | |||
124 | /** | ||
125 | * A `struct GNUNET_IDENTITY_Ego` | ||
126 | */ | ||
127 | ID_LS_EGO = 1 | ||
128 | }; | ||
129 | |||
80 | 130 | ||
81 | #if HAVE_LIBUNIQUE | 131 | #if HAVE_LIBUNIQUE |
82 | static UniqueApp *unique_app; | 132 | static UniqueApp *unique_app; |
@@ -101,6 +151,21 @@ GNUNET_FS_GTK_get_fs_handle () | |||
101 | return fs; | 151 | return fs; |
102 | } | 152 | } |
103 | 153 | ||
154 | /** | ||
155 | * Get an object from the main window. | ||
156 | * | ||
157 | * @param name name of the object | ||
158 | * @return NULL on error, otherwise the object | ||
159 | */ | ||
160 | static GObject * | ||
161 | get_object (const char *name) | ||
162 | { | ||
163 | if (NULL == ml) | ||
164 | return NULL; | ||
165 | return GNUNET_GTK_main_loop_get_object (ml, name); | ||
166 | } | ||
167 | |||
168 | |||
104 | 169 | ||
105 | /** | 170 | /** |
106 | * Remember FS handle if we don't have one yet. | 171 | * Remember FS handle if we don't have one yet. |
@@ -250,6 +315,11 @@ shutdown_task (void *cls) | |||
250 | struct PseuLookupContext *lctx; | 315 | struct PseuLookupContext *lctx; |
251 | struct SearchResult *sr; | 316 | struct SearchResult *sr; |
252 | 317 | ||
318 | in_shutdown = 1; | ||
319 | while (NULL != (sl = main_context.sl_head)) | ||
320 | abort_search_lookup (sl); | ||
321 | while (NULL != (lctx = main_context.lctx_head)) | ||
322 | abort_pseu_lookup (lctx); | ||
253 | while (NULL != (sr = pl_head)) | 323 | while (NULL != (sr = pl_head)) |
254 | { | 324 | { |
255 | GNUNET_FS_probe_stop (sr->probe); | 325 | GNUNET_FS_probe_stop (sr->probe); |
@@ -261,36 +331,16 @@ shutdown_task (void *cls) | |||
261 | GNUNET_FS_stop (fs); | 331 | GNUNET_FS_stop (fs); |
262 | fs = NULL; | 332 | fs = NULL; |
263 | } | 333 | } |
264 | if (NULL != armon) | 334 | if (NULL != iop) |
265 | { | 335 | { |
266 | GNUNET_ARM_monitor_stop (armon); | 336 | GNUNET_IDENTITY_cancel (iop); |
267 | armon = NULL; | 337 | iop = NULL; |
268 | } | ||
269 | if (NULL != arm) | ||
270 | { | ||
271 | GNUNET_ARM_disconnect (arm); | ||
272 | arm = NULL; | ||
273 | } | ||
274 | GNUNET_FS_GTK_close_uri_tab_ (); | ||
275 | if (NULL != ml) | ||
276 | { | ||
277 | GNUNET_GTK_main_loop_quit (ml); | ||
278 | ml = NULL; | ||
279 | } | ||
280 | if (NULL != main_context.id_op) | ||
281 | { | ||
282 | GNUNET_IDENTITY_ego_lookup_cancel (main_context.id_op); | ||
283 | main_context.id_op = NULL; | ||
284 | } | 338 | } |
285 | if (NULL != main_context.identity) | 339 | if (NULL != main_context.identity) |
286 | { | 340 | { |
287 | GNUNET_IDENTITY_disconnect (main_context.identity); | 341 | GNUNET_IDENTITY_disconnect (main_context.identity); |
288 | main_context.identity = NULL; | 342 | main_context.identity = NULL; |
289 | } | 343 | } |
290 | while (NULL != (sl = main_context.sl_head)) | ||
291 | abort_search_lookup (sl); | ||
292 | while (NULL != (lctx = main_context.lctx_head)) | ||
293 | abort_pseu_lookup (lctx); | ||
294 | if (NULL != main_context.zm) | 344 | if (NULL != main_context.zm) |
295 | { | 345 | { |
296 | GNUNET_NAMESTORE_zone_monitor_stop (main_context.zm); | 346 | GNUNET_NAMESTORE_zone_monitor_stop (main_context.zm); |
@@ -301,6 +351,22 @@ shutdown_task (void *cls) | |||
301 | GNUNET_GNS_disconnect (main_context.gns); | 351 | GNUNET_GNS_disconnect (main_context.gns); |
302 | main_context.gns = NULL; | 352 | main_context.gns = NULL; |
303 | } | 353 | } |
354 | if (NULL != armon) | ||
355 | { | ||
356 | GNUNET_ARM_monitor_stop (armon); | ||
357 | armon = NULL; | ||
358 | } | ||
359 | if (NULL != arm) | ||
360 | { | ||
361 | GNUNET_ARM_disconnect (arm); | ||
362 | arm = NULL; | ||
363 | } | ||
364 | GNUNET_FS_GTK_close_uri_tab_ (); | ||
365 | if (NULL != ml) | ||
366 | { | ||
367 | GNUNET_GTK_main_loop_quit (ml); | ||
368 | ml = NULL; | ||
369 | } | ||
304 | } | 370 | } |
305 | 371 | ||
306 | 372 | ||
@@ -664,6 +730,11 @@ handle_sks_zone_identity (void *cls, | |||
664 | "main_window_search_namespace_label"))); | 730 | "main_window_search_namespace_label"))); |
665 | gtk_widget_show (GTK_WIDGET (GNUNET_FS_GTK_get_main_window_object ( | 731 | gtk_widget_show (GTK_WIDGET (GNUNET_FS_GTK_get_main_window_object ( |
666 | "main_window_search_namespace_combobox"))); | 732 | "main_window_search_namespace_combobox"))); |
733 | if (NULL != main_context.zm) | ||
734 | { | ||
735 | GNUNET_NAMESTORE_zone_monitor_stop(main_context.zm); | ||
736 | main_context.zm = NULL; | ||
737 | } | ||
667 | main_context.zm = | 738 | main_context.zm = |
668 | GNUNET_NAMESTORE_zone_monitor_start (main_context.cfg, | 739 | GNUNET_NAMESTORE_zone_monitor_start (main_context.cfg, |
669 | GNUNET_IDENTITY_ego_get_private_key ( | 740 | GNUNET_IDENTITY_ego_get_private_key ( |
@@ -679,9 +750,57 @@ handle_sks_zone_identity (void *cls, | |||
679 | 750 | ||
680 | 751 | ||
681 | /** | 752 | /** |
682 | * We must pass a non-NULL callback to the identity service, | 753 | * The user selected another identity in the combobox. Load it. |
683 | * but we don't actually care about the information here | 754 | * |
684 | * (we will use GNUNET_IDENTITY_get() if and when we do care). | 755 | * @param widget the combo box where the selection was changed |
756 | * @param user_data the builder, unused | ||
757 | */ | ||
758 | void | ||
759 | gnunet_fs_gtk_id_combobox_changed_cb (GtkComboBox *widget, | ||
760 | gpointer user_data) | ||
761 | { | ||
762 | GtkTreeIter iter; | ||
763 | struct GNUNET_IDENTITY_Ego *ego; | ||
764 | char *name; | ||
765 | |||
766 | (void) user_data; | ||
767 | if (! gtk_combo_box_get_active_iter (id_combo_box, &iter)) | ||
768 | { | ||
769 | return; | ||
770 | } | ||
771 | id_iter = iter; | ||
772 | /* clang-format off */ | ||
773 | gtk_tree_model_get (GTK_TREE_MODEL (id_liststore), | ||
774 | &iter, | ||
775 | ID_LS_NAME, &name, | ||
776 | ID_LS_EGO, &ego, | ||
777 | -1); | ||
778 | /* clang-format on */ | ||
779 | handle_sks_zone_identity (name, ego); | ||
780 | } | ||
781 | |||
782 | /** | ||
783 | * Method called to inform about the egos of this peer. Updates the | ||
784 | * `zone_liststore`. | ||
785 | * | ||
786 | * When used with #GNUNET_IDENTITY_connect, this function is | ||
787 | * initially called for all egos and then again whenever a | ||
788 | * ego's name changes or if it is deleted. At the end of | ||
789 | * the initial pass over all egos, the function is once called | ||
790 | * with 'NULL' for @a ego. That does NOT mean that the callback won't | ||
791 | * be invoked in the future or that there was an error. | ||
792 | * | ||
793 | * If @a ego is non-NULL and if '*ctx' is set in those callbacks, the | ||
794 | * value WILL be passed to a subsequent call to the identity callback | ||
795 | * of #GNUNET_IDENTITY_connect (if that one was not NULL). | ||
796 | * | ||
797 | * When an identity is renamed, this function is called with the | ||
798 | * (known) @a ego but the NEW @a name. | ||
799 | * | ||
800 | * When an identity is deleted, this function is called with the | ||
801 | * (known) ego and "NULL" for the @a name. In this case, | ||
802 | * the @a ego is henceforth invalid (and the @a ctx should also be | ||
803 | * cleaned up). | ||
685 | * | 804 | * |
686 | * @param cls closure | 805 | * @param cls closure |
687 | * @param ego ego handle | 806 | * @param ego ego handle |
@@ -692,17 +811,70 @@ handle_sks_zone_identity (void *cls, | |||
692 | * must thus no longer be used | 811 | * must thus no longer be used |
693 | */ | 812 | */ |
694 | static void | 813 | static void |
695 | non_null_cb (void *cls, | 814 | identity_cb (void *cls, |
696 | struct GNUNET_IDENTITY_Ego *ego, | 815 | struct GNUNET_IDENTITY_Ego *ego, |
697 | void **ctx, | 816 | void **ctx, |
698 | const char *name) | 817 | const char *name) |
699 | { | 818 | { |
700 | (void) cls; | 819 | GtkTreeRowReference *rr; |
701 | (void) ego; | 820 | GtkTreeIter iter; |
702 | (void) ctx; | 821 | GtkTreePath *path; |
703 | (void) name; | 822 | |
704 | } | 823 | if (in_shutdown) |
824 | return; | ||
825 | if ((NULL == ego) && (NULL == name) && (NULL == ctx)) | ||
826 | { | ||
827 | /* end of initial iteration, trigger loading selected zone */ | ||
828 | gnunet_fs_gtk_id_combobox_changed_cb (id_combo_box, ml); | ||
829 | return; | ||
830 | } | ||
831 | rr = *ctx; | ||
832 | if (NULL == rr) | ||
833 | { | ||
834 | /* clang-format off */ | ||
835 | gtk_list_store_insert_with_values (id_liststore, | ||
836 | &iter, 0, | ||
837 | ID_LS_NAME, name, | ||
838 | ID_LS_EGO, ego, | ||
839 | -1); | ||
840 | /* clang-format on */ | ||
841 | gtk_combo_box_set_active_iter (id_combo_box, &iter); | ||
842 | gtk_widget_set_sensitive (GTK_WIDGET (id_combo_box), TRUE); | ||
843 | path = gtk_tree_model_get_path (GTK_TREE_MODEL (id_liststore), &iter); | ||
844 | rr = gtk_tree_row_reference_new (GTK_TREE_MODEL (id_liststore), path); | ||
845 | *ctx = rr; | ||
846 | gtk_tree_path_free (path); | ||
847 | return; | ||
848 | } | ||
849 | path = gtk_tree_row_reference_get_path (rr); | ||
850 | GNUNET_break ( | ||
851 | gtk_tree_model_get_iter (GTK_TREE_MODEL (id_liststore), &iter, path)); | ||
852 | gtk_tree_path_free (path); | ||
853 | if (NULL == name) | ||
854 | { | ||
855 | GtkTreeIter act_iter; | ||
705 | 856 | ||
857 | /* identity was removed, remove from list */ | ||
858 | gtk_list_store_remove (id_liststore, &iter); | ||
859 | if (! gtk_combo_box_get_active_iter (id_combo_box, &act_iter)) | ||
860 | { | ||
861 | if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (id_liststore), | ||
862 | &act_iter)) | ||
863 | { | ||
864 | /* make sure combo box remains selected if possible */ | ||
865 | gtk_combo_box_set_active (id_combo_box, 0); | ||
866 | } | ||
867 | else | ||
868 | { | ||
869 | /* make combo box insensitive if nothing can be selected */ | ||
870 | gtk_widget_set_sensitive (GTK_WIDGET (id_combo_box), FALSE); | ||
871 | } | ||
872 | } | ||
873 | return; | ||
874 | } | ||
875 | /* identity was renamed, rename in model */ | ||
876 | gtk_list_store_set (id_liststore, &iter, ID_LS_NAME, name, -1); | ||
877 | } | ||
706 | 878 | ||
707 | /** | 879 | /** |
708 | * Actual main function run right after GNUnet's scheduler | 880 | * Actual main function run right after GNUnet's scheduler |
@@ -720,7 +892,6 @@ run (void *cls) | |||
720 | unsigned long long window_width; | 892 | unsigned long long window_width; |
721 | unsigned long long window_height; | 893 | unsigned long long window_height; |
722 | int maximized; | 894 | int maximized; |
723 | char *default_ego_name; | ||
724 | 895 | ||
725 | ml = cls; | 896 | ml = cls; |
726 | /* setup main context */ | 897 | /* setup main context */ |
@@ -789,6 +960,11 @@ run (void *cls) | |||
789 | GTK_IMAGE (GNUNET_FS_GTK_get_main_window_object ( | 960 | GTK_IMAGE (GNUNET_FS_GTK_get_main_window_object ( |
790 | "GNUNET_FS_GTK_main_window_connection_indicator")); | 961 | "GNUNET_FS_GTK_main_window_connection_indicator")); |
791 | 962 | ||
963 | status_label = GTK_LABEL (get_object ( | ||
964 | "gnunet_fs_gtk_status_label")); | ||
965 | id_combo_box = | ||
966 | GTK_COMBO_BOX (get_object ("gnunet_fs_gtk_id_combobox")); | ||
967 | id_liststore = GTK_LIST_STORE (get_object ("id_liststore")); | ||
792 | GNUNET_GTK_set_icon_search_path (); | 968 | GNUNET_GTK_set_icon_search_path (); |
793 | GNUNET_GTK_setup_nls (); | 969 | GNUNET_GTK_setup_nls (); |
794 | 970 | ||
@@ -856,17 +1032,6 @@ run (void *cls) | |||
856 | "MAX_PARALLEL_REQUESTS", | 1032 | "MAX_PARALLEL_REQUESTS", |
857 | &req_parallel)) | 1033 | &req_parallel)) |
858 | req_parallel = DEFAULT_MAX_PARALLEL_REQUESTS; | 1034 | req_parallel = DEFAULT_MAX_PARALLEL_REQUESTS; |
859 | if (GNUNET_OK != | ||
860 | GNUNET_CONFIGURATION_get_value_string (main_context.cfg, | ||
861 | "fs-sks", | ||
862 | "DEFAULT_IDENTITY", | ||
863 | &default_ego_name)) | ||
864 | { | ||
865 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
866 | "Please set DEFAULT_IDENTITY under [fs-sks]\n"); | ||
867 | GNUNET_GTK_main_loop_quit (cls); | ||
868 | return; | ||
869 | } | ||
870 | /* initialize file-sharing */ | 1035 | /* initialize file-sharing */ |
871 | fs = GNUNET_FS_start (main_context.cfg, | 1036 | fs = GNUNET_FS_start (main_context.cfg, |
872 | "gnunet-fs-gtk", | 1037 | "gnunet-fs-gtk", |
@@ -890,13 +1055,8 @@ run (void *cls) | |||
890 | &service_status_change, | 1055 | &service_status_change, |
891 | &main_context); | 1056 | &main_context); |
892 | main_context.gns = GNUNET_GNS_connect (main_context.cfg); | 1057 | main_context.gns = GNUNET_GNS_connect (main_context.cfg); |
893 | main_context.identity = | 1058 | main_context.identity = GNUNET_IDENTITY_connect (main_context.cfg, |
894 | GNUNET_IDENTITY_connect (main_context.cfg, &non_null_cb, NULL); | 1059 | &identity_cb, NULL); |
895 | main_context.id_op = GNUNET_IDENTITY_ego_lookup (main_context.cfg, | ||
896 | default_ego_name, | ||
897 | &handle_sks_zone_identity, | ||
898 | NULL); | ||
899 | GNUNET_free (default_ego_name); | ||
900 | #if HAVE_LIBUNIQUE | 1060 | #if HAVE_LIBUNIQUE |
901 | unique_app_watch_window (unique_app, GTK_WINDOW (main_context.main_window)); | 1061 | unique_app_watch_window (unique_app, GTK_WINDOW (main_context.main_window)); |
902 | g_signal_connect (unique_app, | 1062 | g_signal_connect (unique_app, |