[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug33254 6/6] gui: Make File|Recent Files remember the correct encoding
From: |
Ben Pfaff |
Subject: |
[bug33254 6/6] gui: Make File|Recent Files remember the correct encoding. |
Date: |
Wed, 11 May 2011 22:42:07 -0700 |
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.
---
src/ui/gui/psppire-data-window.c | 71 ++++++++++++++++++++++++++++++------
src/ui/gui/psppire-syntax-window.c | 5 +++
src/ui/gui/psppire-window.c | 30 +++++++++++-----
src/ui/gui/psppire-window.h | 1 +
4 files changed, 87 insertions(+), 20 deletions(-)
diff --git a/src/ui/gui/psppire-data-window.c b/src/ui/gui/psppire-data-window.c
index 604bd56..10e3fed 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 <gettext.h>
@@ -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 7459a41..b117825 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 81fcb8c..edaa372 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 0aa913c..b80f79d 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
--
1.7.2.5
- [bug33254 1/6] encoding-guesser: New function encoding_guess_whole_file()., Ben Pfaff, 2011/05/12
- [bug33254 6/6] gui: Make File|Recent Files remember the correct encoding.,
Ben Pfaff <=
- [bug33254 2/6] i18n: New function is_encoding_supported()., Ben Pfaff, 2011/05/12
- [bug33254 3/6] gui: Move null_if_empty_param() from psppire-window to helper., Ben Pfaff, 2011/05/12
- [bug33254 5/6] gui: Recode syntax files on load and save., Ben Pfaff, 2011/05/12
- [bug33254 4/6] gui: Refactor checking for .sav and .por suffixes., Ben Pfaff, 2011/05/12
- Re: [bug33254 1/6] encoding-guesser: New function encoding_guess_whole_file()., John Darrington, 2011/05/12