[Xfce4-commits] <exo:master> Use GIO for file loading/saving in the item editor.

Nick Schermer nick at xfce.org
Sun Aug 30 17:52:02 CEST 2009


Updating branch refs/heads/master
         to e812468ea05ba805a82b61a6922f3c50a24e43be (commit)
       from 34e749f93ffac275444fe0d1a284bf85ea3314fa (commit)

commit e812468ea05ba805a82b61a6922f3c50a24e43be
Author: Nick Schermer <nick at xfce.org>
Date:   Sun Aug 30 13:58:11 2009 +0200

    Use GIO for file loading/saving in the item editor.
    
    This makes the editor work with URIs and basically all
    file locations GIO supports.
    Also improved the error reporting a bit.

 configure.in.in                       |    6 +-
 exo-desktop-item-edit/Makefile.am     |    4 +-
 exo-desktop-item-edit/exo-die-utils.c |  101 +++++++++++++-----------------
 exo-desktop-item-edit/exo-die-utils.h |    3 +-
 exo-desktop-item-edit/main.c          |  109 +++++++++++++++++++-------------
 5 files changed, 117 insertions(+), 106 deletions(-)

diff --git a/configure.in.in b/configure.in.in
index 0eab2fb..2a3a1aa 100644
--- a/configure.in.in
+++ b/configure.in.in
@@ -155,9 +155,9 @@ XDT_I18N([@LINGUAS@], [libexo-libexo_version_major().libexo_version_minor()])
 dnl ***********************************
 dnl *** Check for required packages ***
 dnl ***********************************
-XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.16.0])
-XDT_CHECK_PACKAGE([GIO], [gio-2.0], [2.16.0])
-XDT_CHECK_PACKAGE([GIO_UNIX], [gio-unix-2.0], [2.16.0])
+XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.18.0])
+XDT_CHECK_PACKAGE([GIO], [gio-2.0], [2.18.0])
+XDT_CHECK_PACKAGE([GIO_UNIX], [gio-unix-2.0], [2.18.0])
 XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.14.0])
 XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.16.0])
 XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.2.2])
diff --git a/exo-desktop-item-edit/Makefile.am b/exo-desktop-item-edit/Makefile.am
index 99438a3..b0180f8 100644
--- a/exo-desktop-item-edit/Makefile.am
+++ b/exo-desktop-item-edit/Makefile.am
@@ -29,7 +29,8 @@ exo_desktop_item_edit_SOURCES =						\
 exo_desktop_item_edit_CFLAGS =						\
 	$(GTK_CFLAGS)							\
 	$(GTHREAD_CFLAGS)						\
-	$(LIBXFCE4UTIL_CFLAGS)
+	$(LIBXFCE4UTIL_CFLAGS)						\
+	$(GIO_CFLAGS)
 
 exo_desktop_item_edit_LDFLAGS =						\
 	-no-undefined
@@ -42,6 +43,7 @@ exo_desktop_item_edit_LDADD =						\
 	$(GTK_LIBS)							\
 	$(GTHREAD_LIBS)							\
 	$(LIBXFCE4UTIL_LIBS)						\
+	$(GIO_LIBS)							\
 	$(top_builddir)/exo-support/libexo-support.la			\
 	$(top_builddir)/exo/libexo-$(LIBEXO_VERSION_API).la
 
