diff options
Diffstat (limited to 'src/gns/gnunet-gns-gtk_zone.c')
-rw-r--r-- | src/gns/gnunet-gns-gtk_zone.c | 1268 |
1 files changed, 0 insertions, 1268 deletions
diff --git a/src/gns/gnunet-gns-gtk_zone.c b/src/gns/gnunet-gns-gtk_zone.c deleted file mode 100644 index 4015248d..00000000 --- a/src/gns/gnunet-gns-gtk_zone.c +++ /dev/null | |||
@@ -1,1268 +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_zone.c | ||
23 | * @author Christian Grothoff | ||
24 | * @brief everything releated to the zone tree view | ||
25 | */ | ||
26 | #include "gnunet_gtk.h" | ||
27 | #include "gnunet-gns-gtk.h" | ||
28 | |||
29 | |||
30 | /** | ||
31 | * FIXME: duplicated with "enum GNS_ModelColumns"! | ||
32 | */ | ||
33 | enum GNSTreestoreColumn | ||
34 | { | ||
35 | /** | ||
36 | * | ||
37 | */ | ||
38 | GNS_TREESTORE_COL_NAME = 0, | ||
39 | |||
40 | /** | ||
41 | * | ||
42 | */ | ||
43 | GNS_TREESTORE_COL_IS_PUBLIC, | ||
44 | |||
45 | /** | ||
46 | * | ||
47 | */ | ||
48 | GNS_TREESTORE_COL_RECORD_TYPE, | ||
49 | |||
50 | /** | ||
51 | * | ||
52 | */ | ||
53 | GNS_TREESTORE_COL_RECORD_TYPE_AS_STR, | ||
54 | |||
55 | /** | ||
56 | * | ||
57 | */ | ||
58 | GNS_TREESTORE_COL_EXP_TIME, | ||
59 | |||
60 | /** | ||
61 | * | ||
62 | */ | ||
63 | GNS_TREESTORE_COL_EXP_TIME_IS_REL, | ||
64 | |||
65 | /** | ||
66 | * | ||
67 | */ | ||
68 | GNS_TREESTORE_COL_EXP_TIME_AS_STR, | ||
69 | |||
70 | /** | ||
71 | * | ||
72 | */ | ||
73 | GNS_TREESTORE_COL_VAL_AS_STR, | ||
74 | |||
75 | /** | ||
76 | * | ||
77 | */ | ||
78 | GNS_TREESTORE_COL_VAL_COLOR, | ||
79 | |||
80 | /** | ||
81 | * | ||
82 | */ | ||
83 | GNS_TREESTORE_COL_NAME_IS_VISIBLE, | ||
84 | |||
85 | /** | ||
86 | * | ||
87 | */ | ||
88 | GNS_TREESTORE_COL_IS_RECORD_ROW, | ||
89 | |||
90 | /** | ||
91 | * | ||
92 | */ | ||
93 | GNS_TREESTORE_COL_NOT_DUMMY_ROW, | ||
94 | |||
95 | /** | ||
96 | * | ||
97 | */ | ||
98 | GNS_TREESTORE_COL_EXP_TIME_COLOR, | ||
99 | |||
100 | /** | ||
101 | * | ||
102 | */ | ||
103 | GNS_TREESTORE_COL_NAME_COLOR | ||
104 | }; | ||
105 | |||
106 | |||
107 | /** | ||
108 | * | ||
109 | */ | ||
110 | enum LIST_COLUMNS | ||
111 | { | ||
112 | |||
113 | /** | ||
114 | * | ||
115 | */ | ||
116 | GNS_TYPE_TO_NAME_LISTSTORE_COLUMN_TYPE = 0, | ||
117 | |||
118 | |||
119 | /** | ||
120 | * | ||
121 | */ | ||
122 | GNS_TYPE_TO_NAME_LISTSTORE_COLUMN_TYPENAME | ||
123 | }; | ||
124 | |||
125 | |||
126 | /** | ||
127 | * | ||
128 | */ | ||
129 | struct UpdateContext | ||
130 | { | ||
131 | /** | ||
132 | * | ||
133 | */ | ||
134 | struct GNUNET_GNS_Context *gns; | ||
135 | |||
136 | /** | ||
137 | * | ||
138 | */ | ||
139 | struct GNUNET_NAMESTORE_RecordData *rd; | ||
140 | |||
141 | /** | ||
142 | * | ||
143 | */ | ||
144 | char * name; | ||
145 | |||
146 | /** | ||
147 | * | ||
148 | */ | ||
149 | unsigned int rd_count; | ||
150 | }; | ||
151 | |||
152 | |||
153 | static void | ||
154 | check_name_validity_and_commit_remove_proc (void *cls, | ||
155 | int32_t success, | ||
156 | const char *emsg) | ||
157 | { | ||
158 | struct UpdateContext * uc = cls; | ||
159 | unsigned int c; | ||
160 | if ((GNUNET_OK == success) || (GNUNET_NO == success)) | ||
161 | { | ||
162 | for (c = 0; c < uc->rd_count; c++) | ||
163 | { | ||
164 | GNUNET_NAMESTORE_record_create(uc->gns->ns, uc->gns->pkey, | ||
165 | uc->name, &uc->rd[c],NULL, NULL); | ||
166 | GNUNET_free ((void *) uc->rd[c].data); | ||
167 | } | ||
168 | GNUNET_free (uc->rd); | ||
169 | GNUNET_free (uc->name); | ||
170 | GNUNET_free (uc); | ||
171 | } | ||
172 | else if (GNUNET_SYSERR == success) | ||
173 | { | ||
174 | for (c = 0; c < uc->rd_count; c++) | ||
175 | GNUNET_free ((void *) uc->rd[c].data); | ||
176 | GNUNET_free (uc->rd); | ||
177 | GNUNET_free (uc->name); | ||
178 | GNUNET_free (uc); | ||
179 | } | ||
180 | else | ||
181 | { | ||
182 | GNUNET_break (0); | ||
183 | GNUNET_free (uc); | ||
184 | } | ||
185 | } | ||
186 | |||
187 | |||
188 | static void | ||
189 | check_name_validity_and_commit (struct GNUNET_GNS_Context *gns, gchar *path, char * oldname) | ||
190 | { | ||
191 | GtkTreeIter it; | ||
192 | GtkTreeIter parent; | ||
193 | int records; | ||
194 | int children; | ||
195 | int append_pseu; | ||
196 | int c; | ||
197 | int valid = GNUNET_YES; | ||
198 | char * name; | ||
199 | void * data; | ||
200 | size_t data_size; | ||
201 | const gchar * pseu; | ||
202 | |||
203 | char *n_name; | ||
204 | int n_type; | ||
205 | gboolean n_public; | ||
206 | char *n_exp_color; | ||
207 | guint64 n_exp_time; | ||
208 | char *n_exp_str; | ||
209 | gboolean n_is_relative; | ||
210 | char *n_value; | ||
211 | char *n_value_color; | ||
212 | |||
213 | |||
214 | gtk_tree_model_get_iter_from_string(gns->tm, &it, path); | ||
215 | |||
216 | if (FALSE == gtk_tree_model_iter_parent (gns->tm, &parent, &it)) | ||
217 | parent = it; | ||
218 | |||
219 | children = gtk_tree_model_iter_n_children (gns->tm, &parent); | ||
220 | if (children < 1) | ||
221 | { | ||
222 | return; | ||
223 | } | ||
224 | |||
225 | gtk_tree_model_get(gns->tm, &parent, | ||
226 | GNS_TREESTORE_COL_NAME, &name, | ||
227 | -1); | ||
228 | |||
229 | if (0 == strcmp (name, ROOT_STR)) | ||
230 | { | ||
231 | /* We have to append PSEU RECORD */ | ||
232 | append_pseu = GNUNET_YES; | ||
233 | records = children + 1; | ||
234 | } | ||
235 | else | ||
236 | { | ||
237 | append_pseu = GNUNET_NO; | ||
238 | records = children; | ||
239 | } | ||
240 | |||
241 | struct GNUNET_NAMESTORE_RecordData *rd = GNUNET_malloc (records * sizeof (struct GNUNET_NAMESTORE_RecordData)); | ||
242 | |||
243 | if (FALSE == gtk_tree_model_iter_children (gns->tm, &it, &parent)) | ||
244 | return; | ||
245 | |||
246 | for (c = 0; c < children; c++) | ||
247 | { | ||
248 | gtk_tree_model_get(gns->tm, &it, | ||
249 | GNS_TREESTORE_COL_NAME, &n_name, | ||
250 | GNS_TREESTORE_COL_RECORD_TYPE, &n_type, | ||
251 | GNS_TREESTORE_COL_IS_PUBLIC, &n_public, | ||
252 | GNS_TREESTORE_COL_EXP_TIME_COLOR, &n_exp_color, | ||
253 | GNS_TREESTORE_COL_EXP_TIME, &n_exp_time, | ||
254 | GNS_TREESTORE_COL_EXP_TIME_IS_REL, &n_is_relative, | ||
255 | GNS_TREESTORE_COL_EXP_TIME_AS_STR, &n_exp_str, | ||
256 | GNS_TREESTORE_COL_VAL_AS_STR, &n_value, | ||
257 | GNS_TREESTORE_COL_VAL_COLOR, &n_value_color, | ||
258 | -1); | ||
259 | /* valid name */ | ||
260 | if (NULL == n_name) | ||
261 | valid = GNUNET_NO; | ||
262 | else | ||
263 | { | ||
264 | if (GNUNET_SYSERR == GNUNET_NAMESTORE_check_name (n_name)) | ||
265 | valid = GNUNET_NO; | ||
266 | } | ||
267 | |||
268 | /* valid record type */ | ||
269 | if (0 == n_type) | ||
270 | valid = GNUNET_NO; | ||
271 | |||
272 | /* valid expiration */ | ||
273 | if ((n_exp_color != NULL) || (NULL == n_exp_str) || (0 == n_exp_time)) | ||
274 | valid = GNUNET_NO; | ||
275 | |||
276 | /* valid value */ | ||
277 | if ((n_value_color != NULL) || (NULL == n_value)) | ||
278 | valid = GNUNET_NO; | ||
279 | if (NULL != n_value) | ||
280 | { | ||
281 | if (GNUNET_OK != GNUNET_NAMESTORE_string_to_value(n_type, n_value, &data, &data_size)) | ||
282 | valid = GNUNET_NO; | ||
283 | } | ||
284 | |||
285 | if (GNUNET_YES == valid) | ||
286 | { | ||
287 | if (FALSE == n_public) | ||
288 | rd[c].flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_PRIVATE; | ||
289 | else | ||
290 | rd[c].flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_NONE; | ||
291 | rd[c].record_type = n_type; | ||
292 | rd[c].expiration_time = n_exp_time; | ||
293 | rd[c].data_size = data_size; | ||
294 | rd[c].data = GNUNET_malloc(data_size); | ||
295 | memcpy ((void *) rd[c].data, data, data_size); | ||
296 | } | ||
297 | g_free (n_name); | ||
298 | g_free (n_exp_color); | ||
299 | g_free (n_exp_str); | ||
300 | g_free (n_value); | ||
301 | g_free (n_value_color); | ||
302 | |||
303 | if (FALSE == gtk_tree_model_iter_next (gns->tm, &it)) | ||
304 | break; | ||
305 | } | ||
306 | |||
307 | if (GNUNET_NO == valid) | ||
308 | { | ||
309 | for (c = 0; c < children; c++) | ||
310 | GNUNET_free_non_null ((void *) rd[c].data); | ||
311 | GNUNET_free_non_null (rd); | ||
312 | } | ||
313 | else | ||
314 | { | ||
315 | |||
316 | if (GNUNET_YES == append_pseu) | ||
317 | { | ||
318 | GNUNET_assert (children == (records -1)); | ||
319 | |||
320 | /* Append PSEU record */ | ||
321 | GtkEntry * entry = GTK_ENTRY (gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_pseu_entry")); | ||
322 | pseu = gtk_entry_get_text (GTK_ENTRY(entry)); | ||
323 | if ((NULL != pseu) && (0 != strcmp (PSEU_EMPTY_STR, pseu)) && (0 != strcmp ("", pseu))) | ||
324 | { | ||
325 | if (GNUNET_OK != GNUNET_NAMESTORE_string_to_value(GNUNET_NAMESTORE_TYPE_PSEU, | ||
326 | pseu, | ||
327 | (void **) &rd[records - 1].data, | ||
328 | &rd[records - 1].data_size)) | ||
329 | { | ||
330 | GNUNET_break (0); | ||
331 | for (c = 0; c < records; c++) | ||
332 | GNUNET_free_non_null ((void *) rd[c].data); | ||
333 | GNUNET_free_non_null (rd); | ||
334 | } | ||
335 | rd[records - 1].record_type = GNUNET_NAMESTORE_TYPE_PSEU; | ||
336 | rd[records - 1].expiration_time = UINT64_MAX; | ||
337 | rd[records - 1].flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_NONE; | ||
338 | } | ||
339 | else | ||
340 | { | ||
341 | GNUNET_break (0); | ||
342 | } | ||
343 | } | ||
344 | |||
345 | /* Remove old entries */ | ||
346 | struct UpdateContext * uc = GNUNET_malloc (sizeof (struct UpdateContext)); | ||
347 | uc->gns = gns; | ||
348 | uc->rd = rd; | ||
349 | uc->rd_count = records; | ||
350 | uc->name = strdup (name); | ||
351 | if (oldname != NULL) | ||
352 | GNUNET_NAMESTORE_record_remove(gns->ns, gns->pkey, oldname, NULL, &check_name_validity_and_commit_remove_proc, uc); | ||
353 | else | ||
354 | GNUNET_NAMESTORE_record_remove(gns->ns, gns->pkey, name, NULL, &check_name_validity_and_commit_remove_proc, uc); | ||
355 | g_free (name); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | |||
360 | /** | ||
361 | * | ||
362 | */ | ||
363 | struct Remove_Context | ||
364 | { | ||
365 | |||
366 | /** | ||
367 | * | ||
368 | */ | ||
369 | struct GNUNET_GNS_Context *gns; | ||
370 | |||
371 | /** | ||
372 | * | ||
373 | */ | ||
374 | char *path; | ||
375 | }; | ||
376 | |||
377 | |||
378 | static void | ||
379 | check_name_validity_and_remove_proc (void *cls, | ||
380 | int32_t success, | ||
381 | const char *emsg) | ||
382 | { | ||
383 | struct Remove_Context *rcc = cls; | ||
384 | GtkDialog *dialog; | ||
385 | GtkTreeIter it; | ||
386 | if (GNUNET_SYSERR == success) | ||
387 | { | ||
388 | char * message = _("Record could not be deleted:"); | ||
389 | dialog = GTK_DIALOG(gtk_message_dialog_new (GTK_WINDOW (rcc->gns->main_window), | ||
390 | GTK_DIALOG_DESTROY_WITH_PARENT, | ||
391 | GTK_MESSAGE_ERROR, | ||
392 | GTK_BUTTONS_CLOSE, | ||
393 | _("%s\n%s\n"), | ||
394 | message, | ||
395 | emsg)); | ||
396 | |||
397 | g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), rcc->gns); | ||
398 | gtk_widget_show_all (GTK_WIDGET(dialog)); | ||
399 | } | ||
400 | else | ||
401 | { | ||
402 | gtk_tree_model_get_iter_from_string(rcc->gns->tm, &it, rcc->path); | ||
403 | gtk_tree_store_remove (rcc->gns->ts, &it); | ||
404 | } | ||
405 | GNUNET_free (rcc->path); | ||
406 | GNUNET_free (rcc); | ||
407 | } | ||
408 | |||
409 | |||
410 | static void | ||
411 | check_name_validity_and_remove (struct GNUNET_GNS_Context *gns, gchar *path) | ||
412 | { | ||
413 | GtkTreeIter it; | ||
414 | GtkTreeIter parent; | ||
415 | char *name; | ||
416 | int valid = GNUNET_YES; | ||
417 | struct GNUNET_NAMESTORE_RecordData rd; | ||
418 | struct Remove_Context *rcc; | ||
419 | |||
420 | char *n_name; | ||
421 | int n_type; | ||
422 | gboolean n_public; | ||
423 | char *n_exp_color; | ||
424 | guint64 n_exp_time; | ||
425 | char *n_exp_str; | ||
426 | gboolean n_is_relative; | ||
427 | char *n_value; | ||
428 | char *n_value_color; | ||
429 | |||
430 | gtk_tree_model_get_iter_from_string(gns->tm, &it, path); | ||
431 | gtk_tree_model_get(gns->tm, &it, | ||
432 | GNS_TREESTORE_COL_NAME, &name, | ||
433 | -1); | ||
434 | |||
435 | if (TRUE == gtk_tree_model_iter_parent (gns->tm, &parent, &it)) | ||
436 | { | ||
437 | /* Removing a single record */ | ||
438 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
439 | "Removing single record for name `%s'\n", name); | ||
440 | |||
441 | gtk_tree_model_get(gns->tm, &it, | ||
442 | GNS_TREESTORE_COL_NAME, &n_name, | ||
443 | GNS_TREESTORE_COL_RECORD_TYPE, &n_type, | ||
444 | GNS_TREESTORE_COL_IS_PUBLIC, &n_public, | ||
445 | GNS_TREESTORE_COL_EXP_TIME_COLOR, &n_exp_color, | ||
446 | GNS_TREESTORE_COL_EXP_TIME, &n_exp_time, | ||
447 | GNS_TREESTORE_COL_EXP_TIME_IS_REL, &n_is_relative, | ||
448 | GNS_TREESTORE_COL_EXP_TIME_AS_STR, &n_exp_str, | ||
449 | GNS_TREESTORE_COL_VAL_AS_STR, &n_value, | ||
450 | GNS_TREESTORE_COL_VAL_COLOR, &n_value_color, | ||
451 | -1); | ||
452 | |||
453 | /* valid name */ | ||
454 | if (NULL == n_name) | ||
455 | valid = GNUNET_NO; | ||
456 | |||
457 | /* valid record type */ | ||
458 | if (0 == n_type) | ||
459 | valid = GNUNET_NO; | ||
460 | |||
461 | /* valid expiration */ | ||
462 | if ((n_exp_color != NULL) || (NULL == n_exp_str) || (0 == n_exp_time)) | ||
463 | valid = GNUNET_NO; | ||
464 | |||
465 | /* valid value */ | ||
466 | if ((n_value_color != NULL) || (NULL == n_value)) | ||
467 | valid = GNUNET_NO; | ||
468 | |||
469 | if (GNUNET_YES == valid) | ||
470 | { | ||
471 | if (FALSE == n_public) | ||
472 | rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_PRIVATE; | ||
473 | else | ||
474 | rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_NONE; | ||
475 | rd.record_type = n_type; | ||
476 | rd.expiration_time = n_exp_time; | ||
477 | rd.data_size = strlen (n_value) + 1; | ||
478 | rd.data = GNUNET_malloc(rd.data_size); | ||
479 | memcpy ((void *) rd.data, n_value, rd.data_size); | ||
480 | |||
481 | rcc = GNUNET_malloc(sizeof (struct Remove_Context)); | ||
482 | rcc->gns = gns; | ||
483 | rcc->path = strdup (path); | ||
484 | GNUNET_NAMESTORE_record_remove(gns->ns, gns->pkey, name, &rd, &check_name_validity_and_remove_proc, rcc); | ||
485 | GNUNET_free ((void *) rd.data); | ||
486 | } | ||
487 | else | ||
488 | { | ||
489 | gtk_tree_model_get_iter_from_string(gns->tm, &it, path); | ||
490 | gtk_tree_store_remove (gns->ts, &it); | ||
491 | } | ||
492 | g_free (n_name); | ||
493 | g_free (n_exp_color); | ||
494 | g_free (n_exp_str); | ||
495 | g_free (n_value); | ||
496 | g_free (n_value_color); | ||
497 | } | ||
498 | else if (0 != strcmp (name, ROOT_STR)) | ||
499 | { | ||
500 | /* Removing the whole name record */ | ||
501 | rcc = GNUNET_malloc(sizeof (struct Remove_Context)); | ||
502 | rcc->gns = gns; | ||
503 | rcc->path = strdup (path); | ||
504 | GNUNET_NAMESTORE_record_remove(gns->ns, gns->pkey, name, NULL, &check_name_validity_and_remove_proc, rcc); | ||
505 | } | ||
506 | g_free (name); | ||
507 | } | ||
508 | |||
509 | |||
510 | /** | ||
511 | * The user has selected a new record type. Update the | ||
512 | * model, possibly invalidating (marking 'red') the existing | ||
513 | * value. | ||
514 | * | ||
515 | * @param renderer updated renderer | ||
516 | * @param path the path identifying the edited cell | ||
517 | * @param new_iter selected cell in the combo's model (with the record type) | ||
518 | * @param user_data unused | ||
519 | */ | ||
520 | void | ||
521 | GNUNET_GNS_GTK_type_cellrenderercombo_changed_cb (GtkCellRendererCombo *combo, | ||
522 | gchar *path, | ||
523 | GtkTreeIter *new_iter, | ||
524 | gpointer user_data) | ||
525 | { | ||
526 | struct GNUNET_GNS_Context *gns = user_data; | ||
527 | GtkTreeIter it; | ||
528 | GtkTreeIter child; | ||
529 | guint type; | ||
530 | int record_row; | ||
531 | char *type_str; | ||
532 | char *value_str; | ||
533 | char *name_str; | ||
534 | void *data; | ||
535 | size_t data_size; | ||
536 | |||
537 | gtk_tree_model_get(GTK_TREE_MODEL(gns->ls), new_iter, 0, &type, -1); | ||
538 | gtk_tree_model_get(GTK_TREE_MODEL(gns->ls), new_iter, GNS_TYPE_TO_NAME_LISTSTORE_COLUMN_TYPENAME, &type_str, -1); | ||
539 | |||
540 | |||
541 | /* check if this is a new record */ | ||
542 | gtk_tree_model_get_iter_from_string(gns->tm, &it, path); | ||
543 | gtk_tree_model_get(gns->tm, &it, GNS_TREESTORE_COL_IS_RECORD_ROW, &record_row, -1); | ||
544 | gtk_tree_model_get(gns->tm, &it, GNS_TREESTORE_COL_NAME, &name_str, -1); | ||
545 | |||
546 | if (GNUNET_YES == record_row) | ||
547 | { | ||
548 | /* Updating an existing record */ | ||
549 | gtk_tree_store_set(gns->ts, &it, | ||
550 | GNS_TREESTORE_COL_RECORD_TYPE, type, | ||
551 | GNS_TREESTORE_COL_RECORD_TYPE_AS_STR, type_str, | ||
552 | -1); | ||
553 | } | ||
554 | else if ((NULL != name_str) && (0 != strcmp (NEW_NAME_STR, name_str))) | ||
555 | { | ||
556 | /* Adding a new record */ | ||
557 | |||
558 | gtk_tree_store_insert_with_values(gns->ts, &child , &it, 0, | ||
559 | GNS_TREESTORE_COL_NAME, name_str, | ||
560 | GNS_TREESTORE_COL_NAME_IS_VISIBLE, FALSE, | ||
561 | GNS_TREESTORE_COL_RECORD_TYPE, type, | ||
562 | GNS_TREESTORE_COL_RECORD_TYPE_AS_STR, type_str, | ||
563 | GNS_TREESTORE_COL_EXP_TIME_AS_STR, EXPIRE_NEVER_STRING, | ||
564 | GNS_TREESTORE_COL_EXP_TIME, GNUNET_TIME_UNIT_FOREVER_ABS, | ||
565 | GNS_TREESTORE_COL_EXP_TIME_IS_REL, FALSE, | ||
566 | GNS_TREESTORE_COL_IS_RECORD_ROW, GNUNET_YES, | ||
567 | GNS_TREESTORE_COL_NOT_DUMMY_ROW, GNUNET_YES, | ||
568 | -1); | ||
569 | gtk_tree_view_expand_row (gns->tv, gtk_tree_model_get_path(gns->tm, &it), 0); | ||
570 | |||
571 | } | ||
572 | GNUNET_free (type_str); | ||
573 | |||
574 | /* check if value is still valid */ | ||
575 | gtk_tree_model_get(gns->tm, &it, GNS_TREESTORE_COL_VAL_AS_STR, &value_str, -1); | ||
576 | if (NULL != value_str) | ||
577 | { | ||
578 | if (GNUNET_OK != GNUNET_NAMESTORE_string_to_value (type, | ||
579 | value_str, | ||
580 | &data, | ||
581 | &data_size)) | ||
582 | gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_COLOR, "red", -1); | ||
583 | else | ||
584 | gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_COLOR, NULL, -1); | ||
585 | GNUNET_free (value_str); | ||
586 | } | ||
587 | else if (NULL == value_str) | ||
588 | { | ||
589 | /* Empty value field */ | ||
590 | if (GNUNET_YES == record_row) | ||
591 | gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_COLOR, "red", -1); | ||
592 | else | ||
593 | gtk_tree_store_set (gns->ts, &child, GNS_TREESTORE_COL_VAL_COLOR, "red", -1); | ||
594 | } | ||
595 | |||
596 | check_name_validity_and_commit (gns, path, NULL); | ||
597 | GNUNET_free_non_null (name_str); | ||
598 | } | ||
599 | |||
600 | |||
601 | /** | ||
602 | * The user has toggled the 'public' checkmark of a cell. Update the | ||
603 | * model. | ||
604 | * | ||
605 | * @param renderer updated renderer | ||
606 | * @param path the path identifying the edited cell | ||
607 | * @param user_data unused | ||
608 | */ | ||
609 | void | ||
610 | GNUNET_GNS_GTK_ispublic_cellrenderertoggle_toggled_cb (GtkCellRendererToggle *cell_renderer, | ||
611 | gchar *path, | ||
612 | gpointer user_data) | ||
613 | { | ||
614 | struct GNUNET_GNS_Context *gns = user_data; | ||
615 | GtkTreeIter it; | ||
616 | gboolean value; | ||
617 | |||
618 | gtk_tree_model_get_iter_from_string(gns->tm, &it, path); | ||
619 | gtk_tree_model_get(gns->tm, &it, GNS_TREESTORE_COL_IS_PUBLIC, &value, -1); | ||
620 | gtk_tree_store_set(gns->ts, &it, GNS_TREESTORE_COL_IS_PUBLIC, !value, -1); | ||
621 | |||
622 | check_name_validity_and_commit (gns, path, NULL); | ||
623 | } | ||
624 | |||
625 | |||
626 | static char * | ||
627 | convert_time_to_string (struct GNUNET_TIME_Absolute t) | ||
628 | { | ||
629 | time_t tt; | ||
630 | struct tm *time; | ||
631 | char *ret; | ||
632 | |||
633 | if (t.abs_value == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value) | ||
634 | return GNUNET_strdup (_(EXPIRE_NEVER_STRING)); | ||
635 | if (t.abs_value == GNUNET_TIME_UNIT_ZERO_ABS.abs_value) | ||
636 | return GNUNET_strdup (_(EXPIRE_INVALID_STRING)); | ||
637 | |||
638 | tt = t.abs_value / 1000; | ||
639 | time = localtime (&tt); | ||
640 | |||
641 | GNUNET_asprintf(&ret, "%02u/%02u/%04u %02u:%02u",time->tm_mon, time->tm_mday, 1900 + time->tm_year, time->tm_hour, time->tm_min); | ||
642 | return ret; | ||
643 | } | ||
644 | |||
645 | |||
646 | static int | ||
647 | check_time (const char * text) | ||
648 | { | ||
649 | unsigned int t_mon; | ||
650 | unsigned int t_day; | ||
651 | unsigned int t_year; | ||
652 | unsigned int t_hrs; | ||
653 | unsigned int t_min; | ||
654 | |||
655 | int count = SSCANF (text, "%02u/%02u/%04u %02u:%02u", &t_mon, &t_day, &t_year, &t_hrs, &t_min); | ||
656 | if ((EOF == count) || (5 != count)) | ||
657 | return GNUNET_SYSERR; | ||
658 | |||
659 | if (t_mon > 12) | ||
660 | return GNUNET_SYSERR; | ||
661 | if (t_day > 31) | ||
662 | return GNUNET_SYSERR; | ||
663 | if (t_hrs > 24) | ||
664 | return GNUNET_SYSERR; | ||
665 | if (t_min > 59) | ||
666 | return GNUNET_SYSERR; | ||
667 | |||
668 | return GNUNET_OK; | ||
669 | } | ||
670 | |||
671 | |||
672 | static const struct GNUNET_TIME_Absolute | ||
673 | convert_string_to_abs_time (const char * text) | ||
674 | { | ||
675 | static struct GNUNET_TIME_Absolute abs_t; | ||
676 | struct tm time; | ||
677 | time_t t; | ||
678 | |||
679 | int t_mon; | ||
680 | int t_day; | ||
681 | int t_year; | ||
682 | int t_hrs; | ||
683 | int t_min; | ||
684 | |||
685 | GNUNET_assert (NULL != text); | ||
686 | |||
687 | if (0 == strcmp(text, EXPIRE_NEVER_STRING)) | ||
688 | return GNUNET_TIME_UNIT_FOREVER_ABS; | ||
689 | |||
690 | memset (&time, '\0', sizeof (struct tm)); | ||
691 | |||
692 | if (GNUNET_SYSERR == check_time(text)) | ||
693 | { | ||
694 | GNUNET_break (0); | ||
695 | return GNUNET_TIME_UNIT_ZERO_ABS; | ||
696 | } | ||
697 | |||
698 | int count = SSCANF (text, "%02d/%02d/%04d %02d:%02d", &t_mon, &t_day, &t_year, &t_hrs, &t_min); | ||
699 | if ((EOF == count) || (5 != count)) | ||
700 | return GNUNET_TIME_UNIT_ZERO_ABS; | ||
701 | |||
702 | time.tm_mon = (t_mon - 1); | ||
703 | time.tm_mday = t_day; | ||
704 | time.tm_year = t_year - 1900; | ||
705 | time.tm_hour = (t_hrs); | ||
706 | time.tm_min = t_min; | ||
707 | |||
708 | t = mktime (&time); | ||
709 | if (-1 == t) | ||
710 | return GNUNET_TIME_UNIT_ZERO_ABS; | ||
711 | |||
712 | abs_t.abs_value = t * 1000; | ||
713 | |||
714 | return abs_t; | ||
715 | } | ||
716 | |||
717 | |||
718 | /** | ||
719 | * The user has edited a 'expiration' cell. Update the model. | ||
720 | * | ||
721 | * @param renderer updated renderer | ||
722 | * @param path the path identifying the edited cell | ||
723 | * @param new_text the new expiration time | ||
724 | * @param user_data unused | ||
725 | */ | ||
726 | void | ||
727 | GNUNET_GNS_GTK_expiration_cellrenderertext_edited_cb (GtkCellRendererText *renderer, | ||
728 | gchar *path, | ||
729 | gchar *new_text, | ||
730 | gpointer user_data) | ||
731 | { | ||
732 | struct GNUNET_GNS_Context * gns = user_data; | ||
733 | GtkTreeIter it; | ||
734 | struct GNUNET_TIME_Absolute abstime; | ||
735 | gboolean is_rel; | ||
736 | char *old_text; | ||
737 | |||
738 | if ((NULL != new_text)) | ||
739 | { | ||
740 | gtk_tree_model_get_iter_from_string(gns->tm, &it, path); | ||
741 | gtk_tree_model_get(gns->tm, &it, | ||
742 | GNS_TREESTORE_COL_EXP_TIME_AS_STR, &old_text, | ||
743 | GNS_TREESTORE_COL_EXP_TIME_IS_REL, &is_rel, | ||
744 | -1); | ||
745 | if (0 == strcmp(new_text, old_text)) | ||
746 | return; | ||
747 | |||
748 | if ((0 == strcmp(new_text,"")) || (0 == strcmp(new_text,EXPIRE_NEVER_STRING))) | ||
749 | { | ||
750 | new_text = EXPIRE_NEVER_STRING; | ||
751 | abstime = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
752 | } | ||
753 | else | ||
754 | { | ||
755 | if (GNUNET_SYSERR == check_time(new_text)) | ||
756 | { | ||
757 | gtk_tree_store_set (gns->ts, &it, | ||
758 | GNS_TREESTORE_COL_EXP_TIME_AS_STR, new_text, | ||
759 | GNS_TREESTORE_COL_EXP_TIME_COLOR, "red", | ||
760 | GNS_TREESTORE_COL_EXP_TIME, 0, | ||
761 | -1); | ||
762 | abstime = GNUNET_TIME_UNIT_ZERO_ABS; | ||
763 | return; | ||
764 | } | ||
765 | /* TODO: fix this when we have relative time */ | ||
766 | if (TRUE == is_rel) | ||
767 | { | ||
768 | abstime = convert_string_to_abs_time(new_text); | ||
769 | } | ||
770 | else | ||
771 | { | ||
772 | abstime = convert_string_to_abs_time(new_text); | ||
773 | } | ||
774 | } | ||
775 | gtk_tree_store_set (gns->ts, &it, | ||
776 | GNS_TREESTORE_COL_EXP_TIME_AS_STR, new_text, | ||
777 | GNS_TREESTORE_COL_EXP_TIME, abstime.abs_value, | ||
778 | GNS_TREESTORE_COL_EXP_TIME_COLOR, NULL, | ||
779 | -1); | ||
780 | check_name_validity_and_commit (gns, path, NULL); | ||
781 | } | ||
782 | } | ||
783 | |||
784 | |||
785 | /** | ||
786 | * The user has edited a 'value' cell. Update the model, | ||
787 | * including the status on the consistency of the value with | ||
788 | * the type. | ||
789 | * | ||
790 | * @param renderer updated renderer | ||
791 | * @param path the path identifying the edited cell | ||
792 | * @param new_text the new value | ||
793 | * @param user_data unused | ||
794 | */ | ||
795 | void | ||
796 | GNUNET_GNS_GTK_value_cellrenderertext_edited_cb (GtkCellRendererText *renderer, | ||
797 | gchar *path, | ||
798 | gchar *new_text, | ||
799 | gpointer user_data) | ||
800 | { | ||
801 | struct GNUNET_GNS_Context *gns = user_data; | ||
802 | GtkTreeModel *tm = GTK_TREE_MODEL(gns->ts); | ||
803 | GtkTreeIter it; | ||
804 | size_t data_size; | ||
805 | void * data; | ||
806 | int type; | ||
807 | gchar * old_value; | ||
808 | |||
809 | if (0 != strcmp(new_text,"")) | ||
810 | { | ||
811 | gtk_tree_model_get_iter_from_string(tm, &it, path); | ||
812 | gtk_tree_model_get(tm, &it, | ||
813 | GNS_TREESTORE_COL_RECORD_TYPE, &type, | ||
814 | GNS_TREESTORE_COL_VAL_AS_STR, &old_value, | ||
815 | -1); | ||
816 | |||
817 | if (old_value != NULL) | ||
818 | { | ||
819 | if (0 == strcmp(new_text, old_value)) | ||
820 | { | ||
821 | GNUNET_free (old_value); | ||
822 | return; | ||
823 | } | ||
824 | GNUNET_free (old_value); | ||
825 | } | ||
826 | |||
827 | if (GNUNET_OK == GNUNET_NAMESTORE_string_to_value (type, | ||
828 | new_text, | ||
829 | &data, | ||
830 | &data_size)) | ||
831 | { | ||
832 | gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_COLOR, NULL, -1); | ||
833 | gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_AS_STR, new_text, -1); | ||
834 | check_name_validity_and_commit (gns, path, NULL); | ||
835 | } | ||
836 | else | ||
837 | { | ||
838 | gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_COLOR, "red", -1); | ||
839 | gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_VAL_AS_STR, new_text, -1); | ||
840 | } | ||
841 | } | ||
842 | } | ||
843 | |||
844 | |||
845 | /** | ||
846 | * The user has edited a 'name' cell. Update the model (and if needed | ||
847 | * create another fresh line for additional records). | ||
848 | * | ||
849 | * @param renderer updated renderer | ||
850 | * @param path the path identifying the edited cell | ||
851 | * @param new_text the new name | ||
852 | * @param user_data unused | ||
853 | */ | ||
854 | void | ||
855 | GNUNET_GNS_GTK_name_cellrenderertext_edited_cb (GtkCellRendererText *renderer, | ||
856 | gchar *path, | ||
857 | gchar *new_text, | ||
858 | gpointer user_data) | ||
859 | { | ||
860 | struct GNUNET_GNS_Context *gns = user_data; | ||
861 | GtkTreeIter it; | ||
862 | GtkTreeIter child; | ||
863 | GtkTreeModel *tm = GTK_TREE_MODEL(gns->ts); | ||
864 | int not_dummy; | ||
865 | char *name; | ||
866 | |||
867 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New text for `%s' is `%s'\n", path, new_text); | ||
868 | if ((0 == strcmp (new_text, NEW_NAME_STR)) || (0 == strcmp (new_text, ""))) | ||
869 | return; | ||
870 | |||
871 | gtk_tree_model_get_iter_from_string(tm, &it, path); | ||
872 | gtk_tree_model_get(tm, &it, GNS_TREESTORE_COL_NOT_DUMMY_ROW, ¬_dummy, -1); | ||
873 | gtk_tree_model_get(tm, &it, GNS_TREESTORE_COL_NAME, &name, -1); | ||
874 | |||
875 | if (not_dummy == GNUNET_NO) | ||
876 | { | ||
877 | /* update name */ | ||
878 | gtk_tree_store_set (gns->ts, &it, | ||
879 | GNS_TREESTORE_COL_NAME, new_text, | ||
880 | GNS_TREESTORE_COL_RECORD_TYPE, 0, | ||
881 | GNS_TREESTORE_COL_RECORD_TYPE_AS_STR, _(NEW_RECORD_STR), | ||
882 | GNS_TREESTORE_COL_NOT_DUMMY_ROW, GNUNET_YES, | ||
883 | -1); | ||
884 | check_name_validity_and_commit (gns, gtk_tree_model_get_string_from_iter(gns->tm, &it), name); | ||
885 | |||
886 | /* add a new dummy line */ | ||
887 | gtk_tree_store_insert_with_values (gns->ts, &it,NULL, 0, | ||
888 | GNS_TREESTORE_COL_NAME, _(NEW_NAME_STR), | ||
889 | GNS_TREESTORE_COL_NAME_IS_VISIBLE, TRUE, | ||
890 | GNS_TREESTORE_COL_RECORD_TYPE, 1, | ||
891 | GNS_TREESTORE_COL_NOT_DUMMY_ROW, GNUNET_NO, | ||
892 | GNS_TREESTORE_COL_IS_RECORD_ROW, GNUNET_NO, | ||
893 | -1); | ||
894 | } | ||
895 | else | ||
896 | { | ||
897 | /* update name */ | ||
898 | gtk_tree_store_set (gns->ts, &it, GNS_TREESTORE_COL_NAME, new_text, -1); | ||
899 | |||
900 | if (TRUE == gtk_tree_model_iter_children (gns->tm, &child, &it)) | ||
901 | { | ||
902 | do | ||
903 | { | ||
904 | gtk_tree_store_set (gns->ts, &child, | ||
905 | GNS_TREESTORE_COL_NAME, &new_text, | ||
906 | -1); | ||
907 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New text for `%s' is `%s'\n", path, new_text); | ||
908 | } | ||
909 | while (TRUE == gtk_tree_model_iter_next (gns->tm, &child)); | ||
910 | } | ||
911 | |||
912 | check_name_validity_and_commit (gns, gtk_tree_model_get_string_from_iter(gns->tm, &it), name); | ||
913 | } | ||
914 | |||
915 | if (GNUNET_SYSERR == GNUNET_NAMESTORE_check_name (new_text)) | ||
916 | { | ||
917 | gtk_tree_store_set (gns->ts, &it, | ||
918 | GNS_TREESTORE_COL_NAME_COLOR, "red", | ||
919 | -1); | ||
920 | } | ||
921 | else | ||
922 | { | ||
923 | gtk_tree_store_set (gns->ts, &it, | ||
924 | GNS_TREESTORE_COL_NAME_COLOR, NULL, | ||
925 | -1); | ||
926 | } | ||
927 | } | ||
928 | |||
929 | |||
930 | /** | ||
931 | * The zone treeview pop up menu is supposed to be created. | ||
932 | * (Note: this is not the only method that might need to be | ||
933 | * written to handle events to create pop up menus; right-clicks | ||
934 | * might need to be managed separately). | ||
935 | * | ||
936 | * @param widget the widget | ||
937 | * @param user_data unused | ||
938 | * @return TRUE if a menu was activated | ||
939 | */ | ||
940 | gboolean | ||
941 | GNUNET_GNS_GTK_main_treeview_popup_menu_cb (GtkWidget *widget, | ||
942 | gpointer user_data) | ||
943 | { | ||
944 | struct GNUNET_GNS_Context *gns = user_data; | ||
945 | GtkTreeModel *tm; | ||
946 | GtkTreeIter it; | ||
947 | GtkMenu *popup; | ||
948 | GtkTreeSelection * ts; | ||
949 | int not_dummy; | ||
950 | |||
951 | ts = gtk_tree_view_get_selection(gns->tv); | ||
952 | if (! gtk_tree_selection_get_selected (ts, &tm, &it)) | ||
953 | return TRUE; | ||
954 | gtk_tree_model_get(gns->tm, &it, GNS_TREESTORE_COL_NOT_DUMMY_ROW, ¬_dummy, -1); | ||
955 | if (GNUNET_NO == not_dummy) | ||
956 | return TRUE; | ||
957 | |||
958 | popup = GTK_MENU(gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_delete_popup_menu")); | ||
959 | gtk_widget_show_all (GTK_WIDGET(popup)); | ||
960 | gtk_menu_popup(popup, NULL, NULL, NULL, NULL, 0, 0); | ||
961 | return TRUE; | ||
962 | } | ||
963 | |||
964 | |||
965 | static void | ||
966 | set_relative_expiration_time (struct GNUNET_GNS_Context *gns, struct GNUNET_TIME_Relative reltime) | ||
967 | { | ||
968 | GtkTreeIter it; | ||
969 | GtkTreeIter parent; | ||
970 | GtkCellRendererText *renderer; | ||
971 | GtkTreeModel *tm; | ||
972 | GtkTreeSelection * ts = gtk_tree_view_get_selection(gns->tv); | ||
973 | gboolean has_parent; | ||
974 | struct GNUNET_TIME_Absolute abstime; | ||
975 | char *path; | ||
976 | int not_dummy; | ||
977 | |||
978 | if (! gtk_tree_selection_get_selected (ts, &tm, &it)) | ||
979 | return; | ||
980 | |||
981 | gtk_tree_model_get(tm, &it, GNS_TREESTORE_COL_NOT_DUMMY_ROW, ¬_dummy, -1); | ||
982 | if (GNUNET_NO == not_dummy) | ||
983 | return; | ||
984 | |||
985 | /* Has parent? */ | ||
986 | has_parent = gtk_tree_model_iter_parent (tm, &parent, &it); | ||
987 | |||
988 | if (FALSE == has_parent) | ||
989 | return; | ||
990 | |||
991 | abstime = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), reltime); | ||
992 | |||
993 | /* this is a single record */ | ||
994 | renderer = GTK_CELL_RENDERER_TEXT((gtk_builder_get_object (gns->builder, "GNUNET_GNS_GTK_name_cellrenderertext"))); | ||
995 | path = gtk_tree_model_get_string_from_iter (tm, &it); | ||
996 | GNUNET_GNS_GTK_expiration_cellrenderertext_edited_cb (renderer, | ||
997 | path, | ||
998 | convert_time_to_string (abstime), | ||
999 | gns); | ||
1000 | } | ||
1001 | |||
1002 | |||
1003 | gboolean | ||
1004 | GNUNET_GNS_GTK_main_treeview_popup_menu_exp1d_cb (GtkWidget *widget, | ||
1005 | gpointer user_data) | ||
1006 | { | ||
1007 | set_relative_expiration_time (user_data, GNUNET_TIME_UNIT_DAYS); | ||
1008 | return TRUE; | ||
1009 | } | ||
1010 | |||
1011 | |||
1012 | gboolean | ||
1013 | GNUNET_GNS_GTK_main_treeview_popup_menu_exp1w_cb (GtkWidget *widget, | ||
1014 | gpointer user_data) | ||
1015 | { | ||
1016 | set_relative_expiration_time (user_data, GNUNET_TIME_UNIT_WEEKS); | ||
1017 | return TRUE; | ||
1018 | } | ||
1019 | |||
1020 | |||
1021 | gboolean | ||
1022 | GNUNET_GNS_GTK_main_treeview_popup_menu_exp1y_cb (GtkWidget *widget, | ||
1023 | gpointer user_data) | ||
1024 | { | ||
1025 | set_relative_expiration_time (user_data, GNUNET_TIME_UNIT_YEARS); | ||
1026 | return TRUE; | ||
1027 | } | ||
1028 | |||
1029 | |||
1030 | gboolean | ||
1031 | GNUNET_GNS_GTK_main_treeview_popup_menu_expinf_cb (GtkWidget *widget, | ||
1032 | gpointer user_data) | ||
1033 | { | ||
1034 | set_relative_expiration_time (user_data, GNUNET_TIME_UNIT_FOREVER_REL); | ||
1035 | return TRUE; | ||
1036 | } | ||
1037 | |||
1038 | |||
1039 | gboolean | ||
1040 | GNUNET_GNS_GTK_main_treeview_button_press_popup_menu_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data) | ||
1041 | { | ||
1042 | /* Check for right click*/ | ||
1043 | if (NULL == widget) | ||
1044 | return FALSE; | ||
1045 | if (event->type == GDK_BUTTON_PRESS && event->button == 3) | ||
1046 | GNUNET_GNS_GTK_main_treeview_popup_menu_cb (widget, user_data); | ||
1047 | return FALSE; | ||
1048 | } | ||
1049 | |||
1050 | |||
1051 | gboolean | ||
1052 | GNUNET_GNS_GTK_main_treeview_key_press_popup_menu_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data) | ||
1053 | { | ||
1054 | /* Check for delete key */ | ||
1055 | if ((event->type == GDK_KEY_PRESS) && (GDK_KEY_Delete == event->keyval)) | ||
1056 | GNUNET_GNS_GTK_main_treeview_popup_menu_cb (widget, user_data); | ||
1057 | return FALSE; | ||
1058 | } | ||
1059 | |||
1060 | |||
1061 | struct ZoneIteration_Context | ||
1062 | { | ||
1063 | struct GNUNET_GNS_Context *gns; | ||
1064 | struct GNUNET_CRYPTO_ShortHashCode zone; | ||
1065 | struct GNUNET_NAMESTORE_ZoneIterator * it; | ||
1066 | char *label; | ||
1067 | }; | ||
1068 | |||
1069 | |||
1070 | void | ||
1071 | GNUNET_GNS_GTK_delete_popup_menu_delete_cb (GtkMenuItem *menuitem, | ||
1072 | gpointer user_data) | ||
1073 | { | ||
1074 | struct GNUNET_GNS_Context *gns = user_data; | ||
1075 | GtkTreeIter it; | ||
1076 | GtkTreeModel *tm; | ||
1077 | GtkTreeSelection * ts; | ||
1078 | int not_dummy; | ||
1079 | char *path; | ||
1080 | |||
1081 | ts = gtk_tree_view_get_selection(gns->tv); | ||
1082 | if (gtk_tree_selection_get_selected (ts, &tm, &it)) | ||
1083 | { | ||
1084 | gtk_tree_model_get(tm, &it, GNS_TREESTORE_COL_NOT_DUMMY_ROW, ¬_dummy, -1); | ||
1085 | if (GNUNET_NO == not_dummy) | ||
1086 | return; /* do not delete the dummy line */ | ||
1087 | |||
1088 | path = gtk_tree_model_get_string_from_iter (gns->tm, &it); | ||
1089 | check_name_validity_and_remove(gns, path); | ||
1090 | g_free (path); | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | |||
1095 | static void | ||
1096 | zone_iteration_proc (void *cls, | ||
1097 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, | ||
1098 | struct GNUNET_TIME_Absolute expire, | ||
1099 | const char *name, | ||
1100 | unsigned int rd_count, | ||
1101 | const struct GNUNET_NAMESTORE_RecordData *rd, | ||
1102 | const struct GNUNET_CRYPTO_RsaSignature *signature) | ||
1103 | { | ||
1104 | struct ZoneIteration_Context * zc_ctx = cls; | ||
1105 | GtkTreeIter iter_name; | ||
1106 | GtkTreeIter iter_record; | ||
1107 | GtkEntry *pseu_entry; | ||
1108 | int c; | ||
1109 | int time_is_relative; | ||
1110 | |||
1111 | char *exp; | ||
1112 | char *val; | ||
1113 | char * type_str; | ||
1114 | int public; | ||
1115 | guint64 exp_t; | ||
1116 | |||
1117 | GNUNET_assert (zc_ctx != NULL); | ||
1118 | if ((NULL == zone_key) && (NULL == name)) | ||
1119 | { | ||
1120 | struct GNUNET_CRYPTO_ShortHashAsciiEncoded shenc; | ||
1121 | GNUNET_CRYPTO_short_hash_to_enc(&zc_ctx->zone, &shenc); | ||
1122 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone `%s 'iteration done\n", &shenc); | ||
1123 | pseu_entry = GTK_ENTRY((gtk_builder_get_object (zc_ctx->gns->builder, "GNUNET_GNS_GTK_pseu_entry"))); | ||
1124 | if (zc_ctx->label == NULL) | ||
1125 | GNUNET_asprintf(&zc_ctx->label, "%s", PSEU_EMPTY_STR); | ||
1126 | gtk_entry_set_text (pseu_entry, zc_ctx->label); | ||
1127 | zc_ctx->gns->iteration = GNUNET_NO; | ||
1128 | GNUNET_free (zc_ctx->label); | ||
1129 | GNUNET_free (zc_ctx); | ||
1130 | return; | ||
1131 | } | ||
1132 | |||
1133 | |||
1134 | struct GNUNET_CRYPTO_ShortHashAsciiEncoded shenc; | ||
1135 | GNUNET_CRYPTO_short_hash_to_enc(&zc_ctx->zone, &shenc); | ||
1136 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone `%s' iteration result `%s', %u records\n", | ||
1137 | &shenc, name, rd_count); | ||
1138 | |||
1139 | GNUNET_assert(GTK_IS_TREE_STORE(zc_ctx->gns->ts)); | ||
1140 | gtk_tree_store_append(zc_ctx->gns->ts, &iter_name, NULL); | ||
1141 | gtk_tree_store_set(zc_ctx->gns->ts, &iter_name, | ||
1142 | GNS_TREESTORE_COL_NAME, name, | ||
1143 | GNS_TREESTORE_COL_NAME_IS_VISIBLE, TRUE, | ||
1144 | GNS_TREESTORE_COL_RECORD_TYPE, 0, | ||
1145 | GNS_TREESTORE_COL_RECORD_TYPE_AS_STR, _(NEW_RECORD_STR), | ||
1146 | GNS_TREESTORE_COL_IS_RECORD_ROW, GNUNET_NO, | ||
1147 | GNS_TREESTORE_COL_NOT_DUMMY_ROW, GNUNET_YES, | ||
1148 | -1); | ||
1149 | |||
1150 | if (GNUNET_SYSERR == GNUNET_NAMESTORE_check_name (name)) | ||
1151 | { | ||
1152 | gtk_tree_store_set (zc_ctx->gns->ts, &iter_name, | ||
1153 | GNS_TREESTORE_COL_NAME_COLOR, "red", | ||
1154 | -1); | ||
1155 | } | ||
1156 | /* Append elements for records */ | ||
1157 | for (c = 0; c < rd_count; c ++) | ||
1158 | { | ||
1159 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %u: type %u flags %u expiration %llu data_size %u\n", | ||
1160 | c, rd[c].record_type, rd[c].flags, rd[c].expiration_time, rd[c].data_size); | ||
1161 | |||
1162 | /* Set public toggle */ | ||
1163 | if ((rd[c].flags & GNUNET_NAMESTORE_RF_PRIVATE) == GNUNET_NAMESTORE_RF_PRIVATE) | ||
1164 | { | ||
1165 | public = GNUNET_NO; | ||
1166 | } | ||
1167 | else | ||
1168 | { | ||
1169 | public = GNUNET_YES; | ||
1170 | } | ||
1171 | |||
1172 | /* Expiration time */ | ||
1173 | time_is_relative = GNUNET_NO; | ||
1174 | |||
1175 | if (GNUNET_YES == time_is_relative) | ||
1176 | { | ||
1177 | /* TODO: FIX THIS WHEN WE HAVE RELATIVE TIME */ | ||
1178 | struct GNUNET_TIME_Relative rel_time = GNUNET_TIME_UNIT_ZERO; | ||
1179 | struct GNUNET_TIME_Absolute exp_abs; | ||
1180 | exp_abs = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), rel_time); | ||
1181 | exp_t = exp_abs.abs_value; | ||
1182 | exp = convert_time_to_string (exp_abs); | ||
1183 | } | ||
1184 | else | ||
1185 | { | ||
1186 | struct GNUNET_TIME_Absolute exp_abs; | ||
1187 | |||
1188 | exp_abs.abs_value = rd[c].expiration_time; | ||
1189 | exp_t = exp_abs.abs_value; | ||
1190 | exp = convert_time_to_string (exp_abs); | ||
1191 | } | ||
1192 | /* value */ | ||
1193 | val = GNUNET_NAMESTORE_value_to_string (rd[c].record_type, | ||
1194 | rd[c].data, | ||
1195 | rd[c].data_size); | ||
1196 | if (NULL == val) | ||
1197 | GNUNET_asprintf(&val, "%s", EXPIRE_INVALID_STRING); | ||
1198 | |||
1199 | if (NULL != GNUNET_NAMESTORE_number_to_typename(rd[c].record_type)) | ||
1200 | type_str = strdup (GNUNET_NAMESTORE_number_to_typename(rd[c].record_type)); | ||
1201 | else | ||
1202 | GNUNET_asprintf(&type_str, "%s", EXPIRE_INVALID_STRING); | ||
1203 | |||
1204 | if ((0 ==strcmp (name, ROOT_STR)) && (GNUNET_NAMESTORE_TYPE_PSEU == rd[c].record_type)) | ||
1205 | { | ||
1206 | zc_ctx->label = strdup(val); | ||
1207 | zc_ctx->gns->iteration = GNUNET_YES; | ||
1208 | } | ||
1209 | else | ||
1210 | { | ||
1211 | gtk_tree_store_insert_with_values(zc_ctx->gns->ts, &iter_record , &iter_name, 0, | ||
1212 | GNS_TREESTORE_COL_NAME, name, | ||
1213 | GNS_TREESTORE_COL_NAME_IS_VISIBLE, FALSE, | ||
1214 | GNS_TREESTORE_COL_RECORD_TYPE, rd[c].record_type, | ||
1215 | GNS_TREESTORE_COL_RECORD_TYPE_AS_STR, type_str, | ||
1216 | GNS_TREESTORE_COL_IS_PUBLIC, public, | ||
1217 | GNS_TREESTORE_COL_EXP_TIME, exp_t, | ||
1218 | GNS_TREESTORE_COL_EXP_TIME_AS_STR, exp, | ||
1219 | GNS_TREESTORE_COL_EXP_TIME_IS_REL, time_is_relative, | ||
1220 | GNS_TREESTORE_COL_VAL_AS_STR, val, | ||
1221 | GNS_TREESTORE_COL_IS_RECORD_ROW, GNUNET_YES, | ||
1222 | GNS_TREESTORE_COL_NOT_DUMMY_ROW, GNUNET_YES, | ||
1223 | -1); | ||
1224 | } | ||
1225 | GNUNET_free (type_str); | ||
1226 | GNUNET_free (exp); | ||
1227 | GNUNET_free (val); | ||
1228 | } | ||
1229 | |||
1230 | GNUNET_NAMESTORE_zone_iterator_next(zc_ctx->it); | ||
1231 | } | ||
1232 | |||
1233 | |||
1234 | /** | ||
1235 | * The zone treeview was realized. Setup the model. | ||
1236 | * | ||
1237 | * @param widget the widget | ||
1238 | * @param user_data unused | ||
1239 | */ | ||
1240 | void | ||
1241 | GNUNET_GNS_GTK_main_treeview_realize_cb (GtkWidget *widget, | ||
1242 | gpointer user_data) | ||
1243 | { | ||
1244 | struct GNUNET_GNS_Context *gns = user_data; | ||
1245 | struct ZoneIteration_Context *zc_ctx; | ||
1246 | GtkTreeIter toplevel; | ||
1247 | |||
1248 | /* Append a top level row and leave it empty */ | ||
1249 | gtk_tree_store_insert_with_values(gns->ts, &toplevel, NULL, 0, | ||
1250 | GNS_TREESTORE_COL_NAME, _(NEW_NAME_STR), | ||
1251 | GNS_TREESTORE_COL_NAME_IS_VISIBLE, TRUE, | ||
1252 | GNS_TREESTORE_COL_RECORD_TYPE, 1, | ||
1253 | GNS_TREESTORE_COL_IS_RECORD_ROW, GNUNET_NO, | ||
1254 | GNS_TREESTORE_COL_NOT_DUMMY_ROW, GNUNET_NO, | ||
1255 | -1); | ||
1256 | |||
1257 | zc_ctx = GNUNET_malloc (sizeof (struct ZoneIteration_Context)); | ||
1258 | zc_ctx->gns = user_data; | ||
1259 | zc_ctx->zone = gns->zone; | ||
1260 | zc_ctx->it = GNUNET_NAMESTORE_zone_iteration_start(gns->ns, &gns->zone, | ||
1261 | GNUNET_NAMESTORE_RF_NONE, | ||
1262 | GNUNET_NAMESTORE_RF_NONE, | ||
1263 | &zone_iteration_proc, | ||
1264 | zc_ctx); | ||
1265 | } | ||
1266 | |||
1267 | |||
1268 | /* end of gnunet-gns-gtk_zone.c */ | ||