diff options
Diffstat (limited to 'src/fs/edit_publish_dialog.c')
-rw-r--r-- | src/fs/edit_publish_dialog.c | 771 |
1 files changed, 771 insertions, 0 deletions
diff --git a/src/fs/edit_publish_dialog.c b/src/fs/edit_publish_dialog.c new file mode 100644 index 00000000..ab7b968d --- /dev/null +++ b/src/fs/edit_publish_dialog.c | |||
@@ -0,0 +1,771 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2005, 2006, 2010 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/edit_publish_dialog.c | ||
23 | * @author Christian Grothoff | ||
24 | */ | ||
25 | #include "common.h" | ||
26 | #include "edit_publish_dialog.h" | ||
27 | #include <gnunet/gnunet_util_lib.h> | ||
28 | |||
29 | /** | ||
30 | * Builder for the current dialog. | ||
31 | */ | ||
32 | static GtkBuilder *builder; | ||
33 | |||
34 | /** | ||
35 | * Are we editing metadata for a directory? | ||
36 | */ | ||
37 | static int is_directory; | ||
38 | |||
39 | /** | ||
40 | * Set to YES if the preview was changed. | ||
41 | */ | ||
42 | static int preview_changed; | ||
43 | |||
44 | void | ||
45 | GNUNET_GTK_edit_file_information_keyword_list_normalize_button_clicked_cb () | ||
46 | { | ||
47 | GNUNET_break (0); | ||
48 | } | ||
49 | |||
50 | void | ||
51 | GNUNET_GTK_edit_file_information_keyword_list_del_button_clicked_cb () | ||
52 | { | ||
53 | GtkTreeView *tv; | ||
54 | GtkTreeSelection *sel; | ||
55 | GtkTreeModel *tm; | ||
56 | GtkTreeIter iter; | ||
57 | |||
58 | tv = GTK_TREE_VIEW (gtk_builder_get_object (builder, | ||
59 | "GNUNET_GTK_edit_file_information_keyword_list_tree_view")); | ||
60 | sel = gtk_tree_view_get_selection (tv); | ||
61 | if (TRUE != gtk_tree_selection_get_selected (sel, &tm, &iter)) | ||
62 | { | ||
63 | GNUNET_break (0); | ||
64 | return; | ||
65 | } | ||
66 | gtk_list_store_remove (GTK_LIST_STORE (tm), | ||
67 | &iter); | ||
68 | } | ||
69 | |||
70 | void | ||
71 | GNUNET_GTK_edit_file_information_keyword_list_add_button_clicked_cb () | ||
72 | { | ||
73 | const char *keyword; | ||
74 | GtkEntry *entry; | ||
75 | GtkListStore *ls; | ||
76 | GtkTreeIter iter; | ||
77 | |||
78 | ls = GTK_LIST_STORE (gtk_builder_get_object (builder, | ||
79 | "GNUNET_GTK_keyword_list_store")); | ||
80 | entry = GTK_ENTRY (gtk_builder_get_object (builder, | ||
81 | "GNUNET_GTK_edit_file_information_keyword_entry")); | ||
82 | keyword = gtk_entry_get_text (entry); | ||
83 | if (strlen (keyword) > 0) | ||
84 | gtk_list_store_insert_with_values (ls, &iter, G_MAXINT, 0, keyword, -1); | ||
85 | gtk_entry_set_text (entry, ""); | ||
86 | } | ||
87 | |||
88 | |||
89 | void | ||
90 | GNUNET_GTK_edit_file_information_keyword_entry_changed_cb () | ||
91 | { | ||
92 | const char *keyword; | ||
93 | GtkEntry *entry; | ||
94 | GtkWidget *button; | ||
95 | |||
96 | button = GTK_WIDGET (gtk_builder_get_object (builder, | ||
97 | "GNUNET_GTK_edit_file_information_keyword_list_add_button")); | ||
98 | entry = GTK_ENTRY (gtk_builder_get_object (builder, | ||
99 | "GNUNET_GTK_edit_file_information_keyword_entry")); | ||
100 | keyword = gtk_entry_get_text (entry); | ||
101 | gtk_widget_set_sensitive (button, | ||
102 | (strlen (keyword) > 0) ? TRUE : FALSE); | ||
103 | } | ||
104 | |||
105 | |||
106 | static void | ||
107 | metadata_selection_changed_cb (GtkTreeSelection *ts, | ||
108 | gpointer user_data) | ||
109 | { | ||
110 | GtkTreeView *tv; | ||
111 | GtkTreeSelection *sel; | ||
112 | GtkWidget *button; | ||
113 | |||
114 | tv = GTK_TREE_VIEW (gtk_builder_get_object (builder, | ||
115 | "GNUNET_GTK_edit_file_information_metadata_tree_view")); | ||
116 | sel = gtk_tree_view_get_selection (tv); | ||
117 | button = GTK_WIDGET (gtk_builder_get_object (builder, | ||
118 | "GNUNET_GTK_edit_file_information_metadata_delete_button")); | ||
119 | gtk_widget_set_sensitive (button, | ||
120 | gtk_tree_selection_get_selected (sel, NULL, NULL)); | ||
121 | } | ||
122 | |||
123 | |||
124 | static void | ||
125 | keyword_selection_changed_cb (GtkTreeSelection *ts, | ||
126 | gpointer user_data) | ||
127 | { | ||
128 | GtkTreeView *tv; | ||
129 | GtkTreeSelection *sel; | ||
130 | GtkWidget *button; | ||
131 | |||
132 | tv = GTK_TREE_VIEW (gtk_builder_get_object (builder, | ||
133 | "GNUNET_GTK_edit_file_information_keyword_list_tree_view")); | ||
134 | sel = gtk_tree_view_get_selection (tv); | ||
135 | button = GTK_WIDGET (gtk_builder_get_object (builder, | ||
136 | "GNUNET_GTK_edit_file_information_keyword_list_del_button")); | ||
137 | |||
138 | gtk_widget_set_sensitive (button, | ||
139 | gtk_tree_selection_get_selected (sel, NULL, NULL)); | ||
140 | button = GTK_WIDGET (gtk_builder_get_object (builder, | ||
141 | "GNUNET_GTK_edit_file_information_keyword_list_normalize_button")); | ||
142 | gtk_widget_set_sensitive (button, | ||
143 | gtk_tree_selection_get_selected (sel, NULL, NULL)); | ||
144 | } | ||
145 | |||
146 | |||
147 | void | ||
148 | GNUNET_GTK_edit_file_information_metadata_value_entry_changed_cb () | ||
149 | { | ||
150 | GtkTreeView *tv; | ||
151 | GtkTreeSelection *sel; | ||
152 | const char *value; | ||
153 | GtkEntry *entry; | ||
154 | GtkWidget *button; | ||
155 | |||
156 | entry = GTK_ENTRY (gtk_builder_get_object (builder, | ||
157 | "GNUNET_GTK_edit_file_information_metadata_value_entry")); | ||
158 | value = gtk_entry_get_text (entry); | ||
159 | tv = GTK_TREE_VIEW (gtk_builder_get_object (builder, | ||
160 | "GNUNET_GTK_edit_file_information_metadata_type_tree_view")); | ||
161 | sel = gtk_tree_view_get_selection (tv); | ||
162 | button = GTK_WIDGET (gtk_builder_get_object (builder, | ||
163 | "GNUNET_GTK_edit_file_information_metadata_add_button")); | ||
164 | gtk_widget_set_sensitive (button, | ||
165 | (strlen (value) > 0) | ||
166 | ? gtk_tree_selection_get_selected (sel, NULL, NULL) | ||
167 | : FALSE); | ||
168 | } | ||
169 | |||
170 | |||
171 | void | ||
172 | GNUNET_GTK_edit_file_information_keyword_entry_activate_cb () | ||
173 | { | ||
174 | GNUNET_GTK_edit_file_information_keyword_list_add_button_clicked_cb (); | ||
175 | } | ||
176 | |||
177 | |||
178 | void | ||
179 | GNUNET_GTK_edit_file_information_metadata_preview_file_chooser_button_file_set_cb (GtkFileChooserButton *widget, | ||
180 | gpointer user_data) | ||
181 | { | ||
182 | gchar *fn; | ||
183 | GtkImage *image; | ||
184 | |||
185 | fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); | ||
186 | image = GTK_IMAGE (gtk_builder_get_object (builder, | ||
187 | "GNUNET_GTK_edit_file_information_metadata_preview_image")); | ||
188 | gtk_image_set_from_file (image, fn); | ||
189 | preview_changed = GNUNET_YES; | ||
190 | } | ||
191 | |||
192 | |||
193 | void | ||
194 | GNUNET_GTK_edit_file_information_metadata_delete_button_clicked_cb() | ||
195 | { | ||
196 | GtkTreeView *tv; | ||
197 | GtkTreeSelection *sel; | ||
198 | GtkTreeModel *tm; | ||
199 | GtkTreeIter iter; | ||
200 | |||
201 | tv = GTK_TREE_VIEW (gtk_builder_get_object (builder, | ||
202 | "GNUNET_GTK_edit_file_information_metadata_tree_view")); | ||
203 | sel = gtk_tree_view_get_selection (tv); | ||
204 | if (TRUE != gtk_tree_selection_get_selected (sel, &tm, &iter)) | ||
205 | { | ||
206 | GNUNET_break (0); | ||
207 | return; | ||
208 | } | ||
209 | gtk_list_store_remove (GTK_LIST_STORE (tm), | ||
210 | &iter); | ||
211 | } | ||
212 | |||
213 | |||
214 | void | ||
215 | GNUNET_GTK_edit_file_information_metadata_add_button_clicked_cb () | ||
216 | { | ||
217 | const char *value; | ||
218 | char *avalue; | ||
219 | const char *ivalue; | ||
220 | GtkEntry *entry; | ||
221 | GtkListStore *ls; | ||
222 | GtkTreeModel *tm; | ||
223 | GtkTreeView *tv; | ||
224 | GtkTreeSelection *sel; | ||
225 | GtkTreeIter iter; | ||
226 | guint type; | ||
227 | size_t slen; | ||
228 | char *pos; | ||
229 | |||
230 | entry = GTK_ENTRY (gtk_builder_get_object (builder, | ||
231 | "GNUNET_GTK_edit_file_information_metadata_value_entry")); | ||
232 | value = gtk_entry_get_text (entry); | ||
233 | if ((value == NULL) || (strlen (value) == 0)) | ||
234 | { | ||
235 | GNUNET_break (0); | ||
236 | return; | ||
237 | } | ||
238 | tv = GTK_TREE_VIEW (gtk_builder_get_object (builder, | ||
239 | "GNUNET_GTK_edit_file_information_metadata_type_tree_view")); | ||
240 | tm = gtk_tree_view_get_model (tv); | ||
241 | sel = gtk_tree_view_get_selection (tv); | ||
242 | if (TRUE != gtk_tree_selection_get_selected (sel, | ||
243 | &tm, | ||
244 | &iter)) | ||
245 | { | ||
246 | GNUNET_break (0); | ||
247 | return; | ||
248 | } | ||
249 | gtk_tree_model_get (tm, | ||
250 | &iter, | ||
251 | 1, &type, -1); | ||
252 | ls = GTK_LIST_STORE (gtk_builder_get_object (builder, | ||
253 | "GNUNET_GTK_meta_data_list_store")); | ||
254 | if ( (type == EXTRACTOR_METATYPE_FILENAME) && | ||
255 | (value[strlen(value)-1] != '/') && | ||
256 | (is_directory) ) | ||
257 | { | ||
258 | GNUNET_asprintf (&avalue, | ||
259 | "%s/", | ||
260 | value); | ||
261 | /* if user typed '\' instead of '/', change it! */ | ||
262 | slen = strlen (avalue); | ||
263 | while ( (slen > 1) && | ||
264 | (avalue[slen-2] == '\\') ) | ||
265 | { | ||
266 | avalue[slen-2] = '/'; | ||
267 | avalue[slen-1] = '\0'; | ||
268 | slen--; | ||
269 | } | ||
270 | while (NULL != (pos = strstr (avalue, "\\"))) | ||
271 | *pos = '/'; | ||
272 | /* remove '../' everywhere */ | ||
273 | while (NULL != (pos = strstr (avalue, "../"))) | ||
274 | { | ||
275 | pos[0] = '_'; | ||
276 | pos[1] = '_'; | ||
277 | pos[2] = '_'; | ||
278 | } | ||
279 | ivalue = avalue; | ||
280 | } | ||
281 | else | ||
282 | { | ||
283 | ivalue = value; | ||
284 | avalue = NULL; | ||
285 | } | ||
286 | |||
287 | gtk_list_store_insert_with_values (ls, &iter, G_MAXINT, | ||
288 | 0, type, | ||
289 | 1, (guint) EXTRACTOR_METAFORMAT_UTF8, | ||
290 | 2, EXTRACTOR_metatype_to_string (type), | ||
291 | 3, ivalue, | ||
292 | -1); | ||
293 | GNUNET_free_non_null (avalue); | ||
294 | gtk_entry_set_text (GTK_ENTRY (entry), ""); | ||
295 | } | ||
296 | |||
297 | |||
298 | /** | ||
299 | * Add each of the keywords to the keyword list store. | ||
300 | * | ||
301 | * @param cls closure | ||
302 | * @param keyword the keyword | ||
303 | * @param is_mandatory is the keyword mandatory (in a search) | ||
304 | * @return GNUNET_OK to continue to iterate | ||
305 | */ | ||
306 | static int | ||
307 | add_keyword (void *cls, | ||
308 | const char *keyword, | ||
309 | int is_mandatory) | ||
310 | { | ||
311 | GtkListStore *ls; | ||
312 | GtkTreeIter iter; | ||
313 | |||
314 | ls = GTK_LIST_STORE (gtk_builder_get_object (builder, | ||
315 | "GNUNET_GTK_keyword_list_store")); | ||
316 | gtk_list_store_insert_with_values (ls, &iter, | ||
317 | G_MAXINT, | ||
318 | 0, keyword, | ||
319 | -1); | ||
320 | return GNUNET_OK; | ||
321 | } | ||
322 | |||
323 | |||
324 | /** | ||
325 | * Add the given meta data to the model (or make it the preview | ||
326 | * image if it is an image). | ||
327 | * | ||
328 | * @param cls closure, NULL | ||
329 | * @param plugin_name name of the plugin that produced this value; | ||
330 | * special values can be used (i.e. '<zlib>' for zlib being | ||
331 | * used in the main libextractor library and yielding | ||
332 | * meta data). | ||
333 | * @param type libextractor-type describing the meta data | ||
334 | * @param format basic format information about data | ||
335 | * @param data_mime_type mime-type of data (not of the original file); | ||
336 | * can be NULL (if mime-type is not known) | ||
337 | * @param data actual meta-data found | ||
338 | * @param data_len number of bytes in data | ||
339 | * @return 0 to continue extracting | ||
340 | */ | ||
341 | static int | ||
342 | add_meta_item (void *cls, | ||
343 | const char *plugin_name, | ||
344 | enum EXTRACTOR_MetaType type, | ||
345 | enum EXTRACTOR_MetaFormat format, | ||
346 | const char *data_mime_type, | ||
347 | const char *data, | ||
348 | size_t data_len) | ||
349 | { | ||
350 | GtkListStore *ls; | ||
351 | GtkTreeIter iter; | ||
352 | |||
353 | switch (format) | ||
354 | { | ||
355 | case EXTRACTOR_METAFORMAT_UTF8: | ||
356 | case EXTRACTOR_METAFORMAT_C_STRING: | ||
357 | ls = GTK_LIST_STORE (gtk_builder_get_object (builder, | ||
358 | "GNUNET_GTK_meta_data_list_store")); | ||
359 | gtk_list_store_insert_with_values (ls, &iter, | ||
360 | G_MAXINT, | ||
361 | 0, (guint) type, | ||
362 | 1, (guint) format, | ||
363 | 2, EXTRACTOR_metatype_to_string (type), | ||
364 | 3, data, | ||
365 | -1); | ||
366 | break; | ||
367 | case EXTRACTOR_METAFORMAT_UNKNOWN: | ||
368 | break; | ||
369 | case EXTRACTOR_METAFORMAT_BINARY: | ||
370 | break; | ||
371 | default: | ||
372 | GNUNET_break (0); | ||
373 | } | ||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | |||
378 | /** | ||
379 | * Function called to extract the information from FI. | ||
380 | * | ||
381 | * @param cls closure | ||
382 | * @param fi the entry in the publish-structure | ||
383 | * @param length length of the file or directory | ||
384 | * @param meta metadata for the file or directory (can be modified) | ||
385 | * @param uri pointer to the keywords that will be used for this entry (can be modified) | ||
386 | * @param bo block options | ||
387 | * @param do_index should we index (can be modified) | ||
388 | * @param client_info pointer to client context set upon creation (can be modified) | ||
389 | * @return GNUNET_SYSERR (aborts after first call) | ||
390 | */ | ||
391 | static int | ||
392 | file_information_extract (void *cls, | ||
393 | struct GNUNET_FS_FileInformation *fi, | ||
394 | uint64_t length, | ||
395 | struct GNUNET_CONTAINER_MetaData *meta, | ||
396 | struct GNUNET_FS_Uri **uri, | ||
397 | struct GNUNET_FS_BlockOptions *bo, | ||
398 | int *do_index, | ||
399 | void **client_info) | ||
400 | { | ||
401 | GtkImage *img; | ||
402 | GdkPixbuf *pixbuf; | ||
403 | struct tm *t; | ||
404 | int year; | ||
405 | time_t tp; | ||
406 | |||
407 | if (NULL != *uri) | ||
408 | GNUNET_FS_uri_ksk_get_keywords (*uri, &add_keyword, NULL); | ||
409 | if (NULL != meta) | ||
410 | { | ||
411 | GNUNET_CONTAINER_meta_data_iterate (meta, | ||
412 | &add_meta_item, | ||
413 | NULL); | ||
414 | pixbuf = GNUNET_FS_GTK_get_thumbnail_from_meta_data (meta); | ||
415 | if (pixbuf != NULL) | ||
416 | { | ||
417 | img = GTK_IMAGE (gtk_builder_get_object (builder, | ||
418 | "GNUNET_GTK_edit_file_information_metadata_preview_image")); | ||
419 | gtk_image_set_from_pixbuf (img, | ||
420 | pixbuf); | ||
421 | } | ||
422 | } | ||
423 | tp = bo->expiration_time.abs_value / 1000; /* ms to seconds */ | ||
424 | t = gmtime (&tp); | ||
425 | if (t == NULL) | ||
426 | year = 0; | ||
427 | else | ||
428 | year = t->tm_year + 1900; | ||
429 | gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object (builder, | ||
430 | "GNUNET_GTK_edit_file_information_expiration_year_spin_button")), | ||
431 | year); | ||
432 | gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object (builder, | ||
433 | "GNUNET_GTK_edit_file_information_anonymity_spin_button")), | ||
434 | bo->anonymity_level); | ||
435 | gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object (builder, | ||
436 | "GNUNET_GTK_edit_file_information_priority_spin_button")), | ||
437 | bo->content_priority); | ||
438 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, | ||
439 | "GNUNET_GTK_edit_file_information_index_check_button")), | ||
440 | *do_index); | ||
441 | return GNUNET_SYSERR; /* only visit top-level item */ | ||
442 | } | ||
443 | |||
444 | |||
445 | /** | ||
446 | * Copy binary meta data from to the new container and also | ||
447 | * preserve all entries that were not changed. | ||
448 | * | ||
449 | * @param cls closure, new meta data container | ||
450 | * @param plugin_name name of the plugin that produced this value; | ||
451 | * special values can be used (i.e. '<zlib>' for zlib being | ||
452 | * used in the main libextractor library and yielding | ||
453 | * meta data). | ||
454 | * @param type libextractor-type describing the meta data | ||
455 | * @param format basic format information about data | ||
456 | * @param data_mime_type mime-type of data (not of the original file); | ||
457 | * can be NULL (if mime-type is not known) | ||
458 | * @param data actual meta-data found | ||
459 | * @param data_len number of bytes in data | ||
460 | * @return 0 to continue extracting | ||
461 | */ | ||
462 | static int | ||
463 | preserve_meta_items (void *cls, | ||
464 | const char *plugin_name, | ||
465 | enum EXTRACTOR_MetaType type, | ||
466 | enum EXTRACTOR_MetaFormat format, | ||
467 | const char *data_mime_type, | ||
468 | const char *data, | ||
469 | size_t data_len) | ||
470 | { | ||
471 | struct GNUNET_CONTAINER_MetaData *md = cls; | ||
472 | GtkTreeModel *tm; | ||
473 | GtkTreeIter iter; | ||
474 | gchar *value; | ||
475 | guint ntype; | ||
476 | guint nformat; | ||
477 | int keep; | ||
478 | |||
479 | keep = GNUNET_NO; | ||
480 | switch (format) | ||
481 | { | ||
482 | case EXTRACTOR_METAFORMAT_UTF8: | ||
483 | case EXTRACTOR_METAFORMAT_C_STRING: | ||
484 | tm = GTK_TREE_MODEL (gtk_builder_get_object (builder, | ||
485 | "GNUNET_GTK_meta_data_list_store")); | ||
486 | if (TRUE == | ||
487 | gtk_tree_model_get_iter_first (tm, &iter)) | ||
488 | { | ||
489 | do | ||
490 | { | ||
491 | gtk_tree_model_get (tm, &iter, | ||
492 | 0, &ntype, | ||
493 | 1, &nformat, | ||
494 | 3, &value, | ||
495 | -1); | ||
496 | if ( (ntype == type) && | ||
497 | (nformat == format) && | ||
498 | (0 == strcmp (value, data)) ) | ||
499 | { | ||
500 | gtk_list_store_remove (GTK_LIST_STORE (tm), &iter); | ||
501 | keep = GNUNET_YES; | ||
502 | g_free (value); | ||
503 | break; | ||
504 | } | ||
505 | g_free (value); | ||
506 | } | ||
507 | while (TRUE == gtk_tree_model_iter_next (tm, &iter)); | ||
508 | } | ||
509 | break; | ||
510 | case EXTRACTOR_METAFORMAT_UNKNOWN: | ||
511 | break; | ||
512 | case EXTRACTOR_METAFORMAT_BINARY: | ||
513 | if (preview_changed == GNUNET_NO) | ||
514 | keep = GNUNET_YES; | ||
515 | break; | ||
516 | default: | ||
517 | GNUNET_break (0); | ||
518 | break; | ||
519 | } | ||
520 | if (GNUNET_YES == keep) | ||
521 | GNUNET_break (GNUNET_OK == | ||
522 | GNUNET_CONTAINER_meta_data_insert (md, | ||
523 | plugin_name, type, format, | ||
524 | data_mime_type, data, data_len)); | ||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | |||
529 | /** | ||
530 | * Function called to update the information in FI. | ||
531 | * | ||
532 | * @param cls closure (short_fn to update) | ||
533 | * @param fi the entry in the publish-structure | ||
534 | * @param length length of the file or directory | ||
535 | * @param meta metadata for the file or directory (can be modified) | ||
536 | * @param uri pointer to the keywords that will be used for this entry (can be modified) | ||
537 | * @param bo block options (can be modified) | ||
538 | * @param do_index should we index (can be modified) | ||
539 | * @param client_info pointer to client context set upon creation (can be modified) | ||
540 | * @return GNUNET_SYSERR (aborts after first call) | ||
541 | */ | ||
542 | static int | ||
543 | file_information_update (void *cls, | ||
544 | struct GNUNET_FS_FileInformation *fi, | ||
545 | uint64_t length, | ||
546 | struct GNUNET_CONTAINER_MetaData *meta, | ||
547 | struct GNUNET_FS_Uri **uri, | ||
548 | struct GNUNET_FS_BlockOptions *bo, | ||
549 | int *do_index, | ||
550 | void **client_info) | ||
551 | { | ||
552 | char **short_fn = cls; | ||
553 | struct GNUNET_CONTAINER_MetaData *nm; | ||
554 | GtkTreeModel *tm; | ||
555 | GtkTreeIter iter; | ||
556 | struct GNUNET_FS_Uri *nxt; | ||
557 | struct GNUNET_FS_Uri *mrg; | ||
558 | gchar *value; | ||
559 | guint ntype; | ||
560 | guint nformat; | ||
561 | GtkSpinButton *sb; | ||
562 | gchar *fn; | ||
563 | char *data; | ||
564 | gsize data_size; | ||
565 | const char *mime; | ||
566 | GFile *f; | ||
567 | GFileInfo *finfo; | ||
568 | |||
569 | bo->anonymity_level = gtk_spin_button_get_value (GTK_SPIN_BUTTON (gtk_builder_get_object (builder, | ||
570 | "GNUNET_GTK_edit_file_information_anonymity_spin_button"))); | ||
571 | bo->content_priority = gtk_spin_button_get_value (GTK_SPIN_BUTTON (gtk_builder_get_object (builder, | ||
572 | "GNUNET_GTK_edit_file_information_priority_spin_button"))); | ||
573 | *do_index = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, | ||
574 | "GNUNET_GTK_edit_file_information_index_check_button"))); | ||
575 | sb =GTK_SPIN_BUTTON (gtk_builder_get_object (builder, | ||
576 | "GNUNET_GTK_edit_file_information_expiration_year_spin_button")); | ||
577 | bo->expiration_time = GNUNET_FS_GTK_get_expiration_time (sb); | ||
578 | /* update URI */ | ||
579 | if (NULL != (*uri)) | ||
580 | GNUNET_FS_uri_destroy (*uri); | ||
581 | *uri = NULL; | ||
582 | nxt = NULL; | ||
583 | mrg = NULL; | ||
584 | |||
585 | tm = GTK_TREE_MODEL (gtk_builder_get_object (builder, | ||
586 | "GNUNET_GTK_keyword_list_store")); | ||
587 | if (TRUE == | ||
588 | gtk_tree_model_get_iter_first (tm, &iter)) | ||
589 | { | ||
590 | do | ||
591 | { | ||
592 | gtk_tree_model_get (tm, &iter, | ||
593 | 0, &value, | ||
594 | -1); | ||
595 | nxt = GNUNET_FS_uri_ksk_create_from_args (1, (const char**) &value); | ||
596 | mrg = GNUNET_FS_uri_ksk_merge (nxt, *uri); | ||
597 | GNUNET_FS_uri_destroy (nxt); | ||
598 | if (NULL != *uri) | ||
599 | GNUNET_FS_uri_destroy (*uri); | ||
600 | *uri = mrg; | ||
601 | g_free (value); | ||
602 | } | ||
603 | while (TRUE == gtk_tree_model_iter_next (tm, &iter)); | ||
604 | } | ||
605 | |||
606 | /* update meta */ | ||
607 | nm = GNUNET_CONTAINER_meta_data_create (); | ||
608 | GNUNET_CONTAINER_meta_data_iterate (meta, | ||
609 | &preserve_meta_items, | ||
610 | nm); | ||
611 | |||
612 | GNUNET_CONTAINER_meta_data_clear (meta); | ||
613 | tm = GTK_TREE_MODEL (gtk_builder_get_object (builder, | ||
614 | "GNUNET_GTK_meta_data_list_store")); | ||
615 | if (TRUE == | ||
616 | gtk_tree_model_get_iter_first (tm, &iter)) | ||
617 | { | ||
618 | do | ||
619 | { | ||
620 | gtk_tree_model_get (tm, &iter, | ||
621 | 0, &ntype, | ||
622 | 1, &nformat, | ||
623 | 3, &value, | ||
624 | -1); | ||
625 | GNUNET_CONTAINER_meta_data_insert (nm, | ||
626 | "<user>", | ||
627 | ntype, | ||
628 | nformat, | ||
629 | "text/plain", | ||
630 | value, | ||
631 | strlen (value)+1); | ||
632 | g_free (value); | ||
633 | } | ||
634 | while (TRUE == gtk_tree_model_iter_next (tm, &iter)); | ||
635 | } | ||
636 | GNUNET_CONTAINER_meta_data_merge (meta, nm); | ||
637 | if (preview_changed == GNUNET_YES) | ||
638 | { | ||
639 | fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (gtk_builder_get_object (builder, | ||
640 | "GNUNET_GTK_edit_file_information_metadata_preview_file_chooser_button"))); | ||
641 | f = g_file_new_for_path (fn); | ||
642 | finfo = g_file_query_info (f, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, 0, NULL, NULL); | ||
643 | if (FALSE == g_file_load_contents (f, NULL, &data, &data_size, NULL, NULL)) | ||
644 | { | ||
645 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
646 | _("Could not load preview `%s' into memory\n"), | ||
647 | fn); | ||
648 | } | ||
649 | else | ||
650 | { | ||
651 | mime = g_file_info_get_attribute_string (finfo, | ||
652 | G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE); | ||
653 | GNUNET_CONTAINER_meta_data_insert (meta, | ||
654 | "<user>", | ||
655 | EXTRACTOR_METATYPE_THUMBNAIL, | ||
656 | EXTRACTOR_METAFORMAT_BINARY, | ||
657 | mime, | ||
658 | data, | ||
659 | data_size); | ||
660 | } | ||
661 | g_object_unref (finfo); | ||
662 | g_object_unref (f); | ||
663 | } | ||
664 | GNUNET_CONTAINER_meta_data_destroy (nm); | ||
665 | |||
666 | /* update short_fn */ | ||
667 | GNUNET_free_non_null (*short_fn); | ||
668 | *short_fn = GNUNET_CONTAINER_meta_data_get_first_by_types (meta, | ||
669 | EXTRACTOR_METATYPE_FILENAME, | ||
670 | -1); | ||
671 | /* FIXME: update expiration time? (not yet in dialog!) */ | ||
672 | return GNUNET_SYSERR; /* only visit top-level item */ | ||
673 | } | ||
674 | |||
675 | |||
676 | /** | ||
677 | * Open the dialog to edit file information data. | ||
678 | */ | ||
679 | void | ||
680 | GNUNET_GTK_edit_publish_dialog (int *do_index, | ||
681 | char **short_fn, | ||
682 | guint *anonymity_level, | ||
683 | guint *priority, | ||
684 | struct GNUNET_FS_FileInformation *fip) | ||
685 | { | ||
686 | GtkWidget *ad; | ||
687 | GtkListStore *ls; | ||
688 | GtkTreeIter iter; | ||
689 | guint type; | ||
690 | guint max_type; | ||
691 | GtkTreeView *tv; | ||
692 | GtkTreeSelection *sel; | ||
693 | |||
694 | GNUNET_assert (builder == NULL); | ||
695 | builder = GNUNET_GTK_get_new_builder ("publish_edit_dialog.glade"); | ||
696 | if (builder == NULL) | ||
697 | { | ||
698 | GNUNET_break (0); | ||
699 | return; | ||
700 | } | ||
701 | preview_changed = GNUNET_NO; | ||
702 | GNUNET_FS_GTK_setup_expiration_year_adjustment (builder); | ||
703 | if (GNUNET_FS_file_information_is_directory (fip)) | ||
704 | { | ||
705 | /* indexing does not apply to directories */ | ||
706 | gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, | ||
707 | "GNUNET_GTK_edit_file_information_index_check_button"))); | ||
708 | gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, | ||
709 | "GNUNET_GTK_edit_file_information_index_label"))); | ||
710 | |||
711 | } | ||
712 | |||
713 | ad = GTK_WIDGET (gtk_builder_get_object (builder, | ||
714 | "GNUNET_GTK_edit_file_information_dialog")); | ||
715 | ls = GTK_LIST_STORE (gtk_builder_get_object (builder, | ||
716 | "GNUNET_GTK_metatype_list_store")); | ||
717 | max_type = EXTRACTOR_metatype_get_max (); | ||
718 | type = 1; | ||
719 | while (type < max_type - 1) | ||
720 | { | ||
721 | gtk_list_store_insert_with_values (ls, &iter, G_MAXINT, | ||
722 | 0, EXTRACTOR_metatype_to_string (type), | ||
723 | 1, type, | ||
724 | 2, EXTRACTOR_metatype_to_description (type), | ||
725 | -1); | ||
726 | type++; | ||
727 | } | ||
728 | |||
729 | GNUNET_FS_file_information_inspect (fip, | ||
730 | &file_information_extract, | ||
731 | NULL); | ||
732 | tv = GTK_TREE_VIEW (gtk_builder_get_object (builder, | ||
733 | "GNUNET_GTK_edit_file_information_metadata_type_tree_view")); | ||
734 | sel = gtk_tree_view_get_selection (tv); | ||
735 | g_signal_connect(G_OBJECT(sel), "changed", | ||
736 | G_CALLBACK(GNUNET_GTK_edit_file_information_metadata_value_entry_changed_cb), NULL); | ||
737 | |||
738 | tv = GTK_TREE_VIEW (gtk_builder_get_object (builder, | ||
739 | "GNUNET_GTK_edit_file_information_metadata_tree_view")); | ||
740 | sel = gtk_tree_view_get_selection (tv); | ||
741 | g_signal_connect(G_OBJECT(sel), "changed", | ||
742 | G_CALLBACK(metadata_selection_changed_cb), NULL); | ||
743 | |||
744 | tv = GTK_TREE_VIEW (gtk_builder_get_object (builder, | ||
745 | "GNUNET_GTK_edit_file_information_keyword_list_tree_view")); | ||
746 | sel = gtk_tree_view_get_selection (tv); | ||
747 | g_signal_connect(G_OBJECT(sel), "changed", | ||
748 | G_CALLBACK(keyword_selection_changed_cb), NULL); | ||
749 | gtk_window_set_title (GTK_WINDOW (ad), *short_fn); | ||
750 | if (GTK_RESPONSE_OK != gtk_dialog_run (GTK_DIALOG (ad))) | ||
751 | { | ||
752 | gtk_widget_destroy (ad); | ||
753 | g_object_unref (G_OBJECT (builder)); | ||
754 | builder = NULL; | ||
755 | return; | ||
756 | } | ||
757 | GNUNET_FS_file_information_inspect (fip, | ||
758 | &file_information_update, | ||
759 | short_fn); | ||
760 | *anonymity_level = gtk_spin_button_get_value (GTK_SPIN_BUTTON (gtk_builder_get_object (builder, | ||
761 | "GNUNET_GTK_edit_file_information_anonymity_spin_button"))); | ||
762 | *priority = gtk_spin_button_get_value (GTK_SPIN_BUTTON (gtk_builder_get_object (builder, | ||
763 | "GNUNET_GTK_edit_file_information_priority_spin_button"))); | ||
764 | *do_index = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, | ||
765 | "GNUNET_GTK_edit_file_information_index_check_button"))); | ||
766 | gtk_widget_destroy (ad); | ||
767 | g_object_unref (G_OBJECT (builder)); | ||
768 | builder = NULL; | ||
769 | } | ||
770 | |||
771 | /* end of edit_publish_dialog.c */ | ||