diff --git a/exo-desktop-item-edit/exo-die-utils.c b/exo-desktop-item-edit/exo-die-utils.c
index 6b6950f..7ec4ce4 100644
--- a/exo-desktop-item-edit/exo-die-utils.c
+++ b/exo-desktop-item-edit/exo-die-utils.c
@@ -86,34 +86,34 @@ exo_die_g_key_file_set_locale_value (GKeyFile    *key_file,
 gboolean
 exo_die_g_key_file_save (GKeyFile    *key_file,
                          gboolean     create,
-                         const gchar *base,
+                         GFile       *base,
                          GError     **error)
 {
-  gsize  data_length;
-  gchar *filename;
-  gchar *data;
-  gchar *name;
-  gchar *s;
-  FILE  *fp;
-  gint   n;
-
-  g_return_val_if_fail (base != NULL, FALSE);
+  GFileType  file_type;
+  GFile     *file;
+  gchar     *name, *s;
+  gchar     *filename, *data;
+  gsize      length;
+  gboolean   result;
+  guint      n;
+
+  g_return_val_if_fail (G_IS_FILE (base), FALSE);
   g_return_val_if_fail (key_file != NULL, FALSE);
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
   /* check if we should create a new file */
   if (G_LIKELY (create))
     {
-      /* check base */
-      if (g_file_test (base, G_FILE_TEST_IS_REGULAR))
+      file_type = g_file_query_file_type (base, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL);
+      if (file_type == G_FILE_TYPE_REGULAR)
         {
-          /* we can override an existing file */
-          filename = g_strdup (base);
+          file = g_object_ref (G_OBJECT (base));
         }
-      else if (g_file_test (base, G_FILE_TEST_IS_DIR))
+      else if (file_type == G_FILE_TYPE_DIRECTORY)
         {
           /* determine the desktop entry name */
-          name = g_key_file_get_locale_string (key_file, "Desktop Entry", "Name", NULL, NULL);
+          name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
+                                               G_KEY_FILE_DESKTOP_KEY_NAME, NULL, NULL);
           if (G_UNLIKELY (name == NULL))
             name = g_strdup ("launcher");
 
@@ -122,76 +122,63 @@ exo_die_g_key_file_save (GKeyFile    *key_file,
             if (G_IS_DIR_SEPARATOR (*s) || *s == '.')
               *s = '_';
 
-          /* try to transform name to local encoding */
-          s = g_filename_from_utf8 (name, -1, NULL, NULL, NULL);
-          if (G_LIKELY (s != NULL))
-            {
-              /* use the local name */
-              g_free (name);
-              name = s;
-            }
-
-          /* try to come up with a unique file name */
-          filename = g_strconcat (base, G_DIR_SEPARATOR_S, name, ".desktop", NULL);
-          for (n = 0; g_file_test (filename, G_FILE_TEST_EXISTS); ++n)
+          /* create a unique filename */
+          filename = g_strconcat (name, ".desktop", NULL);
+          file = g_file_get_child_for_display_name (base, filename, error);
+          for (n = 0; file != NULL && g_file_query_exists (file, NULL); n++)
             {
               /* release the previous name */
               g_free (filename);
+              g_object_unref (G_OBJECT (file));
 
               /* generate a new file name */
-              filename = g_strdup_printf ("%s%s%s%d.desktop", base, G_DIR_SEPARATOR_S, name, n);
+              filename = g_strdup_printf ("%s%d.desktop", name, n);
+              file = g_file_get_child_for_display_name (base, filename, error);
             }
 
-          /* release the name */
+          /* cleanup */
+          g_free (filename);
           g_free (name);
+
+          if (G_UNLIKELY (file == NULL))
+            return FALSE;
         }
       else
         {
           /* base is not a directory, cannot save */
-          g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (ENOTDIR), "%s", g_strerror (ENOTDIR));
+          g_set_error_literal (error, G_FILE_ERROR, g_file_error_from_errno (ENOTDIR),
+                               _("File location is not a regular file or directory"));
           return FALSE;
         }
     }
   else
     {
-      /* base is the filename */
-      filename = g_strdup (base);
+      /* base is the file */
+      file = g_object_ref (G_OBJECT (base));
     }
 
   /* determine the data for the key file */
-  data = g_key_file_to_data (key_file, &data_length, error);
+  data = g_key_file_to_data (key_file, &length, error);
   if (G_UNLIKELY (data == NULL))
     {
-      g_free (filename);
-      return FALSE;
-    }
-
-  /* try to open the file for writing */
-  fp = fopen (filename, "w");
-  if (G_UNLIKELY (fp == NULL))
-    {
-      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno));
-      g_free (filename);
-      g_free (data);
+      g_object_unref (G_OBJECT (file));
       return FALSE;
     }
 
-  /* try to write the data to the file */
-  if (fwrite (data, data_length, 1, fp) != 1)
-    {
-      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno));
-      g_free (filename);
-      g_free (data);
-      fclose (fp);
-      return FALSE;
-    }
+  /* write the contents to the file */
+  result = g_file_replace_contents (file, data, length, NULL, FALSE,
+#if GLIB_CHECK_VERSION (2, 20, 0)
+                                    G_FILE_CREATE_REPLACE_DESTINATION,
+#else
+                                    G_FILE_CREATE_NONE,
+#endif
+                                    NULL, NULL, error);
 
   /* cleanup */
-  g_free (filename);
   g_free (data);
-  fclose (fp);
+  g_object_unref (G_OBJECT (file));
 
-  return TRUE;
+  return result;
 }
 
 
diff --git a/exo-desktop-item-edit/exo-die-utils.h b/exo-desktop-item-edit/exo-die-utils.h
index 6169edd..1ef5414 100644
--- a/exo-desktop-item-edit/exo-die-utils.h
+++ b/exo-desktop-item-edit/exo-die-utils.h
@@ -22,6 +22,7 @@
 #define __EXO_DIE_UTILS_H__
 
 #include <exo/exo.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
