From 5c5f49c95a5def2db09459fa9ce92301c3d8d4d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1=D1?= =?UTF-8?q?=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= Date: Sat, 24 Dec 2011 23:07:30 +0400 Subject: [PATCH] Temporary fix for charset conversion --- src/fs/gnunet-fs-gtk-common.c | 87 ++++++---- src/fs/gnunet-fs-gtk-common.h | 18 ++ src/fs/gnunet-fs-gtk-download.c | 10 +- src/fs/gnunet-fs-gtk-edit_publish_dialog.c | 5 +- src/fs/gnunet-fs-gtk-event_handler.c | 36 ++++- src/fs/gnunet-fs-gtk-main_window_adv_pseudonym.c | 6 +- .../gnunet-fs-gtk-main_window_create_pseudonym.c | 10 +- src/fs/gnunet-fs-gtk-main_window_file_publish.c | 53 ++++++- src/fs/gnunet-fs-gtk-main_window_open_directory.c | 10 +- src/fs/gnunet-fs-gtk.c | 21 ++- src/include/gnunet_gtk.h | 28 ++++ src/lib/nls.c | 167 ++++++++++++++++++++ 12 files changed, 391 insertions(+), 60 deletions(-) diff --git a/src/fs/gnunet-fs-gtk-common.c b/src/fs/gnunet-fs-gtk-common.c index b2bf9b2..bd33d17 100644 --- a/src/fs/gnunet-fs-gtk-common.c +++ b/src/fs/gnunet-fs-gtk-common.c @@ -26,6 +26,53 @@ #include "gnunet-fs-gtk-common.h" /** + * Converts metadata specified by @data of size @data_len + * and saved in format @format to UTF-8 encoded string. + * Works only for C-string and UTF8 metadata formats + * (returns NULL for everything else). + * Verifies UTF-8 strings. + * + * @param format format of the @data + * @param data data to convert + * @param data_len length of the data buffer (in bytes) + * @return NULL if can't be converted, allocated string otherwise, + * freeable with GNUNET_free* (). + */ +char * +GNUNET_FS_GTK_dubious_meta_to_utf8 (enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len) +{ + gchar *result = NULL; + + if (format == EXTRACTOR_METAFORMAT_UTF8) + { + /* data must not contain NULLs (hence the -1) */ + if (g_utf8_validate (data, data_len - 1, NULL)) + result = GNUNET_strdup (data); + else + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to validate supposedly utf-8 string `%s' of length %u, assuming it to be a C string\n", + data, data_len); + format = EXTRACTOR_METAFORMAT_C_STRING; + } + } + if (format == EXTRACTOR_METAFORMAT_C_STRING) + { + if (data_len > 0) + { /* There are no guarantees that data is NULL-terminated, AFAIU, + * so let's play it safe, shall we? + */ + char *data_copy = GNUNET_malloc (data_len + 1); + memcpy (data_copy, data, data_len); + data_copy[data_len] = '\0'; + result = GNUNET_GTK_from_loc_to_utf8 (data_copy); + GNUNET_free (data_copy); + } + } + return result; +} + +/** * Add meta data to list store. * * @param cls closure (the GtkListStore) @@ -49,44 +96,17 @@ GNUNET_FS_GTK_add_meta_data_to_list_store (void *cls, const char *plugin_name, const char *data, size_t data_len) { GtkListStore *ls = GTK_LIST_STORE (cls); - const gchar *data_to_insert = NULL; - gchar *free_data = NULL; - gsize rd; - gsize wr; + gchar *data_to_insert = NULL; - if (format == EXTRACTOR_METAFORMAT_UTF8) - { - if (g_utf8_validate (data, data_len, NULL)) - data_to_insert = data; - else - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Failed to validate supposedly utf-8 string `%s' of length %u, assuming it to be a C string\n", - data, data_len); - format = EXTRACTOR_METAFORMAT_C_STRING; - } - } - if (format == EXTRACTOR_METAFORMAT_C_STRING) - { - GError *gerr = NULL; - rd = wr = 0; - free_data = g_locale_to_utf8 (data, data_len, &rd, &wr, &gerr); - if (gerr != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Error when converting a C string `%s' of length %u to utf-8 (converted %u to %u bytes): %s\n", - data, data_len, rd, wr, gerr->message); - g_error_free (gerr); - } - data_to_insert = free_data; - } + data_to_insert = GNUNET_FS_GTK_dubious_meta_to_utf8 (format, data, data_len); if (NULL != data_to_insert) + { gtk_list_store_insert_with_values (ls, NULL, G_MAXINT, 0, type, 1, format, 2, EXTRACTOR_metatype_to_string (type), - 3, data_to_insert, -1); - if (NULL != free_data) - g_free (free_data); + 3, data_to_insert, -1); + g_free (data_to_insert); + } return 0; } @@ -194,5 +214,4 @@ GNUNET_FS_GTK_mmap_and_scan (const char *filename, GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh)); } - /* end of gnunet-fs-gtk-common.c */ diff --git a/src/fs/gnunet-fs-gtk-common.h b/src/fs/gnunet-fs-gtk-common.h index 9484b0e..d0d7b4f 100644 --- a/src/fs/gnunet-fs-gtk-common.h +++ b/src/fs/gnunet-fs-gtk-common.h @@ -101,5 +101,23 @@ GNUNET_FS_GTK_add_meta_data_to_list_store (void *cls, const char *plugin_name, const char *data_mime_type, const char *data, size_t data_len); +/** + * Converts metadata specified by @data of size @data_len + * and saved in format @format to UTF-8 encoded string. + * Works only for C-string and UTF8 metadata formats + * (returns NULL for everything else). + * Verifies UTF-8 strings. + * + * @param format format of the @data + * @param data data to convert + * @param data_len length of the data buffer (in bytes) + * @return NULL if can't be converted, allocated string otherwise, + * freeable with GNUNET_free* (). + */ +char * +GNUNET_FS_GTK_dubious_meta_to_utf8 (enum EXTRACTOR_MetaFormat format, + const char *data, size_t data_len); + + #endif /* end of gnunet-fs-gtk-common.h */ diff --git a/src/fs/gnunet-fs-gtk-download.c b/src/fs/gnunet-fs-gtk-download.c index 3f5f213..09ae7e1 100644 --- a/src/fs/gnunet-fs-gtk-download.c +++ b/src/fs/gnunet-fs-gtk-download.c @@ -73,7 +73,7 @@ GNUNET_GTK_save_as_dialog_delete_event_cb (GtkWidget *widget, GdkEvent *event, return FALSE; } GNUNET_free_non_null (dc->filename); - dc->filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlc->dialog)); + dc->filename = GNUNET_GTK_filechooser_get_filename_loc (GTK_FILE_CHOOSER (dlc->dialog)); dc->is_recursive = (TRUE == gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb))) ? GNUNET_YES : @@ -165,6 +165,7 @@ GNUNET_FS_GTK_open_download_as_dialog (struct DownloadContext *dc) if (dc->filename != NULL) { char buf[1024]; + char *buf_utf8; if (NULL != getcwd (buf, sizeof (buf))) { @@ -173,7 +174,12 @@ GNUNET_FS_GTK_open_download_as_dialog (struct DownloadContext *dc) strcat (buf, DIR_SEPARATOR_STR); strcat (buf, dc->filename); } - gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (ad), buf); + buf_utf8 = GNUNET_GTK_from_loc_to_utf8 (buf); + if (buf_utf8 != NULL) + { + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (ad), buf_utf8); + GNUNET_free (buf_utf8); + } } } dlc = g_new0 (struct dialog_context, 1); diff --git a/src/fs/gnunet-fs-gtk-edit_publish_dialog.c b/src/fs/gnunet-fs-gtk-edit_publish_dialog.c index 8c0d76b..5324e3a 100644 --- a/src/fs/gnunet-fs-gtk-edit_publish_dialog.c +++ b/src/fs/gnunet-fs-gtk-edit_publish_dialog.c @@ -530,6 +530,7 @@ GNUNET_GTK_edit_publication_metadata_preview_file_chooser_button_file_set_cb ( (builder, "GNUNET_GTK_edit_publication_metadata_preview_image")); gtk_image_set_from_file (image, fn); + g_free (fn); state->preview_changed = GNUNET_YES; } @@ -589,7 +590,7 @@ preserve_meta_items (void *cls, const char *plugin_name, GNUNET_break (0); return 0; } - + /* FIXME: make sure this is all correct UTF-8-wise */ keep = GNUNET_NO; switch (format) { @@ -808,6 +809,7 @@ file_information_update (void *cls, struct GNUNET_FS_FileInformation *fi, } g_object_unref (finfo); g_object_unref (f); + g_free (fn); } GNUNET_CONTAINER_meta_data_destroy (nm); @@ -1016,6 +1018,7 @@ file_information_extract (void *cls, struct GNUNET_FS_FileInformation *fi, /** * Open the dialog to edit file information data. + * short_fn MUST be UTF-8-encoded */ void GNUNET_FS_GTK_edit_publish_dialog (GtkBuilder *builder, diff --git a/src/fs/gnunet-fs-gtk-event_handler.c b/src/fs/gnunet-fs-gtk-event_handler.c index 23129eb..631c342 100644 --- a/src/fs/gnunet-fs-gtk-event_handler.c +++ b/src/fs/gnunet-fs-gtk-event_handler.c @@ -548,6 +548,7 @@ setup_download (struct DownloadEntry *de, struct DownloadEntry *pde, GtkTreeIter iter; GtkTreePath *path; struct SearchResult *srp; + gchar *filename_utf8; if (de == NULL) { @@ -587,13 +588,15 @@ setup_download (struct DownloadEntry *de, struct DownloadEntry *pde, return de; } gtk_tree_path_free (path); + filename_utf8 = GNUNET_GTK_from_loc_to_utf8 ((char *) filename); gtk_tree_store_set (de->ts, &iter, 4, (guint) ((size > 0) ? (100 * completed / size) : 100) /* progress */ , - 6, filename /* filename/description */ , + 6, filename_utf8 /* filename/description */ , 8, "blue" /* status colour: pending */ , -1); + GNUNET_free_non_null (filename_utf8); return de; } @@ -1111,6 +1114,7 @@ setup_search (struct GNUNET_FS_SearchContext *sc, } else { + /* FS_uri functions should produce UTF-8, so let them be */ if (GNUNET_FS_uri_test_ksk (query)) tab->query_txt = GNUNET_FS_uri_ksk_to_string_fancy (query); else @@ -1291,6 +1295,16 @@ GNUNET_GTK_add_search_result (struct SearchTab *tab, GtkTreeIter * iter, -1); if (desc == NULL) desc = GNUNET_strdup (_("no description supplied")); + else + { + char *utf8_desc = NULL; + utf8_desc = GNUNET_FS_GTK_dubious_meta_to_utf8 (EXTRACTOR_METAFORMAT_UTF8, desc, strlen (desc) + 1); + GNUNET_free (desc); + if (utf8_desc != NULL) + desc = utf8_desc; + else + desc = NULL; + } if (uri == NULL) uris = GNUNET_strdup (_("no URI")); else @@ -1348,7 +1362,7 @@ GNUNET_GTK_add_search_result (struct SearchTab *tab, GtkTreeIter * iter, if (pixbuf != NULL) g_object_unref (pixbuf); GNUNET_free (uris); - GNUNET_free (desc); + GNUNET_free_non_null (desc); GNUNET_free_non_null (mime); tp = gtk_tree_model_get_path (GTK_TREE_MODEL (ts), iter); sr->rr = gtk_tree_row_reference_new (GTK_TREE_MODEL (ts), tp); @@ -1468,6 +1482,16 @@ update_search_result (struct SearchResult *sr, -1); if (desc == NULL) desc = GNUNET_strdup (_("no description supplied")); + else + { + char *utf8_desc = NULL; + utf8_desc = GNUNET_FS_GTK_dubious_meta_to_utf8 (EXTRACTOR_METAFORMAT_UTF8, desc, strlen (desc) + 1); + GNUNET_free (desc); + if (utf8_desc != NULL) + desc = utf8_desc; + else + desc = NULL; + } mime = GNUNET_CONTAINER_meta_data_get_first_by_types (meta, EXTRACTOR_METATYPE_MIMETYPE, @@ -1497,7 +1521,7 @@ update_search_result (struct SearchResult *sr, (gint) availability_rank, -1); if (pixbuf != NULL) g_object_unref (pixbuf); - GNUNET_free (desc); + GNUNET_free_non_null (desc); GNUNET_free_non_null (mime); notebook = @@ -1610,6 +1634,7 @@ setup_publish (struct GNUNET_FS_PublishContext *pc, const char *fn, GtkWidget *close_button; GtkNotebook *notebook; char *size_fancy; + char *fn_utf8 = NULL; if (NULL == parent) { @@ -1676,11 +1701,14 @@ setup_publish (struct GNUNET_FS_PublishContext *pc, const char *fn, ent = GNUNET_malloc (sizeof (struct PublishEntry)); ent->is_top = (parent == NULL) ? GNUNET_YES : GNUNET_NO; ent->tab = publish_tab; - gtk_tree_store_insert_with_values (publish_tab->ts, &iter, pitrptr, G_MAXINT, 0, fn, + fn_utf8 = GNUNET_GTK_from_loc_to_utf8 ((char *) fn); + gtk_tree_store_insert_with_values (publish_tab->ts, &iter, pitrptr, G_MAXINT, + 0, fn_utf8, 1, size_fancy, 2, "white", 3, (guint) 0 /* progress */ , 4, ent, -1); + GNUNET_free_non_null (fn_utf8); path = gtk_tree_model_get_path (GTK_TREE_MODEL (publish_tab->ts), &iter); GNUNET_assert (NULL != path); ent->rr = gtk_tree_row_reference_new (GTK_TREE_MODEL (publish_tab->ts), path); diff --git a/src/fs/gnunet-fs-gtk-main_window_adv_pseudonym.c b/src/fs/gnunet-fs-gtk-main_window_adv_pseudonym.c index b15060b..711b78f 100644 --- a/src/fs/gnunet-fs-gtk-main_window_adv_pseudonym.c +++ b/src/fs/gnunet-fs-gtk-main_window_adv_pseudonym.c @@ -48,12 +48,14 @@ add_to_list (void *cls, const char *name, const GNUNET_HashCode * id) { GtkListStore *ls = cls; GtkTreeIter iter; + char *name_utf8; + name_utf8 = GNUNET_GTK_from_loc_to_utf8 ((char *) name); - gtk_list_store_insert_with_values (ls, &iter, -1, 0, name, 1, + gtk_list_store_insert_with_values (ls, &iter, -1, 0, name_utf8, 1, GNUNET_FS_namespace_create (GNUNET_FS_GTK_get_fs_handle (), name), -1); - + GNUNET_free_non_null (name_utf8); } diff --git a/src/fs/gnunet-fs-gtk-main_window_create_pseudonym.c b/src/fs/gnunet-fs-gtk-main_window_create_pseudonym.c index e0a8b0e..c912aab 100644 --- a/src/fs/gnunet-fs-gtk-main_window_create_pseudonym.c +++ b/src/fs/gnunet-fs-gtk-main_window_create_pseudonym.c @@ -31,6 +31,7 @@ GNUNET_GTK_create_namespace_dialog_response_cb (GtkDialog *dialog, gint response_id, gpointer user_data) { const char *name; + gchar *name_loc; struct GNUNET_FS_Namespace *ns; GtkWidget *ad; GtkBuilder *builder; @@ -51,8 +52,13 @@ GNUNET_GTK_create_namespace_dialog_response_cb (GtkDialog *dialog, (builder, "GNUNET_GTK_create_namespace_name_entry"))); /* FIXME: show busy dialog while doing key creation */ - ns = GNUNET_FS_namespace_create (GNUNET_FS_GTK_get_fs_handle (), name); - GNUNET_FS_namespace_delete (ns, GNUNET_NO); + name_loc = GNUNET_GTK_from_utf8_to_loc ((char *) name); + if (NULL != name_loc) + { + ns = GNUNET_FS_namespace_create (GNUNET_FS_GTK_get_fs_handle (), name_loc); + GNUNET_FS_namespace_delete (ns, GNUNET_NO); + GNUNET_free (name_loc); + } gtk_widget_destroy (ad); g_object_unref (G_OBJECT (builder)); } diff --git a/src/fs/gnunet-fs-gtk-main_window_file_publish.c b/src/fs/gnunet-fs-gtk-main_window_file_publish.c index 1629842..7172e33 100644 --- a/src/fs/gnunet-fs-gtk-main_window_file_publish.c +++ b/src/fs/gnunet-fs-gtk-main_window_file_publish.c @@ -211,6 +211,7 @@ add_file_at_iter (gpointer data, const char *filename, const struct GNUNET_FS_Bl GtkTreePath *path; uint64_t file_size; const char *short_fn; + char *short_fn_utf8; struct GNUNET_CONTAINER_MetaData *meta; struct GNUNET_FS_Uri *ksk_uri; GtkTreeStore *ts; @@ -248,10 +249,11 @@ add_file_at_iter (gpointer data, const char *filename, const struct GNUNET_FS_Bl short_fn = filename; while (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR))) short_fn = 1 + ss; + short_fn_utf8 = GNUNET_GTK_from_loc_to_utf8 ((char *) short_fn); GNUNET_CONTAINER_meta_data_insert (meta, "", EXTRACTOR_METATYPE_FILENAME, EXTRACTOR_METAFORMAT_UTF8, "text/plain", - short_fn, strlen (short_fn) + 1); + short_fn_utf8, strlen (short_fn_utf8) + 1); ksk_uri = GNUNET_FS_uri_ksk_create_from_meta_data (meta); gtk_tree_store_insert_before (ts, &pos, iter, NULL); path = gtk_tree_model_get_path (GTK_TREE_MODEL (ts), &pos); @@ -268,8 +270,9 @@ add_file_at_iter (gpointer data, const char *filename, const struct GNUNET_FS_Bl else file_size_fancy = GNUNET_STRINGS_byte_size_fancy (file_size); gtk_tree_store_set (ts, &pos, 0, file_size_fancy, 1, (gboolean) do_index, 2, - short_fn, 3, (guint) bo->anonymity_level, 4, + short_fn_utf8, 3, (guint) bo->anonymity_level, 4, (guint) bo->content_priority, 5, fi, -1); + GNUNET_free_non_null (short_fn_utf8); GNUNET_free (file_size_fancy); update_selectivity (data); } @@ -294,6 +297,7 @@ create_dir_at_iter (gpointer data, const char *name, const struct GNUNET_FS_Bloc GtkTreeStore *ts; GtkBuilder *builder; + builder = GTK_BUILDER (data); ts = GTK_TREE_STORE (gtk_builder_get_object @@ -504,6 +508,7 @@ extract_file (struct AddDirContext *adc, const char *filename) GNUNET_HashCode hc; const char *short_fn; const char *ss; + char *short_fn_utf8; adc->dir_entry_count++; pd = GNUNET_malloc (sizeof (struct PublishData)); @@ -515,11 +520,12 @@ extract_file (struct AddDirContext *adc, const char *filename) short_fn = filename; while (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR))) short_fn = 1 + ss; + short_fn_utf8 = GNUNET_GTK_from_loc_to_utf8 ((char *) short_fn); GNUNET_CONTAINER_meta_data_insert (pd->meta, "", EXTRACTOR_METATYPE_FILENAME, EXTRACTOR_METAFORMAT_UTF8, "text/plain", - short_fn, strlen (short_fn) + 1); - + short_fn, strlen (short_fn_utf8) + 1); + GNUNET_free_non_null (short_fn_utf8); gtk_tree_store_insert_before (adc->ts, &pd->iter, adc->parent, NULL); GNUNET_CRYPTO_hash (filename, strlen (filename), &hc); @@ -576,6 +582,7 @@ add_entry_to_ts (GtkTreeStore * ts, GtkTreeIter * iter, const char *filename, struct GNUNET_FS_Uri *kill_ksk; const char *ss; const char *short_fn; + char *short_fn_utf8; struct stat sbuf; if (0 != STAT (filename, &sbuf)) @@ -627,9 +634,11 @@ add_entry_to_ts (GtkTreeStore * ts, GtkTreeIter * iter, const char *filename, short_fn = filename; while (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR))) short_fn = 1 + ss; + short_fn_utf8 = GNUNET_GTK_from_loc_to_utf8 ((char *) short_fn); gtk_tree_store_set (ts, iter, 0, file_size_fancy, 1, (gboolean) do_index, 2, - short_fn, 3, (guint) bo->anonymity_level, 4, + short_fn_utf8, 3, (guint) bo->anonymity_level, 4, (guint) bo->content_priority, 5, fi, -1); + GNUNET_free_non_null (short_fn_utf8); GNUNET_free (file_size_fancy); } @@ -774,8 +783,19 @@ scan_directory (void *cls, const char *filename) } else { + char *filename_utf8; + const char *ss, *short_fn; GNUNET_assert (mcm == NULL); /* we're top-level */ + short_fn = filename; + while (NULL != (ss = strstr (short_fn, DIR_SEPARATOR_STR))) + short_fn = 1 + ss; + filename_utf8 = GNUNET_GTK_from_loc_to_utf8 ((char *) short_fn); + GNUNET_CONTAINER_meta_data_insert (pd->meta, "", + EXTRACTOR_METATYPE_FILENAME, + EXTRACTOR_METAFORMAT_UTF8, "text/plain", + filename_utf8, strlen (filename_utf8) + 1); + GNUNET_free_non_null (filename_utf8); add_entry_to_ts (adc->ts, &pd->iter, filename, &adc->bo, adc->do_index, NULL, pd->meta); } @@ -1384,7 +1404,7 @@ GNUNET_GTK_publish_directory_dialog_response_cb (GtkDialog *dialog, "GNUNET_GTK_publish_directory_dialog")); if (response_id == -5) { - filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (ad)); + filename = GNUNET_GTK_filechooser_get_filename_loc (GTK_FILE_CHOOSER (ad)); sb = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "GNUNET_GTK_publish_directory_dialog_expiration_year_spin_button")); if (!GNUNET_GTK_get_selected_anonymity_level (builder, @@ -1539,6 +1559,18 @@ add_updateable_to_ts (void *cls, const char *last_id, EXTRACTOR_METATYPE_COMMENT, EXTRACTOR_METATYPE_SUBJECT, -1); + if (desc == NULL) + desc = GNUNET_strdup (_("no description supplied")); + else + { + char *utf8_desc = NULL; + utf8_desc = GNUNET_FS_GTK_dubious_meta_to_utf8 (EXTRACTOR_METAFORMAT_UTF8, desc, strlen (desc) + 1); + GNUNET_free (desc); + if (utf8_desc != NULL) + desc = utf8_desc; + else + desc = NULL; + } gtk_tree_store_insert_with_values (uc->ts, &iter, uc->parent, G_MAXINT, 0, uc->namespace_name, 1, uc->ns, 2, last_id, 3, GNUNET_FS_uri_dup (last_uri), 4, @@ -1586,13 +1618,15 @@ add_namespace_to_ts (void *cls, const char *name, const GNUNET_HashCode * id) GtkTreeStore *ts = cls; struct UpdateableContext uc; GtkTreeIter iter; + gchar *name_utf8; uc.parent = &iter; uc.namespace_name = name; uc.ts = ts; uc.ns = GNUNET_FS_namespace_create (GNUNET_FS_GTK_get_fs_handle (), name); uc.update_called = GNUNET_NO; - gtk_tree_store_insert_with_values (ts, &iter, NULL, G_MAXINT, 0, name, 1, + name_utf8 = GNUNET_GTK_from_loc_to_utf8 ((char *) name); + gtk_tree_store_insert_with_values (ts, &iter, NULL, G_MAXINT, 0, name_utf8, 1, uc.ns, 2, NULL /* last-id */ , 3, NULL /* last-uri */ , 4, NULL /* meta */ , @@ -1601,6 +1635,7 @@ add_namespace_to_ts (void *cls, const char *name, const GNUNET_HashCode * id) 7, TRUE /* update editable */ , 8, TRUE /* current editable */ , -1); + GNUNET_free_non_null (name_utf8); uc.seen = GNUNET_CONTAINER_multihashmap_create (128); GNUNET_FS_namespace_list_updateable (uc.ns, NULL, &add_updateable_to_ts, &uc); GNUNET_CONTAINER_multihashmap_destroy (uc.seen); @@ -1726,6 +1761,7 @@ hide_master_publish_dialog (gpointer user_data, gint ret) do { fi = get_file_information (tm, &iter); + /* FIXME: should we convert namespace id and uid from UTF8? */ GNUNET_FS_publish_start (GNUNET_FS_GTK_get_fs_handle (), fi, namespace, namespace_id, namespace_uid, GNUNET_FS_PUBLISH_OPTION_NONE); @@ -1801,7 +1837,6 @@ GNUNET_GTK_publish_file_dialog_response_cb (GtkDialog *dialog, if (response_id == -5) { /* OK */ - filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (ad)); sb = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "GNUNET_GTK_publish_file_dialog_expiration_year_spin_button")); @@ -1816,6 +1851,8 @@ GNUNET_GTK_publish_file_dialog_response_cb (GtkDialog *dialog, do_index = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON ( gtk_builder_get_object (builder, "GNUNET_GTK_publish_file_dialog_do_index_checkbutton"))); + + filename = GNUNET_GTK_filechooser_get_filename_loc (GTK_FILE_CHOOSER (ad)); add_file_at_iter (user_data, filename, &bo, do_index, NULL); g_free (filename); update_selectivity (user_data); diff --git a/src/fs/gnunet-fs-gtk-main_window_open_directory.c b/src/fs/gnunet-fs-gtk-main_window_open_directory.c index 23e71fc..e614451 100644 --- a/src/fs/gnunet-fs-gtk-main_window_open_directory.c +++ b/src/fs/gnunet-fs-gtk-main_window_open_directory.c @@ -67,7 +67,7 @@ add_child (void *cls, const char *filename, const struct GNUNET_FS_Uri *uri, dmeta = GNUNET_CONTAINER_meta_data_duplicate (meta); GNUNET_CONTAINER_meta_data_insert (dmeta, "", EXTRACTOR_METATYPE_FILENAME, - EXTRACTOR_METAFORMAT_C_STRING, + EXTRACTOR_METAFORMAT_UTF8, "text/plain", acc->filename, strlen (acc->filename) + 1); acc->tab = GNUNET_GTK_add_to_uri_tab (&acc->iter, &acc->par, dmeta, NULL); @@ -91,7 +91,7 @@ GNUNET_GTK_open_directory_dialog_response_cb (GtkDialog *dialog, { GtkBuilder *builder; GtkWidget *ad; - char *filename; + char *filename, *filename_utf8; struct AddChildContext acc; builder = GTK_BUILDER (user_data); @@ -105,12 +105,14 @@ GNUNET_GTK_open_directory_dialog_response_cb (GtkDialog *dialog, return; } - filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (ad)); + filename = GNUNET_GTK_filechooser_get_filename_loc (GTK_FILE_CHOOSER (ad)); + filename_utf8 = GNUNET_GTK_filechooser_get_filename_utf8 (GTK_FILE_CHOOSER (ad)); gtk_widget_destroy (ad); g_object_unref (G_OBJECT (builder)); - acc.filename = filename; + acc.filename = filename_utf8; acc.ts = NULL; GNUNET_FS_GTK_mmap_and_scan (filename, &add_child, &acc); + g_free (filename_utf8); g_free (filename); } diff --git a/src/fs/gnunet-fs-gtk.c b/src/fs/gnunet-fs-gtk.c index 5545371..bf6e171 100644 --- a/src/fs/gnunet-fs-gtk.c +++ b/src/fs/gnunet-fs-gtk.c @@ -501,8 +501,11 @@ main_window_search_button_clicked_cb (GtkButton *button, gpointer user_data) mime_keyword = NULL; if (mime_model && gtk_combo_box_get_active_iter (mime_combo, &iter)) gtk_tree_model_get (mime_model, &iter, 0, &mime_keyword, -1); - if (mime_keyword == NULL) - mime_keyword = g_strdup (""); + if (strcmp (mime_keyword, " ") == 0) + { + g_free (mime_keyword); + mime_keyword = NULL; + } ref = g_object_get_data (G_OBJECT (toggle_button), "selected-row-reference"); if (ref) @@ -516,7 +519,7 @@ main_window_search_button_clicked_cb (GtkButton *button, gpointer user_data) query_entry = GTK_ENTRY (gtk_builder_get_object (builder, "main_window_search_entry")); entry_keywords = gtk_entry_get_text (query_entry); - keywords = g_strdup_printf ("%s +%s", entry_keywords, mime_keyword); + keywords = g_strdup_printf ("%s %s%s", entry_keywords, mime_keyword ? "+" : "", mime_keyword ? mime_keyword : ""); g_free (mime_keyword); if (nsid != NULL) { @@ -613,6 +616,18 @@ add_namespace_to_ts (void *cls, const GNUNET_HashCode * pseudonym, EXTRACTOR_METATYPE_SUBJECT, EXTRACTOR_METATYPE_KEYWORDS, -1); + if (description == NULL) + description = g_strdup (_("no description supplied")); + else + { + char *utf8_desc = NULL; + utf8_desc = GNUNET_FS_GTK_dubious_meta_to_utf8 (EXTRACTOR_METAFORMAT_UTF8, description, strlen (description)); + GNUNET_free (description); + if (utf8_desc != NULL) + description = utf8_desc; + else + description = NULL; + } gtk_tree_store_insert_with_values (ts, &iter, NULL, G_MAXINT, 0, ns_name, 1, nsid, 2, root, 3, description, -1); GNUNET_free (ns_name); diff --git a/src/include/gnunet_gtk.h b/src/include/gnunet_gtk.h index 4f3e2cd..2ce6447 100644 --- a/src/include/gnunet_gtk.h +++ b/src/include/gnunet_gtk.h @@ -117,6 +117,34 @@ GNUNET_GTK_tray_icon_create (GtkWindow * main, const char *icon_name, void GNUNET_GTK_tray_icon_destroy (void); +char * +GNUNET_GTK_from_utf8_to_loc (gchar *str_utf8); + +char * +GNUNET_GTK_from_loc_to_utf8 (gchar *str_loc); + +char * +GNUNET_GTK_from_filename_to_utf8 (gchar *filename); + +char * +GNUNET_GTK_from_utf8_to_filename (gchar *str_utf8); + +char * +GNUNET_GTK_from_loc_to_filename (gchar *str_loc); + +char * +GNUNET_GTK_from_filename_to_loc (gchar *filename); + +/* Returns filename form filechooser, encoded in locale-dependent + * encoding, suitable to be given to CRT and/or GNUnet + */ +char * +GNUNET_GTK_filechooser_get_filename_loc (GtkFileChooser *fc); + +gchar * +GNUNET_GTK_filechooser_get_filename_utf8 (GtkFileChooser *fc); + + /* ******************* main loop ***************** */ diff --git a/src/lib/nls.c b/src/lib/nls.c index a040f8e..f313ce5 100644 --- a/src/lib/nls.c +++ b/src/lib/nls.c @@ -53,4 +53,171 @@ GNUNET_GTK_setup_nls () #endif } + +char * +GNUNET_GTK_from_utf8_to_loc (gchar *str_utf8) +{ + char *str_loc; + const char *loc_charset; + gboolean is_UTF8; + + if (NULL == str_utf8) + return NULL; + + is_UTF8 = g_get_charset (&loc_charset); + if (is_UTF8) + str_loc = GNUNET_strdup (str_utf8); + else + str_loc = GNUNET_STRINGS_from_utf8 (str_utf8, strlen (str_utf8), loc_charset); + + return str_loc; +} + +char * +GNUNET_GTK_from_loc_to_utf8 (gchar *str_loc) +{ + char *str_utf8; + const char *loc_charset; + gboolean is_UTF8; + + if (NULL == str_loc) + return NULL; + + is_UTF8 = g_get_charset (&loc_charset); + if (is_UTF8) + str_utf8 = GNUNET_strdup (str_loc); + else + str_utf8 = GNUNET_STRINGS_to_utf8 (str_loc, strlen (str_loc), loc_charset); + + return str_utf8; +} + +/* This is copied from GLib */ +static gboolean +get_filename_charset (const gchar **filename_charset) +{ + const gchar **charsets; + gboolean is_utf8; + + is_utf8 = g_get_filename_charsets (&charsets); + + if (filename_charset) + *filename_charset = charsets[0]; + + return is_utf8; +} + +char * +GNUNET_GTK_from_filename_to_utf8 (gchar *filename) +{ + char *str_utf8; + const char *filename_charset; + gboolean is_UTF8; + + if (NULL == filename) + return NULL; + + is_UTF8 = get_filename_charset (&filename_charset); + if (is_UTF8) + str_utf8 = GNUNET_strdup (filename); + else + str_utf8 = GNUNET_STRINGS_to_utf8 (filename, strlen (filename), filename_charset); + + return str_utf8; +} + +char * +GNUNET_GTK_from_utf8_to_filename (gchar *str_utf8) +{ + char *filename; + const char *filename_charset; + gboolean is_UTF8; + + if (NULL == str_utf8) + return NULL; + + is_UTF8 = get_filename_charset (&filename_charset); + if (is_UTF8) + filename = GNUNET_strdup (str_utf8); + else + filename = GNUNET_STRINGS_from_utf8 (str_utf8, strlen (str_utf8), filename_charset); + + return filename; +} + +char * +GNUNET_GTK_from_loc_to_filename (gchar *str_loc) +{ + char *filename; + const char *filename_charset; + const char *loc_charset; + gboolean is_filename_UTF8, is_loc_UTF8; + + if (NULL == str_loc) + return NULL; + + is_filename_UTF8 = get_filename_charset (&filename_charset); + is_loc_UTF8 = g_get_charset (&loc_charset); + if (is_filename_UTF8 && is_loc_UTF8) + filename = GNUNET_strdup (str_loc); + else if (is_filename_UTF8) + filename = GNUNET_STRINGS_to_utf8 (str_loc, strlen (str_loc), loc_charset); + else if (is_loc_UTF8) + filename = GNUNET_STRINGS_from_utf8 (str_loc, strlen (str_loc), filename_charset); + else + /* Pray that iconv() knows these charsets */ + filename = GNUNET_STRINGS_conv (str_loc, strlen (str_loc), loc_charset, filename_charset); + + return filename; +} + +char * +GNUNET_GTK_from_filename_to_loc (gchar *filename) +{ + char *str_loc; + const char *loc_charset; + const char *filename_charset; + gboolean is_loc_UTF8, is_filename_UTF8; + + if (NULL == filename) + return NULL; + + is_filename_UTF8 = get_filename_charset (&filename_charset); + is_loc_UTF8 = g_get_charset (&loc_charset); + if (is_loc_UTF8 && is_filename_UTF8) + str_loc = GNUNET_strdup (filename); + else if (is_loc_UTF8) + str_loc = GNUNET_STRINGS_to_utf8 (filename, strlen (filename), filename_charset); + else if (is_filename_UTF8) + str_loc = GNUNET_STRINGS_from_utf8 (filename, strlen (filename), loc_charset); + else + /* Pray that iconv() knows these charsets */ + str_loc = GNUNET_STRINGS_conv (filename, strlen (filename), filename_charset, loc_charset); + + return str_loc; +} + +/* Returns filename form filechooser, encoded in locale-dependent + * encoding, suitable to be given to CRT and/or GNUnet + */ +char * +GNUNET_GTK_filechooser_get_filename_loc (GtkFileChooser *fc) +{ + char *filename_loc; + gchar *filename = gtk_file_chooser_get_filename (fc); + filename_loc = GNUNET_GTK_from_filename_to_loc (filename); + g_free (filename); + return filename_loc; +} + +gchar * +GNUNET_GTK_filechooser_get_filename_utf8 (GtkFileChooser *fc) +{ + char *filename_utf8; + gchar *filename = gtk_file_chooser_get_filename (fc); + filename_utf8 = GNUNET_GTK_from_filename_to_utf8 (filename); + g_free (filename); + return filename_utf8; +} + /* end of nls.c */ -- 1.7.4