diff options
Diffstat (limited to 'src/identity/gnunet-identity-gtk_ego_organizer.c')
-rw-r--r-- | src/identity/gnunet-identity-gtk_ego_organizer.c | 781 |
1 files changed, 781 insertions, 0 deletions
diff --git a/src/identity/gnunet-identity-gtk_ego_organizer.c b/src/identity/gnunet-identity-gtk_ego_organizer.c new file mode 100644 index 00000000..2cf7db65 --- /dev/null +++ b/src/identity/gnunet-identity-gtk_ego_organizer.c | |||
@@ -0,0 +1,781 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2005, 2006, 2010, 2012 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file src/fs/gnunet-fs-gtk_namespace_organizer.c | ||
23 | * @author LRN | ||
24 | */ | ||
25 | #include "gnunet-fs-gtk_common.h" | ||
26 | #include "gnunet-fs-gtk.h" | ||
27 | #include "gnunet-fs-gtk_advertise-pseudonym.h" | ||
28 | #include <gnunet/gnunet_util_lib.h> | ||
29 | #include <gnunet/gnunet_fs_service.h> | ||
30 | |||
31 | struct GNUNET_GTK_NamespaceSelectorContext | ||
32 | { | ||
33 | GtkBuilder *builder; | ||
34 | GtkWidget *my_ns; | ||
35 | GtkTreeSelection *my_ns_sel; | ||
36 | GtkListStore *my_ns_store; | ||
37 | GtkWindow *namespace_organizer; | ||
38 | GtkWidget *create_button; | ||
39 | GtkWidget *delete_button; | ||
40 | GtkWidget *advertise_button; | ||
41 | GtkWidget *do_delete_button; | ||
42 | GtkWidget *do_keep_button; | ||
43 | GtkWidget *progress_spinner; | ||
44 | GtkWidget *progress_label; | ||
45 | GtkWidget *confirmation_label; | ||
46 | char *default_ns; | ||
47 | GtkTreeRowReference *default_ns_rref; | ||
48 | struct GNUNET_GTK_MainWindowContext *main_ctx; | ||
49 | }; | ||
50 | |||
51 | #define GNUNET_GTK_MY_NAMESPACES_NAME_COLUMN 0 | ||
52 | #define GNUNET_GTK_MY_NAMESPACES_KEY_COLUMN 1 | ||
53 | #define GNUNET_GTK_MY_NAMESPACES_KEY_BINARY_COLUMN 2 | ||
54 | #define GNUNET_GTK_MY_NAMESPACES_USE_THIS_COLUMN 3 | ||
55 | #define GNUNET_GTK_MY_NAMESPACES_ACTUAL_NAME_COLUMN 4 | ||
56 | |||
57 | /** | ||
58 | * User edited the name of a namespace. | ||
59 | * Rename the namespace. | ||
60 | * | ||
61 | * @param renderer cell renderer | ||
62 | * @param path path to the cell that was edited (as a string) | ||
63 | * @param new_text new contents of the cell | ||
64 | * @param user_data context | ||
65 | */ | ||
66 | void | ||
67 | GNUNET_GTK_namespace_organizer_namespaces_treeview_column_name_text_edited_cb ( | ||
68 | GtkCellRendererText *renderer, gchar *path, gchar *new_text, | ||
69 | gpointer user_data) | ||
70 | { | ||
71 | struct GNUNET_GTK_NamespaceSelectorContext *ctx = user_data; | ||
72 | GtkTreePath *tree_path; | ||
73 | GtkTreeIter iter; | ||
74 | |||
75 | if (strlen (new_text) == 0) | ||
76 | return; | ||
77 | |||
78 | tree_path = gtk_tree_path_new_from_string (path); | ||
79 | if (tree_path != NULL) | ||
80 | { | ||
81 | if (gtk_tree_model_get_iter (GTK_TREE_MODEL (ctx->my_ns_store), | ||
82 | &iter, tree_path)) | ||
83 | { | ||
84 | struct GNUNET_FS_PseudonymIdentifier *nsid; | ||
85 | char *old_name; | ||
86 | gtk_tree_model_get (GTK_TREE_MODEL (ctx->my_ns_store), &iter, | ||
87 | GNUNET_GTK_MY_NAMESPACES_NAME_COLUMN, &old_name, | ||
88 | GNUNET_GTK_MY_NAMESPACES_KEY_BINARY_COLUMN, &nsid, | ||
89 | -1); | ||
90 | |||
91 | if ((NULL == nsid) || | ||
92 | (GNUNET_OK == GNUNET_FS_namespace_rename ( | ||
93 | GNUNET_FS_GTK_get_fs_handle (), old_name, new_text))) | ||
94 | { | ||
95 | gtk_list_store_set (ctx->my_ns_store, &iter, | ||
96 | GNUNET_GTK_MY_NAMESPACES_NAME_COLUMN, new_text, -1); | ||
97 | } | ||
98 | |||
99 | GNUNET_free (old_name); | ||
100 | } | ||
101 | gtk_tree_path_free (tree_path); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | /** | ||
106 | * Frees contents of the namespace list (the nsid values that are stored as | ||
107 | * untyped pointers in the tree). | ||
108 | * | ||
109 | * @param ctx NS organizer context | ||
110 | */ | ||
111 | static void | ||
112 | free_lists_contents (struct GNUNET_GTK_NamespaceSelectorContext *ctx) | ||
113 | { | ||
114 | GtkTreeIter iter; | ||
115 | gint i; | ||
116 | gint row_count; | ||
117 | struct GNUNET_FS_PseudonymIdentifier *nsid; | ||
118 | |||
119 | row_count = gtk_tree_model_iter_n_children (GTK_TREE_MODEL ( | ||
120 | ctx->my_ns_store), NULL); | ||
121 | if (! gtk_tree_model_get_iter_first (GTK_TREE_MODEL ( | ||
122 | ctx->my_ns_store), &iter)) | ||
123 | return; | ||
124 | |||
125 | for (i = 0; i < row_count; i++) | ||
126 | { | ||
127 | gtk_tree_model_get (GTK_TREE_MODEL (ctx->my_ns_store), &iter, | ||
128 | GNUNET_GTK_MY_NAMESPACES_KEY_BINARY_COLUMN, &nsid, | ||
129 | -1); | ||
130 | GNUNET_free (nsid); | ||
131 | if (TRUE != gtk_tree_model_iter_next (GTK_TREE_MODEL ( | ||
132 | ctx->my_ns_store), &iter)) | ||
133 | break; | ||
134 | } | ||
135 | |||
136 | gtk_list_store_clear (ctx->my_ns_store); | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * Called when dialog is being closed (for any reason). | ||
141 | * | ||
142 | * @param dialog dialog being closed | ||
143 | * @param response_id identifies the event | ||
144 | * @param user_data context | ||
145 | */ | ||
146 | void | ||
147 | GNUNET_GTK_namespace_organizer_dialog_response_cb (GtkDialog *dialog, | ||
148 | gint response_id, gpointer user_data) | ||
149 | { | ||
150 | struct GNUNET_GTK_NamespaceSelectorContext *ctx = user_data; | ||
151 | switch (response_id) | ||
152 | { | ||
153 | case GTK_RESPONSE_CLOSE: | ||
154 | default: | ||
155 | free_lists_contents (ctx); | ||
156 | gtk_widget_destroy (GTK_WIDGET (ctx->namespace_organizer)); | ||
157 | GNUNET_free (ctx); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * Store a reference to the default namespace for later use. | ||
163 | * | ||
164 | * @param ctx context | ||
165 | * @param iter points to the default namespace in the list | ||
166 | */ | ||
167 | static void | ||
168 | save_default_ns_reference (struct GNUNET_GTK_NamespaceSelectorContext *ctx, GtkTreeIter *iter) | ||
169 | { | ||
170 | GtkTreeRowReference *ref; | ||
171 | GtkTreePath *rowpath; | ||
172 | |||
173 | rowpath = gtk_tree_model_get_path (GTK_TREE_MODEL (ctx->my_ns_store), iter); | ||
174 | if (rowpath) | ||
175 | { | ||
176 | ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (ctx->my_ns_store), rowpath); | ||
177 | if (ref) | ||
178 | { | ||
179 | gtk_tree_row_reference_free (ctx->default_ns_rref); | ||
180 | ctx->default_ns_rref = ref; | ||
181 | } | ||
182 | gtk_tree_path_free (rowpath); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | |||
187 | /** | ||
188 | * Try to mark an item in the list as the default namespace. | ||
189 | * | ||
190 | * @param ctx context | ||
191 | * @param iter points to the new default namespace in the list | ||
192 | */ | ||
193 | static void | ||
194 | try_make_default (struct GNUNET_GTK_NamespaceSelectorContext *ctx, GtkTreeIter *toggled) | ||
195 | { | ||
196 | GtkTreeIter iter; | ||
197 | gchar *new_default_ns; | ||
198 | gint i; | ||
199 | gint row_count; | ||
200 | GtkTreePath *path; | ||
201 | |||
202 | row_count = gtk_tree_model_iter_n_children ( | ||
203 | GTK_TREE_MODEL (ctx->my_ns_store), NULL); | ||
204 | if (! gtk_tree_model_get_iter_first ( | ||
205 | GTK_TREE_MODEL (ctx->my_ns_store), &iter)) | ||
206 | return; | ||
207 | |||
208 | path = gtk_tree_row_reference_get_path (ctx->default_ns_rref); | ||
209 | if (path) | ||
210 | { | ||
211 | /* We know where previous default was, only untoggle that item */ | ||
212 | GtkTreeIter old_default; | ||
213 | if (gtk_tree_model_get_iter (GTK_TREE_MODEL (ctx->my_ns_store), &old_default, path)) | ||
214 | { | ||
215 | gtk_list_store_set (ctx->my_ns_store, &old_default, | ||
216 | GNUNET_GTK_MY_NAMESPACES_USE_THIS_COLUMN, FALSE, | ||
217 | -1); | ||
218 | } | ||
219 | gtk_tree_path_free (path); | ||
220 | } | ||
221 | else | ||
222 | { | ||
223 | /* Just untoggle all items */ | ||
224 | for (i = 0; i < row_count; i++) | ||
225 | { | ||
226 | gtk_list_store_set (ctx->my_ns_store, &iter, | ||
227 | GNUNET_GTK_MY_NAMESPACES_USE_THIS_COLUMN, FALSE, | ||
228 | -1); | ||
229 | if (TRUE != gtk_tree_model_iter_next ( | ||
230 | GTK_TREE_MODEL (ctx->my_ns_store), &iter)) | ||
231 | break; | ||
232 | } | ||
233 | } | ||
234 | |||
235 | gtk_list_store_set (ctx->my_ns_store, toggled, | ||
236 | GNUNET_GTK_MY_NAMESPACES_USE_THIS_COLUMN, TRUE, -1); | ||
237 | gtk_tree_model_get (GTK_TREE_MODEL (ctx->my_ns_store), toggled, | ||
238 | GNUNET_GTK_MY_NAMESPACES_NAME_COLUMN, &new_default_ns, -1); | ||
239 | |||
240 | save_default_ns_reference (ctx, toggled); | ||
241 | |||
242 | if (new_default_ns) | ||
243 | { | ||
244 | ctx->default_ns = GNUNET_strdup (new_default_ns); | ||
245 | GNUNET_CONFIGURATION_set_value_string ( | ||
246 | (struct GNUNET_CONFIGURATION_Handle *) GNUNET_FS_GTK_get_configuration (), | ||
247 | "gnunet-fs-gtk", "DEFAULT_NAMESPACE", ctx->default_ns); | ||
248 | |||
249 | g_free (new_default_ns); | ||
250 | } | ||
251 | } | ||
252 | |||
253 | |||
254 | |||
255 | /** | ||
256 | * Callback with information about local (!) namespaces. | ||
257 | * Contains the names of the local namespace and the global | ||
258 | * ID. | ||
259 | * | ||
260 | * @param cls closure | ||
261 | * @param name human-readable identifier of the namespace | ||
262 | * @param id hash identifier for the namespace | ||
263 | */ | ||
264 | static void | ||
265 | populate_my_ns_list (void *cls, const char *name, | ||
266 | const struct GNUNET_FS_PseudonymIdentifier *id) | ||
267 | { | ||
268 | struct GNUNET_GTK_NamespaceSelectorContext *ctx = cls; | ||
269 | |||
270 | char buf[1024]; | ||
271 | char *ret; | ||
272 | GtkTreeIter my_iter; | ||
273 | struct GNUNET_FS_PseudonymIdentifier *nsid; | ||
274 | gboolean is_default; | ||
275 | |||
276 | nsid = GNUNET_malloc (sizeof (struct GNUNET_FS_PseudonymIdentifier)); | ||
277 | *nsid = *id; | ||
278 | |||
279 | ret = GNUNET_STRINGS_data_to_string (nsid, | ||
280 | sizeof (struct GNUNET_FS_PseudonymIdentifier), buf, sizeof (buf)); | ||
281 | GNUNET_assert (NULL != ret); | ||
282 | ret[0] = '\0'; | ||
283 | |||
284 | if (NULL == ctx->default_ns) | ||
285 | { | ||
286 | ctx->default_ns = GNUNET_strdup (name); | ||
287 | GNUNET_CONFIGURATION_set_value_string ( | ||
288 | (struct GNUNET_CONFIGURATION_Handle *) GNUNET_FS_GTK_get_configuration (), | ||
289 | "gnunet-fs-gtk", "DEFAULT_NAMESPACE", ctx->default_ns); | ||
290 | is_default = TRUE; | ||
291 | } | ||
292 | else | ||
293 | is_default = (0 == strcmp (name, ctx->default_ns)) ? TRUE : FALSE; | ||
294 | |||
295 | gtk_list_store_insert_with_values (ctx->my_ns_store, &my_iter, G_MAXINT, | ||
296 | GNUNET_GTK_MY_NAMESPACES_NAME_COLUMN, name, | ||
297 | GNUNET_GTK_MY_NAMESPACES_KEY_COLUMN, buf, | ||
298 | GNUNET_GTK_MY_NAMESPACES_KEY_BINARY_COLUMN, nsid, | ||
299 | GNUNET_GTK_MY_NAMESPACES_USE_THIS_COLUMN, is_default, | ||
300 | GNUNET_GTK_MY_NAMESPACES_ACTUAL_NAME_COLUMN, NULL, | ||
301 | -1); | ||
302 | |||
303 | if (is_default) | ||
304 | save_default_ns_reference (ctx, &my_iter); | ||
305 | } | ||
306 | |||
307 | /** | ||
308 | * Returns button visibility/sensitivity to normal. | ||
309 | * | ||
310 | * @param ctx context | ||
311 | * @param anything_selected TRUE if a namespace is selected in the list, | ||
312 | * FALSE otherwise | ||
313 | */ | ||
314 | static void | ||
315 | set_normal_state (struct GNUNET_GTK_NamespaceSelectorContext *ctx, gboolean anything_selected) | ||
316 | { | ||
317 | gtk_widget_set_visible (ctx->do_delete_button, FALSE); | ||
318 | gtk_widget_set_visible (ctx->do_keep_button, FALSE); | ||
319 | gtk_widget_set_visible (ctx->confirmation_label, FALSE); | ||
320 | |||
321 | gtk_widget_set_sensitive (ctx->advertise_button, anything_selected); | ||
322 | gtk_widget_set_sensitive (ctx->delete_button, anything_selected); | ||
323 | gtk_widget_set_sensitive (ctx->create_button, TRUE); | ||
324 | } | ||
325 | |||
326 | /** | ||
327 | * Handles ns list selection changes. | ||
328 | * | ||
329 | * @param treeselection selection object | ||
330 | * @param user_data context | ||
331 | */ | ||
332 | static void | ||
333 | my_ns_selection_changed (GtkTreeSelection *treeselection, | ||
334 | gpointer user_data) | ||
335 | { | ||
336 | struct GNUNET_GTK_NamespaceSelectorContext *ctx = user_data; | ||
337 | GtkTreeIter iter; | ||
338 | struct GNUNET_FS_PseudonymIdentifier *nsid; | ||
339 | gboolean selected; | ||
340 | |||
341 | nsid = NULL; | ||
342 | selected = gtk_tree_selection_get_selected (ctx->my_ns_sel, NULL, &iter); | ||
343 | if (selected) | ||
344 | gtk_tree_model_get (GTK_TREE_MODEL (ctx->my_ns_store), &iter, | ||
345 | GNUNET_GTK_MY_NAMESPACES_KEY_BINARY_COLUMN, &nsid, -1); | ||
346 | if (NULL == nsid) | ||
347 | selected = FALSE; | ||
348 | set_normal_state (ctx, selected); | ||
349 | } | ||
350 | |||
351 | /** | ||
352 | * Opens the organizer dialog. Called from outside (by the main window). | ||
353 | * | ||
354 | * @param main_ctx context of the main window | ||
355 | * @return newly-created dialog window object | ||
356 | */ | ||
357 | GtkWindow * | ||
358 | GNUNET_GTK_namespace_organizer_open (struct GNUNET_GTK_MainWindowContext *main_ctx) | ||
359 | { | ||
360 | struct GNUNET_GTK_NamespaceSelectorContext *ctx; | ||
361 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
362 | |||
363 | ctx = GNUNET_malloc (sizeof (struct GNUNET_GTK_NamespaceSelectorContext)); | ||
364 | ctx->builder = GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_namespace_organizer.glade", ctx); | ||
365 | if (ctx->builder == NULL) | ||
366 | { | ||
367 | GNUNET_break (0); | ||
368 | GNUNET_free (ctx); | ||
369 | return NULL; | ||
370 | } | ||
371 | |||
372 | ctx->main_ctx = main_ctx; | ||
373 | |||
374 | /* initialize widget references */ | ||
375 | ctx->my_ns = GTK_WIDGET (gtk_builder_get_object (ctx->builder, | ||
376 | "GNUNET_GTK_namespace_organizer_namespaces_treeview")); | ||
377 | ctx->my_ns_sel = gtk_tree_view_get_selection (GTK_TREE_VIEW ( | ||
378 | ctx->my_ns)); | ||
379 | ctx->my_ns_store = GTK_LIST_STORE (gtk_tree_view_get_model ( | ||
380 | GTK_TREE_VIEW (ctx->my_ns))); | ||
381 | ctx->namespace_organizer = GTK_WINDOW (gtk_builder_get_object ( | ||
382 | ctx->builder, "GNUNET_GTK_namespace_organizer_dialog")); | ||
383 | ctx->create_button = GTK_WIDGET (gtk_builder_get_object (ctx->builder, | ||
384 | "GNUNET_GTK_namespace_organizer_namespaces_create_namespace_button")); | ||
385 | ctx->advertise_button = GTK_WIDGET (gtk_builder_get_object (ctx->builder, | ||
386 | "GNUNET_GTK_namespace_organizer_namespaces_advertise_namespace_button")); | ||
387 | ctx->delete_button = GTK_WIDGET (gtk_builder_get_object (ctx->builder, | ||
388 | "GNUNET_GTK_namespace_organizer_namespaces_delete_namespace_button")); | ||
389 | ctx->do_delete_button = GTK_WIDGET (gtk_builder_get_object (ctx->builder, | ||
390 | "GNUNET_GTK_namespace_organizer_namespaces_delete_namespace_confirmation_button")); | ||
391 | ctx->do_keep_button = GTK_WIDGET (gtk_builder_get_object (ctx->builder, | ||
392 | "GNUNET_GTK_namespace_organizer_namespaces_delete_namespace_unconfirmation_button")); | ||
393 | ctx->progress_spinner = GTK_WIDGET (gtk_builder_get_object (ctx->builder, | ||
394 | "GNUNET_GTK_namespace_organizer_namespaces_create_namespace_progress_spinner")); | ||
395 | ctx->progress_label = GTK_WIDGET (gtk_builder_get_object (ctx->builder, | ||
396 | "GNUNET_GTK_namespace_organizer_namespaces_create_namespace_progress_label")); | ||
397 | ctx->confirmation_label = GTK_WIDGET (gtk_builder_get_object (ctx->builder, | ||
398 | "GNUNET_GTK_namespace_organizer_namespaces_delete_namespace_confirmation_label")); | ||
399 | |||
400 | /* connect signals; FIXME-GTK3: these could be connected with (modern) Glade */ | ||
401 | g_signal_connect (G_OBJECT (ctx->my_ns_sel), "changed", | ||
402 | G_CALLBACK (my_ns_selection_changed), ctx); | ||
403 | |||
404 | cfg = GNUNET_FS_GTK_get_configuration (); | ||
405 | |||
406 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, | ||
407 | "gnunet-fs-gtk", "DEFAULT_NAMESPACE", &ctx->default_ns)) | ||
408 | ctx->default_ns = NULL; | ||
409 | |||
410 | gtk_widget_set_sensitive (ctx->advertise_button, FALSE); | ||
411 | gtk_widget_set_sensitive (ctx->delete_button, FALSE); | ||
412 | |||
413 | gtk_widget_set_visible (ctx->do_delete_button, FALSE); | ||
414 | gtk_widget_set_visible (ctx->do_keep_button, FALSE); | ||
415 | gtk_widget_set_visible (ctx->progress_spinner, FALSE); | ||
416 | gtk_widget_set_visible (ctx->progress_label, FALSE); | ||
417 | gtk_widget_set_visible (ctx->confirmation_label, FALSE); | ||
418 | |||
419 | /* populate namespace model */ | ||
420 | GNUNET_FS_namespace_list (GNUNET_FS_GTK_get_fs_handle (), | ||
421 | populate_my_ns_list, ctx); | ||
422 | |||
423 | /* show dialog */ | ||
424 | gtk_window_present (ctx->namespace_organizer); | ||
425 | return ctx->namespace_organizer; | ||
426 | } | ||
427 | |||
428 | /** | ||
429 | * Called when the organizer dialog is destoryed | ||
430 | * (happens at some point after it's closed). | ||
431 | * Cleans up references to the organizer dialog that main window stores. | ||
432 | * | ||
433 | * @param object the object that is being destroyed | ||
434 | * @param user_data main window context | ||
435 | */ | ||
436 | void | ||
437 | GNUNET_GTK_namespace_organizer_dialog_destroy_cb (GtkWindow *object, gpointer user_data) | ||
438 | { | ||
439 | struct GNUNET_GTK_MainWindowContext *ctx = user_data; | ||
440 | g_signal_handler_disconnect (object, ctx->ns_organizer_delete_handler_id); | ||
441 | g_object_unref (G_OBJECT (ctx->ns_organizer)); | ||
442 | ctx->ns_organizer = NULL; | ||
443 | ctx->ns_organizer_delete_handler_id = 0; | ||
444 | return; | ||
445 | } | ||
446 | |||
447 | /** | ||
448 | * Wrapper for GNUNET_GTK_namespace_organizer_open(), ensures that | ||
449 | * only one instance is opened. | ||
450 | * @param ctx main window context | ||
451 | */ | ||
452 | void | ||
453 | GNUNET_GTK_open_ns_organizer (struct GNUNET_GTK_MainWindowContext *ctx) | ||
454 | { | ||
455 | if (ctx->ns_organizer != NULL) | ||
456 | { | ||
457 | gtk_window_present (ctx->ns_organizer); | ||
458 | return; | ||
459 | } | ||
460 | |||
461 | ctx->ns_organizer = GNUNET_GTK_namespace_organizer_open (ctx); | ||
462 | if (ctx->ns_organizer == NULL) | ||
463 | return; | ||
464 | |||
465 | g_object_ref (G_OBJECT (ctx->ns_organizer)); | ||
466 | ctx->ns_organizer_delete_handler_id = g_signal_connect (G_OBJECT (ctx->ns_organizer), "destroy", G_CALLBACK (GNUNET_GTK_namespace_organizer_dialog_destroy_cb), ctx); | ||
467 | } | ||
468 | |||
469 | /** | ||
470 | * Called when user clicks at 'Advertise namespace' button. | ||
471 | * Opens the advertising dialog (calls GNUNET_FS_GTK_advertise_namespace()). | ||
472 | * | ||
473 | * @param button button that was clicked | ||
474 | * @param user_data context | ||
475 | */ | ||
476 | void | ||
477 | GNUNET_GTK_namespace_organizer_namespaces_advertise_namespace_button_clicked_cb ( | ||
478 | GtkButton *button, gpointer user_data) | ||
479 | { | ||
480 | struct GNUNET_GTK_NamespaceSelectorContext *ctx = user_data; | ||
481 | GtkTreeIter iter; | ||
482 | gchar *name; | ||
483 | struct GNUNET_FS_PseudonymIdentifier *nsid; | ||
484 | |||
485 | nsid = NULL; | ||
486 | name = NULL; | ||
487 | if (gtk_tree_selection_get_selected (ctx->my_ns_sel, NULL, &iter)) | ||
488 | gtk_tree_model_get (GTK_TREE_MODEL (ctx->my_ns_store), &iter, | ||
489 | GNUNET_GTK_MY_NAMESPACES_NAME_COLUMN, &name, | ||
490 | GNUNET_GTK_MY_NAMESPACES_KEY_BINARY_COLUMN, &nsid, | ||
491 | -1); | ||
492 | if (NULL != nsid) | ||
493 | { | ||
494 | struct GNUNET_FS_Namespace *ns; | ||
495 | ns = GNUNET_FS_namespace_open_existing (GNUNET_FS_GTK_get_fs_handle (), name); | ||
496 | if (ns) | ||
497 | GNUNET_FS_GTK_advertise_namespace (ns, ctx->namespace_organizer); | ||
498 | } | ||
499 | g_free (name); | ||
500 | } | ||
501 | |||
502 | /** | ||
503 | * Called when user clicks at 'Do not delete' button. | ||
504 | * Returns the state back to normal (hides [un]confirmation buttons | ||
505 | * and the warning label). | ||
506 | * | ||
507 | * @param button button that was clicked | ||
508 | * @param user_data context | ||
509 | */ | ||
510 | void | ||
511 | GNUNET_GTK_namespace_organizer_namespaces_delete_namespace_unconfirmation_button_clicked_cb ( | ||
512 | GtkButton *button, gpointer user_data) | ||
513 | { | ||
514 | set_normal_state (user_data, TRUE); | ||
515 | } | ||
516 | |||
517 | |||
518 | /** | ||
519 | * Called when user clicks at 'Do delete' button. | ||
520 | * Deletes selected namespace after double-checking that everything is | ||
521 | * in order. | ||
522 | * Returns the state back to normal (hides [un]confirmation buttons | ||
523 | * and the warning label). | ||
524 | * | ||
525 | * @param button button that was clicked | ||
526 | * @param user_data context | ||
527 | */ | ||
528 | void | ||
529 | GNUNET_GTK_namespace_organizer_namespaces_delete_namespace_confirmation_button_clicked_cb ( | ||
530 | GtkButton *button, gpointer user_data) | ||
531 | { | ||
532 | struct GNUNET_GTK_NamespaceSelectorContext *ctx = user_data; | ||
533 | GtkTreeIter iter; | ||
534 | gchar *name; | ||
535 | gboolean selected; | ||
536 | struct GNUNET_FS_PseudonymIdentifier id; | ||
537 | struct GNUNET_FS_PseudonymIdentifier *nsid; | ||
538 | |||
539 | nsid = NULL; | ||
540 | name = NULL; | ||
541 | selected = gtk_tree_selection_get_selected (ctx->my_ns_sel, NULL, &iter); | ||
542 | if (selected) | ||
543 | gtk_tree_model_get (GTK_TREE_MODEL (ctx->my_ns_store), &iter, | ||
544 | GNUNET_GTK_MY_NAMESPACES_NAME_COLUMN, &name, | ||
545 | GNUNET_GTK_MY_NAMESPACES_KEY_BINARY_COLUMN, &nsid, | ||
546 | -1); | ||
547 | if (NULL == nsid) | ||
548 | selected = FALSE; | ||
549 | |||
550 | if (selected) | ||
551 | { | ||
552 | struct GNUNET_FS_Namespace *ns; | ||
553 | ns = GNUNET_FS_namespace_open_existing (GNUNET_FS_GTK_get_fs_handle (), name); | ||
554 | if (ns) | ||
555 | { | ||
556 | if (GNUNET_FS_namespace_get_public_identifier (ns, &id)) | ||
557 | { | ||
558 | if (0 == memcmp (&id, nsid, sizeof (id))) | ||
559 | { | ||
560 | GtkTreeIter first; | ||
561 | |||
562 | GNUNET_free (nsid); | ||
563 | gtk_list_store_remove (ctx->my_ns_store, &iter); | ||
564 | GNUNET_FS_namespace_delete (ns, GNUNET_YES); | ||
565 | |||
566 | if (gtk_tree_model_get_iter_first ( | ||
567 | GTK_TREE_MODEL (ctx->my_ns_store), &first)) | ||
568 | try_make_default (ctx, &first); | ||
569 | } | ||
570 | else | ||
571 | { | ||
572 | /* We were trying to delete namespace FOO with key X | ||
573 | * but when we opened FOO, we discovered that its key is Y. | ||
574 | * Clearly this is not the right namespace (something changed | ||
575 | * the namespace list right under us?). | ||
576 | */ | ||
577 | /* TODO: display error message */ | ||
578 | GNUNET_FS_namespace_delete (ns, GNUNET_NO); | ||
579 | } | ||
580 | } | ||
581 | else | ||
582 | { | ||
583 | /* We were trying to delete namespace FOO, | ||
584 | * but we can't even get its key | ||
585 | */ | ||
586 | /* TODO: display error message */ | ||
587 | GNUNET_FS_namespace_delete (ns, GNUNET_NO); | ||
588 | } | ||
589 | } | ||
590 | } | ||
591 | g_free (name); | ||
592 | set_normal_state (user_data, selected); | ||
593 | } | ||
594 | |||
595 | /** | ||
596 | * Called when user clicks at 'Delete' button. | ||
597 | * Shows the [un]confirmation buttons, as well as the warning. | ||
598 | * | ||
599 | * @param button button that was clicked | ||
600 | * @param user_data context | ||
601 | */ | ||
602 | void | ||
603 | GNUNET_GTK_namespace_organizer_namespaces_delete_namespace_button_clicked_cb ( | ||
604 | GtkButton *button, gpointer user_data) | ||
605 | { | ||
606 | struct GNUNET_GTK_NamespaceSelectorContext *ctx = user_data; | ||
607 | gtk_widget_set_visible (ctx->do_delete_button, TRUE); | ||
608 | gtk_widget_set_visible (ctx->do_keep_button, TRUE); | ||
609 | gtk_widget_set_visible (ctx->confirmation_label, TRUE); | ||
610 | gtk_widget_set_sensitive (ctx->advertise_button, FALSE); | ||
611 | gtk_widget_set_sensitive (ctx->delete_button, FALSE); | ||
612 | gtk_widget_set_sensitive (ctx->create_button, FALSE); | ||
613 | } | ||
614 | |||
615 | /** | ||
616 | * Generates a random ns name. | ||
617 | * | ||
618 | * @return new name (free with GNUNET_free()). | ||
619 | */ | ||
620 | char * | ||
621 | generate_local_ns_name () | ||
622 | { | ||
623 | const char *table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; | ||
624 | size_t tablelen = strlen (table); | ||
625 | char random_str[9]; | ||
626 | char *result; | ||
627 | int i; | ||
628 | for (i = 0; i < 8; i++) | ||
629 | { | ||
630 | uint32_t index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, tablelen); | ||
631 | GNUNET_assert (index < tablelen); | ||
632 | random_str[i] = table[index]; | ||
633 | } | ||
634 | random_str[8] = '\0'; | ||
635 | |||
636 | GNUNET_asprintf (&result, _("MyNamespace-%s"), random_str); | ||
637 | return result; | ||
638 | } | ||
639 | |||
640 | |||
641 | /** | ||
642 | * Called when key generation for a namespace is finished. | ||
643 | * | ||
644 | * @param cls context | ||
645 | * @param ns newly-created namespace (NULL on failure) | ||
646 | * @param emsg error message (NULL on success) | ||
647 | */ | ||
648 | static void | ||
649 | ns_created (void *cls, struct GNUNET_FS_Namespace *ns, char *name, const char *emsg) | ||
650 | { | ||
651 | struct GNUNET_GTK_NamespaceSelectorContext *ctx = cls; | ||
652 | |||
653 | GtkTreeIter iter; | ||
654 | struct GNUNET_FS_PseudonymIdentifier *nsid; | ||
655 | struct GNUNET_FS_PseudonymIdentifier id; | ||
656 | |||
657 | /* If ns was created, get its public key hash */ | ||
658 | nsid = NULL; | ||
659 | if ((NULL != ns) && (GNUNET_OK == GNUNET_FS_namespace_get_public_identifier (ns, &id))) | ||
660 | { | ||
661 | nsid = GNUNET_malloc (sizeof (struct GNUNET_FS_PseudonymIdentifier)); | ||
662 | memcpy (nsid, &id, sizeof (struct GNUNET_FS_PseudonymIdentifier)); | ||
663 | } | ||
664 | |||
665 | /* If anything of the above went wrong, or ns creation failed, we abort */ | ||
666 | if (NULL == nsid) | ||
667 | { | ||
668 | GNUNET_FS_namespace_delete (ns, GNUNET_NO); | ||
669 | } | ||
670 | else | ||
671 | { | ||
672 | char buf[1024]; | ||
673 | char *ret; | ||
674 | gint row_count; | ||
675 | |||
676 | ret = GNUNET_STRINGS_data_to_string (nsid, | ||
677 | sizeof (struct GNUNET_FS_PseudonymIdentifier), | ||
678 | buf, | ||
679 | sizeof (buf)); | ||
680 | GNUNET_assert (NULL != ret); | ||
681 | ret[0] = '\0'; | ||
682 | |||
683 | gtk_list_store_insert_with_values (ctx->my_ns_store, &iter, G_MAXINT, | ||
684 | GNUNET_GTK_MY_NAMESPACES_KEY_COLUMN, buf, | ||
685 | GNUNET_GTK_MY_NAMESPACES_KEY_BINARY_COLUMN, nsid, | ||
686 | GNUNET_GTK_MY_NAMESPACES_NAME_COLUMN, name, | ||
687 | -1); | ||
688 | |||
689 | row_count = gtk_tree_model_iter_n_children ( | ||
690 | GTK_TREE_MODEL (ctx->my_ns_store), NULL); | ||
691 | if (row_count == 1) | ||
692 | try_make_default (ctx, &iter); | ||
693 | } | ||
694 | } | ||
695 | |||
696 | |||
697 | /** | ||
698 | * Create a namespace. | ||
699 | * Adds a dummy to the list, starts the key generation process, | ||
700 | * shows the progress spinner, disables some buttons. | ||
701 | * | ||
702 | * @param ctx context | ||
703 | */ | ||
704 | static void | ||
705 | create_namespace (struct GNUNET_GTK_NamespaceSelectorContext *ctx) | ||
706 | { | ||
707 | gchar *name; | ||
708 | struct GNUNET_FS_Namespace *ns; | ||
709 | |||
710 | ns = NULL; | ||
711 | name = NULL; | ||
712 | do | ||
713 | { | ||
714 | if (ns) | ||
715 | GNUNET_FS_namespace_delete (ns, GNUNET_NO); | ||
716 | GNUNET_free_non_null (name); | ||
717 | name = generate_local_ns_name (); | ||
718 | ns = GNUNET_FS_namespace_open_existing (GNUNET_FS_GTK_get_fs_handle (), name); | ||
719 | } while (NULL != ns); | ||
720 | |||
721 | ns = GNUNET_FS_namespace_create (GNUNET_FS_GTK_get_fs_handle (), name); | ||
722 | |||
723 | if (NULL == ns) | ||
724 | { | ||
725 | GNUNET_free (name); | ||
726 | return; | ||
727 | } | ||
728 | |||
729 | ns_created (ctx, ns, name, NULL); | ||
730 | |||
731 | GNUNET_free (name); | ||
732 | } | ||
733 | |||
734 | /** | ||
735 | * Called when user clicks at 'Create' button. | ||
736 | * Creates a namespace. | ||
737 | * | ||
738 | * @param button button that was clicked | ||
739 | * @param user_data context | ||
740 | */ | ||
741 | void | ||
742 | GNUNET_GTK_namespace_organizer_namespaces_create_namespace_button_clicked_cb ( | ||
743 | GtkButton *button, gpointer user_data) | ||
744 | { | ||
745 | create_namespace (user_data); | ||
746 | } | ||
747 | |||
748 | /** | ||
749 | * Called when user toggles the radio button at a namespace in the list | ||
750 | * Tries to make that namespace the new default. | ||
751 | * | ||
752 | * @param cell_renderer renderer of the call that was toggled. | ||
753 | * @param path path to the cell that was toggled | ||
754 | * @param user_data context | ||
755 | */ | ||
756 | void | ||
757 | GNUNET_GTK_namespace_organizer_namespaces_treeview_column_usethis_toggle_toggled_cb ( | ||
758 | GtkCellRendererToggle *cell_renderer, gchar *path, gpointer user_data) | ||
759 | { | ||
760 | struct GNUNET_GTK_NamespaceSelectorContext *ctx = user_data; | ||
761 | GtkTreeIter iter; | ||
762 | if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (ctx->my_ns_store), | ||
763 | &iter, path)) | ||
764 | try_make_default (ctx, &iter); | ||
765 | } | ||
766 | |||
767 | /** | ||
768 | * Called when user activates the appropriate item in main window `File' menu. | ||
769 | * Opens Namespace organizer dialog. | ||
770 | * | ||
771 | * @param menuitem item that was activated | ||
772 | * @param user_data main window context | ||
773 | */ | ||
774 | void | ||
775 | GNUNET_GTK_main_menu_file_organize_namespaces_activate_cb (GtkMenuItem *menuitem, | ||
776 | gpointer user_data) | ||
777 | { | ||
778 | GNUNET_GTK_open_ns_organizer (user_data); | ||
779 | } | ||
780 | |||
781 | /* end of gnunet-fs-gtk_namespace_organizer.c */ | ||