@@ -32,7 +33,7 @@ void      exo_die_g_key_file_set_locale_value (GKeyFile    *key_file,
 
 gboolean  exo_die_g_key_file_save             (GKeyFile    *key_file,
                                                gboolean     create,
-                                               const gchar *base,
+                                               GFile       *base,
                                                GError     **error);
 
 G_END_DECLS
diff --git a/exo-desktop-item-edit/main.c b/exo-desktop-item-edit/main.c
index 5c99353..8183210 100644
--- a/exo-desktop-item-edit/main.c
+++ b/exo-desktop-item-edit/main.c
@@ -25,7 +25,9 @@
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
+#ifdef HAVE_STDIO_H
 #include <stdio.h>
+#endif
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
@@ -33,8 +35,7 @@
 #include <string.h>
 #endif
 
-#include <glib/gstdio.h>
-
+#include <gio/gio.h>
 #include <exo-desktop-item-edit/exo-die-editor.h>
 #include <exo-desktop-item-edit/exo-die-utils.h>
 
@@ -102,13 +103,16 @@ main (int argc, char **argv)
   GtkWidget       *editor;
   GKeyFile        *key_file;
   GError          *error = NULL;
-  gchar           *filename;
-  gchar           *currentname;
-  gchar           *dirname;
+  gchar           *base_name;
   gchar           *value;
   gchar           *s;
   gint             response;
   gint             result = EXIT_SUCCESS;
+  GFile           *gfile, *gfile_parent;
+  gchar           *contents;
+  gsize            length = 0;
+  gboolean         res;
+  GFileType        file_type;
 
   /* setup translation domain */
   xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
@@ -131,20 +135,16 @@ main (int argc, char **argv)
       if (G_UNLIKELY (error != NULL))
         {
           /* use the supplied error message */
-          s = g_strdup (error->message);
+          g_critical ("%s", error->message);
           g_error_free (error);
         }
       else
         {
           /* no error message, the GUI initialization failed */
-          s = g_strdup_printf ("%s: %s", _("Failed to open display"),
-                               STR_FB (gdk_get_display_arg_name (), " "));
+          g_critical ("%s %s", _("Failed to open display"),
+                      STR_FB (gdk_get_display_arg_name (), ""));
         }
 
-      /* tell the user about it */
-      g_fprintf (stderr, "%s: %s\n", g_get_prgname (), s);
-      g_free (s);
-
       /* and fail */
       return EXIT_FAILURE;
     }
@@ -168,12 +168,13 @@ main (int argc, char **argv)
   /* verify that a file/folder is specified */
   if (G_UNLIKELY (argc != 2))
     {
-      g_fprintf (stderr, "%s: %s\n", g_get_prgname (), _("No file/folder specified"));
+      g_critical (_("No file/folder specified"));
       return EXIT_FAILURE;
     }
 
   /* allocate a key file */
   key_file = g_key_file_new ();
+  gfile = g_file_new_for_commandline_arg (argv[1]);
 
   /* create new key file if --create-new was specified */
   if (G_LIKELY (opt_create_new))
@@ -206,11 +207,32 @@ main (int argc, char **argv)
     }
   else
     {
-      /* try to parse the specified desktop file */
-      if (!g_key_file_load_from_file (key_file, argv[1], G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error))
+      /* try to load the entire file into memory */
+      res = g_file_load_contents (gfile, NULL, &contents, &length, NULL, &error);
+      if (G_UNLIKELY (!res || length == 0))
         {
           /* we cannot open the file */
-          g_fprintf (stderr, "%s: %s: %s\n", g_get_prgname (), argv[1], error->message);
+          if (G_LIKELY (error != NULL))
+            {
+              g_critical (_("Failed to load contents from \"%s\": %s"), argv[1], error->message);
+              g_error_free (error);
+            }
+          else
+            {
+              g_critical (_("The file \"%s\" contains no data"), argv[1]);
+            }
+
+          return EXIT_FAILURE;
+        }
+
+      /* load the data into the key file */
+      res = g_key_file_load_from_data (key_file, contents, length, G_KEY_FILE_KEEP_COMMENTS
+                                       | G_KEY_FILE_KEEP_TRANSLATIONS, &error);
+      g_free (contents);
+      if (G_UNLIKELY (!res))
+        {
+          /* failed to parse the file */
+          g_critical (_("Failed to parse contents of \"%s\": %s"), argv[1], error->message);
           g_error_free (error);
           return EXIT_FAILURE;
         }
@@ -218,12 +240,11 @@ main (int argc, char **argv)
 
   /* determine the type of the desktop file */
   value = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP,
-                                 G_KEY_FILE_DESKTOP_KEY_TYPE, &error);
+                                 G_KEY_FILE_DESKTOP_KEY_TYPE, NULL);
   if (G_UNLIKELY (value == NULL))
     {
       /* we cannot continue without a type */
-      g_fprintf (stderr, "%s: %s: %s\n", g_get_prgname (), argv[1], error->message);
-      g_error_free (error);
+      g_critical (_("File \"%s\" has no type key"), argv[1]);
       return EXIT_FAILURE;
     }
 
