summaryrefslogtreecommitdiff
path: root/src/fs/gnunet-fs-gtk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-fs-gtk.c')
-rw-r--r--src/fs/gnunet-fs-gtk.c262
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 @@
#include "gnunet-fs-gtk_common.h"
#include "gnunet-fs-gtk_event-handler.h"
#include "gnunet-fs-gtk_open-uri.h"
+#include "gnunet/gnunet_namestore_service.h"
+#include <gmodule.h>
#if HAVE_LIBUNIQUE
#include <unique/unique.h>
@@ -73,10 +75,58 @@ static struct GNUNET_ARM_MonitorHandle *armon;
static struct GNUNET_ARM_Handle *arm;
/**
+ * Ongoing identity operation.
+ */
+static struct GNUNET_IDENTITY_Operation *iop;
+
+/**
* Context for main window.
*/
static struct GNUNET_GTK_MainWindowContext main_context;
+/**
+ * Identity combo box in the main window.
+ */
+static GtkComboBox *id_combo_box;
+
+/**
+ * Currently selected entry in #id_liststore.
+ */
+static GtkTreeIter id_iter;
+
+/**
+ * List of all known egos.
+ */
+static GtkListStore *id_liststore;
+
+/**
+ * Status label in main window.
+ */
+static GtkLabel *status_label;
+
+/**
+ * Are we shutting down?
+ */
+static int in_shutdown = 0;
+
+/**
+ * Columns in the id list store.
+ */
+enum ID_COLUMNS
+{
+
+ /**
+ * A gchararray
+ */
+ ID_LS_NAME = 0,
+
+
+ /**
+ * A `struct GNUNET_IDENTITY_Ego`
+ */
+ ID_LS_EGO = 1
+};
+
#if HAVE_LIBUNIQUE
static UniqueApp *unique_app;
@@ -101,6 +151,21 @@ GNUNET_FS_GTK_get_fs_handle ()
return fs;
}
+/**
+ * Get an object from the main window.
+ *
+ * @param name name of the object
+ * @return NULL on error, otherwise the object
+ */
+static GObject *
+get_object (const char *name)
+{
+ if (NULL == ml)
+ return NULL;
+ return GNUNET_GTK_main_loop_get_object (ml, name);
+}
+
+
/**
* Remember FS handle if we don't have one yet.
@@ -250,6 +315,11 @@ shutdown_task (void *cls)
struct PseuLookupContext *lctx;
struct SearchResult *sr;
+ in_shutdown = 1;
+ while (NULL != (sl = main_context.sl_head))
+ abort_search_lookup (sl);
+ while (NULL != (lctx = main_context.lctx_head))
+ abort_pseu_lookup (lctx);
while (NULL != (sr = pl_head))
{
GNUNET_FS_probe_stop (sr->probe);
@@ -261,36 +331,16 @@ shutdown_task (void *cls)
GNUNET_FS_stop (fs);
fs = NULL;
}
- if (NULL != armon)
+ if (NULL != iop)
{
- GNUNET_ARM_monitor_stop (armon);
- armon = NULL;
- }
- if (NULL != arm)
- {
- GNUNET_ARM_disconnect (arm);
- arm = NULL;
- }
- GNUNET_FS_GTK_close_uri_tab_ ();
- if (NULL != ml)
- {
- GNUNET_GTK_main_loop_quit (ml);
- ml = NULL;
- }
- if (NULL != main_context.id_op)
- {
- GNUNET_IDENTITY_ego_lookup_cancel (main_context.id_op);
- main_context.id_op = NULL;
+ GNUNET_IDENTITY_cancel (iop);
+ iop = NULL;
}
if (NULL != main_context.identity)
{
GNUNET_IDENTITY_disconnect (main_context.identity);
main_context.identity = NULL;
}
- while (NULL != (sl = main_context.sl_head))
- abort_search_lookup (sl);
- while (NULL != (lctx = main_context.lctx_head))
- abort_pseu_lookup (lctx);
if (NULL != main_context.zm)
{
GNUNET_NAMESTORE_zone_monitor_stop (main_context.zm);
@@ -301,6 +351,22 @@ shutdown_task (void *cls)
GNUNET_GNS_disconnect (main_context.gns);
main_context.gns = NULL;
}
+ if (NULL != armon)
+ {
+ GNUNET_ARM_monitor_stop (armon);
+ armon = NULL;
+ }
+ if (NULL != arm)
+ {
+ GNUNET_ARM_disconnect (arm);
+ arm = NULL;
+ }
+ GNUNET_FS_GTK_close_uri_tab_ ();
+ if (NULL != ml)
+ {
+ GNUNET_GTK_main_loop_quit (ml);
+ ml = NULL;
+ }
}
@@ -664,6 +730,11 @@ handle_sks_zone_identity (void *cls,
"main_window_search_namespace_label")));
gtk_widget_show (GTK_WIDGET (GNUNET_FS_GTK_get_main_window_object (
"main_window_search_namespace_combobox")));
+ if (NULL != main_context.zm)
+ {
+ GNUNET_NAMESTORE_zone_monitor_stop(main_context.zm);
+ main_context.zm = NULL;
+ }
main_context.zm =
GNUNET_NAMESTORE_zone_monitor_start (main_context.cfg,
GNUNET_IDENTITY_ego_get_private_key (
@@ -679,9 +750,57 @@ handle_sks_zone_identity (void *cls,
/**
- * We must pass a non-NULL callback to the identity service,
- * but we don't actually care about the information here
- * (we will use GNUNET_IDENTITY_get() if and when we do care).
+ * The user selected another identity in the combobox. Load it.
+ *
+ * @param widget the combo box where the selection was changed
+ * @param user_data the builder, unused
+ */
+void
+gnunet_fs_gtk_id_combobox_changed_cb (GtkComboBox *widget,
+ gpointer user_data)
+{
+ GtkTreeIter iter;
+ struct GNUNET_IDENTITY_Ego *ego;
+ char *name;
+
+ (void) user_data;
+ if (! gtk_combo_box_get_active_iter (id_combo_box, &iter))
+ {
+ return;
+ }
+ id_iter = iter;
+ /* clang-format off */
+ gtk_tree_model_get (GTK_TREE_MODEL (id_liststore),
+ &iter,
+ ID_LS_NAME, &name,
+ ID_LS_EGO, &ego,
+ -1);
+ /* clang-format on */
+ handle_sks_zone_identity (name, ego);
+}
+
+/**
+ * Method called to inform about the egos of this peer. Updates the
+ * `zone_liststore`.
+ *
+ * When used with #GNUNET_IDENTITY_connect, this function is
+ * initially called for all egos and then again whenever a
+ * ego's name changes or if it is deleted. At the end of
+ * the initial pass over all egos, the function is once called
+ * with 'NULL' for @a ego. That does NOT mean that the callback won't
+ * be invoked in the future or that there was an error.
+ *
+ * If @a ego is non-NULL and if '*ctx' is set in those callbacks, the
+ * value WILL be passed to a subsequent call to the identity callback
+ * of #GNUNET_IDENTITY_connect (if that one was not NULL).
+ *
+ * When an identity is renamed, this function is called with the
+ * (known) @a ego but the NEW @a name.
+ *
+ * When an identity is deleted, this function is called with the
+ * (known) ego and "NULL" for the @a name. In this case,
+ * the @a ego is henceforth invalid (and the @a ctx should also be
+ * cleaned up).
*
* @param cls closure
* @param ego ego handle
@@ -692,17 +811,70 @@ handle_sks_zone_identity (void *cls,
* must thus no longer be used
*/
static void
-non_null_cb (void *cls,
+identity_cb (void *cls,
struct GNUNET_IDENTITY_Ego *ego,
void **ctx,
const char *name)
{
- (void) cls;
- (void) ego;
- (void) ctx;
- (void) name;
-}
+ GtkTreeRowReference *rr;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+
+ if (in_shutdown)
+ return;
+ if ((NULL == ego) && (NULL == name) && (NULL == ctx))
+ {
+ /* end of initial iteration, trigger loading selected zone */
+ gnunet_fs_gtk_id_combobox_changed_cb (id_combo_box, ml);
+ return;
+ }
+ rr = *ctx;
+ if (NULL == rr)
+ {
+ /* clang-format off */
+ gtk_list_store_insert_with_values (id_liststore,
+ &iter, 0,
+ ID_LS_NAME, name,
+ ID_LS_EGO, ego,
+ -1);
+ /* clang-format on */
+ gtk_combo_box_set_active_iter (id_combo_box, &iter);
+ gtk_widget_set_sensitive (GTK_WIDGET (id_combo_box), TRUE);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (id_liststore), &iter);
+ rr = gtk_tree_row_reference_new (GTK_TREE_MODEL (id_liststore), path);
+ *ctx = rr;
+ gtk_tree_path_free (path);
+ return;
+ }
+ path = gtk_tree_row_reference_get_path (rr);
+ GNUNET_break (
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (id_liststore), &iter, path));
+ gtk_tree_path_free (path);
+ if (NULL == name)
+ {
+ GtkTreeIter act_iter;
+ /* identity was removed, remove from list */
+ gtk_list_store_remove (id_liststore, &iter);
+ if (! gtk_combo_box_get_active_iter (id_combo_box, &act_iter))
+ {
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (id_liststore),
+ &act_iter))
+ {
+ /* make sure combo box remains selected if possible */
+ gtk_combo_box_set_active (id_combo_box, 0);
+ }
+ else
+ {
+ /* make combo box insensitive if nothing can be selected */
+ gtk_widget_set_sensitive (GTK_WIDGET (id_combo_box), FALSE);
+ }
+ }
+ return;
+ }
+ /* identity was renamed, rename in model */
+ gtk_list_store_set (id_liststore, &iter, ID_LS_NAME, name, -1);
+}
/**
* Actual main function run right after GNUnet's scheduler
@@ -720,7 +892,6 @@ run (void *cls)
unsigned long long window_width;
unsigned long long window_height;
int maximized;
- char *default_ego_name;
ml = cls;
/* setup main context */
@@ -789,6 +960,11 @@ run (void *cls)
GTK_IMAGE (GNUNET_FS_GTK_get_main_window_object (
"GNUNET_FS_GTK_main_window_connection_indicator"));
+ status_label = GTK_LABEL (get_object (
+ "gnunet_fs_gtk_status_label"));
+ id_combo_box =
+ GTK_COMBO_BOX (get_object ("gnunet_fs_gtk_id_combobox"));
+ id_liststore = GTK_LIST_STORE (get_object ("id_liststore"));
GNUNET_GTK_set_icon_search_path ();
GNUNET_GTK_setup_nls ();
@@ -856,17 +1032,6 @@ run (void *cls)
"MAX_PARALLEL_REQUESTS",
&req_parallel))
req_parallel = DEFAULT_MAX_PARALLEL_REQUESTS;
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (main_context.cfg,
- "fs-sks",
- "DEFAULT_IDENTITY",
- &default_ego_name))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Please set DEFAULT_IDENTITY under [fs-sks]\n");
- GNUNET_GTK_main_loop_quit (cls);
- return;
- }
/* initialize file-sharing */
fs = GNUNET_FS_start (main_context.cfg,
"gnunet-fs-gtk",
@@ -890,13 +1055,8 @@ run (void *cls)
&service_status_change,
&main_context);
main_context.gns = GNUNET_GNS_connect (main_context.cfg);
- main_context.identity =
- GNUNET_IDENTITY_connect (main_context.cfg, &non_null_cb, NULL);
- main_context.id_op = GNUNET_IDENTITY_ego_lookup (main_context.cfg,
- default_ego_name,
- &handle_sks_zone_identity,
- NULL);
- GNUNET_free (default_ego_name);
+ main_context.identity = GNUNET_IDENTITY_connect (main_context.cfg,
+ &identity_cb, NULL);
#if HAVE_LIBUNIQUE
unique_app_watch_window (unique_app, GTK_WINDOW (main_context.main_window));
g_signal_connect (unique_app,