aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-gns-gtk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/gnunet-gns-gtk.c')
-rw-r--r--src/gns/gnunet-gns-gtk.c616
1 files changed, 0 insertions, 616 deletions
diff --git a/src/gns/gnunet-gns-gtk.c b/src/gns/gnunet-gns-gtk.c
deleted file mode 100644
index 229e4b38..00000000
--- a/src/gns/gnunet-gns-gtk.c
+++ /dev/null
@@ -1,616 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 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/gns/gnunet-gns-gtk.c
23 * @brief Main function of gnunet-gns-gtk
24 * @author Christian Grothoff
25 */
26#include "gnunet_gtk.h"
27#include "gnunet-gns-gtk.h"
28#include <gnunet/gnunet_namestore_service.h>
29
30
31/**
32 * Columns in the gns model.
33 */
34enum GNS_ModelColumns
35 {
36 /**
37 * A gchararray
38 */
39 GNS_MC_NAME = 0,
40
41 /**
42 * A gboolean
43 */
44 GNS_MC_IS_PUBLIC = 1,
45
46 /**
47 * A guint
48 */
49 GNS_MC_RECORD_TYPE = 2,
50
51 /**
52 * A gchararray
53 */
54 GNS_MC_RECORD_TYPE_AS_STRING = 3,
55
56 /**
57 * A guint64
58 */
59 GNS_MC_EXPIRATION_TIME = 4,
60
61 /**
62 * A gboolean
63 */
64 GNS_MC_EXPIRATION_TIME_IS_RELATIVE = 5,
65
66 /**
67 * A gchararray
68 */
69 GNS_MC_EXPIRATION_TIME_AS_STRING = 6,
70
71 /**
72 * A gchararray
73 */
74 GNS_MC_VALUE_AS_STRING = 7,
75
76 /**
77 * A gchararray
78 */
79 GNS_MC_VALUE_COLOR = 8,
80 };
81
82
83/**
84 * Columns in the gns type model.
85 */
86enum GNS_TypeModelColumns
87 {
88 /**
89 * A guint
90 */
91 GNS_TYPE_MC_TYPE = 0,
92
93 /**
94 * A gchararray
95 */
96 GNS_TYPE_MC_TYPENAME = 1,
97 };
98
99
100/**
101 * Handle to our main loop.
102 */
103static struct GNUNET_GTK_MainLoop *ml;
104
105/**
106 * Should gnunet-gns-gtk start in tray mode?
107 */
108static int tray_only;
109
110
111/**
112 * Name of our zone as a string.
113 */
114static char *zone_as_string;
115
116/**
117 * Default directory of zone files as a string.
118 */
119static char *zonekey_directory;
120
121/**
122 * Get cfg.
123 */
124static const struct GNUNET_CONFIGURATION_Handle *
125get_configuration ()
126{
127 return GNUNET_GTK_main_loop_get_configuration (ml);
128}
129
130
131/**
132 * Get an object from the main window.
133 *
134 * @param name name of the object
135 * @return NULL on error
136 */
137static GObject *
138get_object (const char *name)
139{
140 return GNUNET_GTK_main_loop_get_object (ml, name);
141}
142
143
144static void
145pseu_change_cont (void *cls,
146 int32_t success,
147 const char *emsg)
148{
149 struct GNUNET_GNS_Context *gns = cls;
150 GtkWidget *dialog;
151 if (GNUNET_SYSERR == success)
152 {
153 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("New Pseudonym could not be set: `%s'\n"), emsg);
154 dialog = gtk_message_dialog_new (GTK_WINDOW (gns->main_window),
155 GTK_DIALOG_DESTROY_WITH_PARENT,
156 GTK_MESSAGE_ERROR,
157 GTK_BUTTONS_CLOSE,
158 _("New Pseudonym could not be set: `%s'\n"),
159 emsg);
160 g_signal_connect_swapped (dialog, "response",
161 G_CALLBACK (gtk_widget_destroy),
162 dialog);
163 gtk_widget_show_all (dialog);
164 }
165}
166
167
168/**
169 * Task run on shutdown.
170 *
171 * @param cls unused
172 * @param tc scheduler context, unused
173 */
174static void
175shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
176{
177
178 struct GNUNET_GNS_Context *gns = cls;
179 if (NULL == gns)
180 return;
181 if (NULL != gns->ns)
182 {
183 GNUNET_NAMESTORE_disconnect (gns->ns);
184 gns->ns = NULL;
185 }
186 if (NULL != gns->pkey)
187 {
188 GNUNET_CRYPTO_rsa_key_free (gns->pkey);
189 gns->pkey = NULL;
190 }
191 if (NULL != zonekey_directory)
192 {
193 GNUNET_free (zonekey_directory);
194 zonekey_directory = NULL;
195 }
196 GNUNET_free (gns);
197}
198
199
200void
201GNUNET_GNS_GTK_shutdown (struct GNUNET_GNS_Context *gns)
202{
203 GNUNET_GTK_tray_icon_destroy ();
204 GNUNET_GTK_main_loop_quit (ml);
205 GNUNET_SCHEDULER_add_now (&shutdown_task, gns);
206}
207
208
209gboolean
210GNUNET_GNS_GTK_pseu_entry_enter_cb (GtkWidget *widget,
211 GdkEvent *event,
212 gpointer user_data)
213{
214 const gchar * pseu;
215
216 pseu = gtk_entry_get_text (GTK_ENTRY(widget));
217
218 if ((pseu == NULL) || (0 == strcmp (pseu, "")))
219 {
220 //gtk_entry_set_text (GTK_ENTRY(widget), PSEU_EMPTY_STR);
221 }
222 return FALSE;
223}
224
225
226/**
227 * The user edited the preferred name (PSEU) of this namespace.
228 * Push the update to the namestore.
229 *
230 * @param editable the edited widget
231 * @param user_data unused
232 */
233void
234GNUNET_GNS_GTK_pseu_entry_changed_cb (GtkEditable *editable,
235 gpointer user_data)
236{
237 struct GNUNET_GNS_Context *gns = user_data;
238 struct GNUNET_NAMESTORE_RecordData rd;
239 const gchar * pseu;
240
241 pseu = gtk_entry_get_text (GTK_ENTRY(editable));
242 if ((pseu != NULL) && (0 != strcmp (pseu, PSEU_EMPTY_STR)) && (0 != strcmp ("", pseu)) && (GNUNET_NO == gns->iteration))
243 {
244
245 rd.record_type = GNUNET_NAMESTORE_TYPE_PSEU;
246 rd.expiration_time = UINT64_MAX;
247 rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
248 rd.data_size = strlen (pseu) + 1;
249 rd.data = strdup (pseu);
250 GNUNET_NAMESTORE_record_create(gns->ns, gns->pkey, "+", &rd, pseu_change_cont, gns);
251 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New Pseudonym is `%s' %u\n", (char *) rd.data, rd.data_size);
252 }
253 else if ((0 != strcmp (pseu, PSEU_EMPTY_STR)) && ((pseu == NULL) || (0 == strcmp ("", pseu))))
254 {
255 gtk_entry_set_text (GTK_ENTRY(editable), PSEU_EMPTY_STR);
256 }
257
258}
259
260/**
261 * The user toggled the 'autoshort' option. Update the configuration.
262 *
263 * @param checkmenuitem the menu item
264 * @param user_data unused
265 */
266void
267GNUNET_GNS_GTK_autoshort_imagemenuitem_toggled_cb (GtkCheckMenuItem *checkmenuitem,
268 gpointer user_data)
269{
270 struct GNUNET_GNS_Context *gns = user_data;
271 GtkWidget *dialog;
272 struct GNUNET_CONFIGURATION_Handle *cfg = (struct GNUNET_CONFIGURATION_Handle *) get_configuration();
273
274 gboolean state = gtk_check_menu_item_get_active (gns->shorten_menu);
275 if (TRUE == state)
276 GNUNET_CONFIGURATION_set_value_string(cfg,"gns", "AUTO_IMPORT_PKEY","YES");
277 else
278 GNUNET_CONFIGURATION_set_value_string(cfg,"gns", "AUTO_IMPORT_PKEY","NO");
279
280 char * cfgfile = strdup (GNUNET_GTK_main_loop_get_configuration_file(ml));
281 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_write(cfg, cfgfile))
282 {
283 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Changes to autoshorten could not be written to configuration file: `%s'\n"), cfgfile);
284 dialog = gtk_message_dialog_new (GTK_WINDOW (gns->main_window),
285 GTK_DIALOG_DESTROY_WITH_PARENT,
286 GTK_MESSAGE_ERROR,
287 GTK_BUTTONS_CLOSE,
288 _("Changes to autoshorten option could not be written to configuration file: `%s'\n"),
289 cfgfile);
290 g_signal_connect_swapped (dialog, "response",
291 G_CALLBACK (gtk_widget_destroy),
292 dialog);
293 gtk_widget_show_all (dialog);
294 }
295 GNUNET_free (cfgfile);
296}
297
298
299/**
300 * The user selected 'NEW' in the menu. Open a dialog to enter a filename
301 * to create a new zone (for editing).
302 *
303 * @param checkmenuitem the menu item
304 * @param user_data unused
305 */
306void
307GNUNET_GNS_GTK_new_imagemenuitem_activate_cb (GtkMenuItem *menuitem,
308 gpointer user_data)
309{
310 GNUNET_break (0); // FIXME, not implemented
311}
312
313
314/**
315 * Function called from the open-directory dialog upon completion.
316 *
317 * @param dialog the pseudonym selection dialog
318 * @param response_id response code from the dialog
319 * @param user_data the builder of the dialog
320 */
321void
322GNUNET_GNS_GTK_zone_open_dialog_response_cb (GtkDialog * dialog,
323 gint response_id,
324 gpointer user_data)
325{
326 char *filename;
327
328 if (GTK_RESPONSE_OK != response_id)
329 {
330 gtk_widget_destroy (GTK_WIDGET (dialog));
331 g_object_unref (G_OBJECT (dialog));
332 return;
333 }
334 filename = GNUNET_GTK_filechooser_get_filename_utf8 (GTK_FILE_CHOOSER (dialog));
335 gtk_widget_destroy (GTK_WIDGET (dialog));
336 g_object_unref (G_OBJECT (dialog));
337
338 /* FIXME: move to new zone 'filename' */
339 fprintf (stderr, "Got zone `%s'\n", filename);
340 GNUNET_free (filename);
341}
342
343
344/**
345 * The user selected 'OPEN' in the menu. Open a dialog to select
346 * a different zonefile (for editing).
347 *
348 * @param checkmenuitem the menu item
349 * @param user_data unused
350 */
351void
352GNUNET_GNS_GTK_open_imagemenuitem_activate_cb (GtkMenuItem *menuitem,
353 gpointer user_data)
354{
355 GtkWidget *ad;
356 GtkBuilder *builder;
357 GtkWidget *toplevel;
358 GtkFileFilter *ff;
359 GtkFileChooser *fc;
360
361 builder =
362 GNUNET_GTK_get_new_builder ("gnunet_gns_gtk_zone_open.glade", NULL);
363 if (NULL == builder)
364 {
365 GNUNET_break (0);
366 return;
367 }
368 /* This file filter could be set with glade if we use gtk3
369 * With gtk2 we have to set it manually */
370 ff = GTK_FILE_FILTER (gtk_builder_get_object
371 (builder, "GNUNET_GNS_GTK_zone_open_filefilter"));
372 gtk_file_filter_add_pattern (ff, "*.zkey");
373
374 ad = GTK_WIDGET (gtk_builder_get_object
375 (builder, "GNUNET_GNS_GTK_zone_open_filechooserdialog"));
376
377 if (GTK_IS_FILE_CHOOSER(ad))
378 {
379 fc = GTK_FILE_CHOOSER(ad);
380 if (NULL != fc)
381 gtk_file_chooser_set_current_folder(fc, zonekey_directory);
382 }
383
384 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (menuitem));
385 if (GTK_IS_WINDOW (toplevel))
386 gtk_window_set_transient_for (GTK_WINDOW (ad), GTK_WINDOW (toplevel));
387 gtk_window_present (GTK_WINDOW (ad));
388}
389
390
391/**
392 * The user clicked on the 'copy' button. Copy the full string
393 * with the hash of our public key to the clipboard.
394 *
395 * @param button the button that was clicked
396 * @param user_data unused
397 */
398void
399GNUNET_GNS_GTK_public_key_copy_button_clicked_cb (GtkButton *button,
400 gpointer user_data)
401{
402 GtkClipboard *cb;
403
404 cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
405 gtk_clipboard_set_text (cb, zone_as_string, -1);
406}
407
408
409
410/**
411 * Callback invoked if the application is supposed to exit (via menu).
412 *
413 * @param menuitem the quit menu
414 * @param user_data unused
415 */
416void
417GNUNET_GNS_GTK_quit_imagemenuitem_activate_cb (GtkMenuItem *menuitem,
418 gpointer user_data)
419{
420 GNUNET_GTK_tray_icon_destroy ();
421 GNUNET_GTK_main_loop_quit (ml);
422 GNUNET_SCHEDULER_add_now (&shutdown_task, user_data);
423}
424
425
426/**
427 * Callback invoked if the application is supposed to exit (via window-close).
428 *
429 * @param widget the main window
430 * @param event deletion event
431 * @param user_data unused
432 */
433void
434GNUNET_GNS_GTK_main_window_delete_event_cb (GtkWidget *widget,
435 GdkEvent *event,
436 gpointer user_data)
437{
438 GNUNET_GTK_tray_icon_destroy ();
439 GNUNET_GTK_main_loop_quit (ml);
440 GNUNET_SCHEDULER_add_now (&shutdown_task, user_data);
441}
442
443
444static void
445close_error_box (GtkDialog *dialog,
446 gint response_id,
447 gpointer user_data)
448{
449 gtk_widget_destroy (GTK_WIDGET(dialog));
450 GNUNET_GNS_GTK_shutdown (user_data);
451}
452
453static void
454namestore_service_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
455{
456 struct GNUNET_GNS_Context *gns = NULL;
457 struct GNUNET_CRYPTO_ShortHashAsciiEncoded shenc;
458 GtkWidget *dialog;
459 char *label;
460 char *keyfile;
461 char *servicehome;
462
463 gns = GNUNET_malloc (sizeof (struct GNUNET_GNS_Context));
464
465 if ((tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT) != 0)
466 {
467 char * message = _("Namestore service is not running!\n");
468 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, message);
469 dialog = gtk_message_dialog_new (GTK_WINDOW (gns->main_window),
470 GTK_DIALOG_DESTROY_WITH_PARENT,
471 GTK_MESSAGE_ERROR,
472 GTK_BUTTONS_CLOSE,
473 "%s",
474 message);
475
476 g_signal_connect (dialog, "response", G_CALLBACK(close_error_box), gns);
477 gtk_widget_show_all (dialog);
478 return;
479 }
480
481 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (get_configuration (),
482 "PATHS",
483 "SERVICEHOME",
484 &servicehome))
485 {
486 GNUNET_asprintf(&zonekey_directory, "");
487 }
488 else
489 {
490 GNUNET_asprintf(&zonekey_directory, "%s%s%s",servicehome, DIR_SEPARATOR_STR, "gns");
491 GNUNET_free (servicehome);
492 }
493
494 /* setup crypto keys */
495 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (get_configuration (),
496 "gns",
497 "ZONEKEY",
498 &keyfile))
499 {
500 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
501 _("Option `%s' missing in section `%s'\n"), "ZONEKEY", "gns");
502 return;
503 }
504 else
505 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using `%s'\n", keyfile);
506 gns->pkey = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
507 GNUNET_free (keyfile);
508 keyfile = NULL;
509 if (NULL == gns->pkey)
510 {
511 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
512 _("Failed to read or create private zone key\n"));
513 return;
514 }
515 GNUNET_CRYPTO_rsa_key_get_public (gns->pkey, &gns->pubkey);
516 GNUNET_CRYPTO_short_hash (&gns->pubkey,
517 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
518 &gns->zone);
519 GNUNET_CRYPTO_short_hash_to_enc(&gns->zone, &shenc);
520
521 /* connect to namestore */
522 gns->ns = GNUNET_NAMESTORE_connect (get_configuration ());
523 if (NULL == gns->ns)
524 {
525 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
526 _("Failed to connect to namestore\n"));
527 GNUNET_SCHEDULER_add_now (&shutdown_task, gns);
528 return;
529 }
530
531 /* setup gui */
532 if (GNUNET_OK != GNUNET_GTK_main_loop_build_window (ml, gns))
533 {
534 GNUNET_break (0);
535 GNUNET_SCHEDULER_add_now (&shutdown_task, gns);
536 return;
537 }
538 gns->builder = GNUNET_GTK_main_loop_get_builder(ml);
539 gns->main_window = GTK_WIDGET (get_object ("GNUNET_GNS_GTK_main_window"));
540 gns->ts = GTK_TREE_STORE (gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_treestore"));
541 gns->ls = GTK_LIST_STORE (gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_type_liststore"));
542 gns->tv = GTK_TREE_VIEW (gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_main_treeview"));
543 gns->tm = GTK_TREE_MODEL(gns->ts);
544 gns->shorten_menu = GTK_CHECK_MENU_ITEM(gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_autoshort_imagemenuitem"));
545 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (get_configuration (),
546 "gns",
547 "AUTO_IMPORT_PKEY"))
548 gtk_check_menu_item_set_active (gns->shorten_menu, TRUE);
549 else
550 gtk_check_menu_item_set_active (gns->shorten_menu, FALSE);
551
552 /* TODO: implements menus */
553 gtk_widget_set_visible (GTK_WIDGET (gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_new_imagemenuitem")), FALSE);
554 gtk_widget_set_visible (GTK_WIDGET (gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_open_imagemenuitem")), FALSE);
555
556 zone_as_string = GNUNET_strdup ((char *) &shenc);
557 label = g_markup_printf_escaped (_("<b>Editing zone %s</b>"),
558 zone_as_string);
559 gtk_label_set_markup (GTK_LABEL (get_object ("GNUNET_GNS_GTK_zone_label")),
560 label);
561 g_free (label);
562
563 GNUNET_GTK_set_icon_search_path ();
564 GNUNET_GTK_setup_nls ();
565 /* setup main window */
566 GNUNET_GTK_tray_icon_create (GTK_WINDOW (gns->main_window),
567 "gnunet-gtk" /* FIXME: different icon? */ ,
568 "gnunet-gns-gtk");
569
570 /* make GUI visible */
571 if (!tray_only)
572 {
573 gtk_widget_show (gns->main_window);
574 gtk_window_present (GTK_WINDOW (gns->main_window));
575 }
576}
577
578
579/**
580 * Actual main function run right after GNUnet's scheduler
581 * is initialized. Initializes up GTK and Glade.
582 *
583 * @param cls the 'struct GNUNET_GTK_MainLoop'
584 * @param tc scheduler context
585 */
586static void
587run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
588{
589 ml = cls;
590 GNUNET_CLIENT_service_test("namestore", get_configuration(), GNUNET_TIME_UNIT_SECONDS, &namestore_service_check, NULL);
591}
592
593
594int
595main (int argc, char *const *argv)
596{
597 static struct GNUNET_GETOPT_CommandLineOption options[] = {
598 {'t', "tray", NULL,
599 gettext_noop ("start in tray mode"), 0,
600 &GNUNET_GETOPT_set_one, &tray_only},
601
602 GNUNET_GETOPT_OPTION_END
603 };
604
605 if (GNUNET_OK !=
606 GNUNET_GTK_main_loop_start ("gnunet-gns-gtk",
607 "GTK GUI for editing our zone", argc,
608 argv, options,
609 "gnunet_gns_gtk_main_window.glade",
610 &run))
611 return 1;
612 return 0;
613}
614
615
616/* end of gnunet-gns-gtk.c */