@@ -233,11 +254,7 @@ main (int argc, char **argv)
   if (G_UNLIKELY (enum_value == NULL))
     {
       /* tell the user that we don't support the type */
-      s = g_strdup_printf (_("Unsupported desktop file type \"%s\""), value);
-      g_fprintf (stderr, "%s: %s: %s\n", g_get_prgname (), argv[1], s);
-      g_free (s);
-
-      /* and fail */
+      g_critical (_("Unsupported desktop file type \"%s\""), value);
       return EXIT_FAILURE;
     }
   g_free (value);
@@ -341,9 +358,6 @@ main (int argc, char **argv)
     }
 #endif
 
-  /* default to base as file/foldername */
-  filename = g_strdup (argv[1]);
-
   /* run the dialog */
   response = gtk_dialog_run (GTK_DIALOG (dialog));
   if (response == GTK_RESPONSE_ACCEPT)
@@ -390,7 +404,7 @@ main (int argc, char **argv)
         }
 
       /* try to save the file */
-      if (!exo_die_g_key_file_save (key_file, opt_create_new, filename, &error) && opt_create_new)
+      if (!exo_die_g_key_file_save (key_file, opt_create_new, gfile, &error) && opt_create_new)
         {
           /* reset the error */
           g_clear_error (&error);
@@ -405,20 +419,26 @@ main (int argc, char **argv)
           gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), TRUE);
           gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (chooser), TRUE);
 
+          file_type = g_file_query_file_type (gfile, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL);
+
           /* if base is a folder, enter the folder */
-          if (g_file_test (filename, G_FILE_TEST_IS_DIR))
+          if (file_type == G_FILE_TYPE_DIRECTORY)
             {
-              gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), filename);
+              gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (chooser), gfile, NULL);
               gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (chooser), "new-file.desktop");
             }
-          else if (g_path_is_absolute (filename))
+          else if (file_type == G_FILE_TYPE_REGULAR)
             {
-              dirname = g_path_get_dirname (filename);
-              currentname = g_path_get_basename (filename);
-              gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), dirname);
-              gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (chooser), currentname);
-              g_free (currentname);
-              g_free (dirname);
+              gfile_parent = g_file_get_parent (gfile);
+              if (G_LIKELY (gfile_parent != NULL))
+                {
+                  gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (chooser), gfile_parent, NULL);
+                  g_object_unref (G_OBJECT (gfile_parent));
+                }
+
+              base_name = g_file_get_basename (gfile);
+              gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (chooser), base_name);
+              g_free (base_name);
             }
 
           /* run the chooser */
@@ -426,13 +446,12 @@ main (int argc, char **argv)
           if (G_LIKELY (response == GTK_RESPONSE_ACCEPT))
             {
               /* release the previous file name */
-              g_free (filename);
-
-              /* determine the new file name */
-              filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
+              if (G_LIKELY (gfile != NULL))
+                g_object_unref (G_OBJECT (gfile));
 
               /* try again to save to the new file */
-              exo_die_g_key_file_save (key_file, FALSE, filename, &error);
+              gfile = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (chooser));
+              exo_die_g_key_file_save (key_file, FALSE, gfile, &error);
             }
 
           /* destroy the chooser */
@@ -443,16 +462,18 @@ main (int argc, char **argv)
       if (G_UNLIKELY (response == GTK_RESPONSE_ACCEPT && error != NULL))
         {
           /* display an error message to the user */
+          s = g_file_get_uri (gfile);
           message = gtk_message_dialog_new (GTK_WINDOW (dialog),
                                             GTK_DIALOG_DESTROY_WITH_PARENT
                                             | GTK_DIALOG_MODAL,
                                             GTK_MESSAGE_ERROR,
                                             GTK_BUTTONS_CLOSE,
                                             opt_create_new ? _("Failed to create \"%s\".") : _("Failed to save \"%s\"."),
-                                            filename);
+                                            s);
           gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), "%s.", error->message);
           gtk_dialog_run (GTK_DIALOG (message));
           gtk_widget_destroy (message);
+          g_free (s);
 
           /* jep, we failed */
           result = EXIT_FAILURE;
@@ -467,7 +488,7 @@ main (int argc, char **argv)
 
   /* cleanup */
   g_key_file_free (key_file);
-  g_free (filename);
+  g_object_unref (G_OBJECT (gfile));
 
   return result;
 }



More information about the Xfce4-commits mailing list