diff options
Diffstat (limited to 'src/fs/gnunet-fs-gtk_publish-edit-dialog.c')
-rw-r--r-- | src/fs/gnunet-fs-gtk_publish-edit-dialog.c | 1163 |
1 files changed, 1163 insertions, 0 deletions
diff --git a/src/fs/gnunet-fs-gtk_publish-edit-dialog.c b/src/fs/gnunet-fs-gtk_publish-edit-dialog.c new file mode 100644 index 00000000..6dcf5653 --- /dev/null +++ b/src/fs/gnunet-fs-gtk_publish-edit-dialog.c | |||
@@ -0,0 +1,1163 @@ | |||
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_publish-edit-dialog.c | ||
23 | * @author Christian Grothoff | ||
24 | */ | ||
25 | #include "gnunet-fs-gtk-common.h" | ||
26 | #include "gnunet-fs-gtk-edit_publish_dialog.h" | ||
27 | #include "gnunet-fs-gtk.h" | ||
28 | #include <gnunet/gnunet_util_lib.h> | ||
29 | |||
30 | #include "metatypes.c" | ||
31 | |||
32 | |||
33 | /** | ||
34 | * Internal state kept for each "edit" dialog where the user can edit | ||
35 | * publishing information for a file. | ||
36 | */ | ||
37 | struct EditPublicationDialogContext | ||
38 | { | ||
39 | /** | ||
40 | * Builder for the dialog. | ||
41 | */ | ||
42 | GtkBuilder *builder; | ||
43 | |||
44 | /** | ||
45 | * The 'window' object for the dialog. | ||
46 | */ | ||
47 | GtkWindow *edit_publication_window; | ||
48 | |||
49 | /** | ||
50 | * The confirmation button which closes the dialog (only sensitive | ||
51 | * if the values entered are valid). | ||
52 | */ | ||
53 | GtkWidget *confirm_button; | ||
54 | |||
55 | /** | ||
56 | * Tree view showing the meta data for the file. | ||
57 | */ | ||
58 | GtkTreeView *meta_treeview; | ||
59 | |||
60 | /** | ||
61 | * Tree view showing the keywords for the file. | ||
62 | */ | ||
63 | GtkTreeView *keywords_treeview; | ||
64 | |||
65 | /** | ||
66 | * Image showing the preview image for the file. | ||
67 | */ | ||
68 | GtkImage *preview_image; | ||
69 | |||
70 | /** | ||
71 | * Combo box where the user can select the anonymity level. | ||
72 | */ | ||
73 | GtkComboBox *anonymity_combo; | ||
74 | |||
75 | /** | ||
76 | * Liststore of possible publication types. | ||
77 | */ | ||
78 | GtkListStore *pubtypes_liststore; | ||
79 | |||
80 | /** | ||
81 | * Liststore of all possible meta types the user can choose from. | ||
82 | * (updated to based on the selected publication type). | ||
83 | */ | ||
84 | GtkListStore *metatypes_liststore; | ||
85 | |||
86 | /** | ||
87 | * Liststore showing the meta data of the file (associated with | ||
88 | * the 'meta_treeview'. | ||
89 | */ | ||
90 | GtkListStore *meta_liststore; | ||
91 | |||
92 | /** | ||
93 | * Liststore with the keywords of the file (associated with the | ||
94 | * 'keywords_treeview'. | ||
95 | */ | ||
96 | GtkListStore *keywords_liststore; | ||
97 | |||
98 | /** | ||
99 | * Spin button to select content priority level for the file. | ||
100 | */ | ||
101 | GtkSpinButton *priority_spin; | ||
102 | |||
103 | /** | ||
104 | * Spin button to select the expiration year. | ||
105 | */ | ||
106 | GtkSpinButton *expiration_year_spin; | ||
107 | |||
108 | /** | ||
109 | * Spin button to select the replication level. | ||
110 | */ | ||
111 | GtkSpinButton *replication_spin; | ||
112 | |||
113 | /** | ||
114 | * Entry line for adding additional keywords. | ||
115 | */ | ||
116 | GtkEntry *keyword_entry; | ||
117 | |||
118 | /** | ||
119 | * Entry line for setting a namespace root (possibly invisible). | ||
120 | */ | ||
121 | GtkEntry *root_entry; | ||
122 | |||
123 | /** | ||
124 | * Entry line to check indexing vs. inserting (possibly invisible) | ||
125 | */ | ||
126 | GtkToggleButton *index_checkbutton; | ||
127 | |||
128 | /** | ||
129 | * Type ID of the last selected item in the GtkCellRendererCombo | ||
130 | * of the meta data tree view. | ||
131 | */ | ||
132 | gint meta_combo_selected_type_id; | ||
133 | |||
134 | /** | ||
135 | * Continuation to call once the dialog has been closed | ||
136 | */ | ||
137 | GNUNET_FS_GTK_EditPublishDialogCallback cb; | ||
138 | |||
139 | /** | ||
140 | * Closure for 'cb'. | ||
141 | */ | ||
142 | void *cb_cls; | ||
143 | |||
144 | /** | ||
145 | * Briefly used temporary meta data set. | ||
146 | */ | ||
147 | struct GNUNET_CONTAINER_MetaData *md; | ||
148 | |||
149 | /** | ||
150 | * Information about the file being published as seen by the FS-API. | ||
151 | * This is what we are primarily editing. | ||
152 | */ | ||
153 | struct GNUNET_FS_FileInformation *fip; | ||
154 | |||
155 | /** | ||
156 | * Flag to track if we changed the preview and thus should keep/discard | ||
157 | * binary metadata. | ||
158 | */ | ||
159 | int preview_changed; | ||
160 | |||
161 | /** | ||
162 | * Is this operation for a directory? | ||
163 | */ | ||
164 | int is_directory; | ||
165 | |||
166 | /** | ||
167 | * Is it allowed for the user to supply keywords in this dialog? | ||
168 | */ | ||
169 | int allow_no_keywords; | ||
170 | |||
171 | }; | ||
172 | |||
173 | |||
174 | /** | ||
175 | * Free resources associated with the edit publication dialog. | ||
176 | * | ||
177 | * @param ctx the context of the dialog to release resources of | ||
178 | */ | ||
179 | static void | ||
180 | free_edit_dialog_context (struct EditPublicationDialogContext *ctx) | ||
181 | { | ||
182 | gtk_widget_destroy (GTK_WIDGET (ctx->edit_publication_window)); | ||
183 | // FIXME-LEAK: destroy builder! | ||
184 | GNUNET_free (ctx); | ||
185 | } | ||
186 | |||
187 | |||
188 | |||
189 | /* ****************** metadata editing ******************** */ | ||
190 | |||
191 | |||
192 | |||
193 | /** | ||
194 | * Update the set of metatypes listed in the dialog based on the | ||
195 | * given code. | ||
196 | * | ||
197 | * @param ctx main dialog context | ||
198 | * @param code which set of metatypes is desired? | ||
199 | */ | ||
200 | static void | ||
201 | change_metatypes (struct EditPublicationDialogContext *ctx, gint code) | ||
202 | { | ||
203 | gint pubtype_count; | ||
204 | gint max_type; | ||
205 | gint i; | ||
206 | GtkTreeIter iter; | ||
207 | |||
208 | /* double-check that 'code' is valid */ | ||
209 | for (pubtype_count = 0; NULL != types[pubtype_count]; pubtype_count++) ; | ||
210 | GNUNET_assert (code < pubtype_count); | ||
211 | |||
212 | /* clear existing selection of metatypes */ | ||
213 | gtk_list_store_clear (ctx->metatypes_liststore); | ||
214 | max_type = EXTRACTOR_metatype_get_max (); | ||
215 | /* add new types based on selection */ | ||
216 | for (i = 0; types[code][i] != EXTRACTOR_METATYPE_RESERVED; i++) | ||
217 | if ( (types[code][i] < max_type) && (types[code][i] > 0) ) | ||
218 | gtk_list_store_insert_with_values (ctx->metatypes_liststore, | ||
219 | &iter, G_MAXINT, | ||
220 | 0, types[code][i], | ||
221 | 1, EXTRACTOR_METAFORMAT_UTF8, | ||
222 | 2, EXTRACTOR_metatype_to_string (types [code][i]), | ||
223 | 3, EXTRACTOR_metatype_to_description (types[code][i]), | ||
224 | -1); | ||
225 | } | ||
226 | |||
227 | |||
228 | /** | ||
229 | * The user has selected a different publication type. | ||
230 | * Update the meta type selection. | ||
231 | * | ||
232 | * @param widget the publication type combo box widget | ||
233 | * @param user_data the 'struct EditPublicationDialogContext' | ||
234 | */ | ||
235 | void | ||
236 | GNUNET_GTK_edit_publication_type_combo_changed_cb (GtkComboBox * widget, | ||
237 | gpointer user_data) | ||
238 | { | ||
239 | struct EditPublicationDialogContext *ctx = user_data; | ||
240 | GtkTreeIter iter; | ||
241 | gint code; | ||
242 | |||
243 | if (! gtk_combo_box_get_active_iter (widget, &iter)) | ||
244 | return; | ||
245 | gtk_tree_model_get (GTK_TREE_MODEL (ctx->pubtypes_liststore), &iter, 0, &code, -1); | ||
246 | change_metatypes (ctx, code); | ||
247 | } | ||
248 | |||
249 | |||
250 | /** | ||
251 | * The user has changed the selection in the meta data tree view. | ||
252 | * Update the sensitivity of the 'delete' button. | ||
253 | * | ||
254 | * @param ts the tree selection object | ||
255 | * @param user_data the 'struct EditPublicationDialogContext' | ||
256 | */ | ||
257 | /* FIXME-UNCLEAN: connect this signal via glade (modern versions of Glade support this) */ | ||
258 | static void | ||
259 | metadata_selection_changed_cb (GtkTreeSelection *ts, | ||
260 | gpointer user_data) | ||
261 | { | ||
262 | struct EditPublicationDialogContext *ctx = user_data; | ||
263 | |||
264 | gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object | ||
265 | (ctx->builder, | ||
266 | "GNUNET_GTK_edit_publication_delete_button")), | ||
267 | gtk_tree_selection_get_selected (ts, NULL, NULL)); | ||
268 | } | ||
269 | |||
270 | |||
271 | /** | ||
272 | * The user changed (and confirmed the change) the type of a | ||
273 | * meta-data item in the meta data tree view. Update the type and | ||
274 | * text in the list store accordingly. | ||
275 | * | ||
276 | * @param renderer widget where the change happened | ||
277 | * @param path which item was changed in the tree view | ||
278 | * @param new_text new value for the item | ||
279 | * @param user_data the 'struct EditPublicationDialogContext' | ||
280 | */ | ||
281 | void | ||
282 | GNUNET_GTK_edit_publication_metadata_tree_view_type_renderer_edited_cb (GtkCellRendererText *renderer, | ||
283 | gchar * path, | ||
284 | gchar * new_text, | ||
285 | gpointer user_data) | ||
286 | { | ||
287 | struct EditPublicationDialogContext *ctx = user_data; | ||
288 | GtkTreeIter iter; | ||
289 | gint type_id; | ||
290 | |||
291 | if (! gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (ctx->meta_liststore), | ||
292 | &iter, | ||
293 | path)) | ||
294 | { | ||
295 | GNUNET_break (0); | ||
296 | return; | ||
297 | } | ||
298 | if (-1 == ctx->meta_combo_selected_type_id) | ||
299 | { | ||
300 | GNUNET_break (0); | ||
301 | return; | ||
302 | } | ||
303 | type_id = ctx->meta_combo_selected_type_id; | ||
304 | ctx->meta_combo_selected_type_id = -1; | ||
305 | gtk_list_store_set (ctx->meta_liststore, &iter, | ||
306 | 0, type_id, | ||
307 | 1, EXTRACTOR_METAFORMAT_UTF8, | ||
308 | 2, EXTRACTOR_metatype_to_string (type_id), | ||
309 | 4, EXTRACTOR_metatype_to_description (type_id), | ||
310 | -1); | ||
311 | } | ||
312 | |||
313 | |||
314 | /** | ||
315 | * The user changed the type of a meta-data item in the meta data | ||
316 | * tree view. Obtain the selected type_id and store it in | ||
317 | * the 'meta_combo_selected_type_id' field for use by | ||
318 | * 'GNUNET_GTK_edit_publication_metadata_tree_view_type_renderer_edited_cb'. | ||
319 | * | ||
320 | * @param combo combo box that was dropped down | ||
321 | * @param path which item was changed in the tree view | ||
322 | * @param new_iter item that is now selected in the drop-down combo box | ||
323 | * @param user_data the 'struct EditPublicationDialogContext' | ||
324 | */ | ||
325 | void | ||
326 | GNUNET_GTK_edit_publication_metadata_tree_view_type_renderer_changed_cb (GtkCellRendererCombo * combo, | ||
327 | gchar * path_string, | ||
328 | GtkTreeIter * new_iter, | ||
329 | gpointer user_data) | ||
330 | { | ||
331 | struct EditPublicationDialogContext *ctx = user_data; | ||
332 | GtkTreeModel *combo_model; | ||
333 | gint type_id; | ||
334 | |||
335 | g_object_get (combo, | ||
336 | "model", &combo_model, NULL); | ||
337 | gtk_tree_model_get (combo_model, new_iter, | ||
338 | 0, &type_id, | ||
339 | -1); | ||
340 | ctx->meta_combo_selected_type_id = type_id; | ||
341 | } | ||
342 | |||
343 | |||
344 | /** | ||
345 | * The user changed (and confirmed the change) the value of a | ||
346 | * meta-data item in the meta data tree view. Update the value | ||
347 | * in the list store accordingly. | ||
348 | * | ||
349 | * @param renderer widget where the change happened | ||
350 | * @param path which item was changed in the tree view | ||
351 | * @param new_text new value for the item | ||
352 | * @param user_data the 'struct EditPublicationDialogContext' | ||
353 | */ | ||
354 | void | ||
355 | GNUNET_GTK_edit_publication_metadata_tree_view_value_renderer_edited_cb (GtkCellRendererText * renderer, | ||
356 | gchar * path, | ||
357 | gchar * new_text, | ||
358 | gpointer user_data) | ||
359 | { | ||
360 | struct EditPublicationDialogContext *ctx = user_data; | ||
361 | GtkTreeIter iter; | ||
362 | gint metatype; | ||
363 | char *avalue; | ||
364 | const char *ivalue; | ||
365 | size_t slen; | ||
366 | char *pos; | ||
367 | |||
368 | if (! gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (ctx->meta_liststore), | ||
369 | &iter, | ||
370 | path)) | ||
371 | { | ||
372 | GNUNET_break (0); | ||
373 | return; | ||
374 | } | ||
375 | |||
376 | gtk_tree_model_get (GTK_TREE_MODEL (ctx->meta_liststore), &iter, | ||
377 | 0, &metatype, -1); | ||
378 | if (metatype == EXTRACTOR_METATYPE_FILENAME) | ||
379 | { | ||
380 | /* apply filename rules */ | ||
381 | /* First, use UNIX-style separators */ | ||
382 | avalue = GNUNET_strdup (new_text); | ||
383 | while (NULL != (pos = strstr (avalue, "\\"))) | ||
384 | *pos = '/'; | ||
385 | |||
386 | /* if user put '/' at the end, remove it' */ | ||
387 | slen = strlen (avalue); | ||
388 | while ( (slen > 1) && (avalue[slen - 1] == '\\')) | ||
389 | { | ||
390 | avalue[slen - 1] = '\0'; | ||
391 | slen--; | ||
392 | } | ||
393 | |||
394 | /* However, directories must end with '/', so add it */ | ||
395 | if ( (new_text[strlen (new_text) - 1] != '/') && | ||
396 | ctx->is_directory ) | ||
397 | { | ||
398 | char * tmp; | ||
399 | |||
400 | GNUNET_asprintf (&tmp, "%s/", avalue); | ||
401 | GNUNET_free (avalue); | ||
402 | avalue = tmp; | ||
403 | } | ||
404 | |||
405 | /* Also, replace '../' everywhere with "___" */ | ||
406 | while (NULL != (pos = strstr (avalue, "../"))) | ||
407 | memset (pos, '_', 3); | ||
408 | |||
409 | ivalue = avalue; | ||
410 | } | ||
411 | else | ||
412 | { | ||
413 | ivalue = new_text; | ||
414 | avalue = NULL; | ||
415 | } | ||
416 | gtk_list_store_set (ctx->meta_liststore, &iter, | ||
417 | 3, ivalue, | ||
418 | -1); | ||
419 | GNUNET_free_non_null (avalue); | ||
420 | } | ||
421 | |||
422 | |||
423 | /** | ||
424 | * The user has pushed the 'add' button for metadata. Add a 'dummy' value | ||
425 | * to our meta data store (to be edited by the user). | ||
426 | * | ||
427 | * @param button the 'add' button | ||
428 | * @param user_data the 'struct EditPublicationDialogContext' | ||
429 | */ | ||
430 | void | ||
431 | GNUNET_GTK_edit_publication_add_button_clicked_cb (GtkButton * button, | ||
432 | gpointer user_data) | ||
433 | { | ||
434 | struct EditPublicationDialogContext *ctx = user_data; | ||
435 | GtkTreeIter iter; | ||
436 | |||
437 | gtk_list_store_insert_with_values (ctx->meta_liststore, | ||
438 | &iter, 0, | ||
439 | 0, 0, | ||
440 | 1, EXTRACTOR_METAFORMAT_UTF8, | ||
441 | 2, _("Select a type"), | ||
442 | 3, _("Specify a value"), | ||
443 | 4, NULL, | ||
444 | -1); | ||
445 | } | ||
446 | |||
447 | |||
448 | /** | ||
449 | * The user has pushed the 'del' button for metadata. | ||
450 | * If there is a metadata selected, remove it from the list store. | ||
451 | * | ||
452 | * @param widget the button | ||
453 | * @param user_data the 'struct EditPublicationDialogContext' | ||
454 | */ | ||
455 | void | ||
456 | GNUNET_GTK_edit_publication_delete_button_clicked_cb (GtkButton * button, | ||
457 | gpointer user_data) | ||
458 | { | ||
459 | struct EditPublicationDialogContext *ctx = user_data; | ||
460 | GtkTreeIter iter; | ||
461 | GtkTreeSelection *meta_selection; | ||
462 | |||
463 | meta_selection = gtk_tree_view_get_selection (ctx->meta_treeview); | ||
464 | if (! gtk_tree_selection_get_selected (meta_selection, NULL, &iter)) | ||
465 | { | ||
466 | GNUNET_break (0); | ||
467 | return; | ||
468 | } | ||
469 | if (gtk_list_store_remove (ctx->meta_liststore, &iter)) | ||
470 | gtk_tree_selection_select_iter (meta_selection, &iter); | ||
471 | } | ||
472 | |||
473 | |||
474 | /** | ||
475 | * The user has selected another preview image file. Update the | ||
476 | * preview image. | ||
477 | * | ||
478 | * @param widget the file chooser dialog that completed | ||
479 | * @param user_data the 'struct EditPublicationDialogContext' | ||
480 | */ | ||
481 | void | ||
482 | GNUNET_GTK_edit_publication_metadata_preview_file_chooser_button_file_set_cb (GtkFileChooserButton * widget, | ||
483 | gpointer user_data) | ||
484 | { | ||
485 | struct EditPublicationDialogContext *ctx = user_data; | ||
486 | gchar *fn; | ||
487 | |||
488 | fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); | ||
489 | gtk_image_set_from_file (ctx->preview_image, fn); | ||
490 | g_free (fn); | ||
491 | ctx->preview_changed = GNUNET_YES; | ||
492 | } | ||
493 | |||
494 | |||
495 | /* ****************** keyword list editing ******************** */ | ||
496 | |||
497 | |||
498 | |||
499 | /** | ||
500 | * The user has changed the selection in the keyword tree view. | ||
501 | * Update the sensitivity of the 'delete' button. | ||
502 | * | ||
503 | * @param ts the tree selection object | ||
504 | * @param user_data the 'struct EditPublicationDialogContext' | ||
505 | */ | ||
506 | /* FIXME-UNCLEAN: connect this signal via glade (modern versions of Glade support this) */ | ||
507 | static void | ||
508 | keywords_selection_changed_cb (GtkTreeSelection *ts, | ||
509 | gpointer user_data) | ||
510 | { | ||
511 | struct EditPublicationDialogContext *ctx = user_data; | ||
512 | |||
513 | gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object | ||
514 | (ctx->builder, | ||
515 | "GNUNET_GTK_edit_publication_keyword_list_del_button")), | ||
516 | gtk_tree_selection_get_selected (ts, NULL, NULL)); | ||
517 | } | ||
518 | |||
519 | |||
520 | /** | ||
521 | * The user has edited the keyword entry line. Update the | ||
522 | * sensitivity of the 'add' button. | ||
523 | * | ||
524 | * @param editable the entry line for keywords | ||
525 | * @param user_data the 'struct EditPublicationDialogContext' | ||
526 | */ | ||
527 | void | ||
528 | GNUNET_GTK_edit_publication_keyword_entry_changed_cb (GtkEditable * editable, | ||
529 | gpointer user_data) | ||
530 | { | ||
531 | struct EditPublicationDialogContext *ctx = user_data; | ||
532 | const char *keyword; | ||
533 | |||
534 | keyword = gtk_entry_get_text (ctx->keyword_entry); | ||
535 | gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (ctx->builder, | ||
536 | "GNUNET_GTK_edit_publication_keyword_list_add_button")), | ||
537 | (strlen (keyword) > 0) ? TRUE : FALSE); | ||
538 | } | ||
539 | |||
540 | |||
541 | /** | ||
542 | * The user has pushed the 'del' button for the keyword. | ||
543 | * If there is a keyword selected, remove it from the list store. | ||
544 | * | ||
545 | * @param widget the button | ||
546 | * @param user_data the 'struct EditPublicationDialogContext' | ||
547 | */ | ||
548 | void | ||
549 | GNUNET_GTK_edit_publication_keyword_list_del_button_clicked_cb (GtkButton * | ||
550 | button, | ||
551 | gpointer user_data) | ||
552 | { | ||
553 | struct EditPublicationDialogContext *ctx = user_data; | ||
554 | GtkTreeIter iter; | ||
555 | GtkTreeSelection *keywords_selection; | ||
556 | |||
557 | keywords_selection = gtk_tree_view_get_selection (ctx->keywords_treeview); | ||
558 | if (! gtk_tree_selection_get_selected (keywords_selection, NULL, &iter)) | ||
559 | { | ||
560 | GNUNET_break (0); | ||
561 | return; | ||
562 | } | ||
563 | if (gtk_list_store_remove (GTK_LIST_STORE (ctx->keywords_liststore), &iter)) | ||
564 | gtk_tree_selection_select_iter (keywords_selection, &iter); | ||
565 | |||
566 | /* disable confirm button if keywords are required and we have no more keywords */ | ||
567 | if ( (! ctx->allow_no_keywords) && | ||
568 | (! gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ctx->keywords_liststore), | ||
569 | &iter)) ) | ||
570 | gtk_widget_set_sensitive (ctx->confirm_button, FALSE); | ||
571 | } | ||
572 | |||
573 | |||
574 | /** | ||
575 | * The user has pushed the 'add' button for the keyword (or pressed RETURN). | ||
576 | * If there is a keyword in the line, add it to the list store. | ||
577 | * | ||
578 | * @param widget the entry line, or NULL (if we are called from 'RETURN') | ||
579 | * @param user_data the 'struct EditPublicationDialogContext' | ||
580 | */ | ||
581 | void | ||
582 | GNUNET_GTK_edit_publication_keyword_list_add_button_clicked_cb (GtkButton * | ||
583 | button, | ||
584 | gpointer user_data) | ||
585 | { | ||
586 | struct EditPublicationDialogContext *ctx = user_data; | ||
587 | const char *keyword; | ||
588 | GtkTreeIter iter; | ||
589 | |||
590 | keyword = gtk_entry_get_text (ctx->keyword_entry); | ||
591 | if (strlen (keyword) == 0) | ||
592 | return; | ||
593 | gtk_list_store_insert_with_values (ctx->keywords_liststore, | ||
594 | &iter, G_MAXINT, | ||
595 | 0, keyword, | ||
596 | 1, TRUE, | ||
597 | -1); | ||
598 | gtk_widget_set_sensitive (ctx->confirm_button, TRUE); | ||
599 | gtk_entry_set_text (ctx->keyword_entry, ""); | ||
600 | } | ||
601 | |||
602 | |||
603 | /** | ||
604 | * The user has pushed a button in the entry line. Check if it was 'RETURN' | ||
605 | * and if so consider executing the 'add' action. | ||
606 | * | ||
607 | * @param widget the entry line | ||
608 | * @param event the event information | ||
609 | * @param user_data the 'struct EditPublicationDialogContext' | ||
610 | */ | ||
611 | gboolean | ||
612 | GNUNET_GTK_edit_publication_keyword_entry_key_press_event_cb (GtkWidget * | ||
613 | widget, | ||
614 | GdkEventKey * | ||
615 | event, | ||
616 | gpointer user_data) | ||
617 | { | ||
618 | struct EditPublicationDialogContext *ctx = user_data; | ||
619 | |||
620 | if (event->keyval != GDK_KEY_Return) | ||
621 | return FALSE; | ||
622 | GNUNET_GTK_edit_publication_keyword_list_add_button_clicked_cb (NULL, ctx); | ||
623 | return TRUE; | ||
624 | } | ||
625 | |||
626 | |||
627 | |||
628 | /* ****************** handlers for closing the dialog ******************** */ | ||
629 | |||
630 | |||
631 | /** | ||
632 | * The user clicked the 'cancel' button. Abort the operation. | ||
633 | * | ||
634 | * @param button the cancel button | ||
635 | * @param user_data the 'struct EditPublicationDialogContext' | ||
636 | */ | ||
637 | void | ||
638 | GNUNET_GTK_edit_publication_cancel_button_clicked_cb (GtkButton * button, | ||
639 | gpointer user_data) | ||
640 | { | ||
641 | struct EditPublicationDialogContext *ctx = user_data; | ||
642 | |||
643 | ctx->cb (ctx->cb_cls, GTK_RESPONSE_CANCEL, NULL); | ||
644 | free_edit_dialog_context (ctx); | ||
645 | } | ||
646 | |||
647 | |||
648 | /** | ||
649 | * The user closed the window. Abort the operation. | ||
650 | * | ||
651 | * @param widget the window | ||
652 | * @param event the event that caused the window to close | ||
653 | * @param user_data the 'struct EditPublicationDialogContext' | ||
654 | * @return TRUE (always) | ||
655 | */ | ||
656 | gboolean | ||
657 | GNUNET_GTK_edit_publication_window_delete_event_cb (GtkWidget * widget, | ||
658 | GdkEvent * event, | ||
659 | gpointer user_data) | ||
660 | { | ||
661 | struct EditPublicationDialogContext *ctx = user_data; | ||
662 | |||
663 | ctx->cb (ctx->cb_cls, GTK_RESPONSE_CANCEL, NULL); | ||
664 | free_edit_dialog_context (ctx); | ||
665 | return TRUE; | ||
666 | } | ||
667 | |||
668 | |||
669 | /** | ||
670 | * Copy binary meta data from to the new container and also preserve | ||
671 | * all entries that were not changed. In particular, all binary meta | ||
672 | * data is removed if the preview was changed, otherwise it is all | ||
673 | * kept. Similarly, if values are still in the liststore, they are | ||
674 | * fully kept (including plugin name and original format). "Keeping" | ||
675 | * a value means that it is added to the 'md' meta data in the dialog | ||
676 | * context. | ||
677 | * | ||
678 | * @param cls closure, a 'struct FileInformationUpdateContext'; | ||
679 | * contains the 'new' meta data to construct in the 'md' | ||
680 | * field and the liststore to check the current value | ||
681 | * against in 'meta_liststore'. | ||
682 | * @param plugin_name name of the plugin that produced this value; | ||
683 | * special values can be used (i.e. '<zlib>' for zlib being | ||
684 | * used in the main libextractor library and yielding | ||
685 | * meta data). | ||
686 | * @param type libextractor-type describing the meta data | ||
687 | * @param format basic format information about data | ||
688 | * @param data_mime_type mime-type of data (not of the original file); | ||
689 | * can be NULL (if mime-type is not known) | ||
690 | * @param data actual meta-data found | ||
691 | * @param data_len number of bytes in data | ||
692 | * @return 0 to continue extracting | ||
693 | */ | ||
694 | static int | ||
695 | preserve_meta_items (void *cls, const char *plugin_name, | ||
696 | enum EXTRACTOR_MetaType type, | ||
697 | enum EXTRACTOR_MetaFormat format, | ||
698 | const char *data_mime_type, const char *data, | ||
699 | size_t data_len) | ||
700 | { | ||
701 | struct EditPublicationDialogContext *ctx = cls; | ||
702 | GtkTreeIter iter; | ||
703 | gchar *value; | ||
704 | guint ntype; | ||
705 | guint nformat; | ||
706 | int keep; | ||
707 | |||
708 | keep = GNUNET_NO; | ||
709 | switch (format) | ||
710 | { | ||
711 | case EXTRACTOR_METAFORMAT_UTF8: | ||
712 | case EXTRACTOR_METAFORMAT_C_STRING: | ||
713 | if (TRUE == gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ctx->meta_liststore), &iter)) | ||
714 | { | ||
715 | do | ||
716 | { | ||
717 | gtk_tree_model_get (GTK_TREE_MODEL (ctx->meta_liststore), &iter, 0, &ntype, 1, &nformat, 3, &value, -1); | ||
718 | if ((ntype == type) && (nformat == format) && | ||
719 | (0 == strcmp (value, data))) | ||
720 | { | ||
721 | gtk_list_store_remove (ctx->meta_liststore, &iter); | ||
722 | keep = GNUNET_YES; | ||
723 | g_free (value); | ||
724 | break; | ||
725 | } | ||
726 | g_free (value); | ||
727 | } | ||
728 | while (TRUE == gtk_tree_model_iter_next (GTK_TREE_MODEL (ctx->meta_liststore), &iter)); | ||
729 | } | ||
730 | break; | ||
731 | case EXTRACTOR_METAFORMAT_UNKNOWN: | ||
732 | break; | ||
733 | case EXTRACTOR_METAFORMAT_BINARY: | ||
734 | if (ctx->preview_changed == GNUNET_NO) | ||
735 | keep = GNUNET_YES; | ||
736 | break; | ||
737 | default: | ||
738 | GNUNET_break (0); | ||
739 | break; | ||
740 | } | ||
741 | if (GNUNET_YES == keep) | ||
742 | GNUNET_break (GNUNET_OK == | ||
743 | GNUNET_CONTAINER_meta_data_insert (ctx->md, plugin_name, type, | ||
744 | format, data_mime_type, | ||
745 | data, data_len)); | ||
746 | return 0; | ||
747 | } | ||
748 | |||
749 | |||
750 | /** | ||
751 | * Function called to update the information in FI based on the changes made in | ||
752 | * the edit dialog. | ||
753 | * | ||
754 | * @param cls closure with a 'struct FileInformationUpdateContext *' | ||
755 | * @param fi the entry in the publish-structure | ||
756 | * @param length length of the file or directory | ||
757 | * @param meta metadata for the file or directory (can be modified) | ||
758 | * @param uri pointer to the keywords that will be used for this entry (can be modified) | ||
759 | * @param bo block options (can be modified) | ||
760 | * @param do_index should we index (can be modified) | ||
761 | * @param client_info pointer to client context set upon creation (can be modified) | ||
762 | * @return GNUNET_SYSERR (aborts after first call) | ||
763 | */ | ||
764 | static int | ||
765 | file_information_update (void *cls, struct GNUNET_FS_FileInformation *fi, | ||
766 | uint64_t length, | ||
767 | struct GNUNET_CONTAINER_MetaData *meta, | ||
768 | struct GNUNET_FS_Uri **uri, | ||
769 | struct GNUNET_FS_BlockOptions *bo, int *do_index, | ||
770 | void **client_info) | ||
771 | { | ||
772 | struct EditPublicationDialogContext *ctx = cls; | ||
773 | GtkTreeIter iter; | ||
774 | gint year; | ||
775 | |||
776 | /* gather publishing options */ | ||
777 | *do_index = gtk_toggle_button_get_active (ctx->index_checkbutton); | ||
778 | GNUNET_break (GNUNET_GTK_get_selected_anonymity_combo_level (ctx->anonymity_combo, | ||
779 | &bo->anonymity_level)); | ||
780 | bo->content_priority = gtk_spin_button_get_value (ctx->priority_spin); | ||
781 | bo->replication_level = gtk_spin_button_get_value (ctx->replication_spin); | ||
782 | year = gtk_spin_button_get_value (ctx->expiration_year_spin); | ||
783 | bo->expiration_time = GNUNET_FS_year_to_time (year); | ||
784 | |||
785 | /* update keyword-URI */ | ||
786 | if (NULL != (*uri)) | ||
787 | GNUNET_FS_uri_destroy (*uri); | ||
788 | *uri = NULL; | ||
789 | if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ctx->keywords_liststore), &iter)) | ||
790 | { | ||
791 | do | ||
792 | { | ||
793 | gchar *value; | ||
794 | |||
795 | gtk_tree_model_get (GTK_TREE_MODEL (ctx->keywords_liststore), &iter, 0, &value, -1); | ||
796 | if (NULL == *uri) | ||
797 | *uri = GNUNET_FS_uri_ksk_create_from_args (1, (const char **) &value); | ||
798 | else | ||
799 | GNUNET_FS_uri_ksk_add_keyword (*uri, value, GNUNET_NO); | ||
800 | g_free (value); | ||
801 | } | ||
802 | while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ctx->keywords_liststore), &iter)); | ||
803 | } | ||
804 | |||
805 | /* update meta data; first, we copy the unchanged values from the original meta data */ | ||
806 | ctx->md = GNUNET_CONTAINER_meta_data_create (); | ||
807 | GNUNET_CONTAINER_meta_data_iterate (meta, | ||
808 | &preserve_meta_items, | ||
809 | ctx); | ||
810 | /* clear original meta data */ | ||
811 | GNUNET_CONTAINER_meta_data_clear (meta); | ||
812 | /* add all of the 'preserved' values */ | ||
813 | GNUNET_CONTAINER_meta_data_merge (meta, ctx->md); | ||
814 | GNUNET_CONTAINER_meta_data_destroy (ctx->md); | ||
815 | ctx->md = NULL; | ||
816 | /* now add all of the values from the model; adding will simply do | ||
817 | nothing for values that are already in the set because they were preserved */ | ||
818 | if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (ctx->meta_liststore), &iter)) | ||
819 | { | ||
820 | do | ||
821 | { | ||
822 | guint ntype; | ||
823 | guint nformat; | ||
824 | gchar *value; | ||
825 | |||
826 | gtk_tree_model_get (GTK_TREE_MODEL (ctx->meta_liststore), &iter, 0, &ntype, 1, &nformat, 3, &value, -1); | ||
827 | if (ntype > 0) | ||
828 | GNUNET_CONTAINER_meta_data_insert (ctx->md, "<user>", ntype, nformat, | ||
829 | "text/plain", value, | ||
830 | strlen (value) + 1); | ||
831 | g_free (value); | ||
832 | } | ||
833 | while (gtk_tree_model_iter_next (GTK_TREE_MODEL (ctx->meta_liststore), &iter)); | ||
834 | } | ||
835 | |||
836 | /* finally, if we got a new preview, add it as well */ | ||
837 | if (ctx->preview_changed == GNUNET_YES) | ||
838 | { | ||
839 | gchar *fn; | ||
840 | char *data; | ||
841 | gsize data_size; | ||
842 | const char *mime; | ||
843 | GFile *f; | ||
844 | GFileInfo *finfo; | ||
845 | |||
846 | fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER | ||
847 | (gtk_builder_get_object | ||
848 | (ctx->builder, | ||
849 | "GNUNET_GTK_edit_publication_metadata_preview_file_chooser_button"))); | ||
850 | f = g_file_new_for_path (fn); | ||
851 | finfo = | ||
852 | g_file_query_info (f, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, 0, NULL, | ||
853 | NULL); | ||
854 | if (! g_file_load_contents (f, NULL, &data, &data_size, NULL, NULL)) | ||
855 | { | ||
856 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
857 | _("Could not load preview `%s' into memory\n"), fn); | ||
858 | } | ||
859 | else | ||
860 | { | ||
861 | mime = | ||
862 | g_file_info_get_attribute_string (finfo, | ||
863 | G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE); | ||
864 | GNUNET_CONTAINER_meta_data_insert (meta, "<user>", | ||
865 | EXTRACTOR_METATYPE_THUMBNAIL, | ||
866 | EXTRACTOR_METAFORMAT_BINARY, mime, | ||
867 | data, data_size); | ||
868 | } | ||
869 | g_object_unref (finfo); | ||
870 | g_object_unref (f); | ||
871 | g_free (fn); | ||
872 | } | ||
873 | return GNUNET_SYSERR; /* only visit top-level item */ | ||
874 | } | ||
875 | |||
876 | |||
877 | /** | ||
878 | * The user clicked the 'confirm' button. Push the edits back into the | ||
879 | * FileInformation structure and given it and the options back to the | ||
880 | * callback. Then clean up the dialog. | ||
881 | * | ||
882 | * @param button the cancel button | ||
883 | * @param user_data the 'struct EditPublicationDialogContext' | ||
884 | */ | ||
885 | void | ||
886 | GNUNET_GTK_edit_publication_confirm_button_clicked_cb (GtkButton * button, | ||
887 | gpointer user_data) | ||
888 | { | ||
889 | struct EditPublicationDialogContext *ctx = user_data; | ||
890 | |||
891 | /* push back changes to file-information */ | ||
892 | GNUNET_FS_file_information_inspect (ctx->fip, | ||
893 | &file_information_update, | ||
894 | ctx); | ||
895 | /* call our continuation */ | ||
896 | ctx->cb (ctx->cb_cls, | ||
897 | GTK_RESPONSE_OK, | ||
898 | gtk_entry_get_text (ctx->root_entry)); | ||
899 | /* free resources from the edit dialog */ | ||
900 | free_edit_dialog_context (ctx); | ||
901 | } | ||
902 | |||
903 | |||
904 | |||
905 | /* ****************** code for initialization of the dialog ******************** */ | ||
906 | |||
907 | |||
908 | |||
909 | /** | ||
910 | * Add each of the keywords to the keyword list store. | ||
911 | * | ||
912 | * @param cls closure | ||
913 | * @param keyword the keyword | ||
914 | * @param is_mandatory is the keyword mandatory (in a search) | ||
915 | * @return GNUNET_OK to continue to iterate | ||
916 | */ | ||
917 | static int | ||
918 | add_keyword (void *cls, const char *keyword, int is_mandatory) | ||
919 | { | ||
920 | GtkListStore *ls; | ||
921 | GtkTreeIter iter; | ||
922 | |||
923 | ls = GTK_LIST_STORE (cls); | ||
924 | gtk_list_store_insert_with_values (ls, &iter, G_MAXINT, | ||
925 | 0, keyword, | ||
926 | 1, FALSE, | ||
927 | -1); | ||
928 | return GNUNET_OK; | ||
929 | } | ||
930 | |||
931 | |||
932 | /** | ||
933 | * Function called to extract the information from FI to populate the edit dialog. | ||
934 | * | ||
935 | * @param cls the 'struct EditPublicationDialogContext' | ||
936 | * @param fi the entry in the publish-structure (unused) | ||
937 | * @param length length of the file or directory (unused) | ||
938 | * @param meta metadata for the file or directory (can be modified) | ||
939 | * @param uri pointer to the keywords that will be used for this entry (can be modified) | ||
940 | * @param bo block options | ||
941 | * @param do_index should we index (can be modified) | ||
942 | * @param client_info pointer to client context set upon creation (can be modified) | ||
943 | * @return GNUNET_SYSERR (aborts after first call) | ||
944 | */ | ||
945 | static int | ||
946 | file_information_import (void *cls, | ||
947 | struct GNUNET_FS_FileInformation *fi, | ||
948 | uint64_t length, | ||
949 | struct GNUNET_CONTAINER_MetaData *meta, | ||
950 | struct GNUNET_FS_Uri **uri, | ||
951 | struct GNUNET_FS_BlockOptions *bo, int *do_index, | ||
952 | void **client_info) | ||
953 | { | ||
954 | struct EditPublicationDialogContext *ctx = cls; | ||
955 | GdkPixbuf *pixbuf; | ||
956 | char *short_fn; | ||
957 | int year; | ||
958 | |||
959 | /* import options */ | ||
960 | year = (int) GNUNET_FS_time_to_year (bo->expiration_time); | ||
961 | gtk_spin_button_set_value (ctx->expiration_year_spin, year); | ||
962 | GNUNET_GTK_select_anonymity_combo_level (ctx->anonymity_combo, | ||
963 | bo->anonymity_level); | ||
964 | gtk_spin_button_set_value (ctx->priority_spin, bo->content_priority); | ||
965 | gtk_spin_button_set_value (ctx->replication_spin, bo->replication_level); | ||
966 | gtk_toggle_button_set_active (ctx->index_checkbutton, *do_index); | ||
967 | |||
968 | |||
969 | /* import keywords */ | ||
970 | if (NULL != *uri) | ||
971 | GNUNET_FS_uri_ksk_get_keywords (*uri, &add_keyword, ctx->keywords_liststore); | ||
972 | |||
973 | /* import meta data */ | ||
974 | if (NULL != meta) | ||
975 | { | ||
976 | GNUNET_CONTAINER_meta_data_iterate (meta, | ||
977 | &GNUNET_FS_GTK_add_meta_data_to_list_store, | ||
978 | ctx->meta_liststore); | ||
979 | pixbuf = GNUNET_FS_GTK_get_thumbnail_from_meta_data (meta); | ||
980 | if (pixbuf != NULL) | ||
981 | { | ||
982 | gtk_image_set_from_pixbuf (ctx->preview_image, pixbuf); | ||
983 | } | ||
984 | } | ||
985 | |||
986 | /* Also update window title based on filename */ | ||
987 | short_fn = GNUNET_CONTAINER_meta_data_get_first_by_types (meta, | ||
988 | EXTRACTOR_METATYPE_FILENAME, | ||
989 | -1); | ||
990 | if (NULL == short_fn) | ||
991 | { | ||
992 | gtk_window_set_title (ctx->edit_publication_window, _("<unnamed>")); | ||
993 | } | ||
994 | else | ||
995 | { | ||
996 | /* FIXME-BUG-MAYBE: ensure that short_fn is UTF-8 encoded */ | ||
997 | gtk_window_set_title (ctx->edit_publication_window, short_fn); | ||
998 | GNUNET_free (short_fn); | ||
999 | } | ||
1000 | return GNUNET_SYSERR; /* only visit top-level item */ | ||
1001 | } | ||
1002 | |||
1003 | |||
1004 | /** | ||
1005 | * Open the dialog to edit file information data. | ||
1006 | * | ||
1007 | * @param parent parent window of the dialog | ||
1008 | * @param fip information about the file information that is to be edited | ||
1009 | * @param allow_no_keywords is it OK to close the dialog without any keywords? | ||
1010 | * also used to indicate that this is a namespace operation | ||
1011 | * (FIXME-UNCLEAN: overloaded/badly-named argument) | ||
1012 | * @param anon_liststore liststore with anonymity options (FIXME-UNCLEAN: bad sharing) | ||
1013 | * @param cb function to call when the dialog is closed | ||
1014 | * @param cb_cls closure for 'cb' | ||
1015 | */ | ||
1016 | void | ||
1017 | GNUNET_FS_GTK_edit_publish_dialog (GtkWindow * parent, | ||
1018 | struct GNUNET_FS_FileInformation *fip, | ||
1019 | int allow_no_keywords, | ||
1020 | GtkListStore *anon_liststore, | ||
1021 | GNUNET_FS_GTK_EditPublishDialogCallback cb, | ||
1022 | gpointer cb_cls) | ||
1023 | { | ||
1024 | GtkTreeIter iter; | ||
1025 | gint code; | ||
1026 | GtkComboBox *pubtypes_combo; | ||
1027 | GtkLabel *index_label; | ||
1028 | GtkLabel *root_label; | ||
1029 | struct EditPublicationDialogContext *ctx; | ||
1030 | GtkTreeSelection *meta_selection; | ||
1031 | GtkTreeSelection *keywords_selection; | ||
1032 | |||
1033 | ctx = GNUNET_malloc (sizeof (struct EditPublicationDialogContext)); | ||
1034 | ctx->fip = fip; | ||
1035 | ctx->preview_changed = GNUNET_NO; | ||
1036 | ctx->allow_no_keywords = allow_no_keywords; | ||
1037 | ctx->is_directory = GNUNET_FS_file_information_is_directory (fip); | ||
1038 | ctx->cb = cb; | ||
1039 | ctx->cb_cls = cb_cls; | ||
1040 | ctx->meta_combo_selected_type_id = -1; | ||
1041 | ctx->builder = GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_edit_publication.glade", ctx); | ||
1042 | |||
1043 | if (ctx->builder == NULL) | ||
1044 | { | ||
1045 | GNUNET_free (ctx); | ||
1046 | return; | ||
1047 | } | ||
1048 | |||
1049 | /* obtain various widgets for use later */ | ||
1050 | ctx->pubtypes_liststore = | ||
1051 | GTK_LIST_STORE (gtk_builder_get_object | ||
1052 | (ctx->builder, "GNUNET_GTK_publication_types_liststore")); | ||
1053 | ctx->metatypes_liststore = | ||
1054 | GTK_LIST_STORE (gtk_builder_get_object | ||
1055 | (ctx->builder, | ||
1056 | "GNUNET_GTK_publication_metadata_types_liststore")); | ||
1057 | ctx->meta_treeview = GTK_TREE_VIEW (gtk_builder_get_object | ||
1058 | (ctx->builder, | ||
1059 | "GNUNET_GTK_edit_publication_metadata_tree_view")); | ||
1060 | ctx->keywords_treeview = GTK_TREE_VIEW (gtk_builder_get_object | ||
1061 | (ctx->builder, | ||
1062 | "GNUNET_GTK_edit_publication_keyword_list_tree_view")); | ||
1063 | ctx->edit_publication_window = | ||
1064 | GTK_WINDOW (gtk_builder_get_object (ctx->builder, | ||
1065 | "GNUNET_GTK_edit_publication_window")); | ||
1066 | ctx->keywords_liststore = GTK_LIST_STORE (gtk_builder_get_object | ||
1067 | (ctx->builder, "GNUNET_GTK_publication_keywords_liststore")); | ||
1068 | ctx->keyword_entry = | ||
1069 | GTK_ENTRY (gtk_builder_get_object | ||
1070 | (ctx->builder, "GNUNET_GTK_edit_publication_keyword_entry")); | ||
1071 | ctx->confirm_button = GTK_WIDGET (gtk_builder_get_object | ||
1072 | (ctx->builder, "GNUNET_GTK_edit_publication_confirm_button")); | ||
1073 | ctx->preview_image = | ||
1074 | GTK_IMAGE (gtk_builder_get_object | ||
1075 | (ctx->builder, | ||
1076 | "GNUNET_GTK_edit_publication_metadata_preview_image")); | ||
1077 | ctx->meta_liststore = GTK_LIST_STORE (gtk_builder_get_object | ||
1078 | (ctx->builder, | ||
1079 | "GNUNET_GTK_publication_metadata_liststore")); | ||
1080 | ctx->root_entry = GTK_ENTRY (gtk_builder_get_object | ||
1081 | (ctx->builder, "GNUNET_GTK_edit_publication_root_entry")); | ||
1082 | ctx->expiration_year_spin = GTK_SPIN_BUTTON | ||
1083 | (gtk_builder_get_object | ||
1084 | (ctx->builder, | ||
1085 | "GNUNET_GTK_edit_publication_expiration_year_spin_button")); | ||
1086 | ctx->priority_spin = GTK_SPIN_BUTTON | ||
1087 | (gtk_builder_get_object | ||
1088 | (ctx->builder, | ||
1089 | "GNUNET_GTK_edit_publication_priority_spin_button")); | ||
1090 | ctx->replication_spin = GTK_SPIN_BUTTON | ||
1091 | (gtk_builder_get_object | ||
1092 | (ctx->builder, | ||
1093 | "GNUNET_GTK_edit_publication_replication_spin_button")); | ||
1094 | ctx->index_checkbutton = GTK_TOGGLE_BUTTON | ||
1095 | (gtk_builder_get_object | ||
1096 | (ctx->builder, | ||
1097 | "GNUNET_GTK_edit_publication_index_checkbutton")); | ||
1098 | ctx->anonymity_combo = GTK_COMBO_BOX (gtk_builder_get_object (ctx->builder, | ||
1099 | "GNUNET_GTK_edit_publication_anonymity_combobox")); | ||
1100 | |||
1101 | /* Basic initialization of widgets models and visibility */ | ||
1102 | gtk_combo_box_set_model (ctx->anonymity_combo, | ||
1103 | GTK_TREE_MODEL (anon_liststore)); | ||
1104 | GNUNET_FS_GTK_setup_expiration_year_adjustment (ctx->builder); | ||
1105 | |||
1106 | /* FIXME-UNCLEAN: are the following three even required anymore? */ | ||
1107 | gtk_list_store_clear (ctx->keywords_liststore); | ||
1108 | gtk_list_store_clear (ctx->meta_liststore); | ||
1109 | gtk_entry_set_text (ctx->keyword_entry, ""); | ||
1110 | |||
1111 | pubtypes_combo = | ||
1112 | GTK_COMBO_BOX (gtk_builder_get_object | ||
1113 | (ctx->builder, "GNUNET_GTK_edit_publication_type_combo")); | ||
1114 | if (gtk_combo_box_get_active_iter (pubtypes_combo, &iter)) | ||
1115 | { | ||
1116 | gtk_tree_model_get (GTK_TREE_MODEL (ctx->pubtypes_liststore), &iter, 0, &code, -1); | ||
1117 | change_metatypes (ctx, 0); | ||
1118 | } | ||
1119 | else | ||
1120 | gtk_combo_box_set_active (pubtypes_combo, 0); | ||
1121 | |||
1122 | /* indexing does not apply to directories */ | ||
1123 | gtk_widget_set_visible (GTK_WIDGET (ctx->index_checkbutton), | ||
1124 | ! ctx->is_directory); | ||
1125 | index_label = GTK_LABEL (gtk_builder_get_object | ||
1126 | (ctx->builder, | ||
1127 | "GNUNET_GTK_edit_publication_index_label")); | ||
1128 | gtk_widget_set_visible (GTK_WIDGET (index_label), | ||
1129 | ! ctx->is_directory); | ||
1130 | |||
1131 | /* show root label only if we must have keywords, which is also only the | ||
1132 | case for namespaces (FIXME-UNCLEAN: overloaded use of the argument) */ | ||
1133 | gtk_widget_set_visible (GTK_WIDGET (ctx->root_entry), | ||
1134 | !allow_no_keywords); | ||
1135 | root_label = GTK_LABEL (gtk_builder_get_object | ||
1136 | (ctx->builder, "GNUNET_GTK_edit_publication_root_label")); | ||
1137 | gtk_widget_set_visible (GTK_WIDGET (root_label), | ||
1138 | !allow_no_keywords); | ||
1139 | |||
1140 | /* FIXME-UNCLEAN: what if we already have keywords? Again, does not really | ||
1141 | apply to namespace-case, but this seems a bit ugly */ | ||
1142 | gtk_widget_set_sensitive (ctx->confirm_button, allow_no_keywords ? TRUE : FALSE); | ||
1143 | |||
1144 | |||
1145 | /* FIXME-UNCLEAN: these signal handlers can be set by (modern) versions of Glade */ | ||
1146 | keywords_selection = gtk_tree_view_get_selection (ctx->keywords_treeview); | ||
1147 | g_signal_connect (G_OBJECT (keywords_selection), "changed", | ||
1148 | G_CALLBACK (keywords_selection_changed_cb), ctx); | ||
1149 | meta_selection = gtk_tree_view_get_selection (ctx->meta_treeview); | ||
1150 | g_signal_connect (G_OBJECT (meta_selection), "changed", | ||
1151 | G_CALLBACK (metadata_selection_changed_cb), ctx); | ||
1152 | |||
1153 | /* import meta data and options */ | ||
1154 | GNUNET_FS_file_information_inspect (fip, &file_information_import, ctx); | ||
1155 | |||
1156 | |||
1157 | /* Finally, display window */ | ||
1158 | gtk_window_set_transient_for (ctx->edit_publication_window, parent); | ||
1159 | gtk_window_present (ctx->edit_publication_window); | ||
1160 | } | ||
1161 | |||
1162 | |||
1163 | /* end of gnunet-fs-gtk-edit_publish_dialog.c */ | ||