pspp-dev
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]