From: Ben Pfaff Date: Thu, 12 May 2011 05:36:45 +0000 (-0700) Subject: gui: Make File|Recent Files remember the correct encoding. X-Git-Tag: v0.7.9~289 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5592ebfc98cd6ca4285abf0771c877e3deb00ec8;p=pspp-builds.git gui: Make File|Recent Files remember the correct encoding. It's no good to have File|Open... able to open a file in any encoding if later pulling up the same file with File|Recent Files screws that up, so this commit fixes the problem by noting the charset in the file's mime-type. --- diff --git a/src/ui/gui/psppire-data-window.c b/src/ui/gui/psppire-data-window.c index 604bd566..10e3fed5 100644 --- a/src/ui/gui/psppire-data-window.c +++ b/src/ui/gui/psppire-data-window.c @@ -23,6 +23,7 @@ #include "data/session.h" #include "language/lexer/lexer.h" #include "libpspp/message.h" +#include "libpspp/str.h" #include "ui/gui/aggregate-dialog.h" #include "ui/gui/binomial-dialog.h" #include "ui/gui/chi-square-dialog.h" @@ -64,6 +65,7 @@ #include "ui/syntax-gen.h" #include "gl/c-strcase.h" +#include "gl/c-strcasestr.h" #include "gl/xvasprintf.h" #include @@ -359,8 +361,9 @@ name_has_suffix (const gchar *name) static gboolean load_file (PsppireWindow *de, const gchar *file_name) { - gchar *utf8_file_name; struct string filename; + gchar *utf8_file_name; + const char *mime_type; gchar *syntax; bool ok; @@ -378,10 +381,14 @@ load_file (PsppireWindow *de, const gchar *file_name) ok = execute_syntax (PSPPIRE_DATA_WINDOW (de), lex_reader_for_string (syntax)); g_free (syntax); - return ok; -} + mime_type = (name_has_por_suffix (file_name) + ? "application/x-spss-por" + : "application/x-spss-sav"); + add_most_recent (ds_cstr (&filename), mime_type); + return ok; +} /* Save DE to file */ static void @@ -756,21 +763,63 @@ on_recent_data_select (GtkMenuShell *menushell, g_free (file); } +static char * +charset_from_mime_type (const char *mime_type) +{ + const char *charset; + struct string s; + const char *p; + + if (mime_type == NULL) + return NULL; + + charset = c_strcasestr (mime_type, "charset="); + if (charset == NULL) + return NULL; + + ds_init_empty (&s); + p = charset + 8; + if (*p == '"') + { + /* Parse a "quoted-string" as defined by RFC 822. */ + for (p++; *p != '\0' && *p != '"'; p++) + { + if (*p != '\\') + ds_put_byte (&s, *p); + else if (*++p != '\0') + ds_put_byte (&s, *p); + } + } + else + { + /* Parse a "token" as defined by RFC 2045. */ + while (*p > 32 && *p < 127 && strchr ("()<>@,;:\\\"/[]?=", *p) == NULL) + ds_put_byte (&s, *p++); + } + if (!ds_is_empty (&s)) + return ds_steal_cstr (&s); + + ds_destroy (&s); + return NULL; +} + static void on_recent_files_select (GtkMenuShell *menushell, gpointer user_data) { + GtkRecentInfo *item; + char *encoding; + GtkWidget *se; gchar *file; - GtkWidget *se ; + /* Get the file name and its encoding. */ + item = gtk_recent_chooser_get_current_item (GTK_RECENT_CHOOSER (menushell)); + file = g_filename_from_uri (gtk_recent_info_get_uri (item), NULL, NULL); + encoding = charset_from_mime_type (gtk_recent_info_get_mime_type (item)); + gtk_recent_info_unref (item); - gchar *uri = - gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell)); - - file = g_filename_from_uri (uri, NULL, NULL); - - g_free (uri); + se = psppire_syntax_window_new (encoding); - se = psppire_syntax_window_new (NULL); + free (encoding); if ( psppire_window_load (PSPPIRE_WINDOW (se), file) ) gtk_widget_show (se); diff --git a/src/ui/gui/psppire-syntax-window.c b/src/ui/gui/psppire-syntax-window.c index 7459a41d..b117825f 100644 --- a/src/ui/gui/psppire-syntax-window.c +++ b/src/ui/gui/psppire-syntax-window.c @@ -867,6 +867,7 @@ syntax_load (PsppireWindow *window, const gchar *filename) GtkTextIter iter; PsppireSyntaxWindow *sw = PSPPIRE_SYNTAX_WINDOW (window); gchar *encoding; + char *mime_type; /* FIXME: What if it's a very big file ? */ if ( ! g_file_get_contents (filename, &text_locale, &len_locale, &err) ) @@ -897,6 +898,10 @@ syntax_load (PsppireWindow *window, const gchar *filename) free (text_utf8); + mime_type = xasprintf ("text/x-spss-syntax; charset=%s", sw->encoding); + add_most_recent (filename, mime_type); + free (mime_type); + return TRUE; } diff --git a/src/ui/gui/psppire-window.c b/src/ui/gui/psppire-window.c index 81fcb8c0..edaa3726 100644 --- a/src/ui/gui/psppire-window.c +++ b/src/ui/gui/psppire-window.c @@ -692,8 +692,6 @@ psppire_window_save_as (PsppireWindow *w) } } - -static void add_most_recent (const char *file_name); static void delete_recent (const char *file_name); gboolean @@ -713,7 +711,6 @@ psppire_window_load (PsppireWindow *w, const gchar *file) if ( ok ) { psppire_window_set_filename (w, file); - add_most_recent (file); w->dirty = FALSE; } else @@ -832,16 +829,31 @@ psppire_window_open (PsppireWindow *de) } -/* Puts FILE_NAME into the recent list. - If it's already in the list, it moves it to the top -*/ -static void -add_most_recent (const char *file_name) +/* Puts FILE_NAME (encoded in the glib file name encoding) into the recent list + with associated MIME_TYPE. If it's already in the list, it moves it to the + top. */ +void +add_most_recent (const char *file_name, const char *mime_type) { gchar *uri = g_filename_to_uri (file_name, NULL, NULL); if ( uri ) - gtk_recent_manager_add_item (gtk_recent_manager_get_default (), uri); + { + GtkRecentData recent_data; + + recent_data.display_name = NULL; + recent_data.description = NULL; + recent_data.mime_type = CONST_CAST (gchar *, mime_type); + recent_data.app_name = CONST_CAST (gchar *, g_get_application_name ()); + recent_data.app_exec = g_strjoin (" ", g_get_prgname (), "%u", NULL); + recent_data.groups = NULL; + recent_data.is_private = FALSE; + + gtk_recent_manager_add_full (gtk_recent_manager_get_default (), + uri, &recent_data); + + g_free (recent_data.app_exec); + } g_free (uri); } diff --git a/src/ui/gui/psppire-window.h b/src/ui/gui/psppire-window.h index 0aa913c1..b80f79d6 100644 --- a/src/ui/gui/psppire-window.h +++ b/src/ui/gui/psppire-window.h @@ -114,6 +114,7 @@ gboolean psppire_window_load (PsppireWindow *w, const gchar *file); void psppire_window_open (PsppireWindow *de); GtkWidget *psppire_window_file_chooser_dialog (PsppireWindow *toplevel); +void add_most_recent (const char *file_name, const char *mime_type); G_END_DECLS